X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/55a31c2eec8e219a297ba7fa2f11c3f5108b0fe2..ec173fd2c:/mts/smtp/smtp.c?ds=sidebyside diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c index 2f32877c..8270b343 100644 --- a/mts/smtp/smtp.c +++ b/mts/smtp/smtp.c @@ -5,15 +5,18 @@ * complete copyright information. */ -#include +#include "h/mh.h" +#include "sbr/r1bindex.h" +#include "sbr/client.h" +#include "sbr/error.h" #include "smtp.h" -#include -#include -#include -#include +#include "h/mts.h" +#include "h/signals.h" +#include "h/utils.h" +#include "h/netsec.h" #include -#include "../../sbr/base64.h" +#include "sbr/base64.h" /* * This module implements an interface to SendMail very similar @@ -38,7 +41,7 @@ static int sm_addrs = 0; static int sm_child = NOTOK; static int sm_debug = 0; -static int sm_nl = TRUE; +static bool sm_nl = true; static int sm_verbose = 0; static netsec_context *nsc = NULL; @@ -68,7 +71,7 @@ static int smhear (void); static char *EHLOset (char *) PURE; static int sm_sasl_callback(enum sasl_message_type, unsigned const char *, unsigned int, unsigned char **, unsigned int *, - char **); + void *, char **); int sm_init (char *client, char *server, char *port, int watch, int verbose, @@ -92,7 +95,7 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, char *errstr, *chosen_server; if (watch) - verbose = TRUE; + verbose = true; sm_verbose = verbose; sm_debug = debug; @@ -133,7 +136,7 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, if (sasl) { if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback, - &errstr) != OK) + NULL, &errstr) != OK) return sm_nerror(errstr); } @@ -263,7 +266,7 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl, char *vec[15], *errstr; if (watch) - verbose = TRUE; + verbose = true; sm_verbose = verbose; sm_debug = debug; @@ -295,7 +298,7 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl, if (sasl) { if (netsec_set_sasl_params(nsc, "smtp", saslmech, sm_sasl_callback, - &errstr) != OK) + NULL, &errstr) != OK) return sm_nerror(errstr); } @@ -307,9 +310,7 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl, return sm_ierror ("no pipes"); } - for (i = 0; (sm_child = fork ()) == NOTOK && i < 5; i++) - sleep (5); - + sm_child = fork(); switch (sm_child) { case NOTOK: close (pdo[0]); @@ -341,7 +342,7 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl, execvp (sendmail, vec); fprintf (stderr, "unable to exec "); perror (sendmail); - _exit (-1); /* NOTREACHED */ + _exit(1); /* NOTREACHED */ default: SIGNAL (SIGPIPE, SIG_IGN); @@ -349,7 +350,7 @@ sendmail_init (char *client, int watch, int verbose, int debug, int sasl, close (pdi[1]); close (pdo[0]); - netsec_set_fd(nsc, pdi[i], pdo[1]); + netsec_set_fd(nsc, pdi[0], pdo[1]); netsec_set_timeout(nsc, SM_OPEN); result = smhear (); switch (result) { @@ -509,7 +510,7 @@ sm_waend (void) { switch (smtalk (SM_DATA, "DATA")) { case 354: - sm_nl = TRUE; + sm_nl = true; return RP_OK; case 451: @@ -531,20 +532,45 @@ sm_waend (void) int sm_wtxt (char *buffer, int len) { - int result; + int result, snoopstate; + + if ((snoopstate = netsec_get_snoop(nsc))) + netsec_set_snoop(nsc, 0); result = sm_wstream (buffer, len); - return (result == NOTOK ? RP_BHST : RP_OK); + netsec_set_snoop(nsc, snoopstate); + return result == NOTOK ? RP_BHST : RP_OK; } int sm_wtend (void) { - if (sm_wstream ((char *) NULL, 0) == NOTOK) + int snoopstate; + + if ((snoopstate = netsec_get_snoop(nsc))) + netsec_set_snoop(nsc, 0); + + if (sm_wstream(NULL, 0) == NOTOK) return RP_BHST; + /* + * Because snoop output now happens at flush time, if we are using snoop + * we force an extra flush here. While this introduces some extra network + * traffic, we're only doing it when snoop is in effect so I think it's + * reasonable. + */ + + if (snoopstate) { + char *errstr; + if (netsec_flush(nsc, &errstr) != OK) { + sm_nerror(errstr); + return RP_BHST; + } + netsec_set_snoop(nsc, snoopstate); + } + switch (smtalk (SM_DOT + 3 * sm_addrs, ".")) { case 250: case 251: @@ -634,7 +660,7 @@ sm_end (int type) status = OK; } - return (status ? RP_BHST : RP_OK); + return status ? RP_BHST : RP_OK; } @@ -720,7 +746,7 @@ sm_wstream (char *buffer, int len) for (bp = buffer; bp && len > 0; bp++, len--) { switch (*bp) { case '\n': - sm_nl = TRUE; + sm_nl = true; if (netsec_write(nsc, "\r", 1, &errstr) != OK) { sm_nerror(errstr); return NOTOK; @@ -736,7 +762,7 @@ sm_wstream (char *buffer, int len) /* FALLTHRU */ default: - sm_nl = FALSE; + sm_nl = false; } if (netsec_write(nsc, bp, 1, &errstr) != OK) { sm_nerror(errstr); @@ -753,7 +779,8 @@ sm_wstream (char *buffer, int len) static int smhear (void) { - int i, code, cont, more; + int i, code; + bool cont, more; size_t buflen, rc; unsigned char *bp; char *rp; @@ -761,7 +788,7 @@ smhear (void) char **ehlo = EHLOkeys, *buffer; if (doingEHLO) { - static int at_least_once = 0; + static bool at_least_once; if (at_least_once) { char *ep; @@ -771,7 +798,7 @@ smhear (void) free (ep); } } else { - at_least_once = 1; + at_least_once = true; } ehlo = EHLOkeys; @@ -785,7 +812,7 @@ again: ; rp = sm_reply.text; rc = sizeof(sm_reply.text) - 1; - for (more = FALSE; (buffer = netsec_readline(nsc, &buflen, + for (more = false; (buffer = netsec_readline(nsc, &buflen, &errstr)) != NULL ; ) { if (doingEHLO @@ -811,13 +838,13 @@ again: ; for (; buflen > 0 && (!isascii (*bp) || !isdigit (*bp)); bp++, buflen--) continue; - cont = FALSE; + cont = false; code = atoi ((char *) bp); bp += 3, buflen -= 3; for (; buflen > 0 && isspace (*bp); bp++, buflen--) continue; if (buflen > 0 && *bp == '-') { - cont = TRUE; + cont = true; bp++, buflen--; for (; buflen > 0 && isspace (*bp); bp++, buflen--) continue; @@ -826,7 +853,7 @@ again: ; if (more) { if (code != sm_reply.code || cont) continue; - more = FALSE; + more = false; } else { sm_reply.code = code; more = cont; @@ -936,7 +963,7 @@ EHLOset (char *s) } } - return 0; + return NULL; } /* @@ -948,11 +975,12 @@ EHLOset (char *s) static int sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata, unsigned int indatalen, unsigned char **outdata, - unsigned int *outdatalen, char **errstr) + unsigned int *outdatalen, void *context, char **errstr) { int rc, snoopoffset; char *mech, *line; size_t len; + NMH_UNUSED(context); switch (mtype) { case NETSEC_SASL_START: @@ -975,15 +1003,19 @@ sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata, snoopoffset = 6 + strlen(mech); rc = netsec_printf(nsc, errstr, "AUTH %s %s\r\n", mech, b64data); free(b64data); - netsec_set_snoop_callback(nsc, NULL, NULL); } else { rc = netsec_printf(nsc, errstr, "AUTH %s\r\n", mech); } - if (rc != OK) + if (rc != OK) { + netsec_set_snoop_callback(nsc, NULL, NULL); return NOTOK; + } + + rc = netsec_flush(nsc, errstr); + netsec_set_snoop_callback(nsc, NULL, NULL); - if (netsec_flush(nsc, errstr) != OK) + if (rc != OK) return NOTOK; break; @@ -1037,14 +1069,16 @@ sm_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata, writeBase64raw(indata, indatalen, b64data); netsec_set_snoop_callback(nsc, netsec_b64_snoop_decoder, NULL); rc = netsec_printf(nsc, errstr, "%s\r\n", b64data); - netsec_set_snoop_callback(nsc, NULL, NULL); free(b64data); } if (rc != OK) return NOTOK; - if (netsec_flush(nsc, errstr) != OK) + rc = netsec_flush(nsc, errstr); + netsec_set_snoop_callback(nsc, NULL, NULL); + + if (rc != OK) return NOTOK; break;