]> diplodocus.org Git - nmh/commitdiff
Reworked retrieval of username and password with SMTP and sasl so
authorDavid Levine <levinedl@acm.org>
Wed, 16 Apr 2014 01:58:32 +0000 (20:58 -0500)
committerDavid Levine <levinedl@acm.org>
Wed, 16 Apr 2014 01:58:32 +0000 (20:58 -0500)
that if getusername() and no password are accepted by the mechanism,
then the user need not provide them.

mts/smtp/smtp.c
sbr/credentials.c

index e4522f4a7c4757f82c0a7f6acb23ae100055d919..0261d6d6bed6b328b36be33974682609ed5cbfa0 100644 (file)
@@ -97,7 +97,6 @@ static FILE *sm_wfp = NULL;
 static sasl_conn_t *conn = NULL;       /* SASL connection state */
 static int sasl_complete = 0;          /* Has authentication succeded? */
 static sasl_ssf_t sasl_ssf;            /* Our security strength factor */
 static sasl_conn_t *conn = NULL;       /* SASL connection state */
 static int sasl_complete = 0;          /* Has authentication succeded? */
 static sasl_ssf_t sasl_ssf;            /* Our security strength factor */
-static char *sasl_pw_context[3];       /* Context to pass into sm_get_pass */
 static int maxoutbuf;                  /* Maximum crypto output buffer */
 static char *sasl_outbuffer;           /* SASL output buffer for encryption */
 static int sasl_outbuflen;             /* Current length of data in outbuf */
 static int maxoutbuf;                  /* Maximum crypto output buffer */
 static char *sasl_outbuffer;           /* SASL output buffer for encryption */
 static int sasl_outbuflen;             /* Current length of data in outbuf */
@@ -851,17 +850,13 @@ sm_auth_sasl(char *user, int saslssf, char *mechlist, char *inhost)
        strncpy(host, inhost, sizeof(host) - 1);
     }
 
        strncpy(host, inhost, sizeof(host) - 1);
     }
 
-    nmh_get_credentials (host, user, 0, &creds);
-
-    /* It's OK to copy the creds pointers here.  The callbacks that
-       use them will only be called before this function returns. */
-    callbacks[SM_SASL_N_CB_USER].context = creds.user;
-    callbacks[SM_SASL_N_CB_AUTHNAME].context = creds.user;
-    sasl_pw_context[0] = host;
-    sasl_pw_context[1] = creds.user;
-    sasl_pw_context[2] = creds.password;
-
-    callbacks[SM_SASL_N_CB_PASS].context = sasl_pw_context;
+    /* It's OK to copy the addresses here.  The callbacks that use
+       them will only be called before this function returns. */
+    creds.host = host;
+    creds.user = user;
+    callbacks[SM_SASL_N_CB_USER].context = &creds;
+    callbacks[SM_SASL_N_CB_AUTHNAME].context = &creds;
+    callbacks[SM_SASL_N_CB_PASS].context = &creds;
 
     result = sasl_client_init(callbacks);
 
 
     result = sasl_client_init(callbacks);
 
@@ -1051,14 +1046,25 @@ sm_auth_sasl(char *user, int saslssf, char *mechlist, char *inhost)
 static int
 sm_get_user(void *context, int id, const char **result, unsigned *len)
 {
 static int
 sm_get_user(void *context, int id, const char **result, unsigned *len)
 {
-    char *user = (char *) context;
+    nmh_creds_t creds = (nmh_creds_t) context;
 
     if (! result || ((id != SASL_CB_USER) && (id != SASL_CB_AUTHNAME)))
        return SASL_BADPARAM;
 
 
     if (! result || ((id != SASL_CB_USER) && (id != SASL_CB_AUTHNAME)))
        return SASL_BADPARAM;
 
-    *result = user;
+    if (creds->user == NULL) {
+        /*
+         * Pass the 1 third argument to nmh_get_credentials() so
+         * that a default user if the -user switch to send(1)/post(8)
+         * wasn't used, and so that a default password will be supplied.
+         * That's used when those values really don't matter, and only
+         * with legacy/.netrc, i.e., with a credentials profile entry.
+         */
+        nmh_get_credentials (creds->host, creds->user, 1, creds);
+    }
+
+    *result = creds->user;
     if (len)
     if (len)
-       *len = strlen(user);
+       *len = strlen(creds->user);
 
     return SASL_OK;
 }
 
     return SASL_OK;
 }
@@ -1067,7 +1073,7 @@ static int
 sm_get_pass(sasl_conn_t *conn, void *context, int id,
            sasl_secret_t **psecret)
 {
 sm_get_pass(sasl_conn_t *conn, void *context, int id,
            sasl_secret_t **psecret)
 {
-    char **pw_context = (char **) context;
+    nmh_creds_t creds = (nmh_creds_t) context;
     int len;
 
     NMH_UNUSED (conn);
     int len;
 
     NMH_UNUSED (conn);
@@ -1075,14 +1081,24 @@ sm_get_pass(sasl_conn_t *conn, void *context, int id,
     if (! psecret || id != SASL_CB_PASS)
        return SASL_BADPARAM;
 
     if (! psecret || id != SASL_CB_PASS)
        return SASL_BADPARAM;
 
-    len = strlen (pw_context[2]);
+    if (creds->password == NULL) {
+        /*
+         * Pass the 0 third argument to nmh_get_credentials() so
+         * that the default password isn't used.  With legacy/.netrc
+         * credentials support, we'll only get here if the -user
+         * switch to send(1)/post(8) wasn used.
+         */
+        nmh_get_credentials (creds->host, creds->user, 0, creds);
+    }
+
+    len = strlen (creds->password);
 
     if (! (*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len))) {
        return SASL_NOMEM;
     }
 
     (*psecret)->len = len;
 
     if (! (*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len))) {
        return SASL_NOMEM;
     }
 
     (*psecret)->len = len;
-    strcpy((char *) (*psecret)->data, pw_context[2]);
+    strcpy((char *) (*psecret)->data, creds->password);
 
     return SASL_OK;
 }
 
     return SASL_OK;
 }
index 9f3faa95eec3ee6c2efc872006167275436ab4cc..ae53a742b9b6ecc0f6bda3a63f2a791d585ce2a3 100644 (file)
@@ -49,9 +49,10 @@ nmh_get_credentials (char *host, char *user, int sasl, nmh_creds_t creds) {
 
     if (cred_style == NULL  ||  ! strcmp (cred_style, "legacy")) {
         if (sasl) {
 
     if (cred_style == NULL  ||  ! strcmp (cred_style, "legacy")) {
         if (sasl) {
+            creds->user = user == NULL  ?  getusername ()  :  user;
+
             /* This is what inc.c and msgchk.c used to contain. */
             /* Only inc.c and msgchk.c do this.  smtp.c doesn't. */
             /* This is what inc.c and msgchk.c used to contain. */
             /* Only inc.c and msgchk.c do this.  smtp.c doesn't. */
-            creds->user = user == NULL  ?  getusername ()  :  user;
             creds->password = getusername ();
         }
     } else if (! strncasecmp (cred_style, "file:", 5)) {
             creds->password = getusername ();
         }
     } else if (! strncasecmp (cred_style, "file:", 5)) {