X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/a6a073be4aea5e0a1ca2e55920d0f97c8a5f273a..5be8db81:/mts/smtp/smtp.c?ds=inline diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c index 4f929cae..e6ac1661 100644 --- a/mts/smtp/smtp.c +++ b/mts/smtp/smtp.c @@ -9,7 +9,6 @@ #include #include "smtp.h" #include -#include #include #ifdef CYRUS_SASL @@ -26,7 +25,6 @@ #include #include #include -#include #endif /* CYRUS_SASL */ #ifdef TLS_SUPPORT @@ -99,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 char *sasl_pw_context[2]; /* 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 */ @@ -109,10 +106,10 @@ static int sm_get_pass(sasl_conn_t *, void *, int, sasl_secret_t **); static sasl_callback_t callbacks[] = { { SASL_CB_USER, (sasl_callback_ft) sm_get_user, NULL }, #define SM_SASL_N_CB_USER 0 - { SASL_CB_PASS, (sasl_callback_ft) sm_get_pass, NULL }, -#define SM_SASL_N_CB_PASS 1 { SASL_CB_AUTHNAME, (sasl_callback_ft) sm_get_user, NULL }, -#define SM_SASL_N_CB_AUTHNAME 2 +#define SM_SASL_N_CB_AUTHNAME 1 + { SASL_CB_PASS, (sasl_callback_ft) sm_get_pass, NULL }, +#define SM_SASL_N_CB_PASS 2 { SASL_CB_LIST_END, NULL, NULL }, }; @@ -144,20 +141,19 @@ static int tls_active = 0; static char *sm_noreply = "No reply text given"; static char *sm_moreply = "; "; - -struct smtp sm_reply; /* global... */ +static struct smtp sm_reply; #define MAXEHLO 20 static int doingEHLO; -char *EHLOkeys[MAXEHLO + 1]; +static char *EHLOkeys[MAXEHLO + 1]; /* * static prototypes */ -static int smtp_init (char *, char *, char *, int, int, int, int, int, int, +static int smtp_init (char *, char *, char *, int, int, int, int, int, char *, char *, int); -static int sendmail_init (char *, char *, int, int, int, int, int, int, +static int sendmail_init (char *, char *, int, int, int, int, int, char *, char *); static int rclient (char *, char *); @@ -187,22 +183,19 @@ static int sm_auth_sasl(char *, int, char *, char *); int sm_init (char *client, char *server, char *port, int watch, int verbose, - int debug, int queued, int sasl, int saslssf, - char *saslmech, char *user, int tls) + int debug, int sasl, int saslssf, char *saslmech, char *user, int tls) { if (sm_mts == MTS_SMTP) return smtp_init (client, server, port, watch, verbose, - debug, queued, sasl, saslssf, saslmech, - user, tls); + debug, sasl, saslssf, saslmech, user, tls); else return sendmail_init (client, server, watch, verbose, - debug, queued, sasl, saslssf, saslmech, - user); + debug, sasl, saslssf, saslmech, user); } static int smtp_init (char *client, char *server, char *port, int watch, int verbose, - int debug, int queued, + int debug, int sasl, int saslssf, char *saslmech, char *user, int tls) { int result, sd1, sd2; @@ -391,16 +384,13 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, send_options: ; if (watch && EHLOset ("XVRB")) smtalk (SM_HELO, "VERB on"); - if (queued && EHLOset ("XQUE")) - smtalk (SM_HELO, "QUED"); return RP_OK; } int sendmail_init (char *client, char *server, int watch, int verbose, - int debug, int queued, - int sasl, int saslssf, char *saslmech, char *user) + int debug, int sasl, int saslssf, char *saslmech, char *user) { unsigned int i, result, vecp; int pdi[2], pdo[2]; @@ -476,15 +466,13 @@ sendmail_init (char *client, char *server, int watch, int verbose, vecp = 0; vec[vecp++] = r1bindex (sendmail, '/'); vec[vecp++] = "-bs"; - vec[vecp++] = watch ? "-odi" : queued ? "-odq" : "-odb"; + vec[vecp++] = watch ? "-odi" : "-odb"; vec[vecp++] = "-oem"; vec[vecp++] = "-om"; if (verbose) vec[vecp++] = "-ov"; vec[vecp++] = NULL; - setgid (getegid ()); - setuid (geteuid ()); execvp (sendmail, vec); fprintf (stderr, "unable to exec "); perror (sendmail); @@ -820,17 +808,12 @@ sm_auth_sasl(char *user, int saslssf, char *mechlist, char *inhost) sasl_security_properties_t secprops; sasl_ssf_t *ssf; int *outbufmax; + struct nmh_creds creds = { 0, 0, 0 }; /* * Initialize the callback contexts */ - if (user == NULL) - user = getusername(); - - callbacks[SM_SASL_N_CB_USER].context = user; - callbacks[SM_SASL_N_CB_AUTHNAME].context = user; - /* * This is a _bit_ of a hack ... but if the hostname wasn't supplied * to us on the command line, then call getpeername and do a @@ -861,10 +844,13 @@ sm_auth_sasl(char *user, int saslssf, char *mechlist, char *inhost) strncpy(host, inhost, sizeof(host) - 1); } - sasl_pw_context[0] = host; - sasl_pw_context[1] = user; - - 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); @@ -963,7 +949,6 @@ sm_auth_sasl(char *user, int saslssf, char *mechlist, char *inhost) } else { result = sasl_decode64(sm_reply.text, sm_reply.length, outbuf, sizeof(outbuf), &outlen); - if (result != SASL_OK) { smtalk(SM_AUTH, "*"); sm_ierror("SASL base64 decode failed: %s", @@ -1055,14 +1040,27 @@ 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) { - 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; - *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. + */ + if (nmh_get_credentials (creds->host, creds->user, 1, creds) != OK) { + return SASL_BADPARAM; + } + } + + *result = creds->user; if (len) - *len = strlen(user); + *len = strlen(creds->user); return SASL_OK; } @@ -1071,8 +1069,7 @@ static int sm_get_pass(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret) { - char **pw_context = (char **) context; - char *pass = NULL; + nmh_creds_t creds = (nmh_creds_t) context; int len; NMH_UNUSED (conn); @@ -1080,20 +1077,26 @@ sm_get_pass(sasl_conn_t *conn, void *context, int id, if (! psecret || id != SASL_CB_PASS) return SASL_BADPARAM; - ruserpass(pw_context[0], &(pw_context[1]), &pass); - - len = strlen(pass); + 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't used. + */ + if (nmh_get_credentials (creds->host, creds->user, 0, creds) != OK) { + return SASL_BADPARAM; + } + } - *psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len); + len = strlen (creds->password); - if (! *psecret) { - free(pass); + if (! (*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len))) { return SASL_NOMEM; } (*psecret)->len = len; - strcpy((char *) (*psecret)->data, pass); -/* free(pass); */ + strcpy((char *) (*psecret)->data, creds->password); return SASL_OK; } @@ -1273,7 +1276,8 @@ tls_negotiate(void) method = TLSv1_client_method(); /* Not sure about this */ - sslctx = SSL_CTX_new(method); + /* Older ssl takes a non-const arg. */ + sslctx = SSL_CTX_new((SSL_METHOD *) method); if (! sslctx) { sm_end(NOTOK);