]> arthur.barton.de Git - netatalk.git/blobdiff - etc/uams/uams_dhx2_pam.c
IPv6 support for afpd and cnid_metad
[netatalk.git] / etc / uams / uams_dhx2_pam.c
index bcd858cb93e99fa4215985fee5ca80e830de65cd..dae84673a3ea8935c373fe284cb6419b358a58a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: uams_dhx2_pam.c,v 1.1 2008-11-22 12:07:26 didg Exp $
+ * $Id: uams_dhx2_pam.c,v 1.9 2009-11-05 14:38:07 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
@@ -63,7 +63,7 @@ static struct passwd *dhxpwd;
 
 /*********************************************************
  * Crypto helper func to generate p and g for use in DH.
- * libgcrpyt doesn't provide one directly.
+ * libgcrypt doesn't provide one directly.
  * Algorithm taken from GNUTLS:gnutls_dh_primes.c 
  *********************************************************/
 
@@ -253,20 +253,13 @@ static struct pam_conv PAM_conversation = {
 };
 
 
-static int dhx2_setup(void *obj, char *ibuf, int ibuflen _U_,
-                     char *rbuf, int *rbuflen)
+static int dhx2_setup(void *obj, char *ibuf _U_, size_t ibuflen _U_,
+                     char *rbuf, size_t *rbuflen)
 {
-    int i, ret;
-
-    unsigned int g_uint;
+    int ret;
+    size_t nwritten;
     gcry_mpi_t g, Ma;
     char *Ra_binary = NULL;
-    gcry_cipher_hd_t ctx;
-    gcry_error_t ctxerror;
-
-    const int g_len = 4;
-    size_t len;
-    size_t nwritten;
 
     *rbuflen = 0;
 
@@ -307,7 +300,7 @@ static int dhx2_setup(void *obj, char *ibuf, int ibuflen _U_,
     *rbuflen += 2;
 
     /* g is next */
-    gcry_mpi_print( GCRYMPI_FMT_USG, rbuf, 4, &nwritten, g);
+    gcry_mpi_print( GCRYMPI_FMT_USG, (unsigned char *)rbuf, 4, &nwritten, g);
     if (nwritten < 4) {
        memmove( rbuf+4-nwritten, rbuf, nwritten);
        memset( rbuf, 0, 4-nwritten);
@@ -321,15 +314,15 @@ static int dhx2_setup(void *obj, char *ibuf, int ibuflen _U_,
     *rbuflen += 2;
 
     /* p */
-    gcry_mpi_print( GCRYMPI_FMT_USG, rbuf, PRIMEBITS/8, NULL, p);
+    gcry_mpi_print( GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS/8, NULL, p);
     rbuf += PRIMEBITS/8;
     *rbuflen += PRIMEBITS/8;
 
     /* Ma */
-    gcry_mpi_print( GCRYMPI_FMT_USG, rbuf, PRIMEBITS/8, &len, Ma);
-    if (len < PRIMEBITS/8) {
-       memmove(rbuf + (PRIMEBITS/8) - len, rbuf, len);
-       memset(rbuf, 0, (PRIMEBITS/8) - len);
+    gcry_mpi_print( GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS/8, &nwritten, Ma);
+    if (nwritten < PRIMEBITS/8) {
+       memmove(rbuf + (PRIMEBITS/8) - nwritten, rbuf, nwritten);
+       memset(rbuf, 0, (PRIMEBITS/8) - nwritten);
     }
     rbuf += PRIMEBITS/8;
     *rbuflen += PRIMEBITS/8;
@@ -345,8 +338,8 @@ error:                              /* We exit here anyway */
 
 /* -------------------------------- */
 static int login(void *obj, char *username, int ulen,  struct passwd **uam_pwd _U_,
-                 char *ibuf, int ibuflen,
-                 char *rbuf, int *rbuflen)
+                 char *ibuf, size_t ibuflen,
+                 char *rbuf, size_t *rbuflen)
 {
     if (( dhxpwd = uam_getname(obj, username, ulen)) == NULL ) {
         LOG(log_info, logtype_uams, "DHX2: unknown username");
@@ -362,11 +355,11 @@ static int login(void *obj, char *username, int ulen,  struct passwd **uam_pwd _
 /* dhx login: things are done in a slightly bizarre order to avoid
  * having to clean things up if there's an error. */
 static int pam_login(void *obj, struct passwd **uam_pwd,
-                     char *ibuf, int ibuflen,
-                     char *rbuf, int *rbuflen)
+                     char *ibuf, size_t ibuflen,
+                     char *rbuf, size_t *rbuflen)
 {
     char *username;
-    int len, ulen;
+    size_t len, ulen;
 
     *rbuflen = 0;
 
@@ -396,11 +389,11 @@ static int pam_login(void *obj, struct passwd **uam_pwd,
 
 /* ----------------------------- */
 static int pam_login_ext(void *obj, char *uname, struct passwd **uam_pwd,
-                         char *ibuf, int ibuflen,
-                         char *rbuf, int *rbuflen)
+                         char *ibuf, size_t ibuflen,
+                         char *rbuf, size_t *rbuflen)
 {
     char *username;
-    int len, ulen;
+    size_t len, ulen;
     u_int16_t  temp16;
 
     *rbuflen = 0;
@@ -431,19 +424,18 @@ static int pam_login_ext(void *obj, char *uname, struct passwd **uam_pwd,
 
 /* -------------------------------- */
 
-static int logincont1(void *obj, char *ibuf, int ibuflen, char *rbuf, int *rbuflen)
+static int logincont1(void *obj _U_, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 {
-    u_int16_t retID;
-    size_t nwritten;
     int ret;
-    *rbuflen = 0;
-
+    size_t nwritten;
     gcry_mpi_t Mb, K, clientNonce;
-    char *K_bin = NULL;
+    unsigned char *K_bin = NULL;
     char serverNonce_bin[16];
     gcry_cipher_hd_t ctx;
     gcry_error_t ctxerror;
 
+    *rbuflen = 0;
+
     Mb = gcry_mpi_new(0);
     K = gcry_mpi_new(0);
     clientNonce = gcry_mpi_new(0);
@@ -531,7 +523,7 @@ static int logincont1(void *obj, char *ibuf, int ibuflen, char *rbuf, int *rbufl
     *rbuflen += 2;
 
     /* Client nonce + 1 */
-    gcry_mpi_print(GCRYMPI_FMT_USG, rbuf, PRIMEBITS/8, NULL, clientNonce);
+    gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char *)rbuf, PRIMEBITS/8, NULL, clientNonce);
     /* Server nonce */
     memcpy(rbuf+16, serverNonce_bin, 16);
 
@@ -569,21 +561,21 @@ exit:
 }
 
 static int logincont2(void *obj, struct passwd **uam_pwd,
-                     char *ibuf, int ibuflen,
-                     char *rbuf, int *rbuflen)
+                     char *ibuf, size_t ibuflen,
+                     char *rbuf _U_, size_t *rbuflen)
 {
     int ret;
     int PAM_error;
-    char *hostname = NULL;
+    const char *hostname = NULL;
     gcry_mpi_t retServerNonce;
     gcry_cipher_hd_t ctx;
     gcry_error_t ctxerror;
 
     *rbuflen = 0;
 
-    /* Packet size should be: Session ID + ServerNonce + Passwd buffer */
-    if (ibuflen != 2 + 16 + 256) {
-        LOG(log_error, logtype_uams, "DHX2: Paket length not correct");
+    /* Packet size should be: Session ID + ServerNonce + Passwd buffer (evantually +10 extra bytes, see Apples Docs) */
+    if ((ibuflen != 2 + 16 + 256) && (ibuflen != 2 + 16 + 256 + 10)) {
+        LOG(log_error, logtype_uams, "DHX2: Paket length not correct: %u. Should be 274 or 284.", ibuflen);
         ret = AFPERR_PARAM;
         goto error_noctx;
     }
@@ -707,8 +699,8 @@ error_noctx:
 }
 
 static int pam_logincont(void *obj, struct passwd **uam_pwd,
-                         char *ibuf, int ibuflen,
-                         char *rbuf, int *rbuflen)
+                         char *ibuf, size_t ibuflen,
+                         char *rbuf, size_t *rbuflen)
 {
     u_int16_t retID;
     int ret;
@@ -728,7 +720,7 @@ static int pam_logincont(void *obj, struct passwd **uam_pwd,
 
 
 /* logout */
-static void pam_logout() {
+static void pam_logout(void) {
     pam_close_session(pamh, 0);
     pam_end(pamh, 0);
     pamh = NULL;
@@ -738,34 +730,30 @@ static void pam_logout() {
  * --- Change pwd stuff --- */
 
 static int changepw_1(void *obj, char *uname,
-                     char *ibuf, int ibuflen, char *rbuf, int *rbuflen)
+                     char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 {
-    unsigned int len;
     *rbuflen = 0;
 
     /* Remember it now, use it in changepw_3 */
     PAM_username = uname;
-    LOG(log_error, logtype_uams, "DHX2 ChangePW: packet 1 processin for user: %s",PAM_username);
-
     return( dhx2_setup(obj, ibuf, ibuflen, rbuf, rbuflen) );
 }
 
 static int changepw_2(void *obj, 
-                     char *ibuf, int ibuflen, char *rbuf, int *rbuflen)
+                     char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen)
 {
-    LOG(log_error, logtype_uams, "DHX2 ChangePW: packet 2 processing");
     return( logincont1(obj, ibuf, ibuflen, rbuf, rbuflen) );
 }
 
 static int changepw_3(void *obj _U_,
-                     char *ibuf, int ibuflen _U_, 
-                     char *rbuf _U_, int *rbuflen _U_)
+                     char *ibuf, size_t ibuflen _U_, 
+                     char *rbuf _U_, size_t *rbuflen _U_)
 {
     int ret;
     int PAM_error;
     uid_t uid;
     pam_handle_t *lpamh;
-    char *hostname = NULL;
+    const char *hostname = NULL;
     gcry_mpi_t retServerNonce;
     gcry_cipher_hd_t ctx;
     gcry_error_t ctxerror;
@@ -829,9 +817,6 @@ static int changepw_3(void *obj _U_,
     ibuf[255] = '\0';          /* For safety */
     ibuf[511] = '\0';
 
-    LOG(log_info, logtype_uams, "DHX2 Chgpwd: new pwd \'%s\'",ibuf);
-    LOG(log_info, logtype_uams, "DHX2 Chgpwd: old pwd \'%s\'",ibuf+256);
-
     /* check if new and old password are equal */
     if (memcmp(ibuf, ibuf + 256, 255) == 0) {
        LOG(log_info, logtype_uams, "DHX2 Chgpwd: new and old password are equal");
@@ -876,7 +861,6 @@ static int changepw_3(void *obj _U_,
 error_ctx:
     gcry_cipher_close(ctx);
 error_noctx:
-exit:
     free(K_MD5hash);
     K_MD5hash=NULL;
     gcry_mpi_release(serverNonce);
@@ -885,26 +869,24 @@ exit:
 }
 
 static int dhx2_changepw(void *obj _U_, char *uname,
-                        struct passwd *pwd _U_, char *ibuf, int ibuflen _U_,
-                        char *rbuf _U_, int *rbuflen _U_)
+                        struct passwd *pwd _U_, char *ibuf, size_t ibuflen _U_,
+                        char *rbuf _U_, size_t *rbuflen _U_)
 {
     /* We use this to serialize the three incoming FPChangePassword calls */
     static int dhx2_changepw_status = 1;
 
-    int ret;
-
-    LOG(log_error, logtype_uams, "DHX2 ChangePW: Start!");
+    int ret = AFPERR_NOTAUTH;  /* gcc can't figure out it's always initialized */
 
     switch (dhx2_changepw_status) {
     case 1:
        ret = changepw_1( obj, uname, ibuf, ibuflen, rbuf, rbuflen);
        if ( ret == AFPERR_AUTHCONT)
-           dhx2_changepw_status += 1;
+           dhx2_changepw_status = 2;
        break;
     case 2:
        ret = changepw_2( obj, ibuf, ibuflen, rbuf, rbuflen);
         if ( ret == AFPERR_AUTHCONT)
-            dhx2_changepw_status += 1;
+            dhx2_changepw_status = 3;
        else
            dhx2_changepw_status = 1;
        break;