X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/eda0cc87eedfbbe5a15a91a59489e31f69e30998..4974d09cc659e2859fcf916ad020628c9695e2f8:/uip/post.c diff --git a/uip/post.c b/uip/post.c index bf1c042d..81bd7b4a 100644 --- a/uip/post.c +++ b/uip/post.c @@ -1,5 +1,4 @@ -/* - * post.c -- enter messages into the mail transport system +/* post.c -- enter messages into the mail transport system * * This code is Copyright (c) 2002, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for @@ -16,6 +15,8 @@ #include #include #include +#include "../sbr/m_mktemp.h" +#include "../sbr/message_id.h" #ifdef HAVE_SYS_TIME_H # include @@ -89,6 +90,8 @@ X("tls", TLSminc(-3), TLSSW) \ X("initialtls", TLSminc(-10), INITTLSSW) \ X("notls", TLSminc(-5), NTLSSW) \ + X("certverify", TLSminc(-10), CERTVERSW) \ + X("nocertverify", TLSminc(-12), NOCERTVERSW) \ X("fileproc", -4, FILEPROCSW) \ X("mhlproc", -3, MHLPROCSW) \ X("sendmail program", 0, MTSSM) \ @@ -118,7 +121,7 @@ DEFINE_SWITCH_ARRAY(POST, switches); * from 'send'. We use a service name of 'post' internally. */ -static struct oauth_profile { +static struct { const char *profname; int switchnum; const char *value; @@ -168,7 +171,7 @@ struct headers { #define MVIS 0x0008 /* we've seen sighted addrs */ #define MINV 0x0010 /* we've seen blind addrs */ #define MSND 0x0020 /* we've seen a Sender: */ -#define MRSN 0x0040 /* We've seen a Resent-Sendr:*/ +#define MRSN 0x0040 /* We've seen a Resent-Sender: */ #define MEFM 0x0080 /* We've seen Envelope-From: */ #define MMIM 0x0100 /* We've seen Mime-Version: */ @@ -239,7 +242,7 @@ static int sasl=0; /* Use SASL auth for SMTP */ static char *saslmech=NULL; /* Force use of particular SASL mech */ static char *user=NULL; /* Authenticate as this user */ static char *port="submission"; /* Name of server port for SMTP submission */ -static int tls=-1; /* Use TLS for encryption */ +static int tlsflag=0; /* Flags to control TLS settings */ static int fromcount=0; /* Count of addresses on From: header */ static int seensender=0; /* Have we seen a Sender: header? */ @@ -313,10 +316,11 @@ static int find_prefix (void); int main (int argc, char **argv) { - int state, compnum, dashstuff = 0, swnum, oauth_flag = 0; + int state, compnum, dashstuff = 0, swnum, oauth_flag = 0, tls = -1; + int noverify = 0; int eai = 0; /* use Email Address Internationalization (EAI) (SMTPUTF8) */ char *cp, *msg = NULL, **argp, **arguments, *envelope; - char buf[BUFSIZ], name[NAMESZ], *auth_svc = NULL; + char buf[NMH_BUFSIZ], name[NAMESZ], *auth_svc = NULL; FILE *in, *out; m_getfld_state_t gstate = 0; @@ -530,6 +534,14 @@ main (int argc, char **argv) tls = 0; continue; + case CERTVERSW: + noverify = 0; + continue; + + case NOCERTVERSW: + noverify++; + continue; + case FILEPROCSW: if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); @@ -612,7 +624,7 @@ main (int argc, char **argv) case FLD: case FLDPLUS: compnum++; - cp = add (buf, NULL); + cp = mh_xstrdup(buf); while (state == FLDPLUS) { bufsz = sizeof buf; state = m_getfld (&gstate, name, buf, &bufsz, in); @@ -692,6 +704,16 @@ main (int argc, char **argv) #endif /* ! TLS_SUPPORT */ } + if (tls == 1) + tlsflag = S_STARTTLS; + else if (tls == 2) + tlsflag = S_INITTLS; + else + tlsflag = 0; + + if (noverify) + tlsflag |= S_NOVERIFY; + /* * If we were given any oauth flags, store the appropriate profile * entries and make sure an authservice was given (we have to do this @@ -775,7 +797,7 @@ putfmt (char *name, char *str, int *eai, FILE *out) str++; if (msgstate == NORMAL && uprf (name, "resent")) { - advise (NULL, "illegal header line -- %s:", name); + inform("illegal header line -- %s:", name); badmsg++; return; } @@ -804,9 +826,9 @@ putfmt (char *name, char *str, int *eai, FILE *out) should never have reached this point. Warn about any that are non-empty. */ if (strcmp (str, "\n")) { - TrimSuffixC(str, '\n'); + trim_suffix_c(str, '\n'); if (! whomsw) { - advise (NULL, "ignoring header line -- %s: %s", name, str); + inform("ignoring header line -- %s: %s", name, str); } } } @@ -819,7 +841,7 @@ putfmt (char *name, char *str, int *eai, FILE *out) return; } if (hdr->flags & HBAD) { - advise (NULL, "illegal header line -- %s:", name); + inform("illegal header line -- %s:", name); badmsg++; return; } @@ -879,11 +901,11 @@ putfmt (char *name, char *str, int *eai, FILE *out) */ if ((msgstate == RESENT) ? (hdr->set & MRSN) : (hdr->set & MSND)) { - advise (NULL, "%s: field requires one address", name); + inform("%s: field requires one address", name); badmsg++; } #ifdef notdef - advise (NULL, "%s: field requires at least one address", name); + inform("%s: field requires at least one address", name); badmsg++; #endif /* notdef */ } @@ -891,7 +913,7 @@ putfmt (char *name, char *str, int *eai, FILE *out) } if (count > 1 && (hdr->flags & HONE)) { - advise (NULL, "%s: field only permits one address", name); + inform("%s: field only permits one address", name); badmsg++; return; } @@ -1047,7 +1069,7 @@ putfmt (char *name, char *str, int *eai, FILE *out) } if (grp > 0 && (hdr->flags & HNGR)) { - advise (NULL, "%s: field does not allow groups", name); + inform("%s: field does not allow groups", name); badmsg++; } if (linepos) { @@ -1087,14 +1109,14 @@ finish_headers (FILE *out) /* * A From: header is now required in the draft. */ - advise (NULL, "message has no From: header"); - advise (NULL, "See default components files for examples"); + inform("message has no From: header"); + inform("See default components files for examples"); badmsg++; break; } if (fromcount > 1 && (seensender == 0 && !(msgflags & MEFM))) { - advise (NULL, "A Sender: or Envelope-From: header is required " + inform("A Sender: or Envelope-From: header is required " "with multiple\nFrom: addresses"); badmsg++; break; @@ -1114,7 +1136,7 @@ finish_headers (FILE *out) if (fromcount > 1 && seensender == 0) { if (efrom[0] == '\0') { - advise (NULL, "Envelope-From cannot be blank when there " + inform("Envelope-From cannot be blank when there " "is multiple From: addresses\nand no Sender: " "header"); badmsg++; @@ -1129,21 +1151,21 @@ finish_headers (FILE *out) case RESENT: if (!(msgflags & MDAT)) { - advise (NULL, "message has no Date: header"); + inform("message has no Date: header"); badmsg++; } if (!(msgflags & MFRM)) { - advise (NULL, "message has no From: header"); + inform("message has no From: header"); badmsg++; } if (!(msgflags & MRFM)) { - advise (NULL, "message has no Resent-From: header"); - advise (NULL, "See default components files for examples"); + inform("message has no Resent-From: header"); + inform("See default components files for examples"); badmsg++; break; } if (fromcount > 1 && (seensender == 0 && !(msgflags & MEFM))) { - advise (NULL, "A Resent-Sender: or Envelope-From: header is " + inform("A Resent-Sender: or Envelope-From: header is " "required with multiple\nResent-From: addresses"); badmsg++; break; @@ -1164,7 +1186,7 @@ finish_headers (FILE *out) if (fromcount > 1 && seensender == 0) { if (efrom[0] == '\0') { - advise (NULL, "Envelope-From cannot be blank when there " + inform("Envelope-From cannot be blank when there " "is multiple Resent-From: addresses and no " "Resent-Sender: header"); badmsg++; @@ -1191,7 +1213,7 @@ get_header (char *header, struct headers *table) struct headers *h; for (h = table; h->value; h++) - if (!strcasecmp (header ? header : "", h->value ? h->value : "")) + if (!strcasecmp (FENDNULL(header), FENDNULL(h->value))) return (h - table); return NOTOK; @@ -1292,10 +1314,10 @@ insert (struct mailname *np) : &netaddrs; mp->m_next; mp = mp->m_next) - if (!strcasecmp (np->m_host ? np->m_host : "", - mp->m_next->m_host ? mp->m_next->m_host : "") && - !strcasecmp (np->m_mbox ? np->m_mbox : "", - mp->m_next->m_mbox ? mp->m_next->m_mbox : "") && + if (!strcasecmp (FENDNULL(np->m_host), + FENDNULL(mp->m_next->m_host)) && + !strcasecmp (FENDNULL(np->m_mbox), + FENDNULL(mp->m_next->m_mbox)) && np->m_bcc == mp->m_next->m_bcc) return 0; @@ -1319,7 +1341,7 @@ pl (void) printf ("\nnet:\t"); for (mp = netaddrs.m_next; mp; mp = mp->m_next) - printf ("%s%s@%s%s%s", mp->m_path ? mp->m_path : "", + printf ("%s%s@%s%s%s", FENDNULL(mp->m_path), mp->m_mbox, mp->m_host, mp->m_bcc ? "[BCC]" : "", mp->m_next ? ",\n\t" : ""); @@ -1527,7 +1549,7 @@ find_prefix (void) if ((in = fopen (tmpfil, "r")) == NULL) adios (tmpfil, "unable to re-open"); - while (fgets (buffer, sizeof(buffer) - 1, in)) + while (fgets (buffer, sizeof buffer, in)) if (buffer[0] == '-' && buffer[1] == '-') { char *cp; @@ -1546,18 +1568,16 @@ find_prefix (void) } -#define plural(x) (x == 1 ? "" : "s") - static void chkadr (void) { if (badadr && unkadr) die (NULL, "%d address%s unparsable, %d addressee%s undeliverable", - badadr, plural (badadr), unkadr, plural (badadr)); + badadr, PLURALS(badadr), unkadr, PLURALS(badadr)); if (badadr) - die (NULL, "%d address%s unparsable", badadr, plural (badadr)); + die (NULL, "%d address%s unparsable", badadr, PLURALS(badadr)); if (unkadr) - die (NULL, "%d addressee%s undeliverable", unkadr, plural (unkadr)); + die (NULL, "%d addressee%s undeliverable", unkadr, PLURALS(unkadr)); } @@ -1680,7 +1700,7 @@ post (char *file, int bccque, int talk, int eai, char *envelope, if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, verbose, snoop, sasl, saslmech, user, - oauth_flag ? auth_svc : NULL, tls)) + oauth_flag ? auth_svc : NULL, tlsflag)) || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) { close (fd); die (NULL, "problem initializing server; %s", rp_string (retval)); @@ -1724,7 +1744,7 @@ verify_all_addresses (int talk, int eai, char *envelope, int oauth_flag, if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, verbose, snoop, sasl, saslmech, user, - oauth_flag ? auth_svc : NULL, tls)) + oauth_flag ? auth_svc : NULL, tlsflag)) || rp_isbad (retval = sm_winit (envelope, eai, eightbit))) { die (NULL, "problem initializing server; %s", rp_string (retval)); } @@ -1829,7 +1849,7 @@ do_text (char *file, int fd) int retval, state; char buf[BUFSIZ]; - lseek (fd, (off_t) 0, SEEK_SET); + lseek(fd, 0, SEEK_SET); while ((state = read (fd, buf, sizeof(buf))) > 0) { if (rp_isbad (retval = sm_wtxt (buf, state))) @@ -1846,6 +1866,7 @@ do_text (char *file, int fd) case RP_NO: case RP_NDEL: die (NULL, "posting failed; %s", rp_string (retval)); + break; default: die (NULL, "unexpected response; %s", rp_string (retval)); @@ -1967,7 +1988,7 @@ fcc (char *file, char *folder) if (!verbose) fprintf (stderr, " %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder); - pidstatus (status, verbose ? stdout : stderr, NULL); + pidstatus (status, verbose ? stdout : stderr, fileproc); } else { if (verbose) puts("folder ok"); @@ -1984,8 +2005,11 @@ fcc (char *file, char *folder) static void die (char *what, char *fmt, ...) { + int err; va_list ap; + err = errno; + (void) m_unlink (tmpfil); if (msgflags & MINV) (void) m_unlink (bccfil); @@ -1994,6 +2018,7 @@ die (char *what, char *fmt, ...) sm_end (NOTOK); va_start(ap, fmt); + errno = err; advertise (what, NULL, fmt, ap); va_end(ap); done (1);