X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/80f396c977d664dfb8d29411a3cd64393764c166..665dfc96:/mts/smtp/smtp.c?ds=sidebyside diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c index fdc56b06..b09fde33 100644 --- a/mts/smtp/smtp.c +++ b/mts/smtp/smtp.c @@ -1,5 +1,4 @@ -/* - * smtp.c -- nmh SMTP interface +/* smtp.c -- nmh SMTP interface * * This code is Copyright (c) 2002, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for @@ -42,20 +41,16 @@ #define NBITS ((sizeof (int)) * 8) -/* - * these codes must all be different! - */ +/* Timeout in seconds for SMTP commands. + * Lore has it they must be distinct. */ #define SM_OPEN 300 /* Changed to 5 minutes to comply with a SHOULD in RFC 1123 */ #define SM_HELO 20 #define SM_RSET 15 #define SM_MAIL 301 /* changed to 5 minutes and a second (for uniqueness), see above */ #define SM_RCPT 302 /* see above */ #define SM_DATA 120 /* see above */ -#define SM_TEXT 180 /* see above */ #define SM_DOT 600 /* see above */ #define SM_QUIT 30 -#define SM_CLOS 10 -#define SM_AUTH 45 static int sm_addrs = 0; static int sm_child = NOTOK; @@ -81,7 +76,7 @@ static int smtp_init (char *, char *, char *, int, int, int, int, const char *, static int sendmail_init (char *, int, int, int, int, const char *, const char *); -static int rclient (char *, char *); +static int rclient (char *, char *, char **); static int sm_ierror (const char *fmt, ...); static int sm_nerror (char *); static int smtalk (int time, char *fmt, ...); @@ -111,7 +106,7 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, const char *oauth_svc, int tls) { int result, sd1; - char *errstr; + char *errstr, *chosen_server; if (watch) verbose = TRUE; @@ -141,12 +136,21 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, if (user) netsec_set_userid(nsc, user); + if ((sd1 = rclient (server, port, &chosen_server)) == NOTOK) + return RP_BHST; + + SIGNAL (SIGPIPE, SIG_IGN); + + netsec_set_fd(nsc, sd1, sd1); + + netsec_set_hostname(nsc, chosen_server); + if (sm_debug) netsec_set_snoop(nsc, 1); if (sasl) { - if (netsec_set_sasl_params(nsc, server, "smtp", saslmech, - sm_sasl_callback, &errstr) != OK) + if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback, + &errstr) != OK) return sm_nerror(errstr); } @@ -155,25 +159,18 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, return sm_ierror("OAuth2 not supported"); } - if ((sd1 = rclient (server, port)) == NOTOK) - return RP_BHST; - - SIGNAL (SIGPIPE, SIG_IGN); - - netsec_set_fd(nsc, sd1, sd1); - - if (tls) { - if (netsec_set_tls(nsc, 1, &errstr) != OK) + if (tls & S_TLSENABLEMASK) { + if (netsec_set_tls(nsc, 1, tls & S_NOVERIFY, &errstr) != OK) return sm_nerror(errstr); } /* - * If tls == 2, that means that the user requested "initial" TLS, - * which happens right after the connection has opened. Do that - * negotiation now + * If tls == S_INITTLS, that means that the user requested + * "initial" TLS, which happens right after the connection has + * opened. Do that negotiation now */ - if (tls == 2) { + if (tls & S_INITTLS) { if (netsec_negotiate_tls(nsc, &errstr) != OK) { sm_end(NOTOK); return sm_nerror(errstr); @@ -214,7 +211,7 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, * restart the EHLO dialog after TLS negotiation is complete. */ - if (tls == 1) { + if (tls & S_STARTTLS) { if (! EHLOset("STARTTLS")) { sm_end(NOTOK); return sm_ierror("SMTP server does not support TLS"); @@ -308,12 +305,14 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl, if (user) netsec_set_userid(nsc, user); + netsec_set_hostname(nsc, client); + if (sm_debug) netsec_set_snoop(nsc, 1); if (sasl) { - if (netsec_set_sasl_params(nsc, client, "smtp", saslmech, - sm_sasl_callback, &errstr) != OK) + if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback, + &errstr) != OK) return sm_nerror(errstr); } @@ -422,11 +421,16 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl, } static int -rclient (char *server, char *service) +rclient (char *server, char *service, char **chosen_server) { int sd; char response[BUFSIZ]; + if (server == NULL) + server = servers; + + *chosen_server = server; + if ((sd = client (server, service, response, sizeof(response), sm_debug)) != NOTOK) return sd; @@ -448,7 +452,7 @@ sm_winit (char *from, int smtputf8, int eightbit) if (EHLOset ("8BITMIME") && EHLOset ("SMTPUTF8")) { mail_parameters = " BODY=8BITMIME SMTPUTF8"; } else { - advise (NULL, "SMTP server does not support %s, not sending.\n" + inform("SMTP server does not support %s, not sending.\n" "Rebuild message with 7-bit headers, WITHOUT -headerencoding utf-8.", EHLOset ("SMTPUTF8") ? "8BITMIME" : "SMTPUTF8"); sm_end (NOTOK); @@ -460,7 +464,7 @@ sm_winit (char *from, int smtputf8, int eightbit) if (EHLOset ("8BITMIME")) { mail_parameters = " BODY=8BITMIME"; } else { - advise (NULL, "SMTP server does not support 8BITMIME, not sending.\n" + inform("SMTP server does not support 8BITMIME, not sending.\n" "Suggest encoding message for 7-bit transport by setting your\n" "locale to C, and/or specifying *b64 in mhbuild directives."); sm_end (NOTOK); @@ -489,7 +493,7 @@ sm_wadr (char *mbox, char *host, char *path) { switch (smtalk (SM_RCPT, host && *host ? "RCPT TO:<%s%s@%s>" : "RCPT TO:<%s%s>", - path ? path : "", mbox, host)) { + FENDNULL(path), mbox, host)) { case 250: case 251: sm_addrs++; @@ -614,7 +618,8 @@ sm_end (int type) case NOTOK: sm_note.code = sm_reply.code; sm_note.length = sm_reply.length; - memcpy (sm_note.text, sm_reply.text, sm_reply.length + 1);/* fall */ + memcpy (sm_note.text, sm_reply.text, sm_reply.length + 1); + /* FALLTHRU */ case DONE: if (smtalk (SM_RSET, "RSET") == 250 && type == DONE) return RP_OK; @@ -755,7 +760,8 @@ sm_wstream (char *buffer, int len) if (netsec_write(nsc, ".", 1, &errstr) != OK) { sm_nerror(errstr); return NOTOK; - } /* FALL THROUGH */ + } + /* FALLTHRU */ default: sm_nl = FALSE; @@ -811,7 +817,7 @@ again: ; &errstr)) != NULL ; ) { if (doingEHLO - && HasPrefix(buffer, "250") + && has_prefix(buffer, "250") && (buffer[3] == '-' || doingEHLO == 2) && buffer[4]) { if (doingEHLO == 2) { @@ -950,7 +956,7 @@ EHLOset (char *s) for (ehlo = EHLOkeys; *ehlo; ehlo++) { ep = *ehlo; - if (HasPrefix(ep, s)) { + if (has_prefix(ep, s)) { for (ep += len; *ep == ' '; ep++) continue; return ep; @@ -1028,7 +1034,7 @@ sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata, return NOTOK; } - if (!HasPrefix(line, "334 ")) { + if (!has_prefix(line, "334 ")) { netsec_err(errstr, "Improper SASL protocol response: %s", line); return NOTOK; } @@ -1077,7 +1083,7 @@ sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata, if (line == NULL) return NOTOK; - if (!HasPrefix(line, "235 ")) { + if (!has_prefix(line, "235 ")) { if (len > 4) netsec_err(errstr, "Authentication failed: %s", line + 4); else