X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fpost.c;h=75468185c4faa8f01135410e511bc4d188c22bb2;hp=a66e24110b32e767f9477f5353d00f9e6fb1d20a;hb=d8916ff5d389de5ab225cd6f40aeda1b285d0f28;hpb=e804a366f5091e90f1c0971e2b7546df69f1315a diff --git a/uip/post.c b/uip/post.c index a66e241..7546818 100644 --- a/uip/post.c +++ b/uip/post.c @@ -3,6 +3,10 @@ * post.c -- enter messages into the mail transport system * * $Id$ + * + * This code is Copyright (c) 2002, by the authors of nmh. See the + * COPYRIGHT file in the root directory of the nmh distribution for + * complete copyright information. */ #include @@ -12,9 +16,10 @@ #include #include #include +#include -#include -#include +#include +#include #include #include @@ -31,29 +36,20 @@ # endif #endif -#ifdef MMDFMTS -# include -# include -#endif - -/* - * Currently smtp and sendmail use - * the same interface for posting. - */ #ifdef SMTPMTS -# define SENDMTS -#endif - -#ifdef SENDMTS # include #endif -#ifndef MMDFMTS -# define uptolow(c) ((isalpha(c) && isupper (c)) ? tolower (c) : (c)) -#endif +#ifndef CYRUS_SASL +# define SASLminc(a) (a) +#else /* CYRUS_SASL */ +# define SASLminc(a) 0 +#endif /* CYRUS_SASL */ #define FCCS 10 /* max number of fccs allowed */ +#define uptolow(c) ((isalpha(c) && isupper (c)) ? tolower (c) : c) + /* In the following array of structures, the numeric second field of the structures (minchars) is apparently used like this: @@ -136,6 +132,14 @@ static struct swit switches[] = { { "partno", -6 }, #define QUEUESW 36 { "queued", -6 }, +#define SASLSW 37 + { "sasl", SASLminc(-4) }, +#define SASLMECHSW 38 + { "saslmech", SASLminc(-5) }, +#define USERSW 39 + { "user", SASLminc(-4) }, +#define PORTSW 40 + { "port server port name/number", 4 }, { NULL, 0 } }; @@ -202,11 +206,7 @@ static struct headers RHeaders[] = { { "Resent-Fcc", HFCC, 0 }, { "Reply-To", HADR, 0 }, { "From", HADR|HNGR, MFRM }, -#ifdef MMDFI - { "Sender", HADR|HNGR|HMNG, 0 }, -#else { "Sender", HADR|HNGR, 0 }, -#endif { "Date", HNOP, MDAT }, { "To", HADR|HNIL, 0 }, { "cc", HADR|HNIL, 0 }, @@ -235,6 +235,10 @@ static int whomsw = 0; /* we are whom not post */ static int checksw = 0; /* whom -check */ static int linepos=0; /* putadr()'s position on the line */ static int nameoutput=0; /* putadr() has output header name */ +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="smtp"; /* Name of server port for SMTP */ static unsigned msgflags = 0; /* what we've seen */ @@ -262,19 +266,14 @@ static struct mailname netaddrs={NULL}; /* network addrs */ static struct mailname uuaddrs={NULL}; /* uucp addrs */ static struct mailname tmpaddrs={NULL}; /* temporary queue */ -#ifdef MMDFMTS -static char *submitmode = "m"; /* deliver to mailbox only */ -static char submitopts[6] = "vl"; /* initial options for submit */ -#endif /* MMDFMTS */ - -#ifdef SENDMTS +#ifdef SMTPMTS static int snoop = 0; static int smtpmode = S_MAIL; static char *clientsw = NULL; static char *serversw = NULL; extern struct smtp sm_reply; -#endif /* SENDMTS */ +#endif /* SMTPMTS */ static char prefix[] = "----- =_aaaaaaaaaa"; @@ -283,7 +282,7 @@ static char *fill_in = NULL; static char *partno = NULL; static int queued = 0; -extern int MMailids; +extern boolean draft_from_masquerading; /* defined in mts.c */ /* * static prototypes @@ -298,7 +297,7 @@ static int insert (struct mailname *); static void pl (void); static void anno (void); static int annoaux (struct mailname *); -static void insert_fcc (struct headers *, char *); +static void insert_fcc (struct headers *, unsigned char *); static void make_bcc_file (int); static void verify_all_addresses (int); static void chkadr (void); @@ -335,10 +334,6 @@ main (int argc, char **argv) arguments = getarguments (invo_name, argc, argv, 0); argp = arguments; -#if defined(MMDFMTS) && defined(MMDFII) - mmdf_init (invo_name); -#endif /* MMDFMTS and MMDFII */ - while ((cp = *argp++)) { if (*cp == '-') { switch (smatch (++cp, switches)) { @@ -457,25 +452,12 @@ main (int argc, char **argv) adios (NULL, "bad argument %s %s", argp[-2], cp); continue; -#ifdef MMDFMTS - case MAILSW: - submitmode = "m"; - continue; - case SOMLSW: /* for right now, sigh... */ - case SAMLSW: - submitmode = "b"; - continue; - case SENDSW: - submitmode = "y"; - continue; -#endif /* MMDFMTS */ - case DLVRSW: if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); continue; -#ifndef SENDMTS +#ifndef SMTPMTS case CLIESW: case SERVSW: if (!(cp = *argp++) || *cp == '-') @@ -484,7 +466,7 @@ main (int argc, char **argv) case SNOOPSW: continue; -#else /* SENDMTS */ +#else /* SMTPMTS */ case MAILSW: smtpmode = S_MAIL; continue; @@ -508,7 +490,7 @@ main (int argc, char **argv) case SNOOPSW: snoop++; continue; -#endif /* SENDMTS */ +#endif /* SMTPMTS */ case FILLSW: if (!(fill_in = *argp++) || *fill_in == '-') @@ -525,6 +507,25 @@ main (int argc, char **argv) case QUEUESW: queued++; continue; + + case SASLSW: + sasl++; + continue; + + case SASLMECHSW: + if (!(saslmech = *argp++) || *saslmech == '-') + adios (NULL, "missing argument to %s", argp[-2]); + continue; + + case USERSW: + if (!(user = *argp++) || *user == '-') + adios (NULL, "missing argument to %s", argp[-2]); + continue; + + case PORTSW: + if (!(port = *argp++) || *port == '-') + adios (NULL, "missing argument to %s", argp[-2]); + continue; } } if (msg) @@ -628,12 +629,6 @@ main (int argc, char **argv) done (0); } -#ifdef MMDFMTS - strcat (submitopts, submitmode); - if (watch) - strcat (submitopts, "nw"); -#endif /* MMDFMTS */ - if (msgflags & MINV) { make_bcc_file (dashstuff); if (msgflags & MVIS) { @@ -652,7 +647,8 @@ main (int argc, char **argv) if (verbose) printf (partno ? "Partial Message #%s Processed\n" : "Message Processed\n", partno); - return done (0); + done (0); + return 1; } @@ -726,14 +722,6 @@ putfmt (char *name, char *str, FILE *out) tmpaddrs.m_next = NULL; for (count = 0; (cp = getname (str)); count++) if ((mp = getm (cp, NULL, 0, AD_HOST, NULL))) { - if (MMailids && (hdr->set & MFRM)) - /* The user manually specified a From: address in their draft - and mts.conf turned on "mmailid", so we'll set things up to - use the actual email address embedded in the draft From: - (without the GECOS full name or angle brackets) as the - envelope From:. */ - strncpy(from, auxformat(mp, 0), sizeof(from) - 1); - if (tmpaddrs.m_next) np->m_next = mp; else @@ -764,7 +752,8 @@ putfmt (char *name, char *str, FILE *out) for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np) if (mp->m_nohost) { /* also used to test (hdr->flags & HTRY) */ - pp = akvalue (mp->m_mbox); + /* The address doesn't include a host, so it might be an alias. */ + pp = akvalue (mp->m_mbox); /* do mh alias substitution */ qp = akvisible () ? mp->m_mbox : ""; np = mp; if (np->m_gname) @@ -774,6 +763,19 @@ putfmt (char *name, char *str, FILE *out) badadr++; continue; } + + if (draft_from_masquerading && ((msgstate == RESENT) + ? (hdr->set & MRFM) + : (hdr->set & MFRM))) + /* The user manually specified a [Resent-]From: address in + their draft and the "masquerade:" line in mts.conf + doesn't contain "draft_from", so we'll set things up to + use the actual email address embedded in the draft + [Resent-]From: (after alias substitution, and without the + GECOS full name or angle brackets) as the envelope + From:. */ + strncpy(from, auxformat(mp, 0), sizeof(from) - 1); + if (hdr->flags & HBCC) mp->m_bcc++; if (np->m_ingrp) @@ -793,6 +795,19 @@ putfmt (char *name, char *str, FILE *out) mnfree (mp); } else { + /* Address includes a host, so no alias substitution is needed. */ + if (draft_from_masquerading && ((msgstate == RESENT) + ? (hdr->set & MRFM) + : (hdr->set & MFRM))) + /* The user manually specified a [Resent-]From: address in + their draft and the "masquerade:" line in mts.conf + doesn't contain "draft_from", so we'll set things up to + use the actual email address embedded in the draft + [Resent-]From: (after alias substitution, and without the + GECOS full name or angle brackets) as the envelope + From:. */ + strncpy(from, auxformat(mp, 0), sizeof(from) - 1); + if (hdr->flags & HBCC) mp->m_bcc++; if (mp->m_gname) @@ -824,7 +839,7 @@ putfmt (char *name, char *str, FILE *out) static void start_headers (void) { - char *cp; + unsigned char *cp; char myhost[BUFSIZ], sigbuf[BUFSIZ]; struct mailname *mp; @@ -875,10 +890,11 @@ finish_headers (FILE *out) (int) getpid (), (long) tclock, LocalName ()); if (msgflags & MFRM) { /* There was already a From: in the draft. Don't add one. */ - if (!MMailids) - /* mts.conf didn't turn on mmailid, so we'll reveal the - user's actual account@thismachine address in a Sender: - header (and use it as the envelope From: later). */ + if (!draft_from_masquerading) + /* mts.conf didn't contain "masquerade:[...]draft_from[...]" + so we'll reveal the user's actual account@thismachine + address in a Sender: header (and use it as the envelope + From: later). */ fprintf (out, "Sender: %s\n", from); } else @@ -903,17 +919,21 @@ finish_headers (FILE *out) if (whomsw && !fill_up) break; -#ifdef MMDFI /* sigh */ - fprintf (out, "Sender: %s\n", from); -#endif /* MMDFI */ - fprintf (out, "Resent-Date: %s\n", dtime (&tclock, 0)); if (msgid) fprintf (out, "Resent-Message-ID: <%d.%ld@%s>\n", (int) getpid (), (long) tclock, LocalName ()); - if (msgflags & MRFM) - fprintf (out, "Resent-Sender: %s\n", from); + if (msgflags & MRFM) { + /* There was already a Resent-From: in draft. Don't add one. */ + if (!draft_from_masquerading) + /* mts.conf didn't contain "masquerade:[...]draft_from[...]" + so we'll reveal the user's actual account@thismachine + address in a Sender: header (and use it as the envelope + From: later). */ + fprintf (out, "Resent-Sender: %s\n", from); + } else + /* Construct a Resent-From: header. */ fprintf (out, "Resent-From: %s\n", signature); if (whomsw) break; @@ -935,7 +955,7 @@ get_header (char *header, struct headers *table) struct headers *h; for (h = table; h->value; h++) - if (!strcasecmp (header, h->value)) + if (!mh_strcasecmp (header, h->value)) return (h - table); return NOTOK; @@ -1037,8 +1057,8 @@ insert (struct mailname *np) : &netaddrs; mp->m_next; mp = mp->m_next) - if (!strcasecmp (np->m_host, mp->m_next->m_host) - && !strcasecmp (np->m_mbox, mp->m_next->m_mbox) + if (!mh_strcasecmp (np->m_host, mp->m_next->m_host) + && !mh_strcasecmp (np->m_mbox, mp->m_next->m_mbox) && np->m_bcc == mp->m_next->m_bcc) return 0; @@ -1117,9 +1137,9 @@ annoaux (struct mailname *mp) static void -insert_fcc (struct headers *hdr, char *pp) +insert_fcc (struct headers *hdr, unsigned char *pp) { - char *cp; + unsigned char *cp; for (cp = pp; isspace (*cp); cp++) continue; @@ -1156,7 +1176,18 @@ make_bcc_file (int dashstuff) if (msgid) fprintf (out, "Message-ID: <%d.%ld@%s>\n", (int) getpid (), (long) tclock, LocalName ()); - fprintf (out, "From: %s\n", signature); + if (msgflags & MFRM) { + /* There was already a From: in the draft. Don't add one. */ + if (!draft_from_masquerading) + /* mts.conf didn't contain "masquerade:[...]draft_from[...]" + so we'll reveal the user's actual account@thismachine + address in a Sender: header (and use it as the envelope + From: later). */ + fprintf (out, "Sender: %s\n", from); + } + else + /* Construct a From: header. */ + fprintf (out, "From: %s\n", signature); if (subject) fprintf (out, "Subject: %s", subject); fprintf (out, "BCC:\n"); @@ -1266,7 +1297,7 @@ static int find_prefix (void) { int len, result; - char buffer[BUFSIZ]; + unsigned char buffer[BUFSIZ]; FILE *in; if ((in = fopen (tmpfil, "r")) == NULL) @@ -1277,7 +1308,7 @@ find_prefix (void) result = OK; while (fgets (buffer, sizeof(buffer) - 1, in)) if (buffer[0] == '-' && buffer[1] == '-') { - char *cp; + unsigned char *cp; for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--) if (!isspace (*cp)) @@ -1345,15 +1376,10 @@ do_addresses (int bccque, int talk) chkadr (); -#ifdef MMDFMTS - if (rp_isbad (retval = mm_waend ())) - die (NULL, "problem ending addresses [%s]\n", rp_valstr (retval)); -#endif /* MMDFMTS */ - -#ifdef SENDMTS +#ifdef SMTPMTS if (rp_isbad (retval = sm_waend ())) die (NULL, "problem ending addresses; %s", rp_string (retval)); -#endif /* SENDMTS */ +#endif /* SMTPMTS */ } @@ -1366,7 +1392,7 @@ do_addresses (int bccque, int talk) * SENDMAIL/SMTP routines */ -#ifdef SENDMTS +#ifdef SMTPMTS static void post (char *file, int bccque, int talk) @@ -1385,8 +1411,9 @@ post (char *file, int bccque, int talk) sigon (); - if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, - snoop, onex, queued)) + if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, verbose, + snoop, onex, queued, sasl, saslmech, + user)) || rp_isbad (retval = sm_winit (smtpmode, from))) die (NULL, "problem initializing server; %s", rp_string (retval)); @@ -1423,7 +1450,9 @@ verify_all_addresses (int talk) sigon (); if (!whomsw || checksw) - if (rp_isbad (retval = sm_init (clientsw, serversw, 0, 0, snoop, 0, 0)) + if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, + verbose, snoop, 0, queued, sasl, + saslmech, user)) || rp_isbad (retval = sm_winit (smtpmode, from))) die (NULL, "problem initializing server; %s", rp_string (retval)); @@ -1549,277 +1578,7 @@ do_text (char *file, int fd) } } -#endif /* SENDMTS */ - -/* - * MMDF routines - */ - -#ifdef MMDFMTS - -static void -post (char *file, int bccque, int talk) -{ - int fd, onex; - int retval; -#ifdef RP_NS - int len; - struct rp_bufstruct reply; -#endif /* RP_NS */ - - onex = !(msgflags & MINV) || bccque; - if (verbose) { - if (msgflags & MINV) - printf (" -- Posting for %s Recipients --\n", - bccque ? "Blind" : "Sighted"); - else - printf (" -- Posting for All Recipients --\n"); - } - - sigon (); - - if (rp_isbad (retval = mm_init ()) - || rp_isbad (retval = mm_sbinit ()) - || rp_isbad (retval = mm_winit (NULL, submitopts, from))) - die (NULL, "problem initializing MMDF system [%s]", - rp_valstr (retval)); -#ifdef RP_NS - if (rp_isbad (retval = mm_rrply (&reply, &len))) - die (NULL, "problem with sender address [%s]", - rp_valstr (retval)); -#endif /* RP_NS */ - - do_addresses (bccque, talk && verbose); - if ((fd = open (file, O_RDONLY)) == NOTOK) - die (file, "unable to re-open"); - do_text (file, fd); - close (fd); - fflush (stdout); - - mm_sbend (); - mm_end (OK); - sigoff (); - - if (verbose) - if (msgflags & MINV) - printf (" -- %s Recipient Copies Posted --\n", - bccque ? "Blind" : "Sighted"); - else - printf (" -- Recipient Copies Posted --\n"); - fflush (stdout); -} - - -/* Address Verification */ - -static void -verify_all_addresses (int talk) -{ - int retval; - struct mailname *lp; - -#ifdef RP_NS - int len; - struct rp_bufstruct reply; -#endif /* RP_NS */ - - sigon (); - - if (!whomsw || checksw) { - if (rp_isbad (retval = mm_init ()) - || rp_isbad (retval = mm_sbinit ()) - || rp_isbad (retval = mm_winit (NULL, submitopts, from))) - die (NULL, "problem initializing MMDF system [%s]", - rp_valstr (retval)); -#ifdef RP_NS - if (rp_isbad (retval = mm_rrply (&reply, &len))) - die (NULL, "problem with sender address [%s]", rp_valstr (retval)); -#endif /* RP_NS */ - } - - if (talk && !whomsw) - printf (" -- Address Verification --\n"); - if (talk && localaddrs.m_next) - printf (" -- Local Recipients --\n"); - for (lp = localaddrs.m_next; lp; lp = lp->m_next) - do_an_address (lp, talk); - - if (talk && uuaddrs.m_next) - printf (" -- UUCP Recipients --\n"); - for (lp = uuaddrs.m_next; lp; lp = lp->m_next) - do_an_address (lp, talk); - - if (talk && netaddrs.m_next) - printf (" -- Network Recipients --\n"); - for (lp = netaddrs.m_next; lp; lp = lp->m_next) - do_an_address (lp, talk); - - chkadr (); - if (talk && !whomsw) - printf (" -- Address Verification Successful --\n"); - - if (!whomsw || checksw) - mm_end (NOTOK); - - fflush (stdout); - sigoff (); -} - - -static void -do_an_address (struct mailname *lp, int talk) -{ - int len, retval; - char *mbox, *host, *text, *path; - char addr[BUFSIZ]; - struct rp_bufstruct reply; - - switch (lp->m_type) { - case LOCALHOST: - mbox = lp->m_mbox; - host = LocalName (); - strncpy (addr, mbox, sizeof(addr)); - break; - - case UUCPHOST: - fprintf (talk ? stdout : stderr, " %s!%s: %s\n", - lp->m_host, lp->m_mbox, "not supported; UUCP address"); - unkadr++; - fflush (stdout); - return; - - default: /* let MMDF decide if the host is bad */ - mbox = lp->m_mbox; - host = lp->m_host; - snprintf (addr, sizeof(addr), "%s at %s", mbox, host); - break; - } - - if (talk) - printf (" %s%s", addr, whomsw && lp->m_bcc ? "[BCC]" : ""); - - if (whomsw && !checksw) { - putchar ('\n'); - return; - } - if (talk) - printf (": "); - fflush (stdout); - -#ifdef MMDFII - if (lp->m_path) - path = concat (lp->m_path, mbox, "@", host, NULL); - else -#endif /* MMDFII */ - path = NULL; - if (rp_isbad (retval = mm_wadr (path ? NULL : host, path ? path : mbox)) - || rp_isbad (retval = mm_rrply (&reply, &len))) - die (NULL, "problem submitting address [%s]", rp_valstr (retval)); - - switch (rp_gval (reply.rp_val)) { - case RP_AOK: - if (talk) - printf ("address ok\n"); - fflush (stdout); - return; - -#ifdef RP_DOK - case RP_DOK: - if (talk) - printf ("nameserver timeout - queued for checking\n"); - fflush (stdout); - return; -#endif /* RP_DOK */ - - case RP_NO: - text = "you lose"; - break; - -#ifdef RP_NS - case RP_NS: - text = "temporary nameserver failure"; - break; - -#endif /* RP_NS */ - - case RP_USER: - case RP_NDEL: - text = "not deliverable"; - break; - - case RP_AGN: - text = "try again later"; - break; - - case RP_NOOP: - text = "nothing done"; - break; - - default: - if (!talk) - fprintf (stderr, " %s: ", addr); - text = "unexpected response"; - die (NULL, "%s;\n [%s] -- %s", text, - rp_valstr (reply.rp_val), reply.rp_line); - } - - if (!talk) - fprintf (stderr, " %s: ", addr); - fprintf (talk ? stdout : stderr, "%s;\n %s\n", text, reply.rp_line); - unkadr++; - - fflush (stdout); -} - - -static void -do_text (char *file, int fd) -{ - int retval, state; - char buf[BUFSIZ]; - struct rp_bufstruct reply; - - lseek (fd, (off_t) 0, SEEK_SET); - - while ((state = read (fd, buf, sizeof(buf))) > 0) { - if (rp_isbad (mm_wtxt (buf, state))) - die (NULL, "problem writing text [%s]\n", rp_valstr (retval)); - } - - if (state == NOTOK) - die (file, "problem reading from"); - - if (rp_isbad (retval = mm_wtend ())) - die (NULL, "problem ending text [%s]\n", rp_valstr (retval)); - - if (rp_isbad (retval = mm_rrply (&reply, &state))) - die (NULL, "problem getting submission status [%s]\n", - rp_valstr (retval)); - - switch (rp_gval (reply.rp_val)) { - case RP_OK: - case RP_MOK: - break; - - case RP_NO: - die (NULL, "you lose; %s", reply.rp_line); - - case RP_NDEL: - die (NULL, "no delivery occurred; %s", reply.rp_line); - - case RP_AGN: - die (NULL, "try again later; %s", reply.rp_line); - - case RP_NOOP: - die (NULL, "nothing done; %s", reply.rp_line); - - default: - die (NULL, "unexpected response;\n\t[%s] -- %s", - rp_valstr (reply.rp_val), reply.rp_line); - } -} - -#endif /* MMDFMTS */ +#endif /* SMTPMTS */ /* @@ -1837,15 +1596,10 @@ sigser (int i) if (msgflags & MINV) unlink (bccfil); -#ifdef MMDFMTS - if (!whomsw || checksw) - mm_end (NOTOK); -#endif /* MMDFMTS */ - -#ifdef SENDMTS +#ifdef SMTPMTS if (!whomsw || checksw) sm_end (NOTOK); -#endif /* SENDMTS */ +#endif /* SMTPMTS */ done (1); } @@ -1961,42 +1715,13 @@ die (char *what, char *fmt, ...) if (msgflags & MINV) unlink (bccfil); -#ifdef MMDFMTS - if (!whomsw || checksw) - mm_end (NOTOK); -#endif /* MMDFMTS */ - -#ifdef SENDMTS +#ifdef SMTPMTS if (!whomsw || checksw) sm_end (NOTOK); -#endif /* SENDMTS */ +#endif /* SMTPMTS */ va_start(ap, fmt); advertise (what, NULL, fmt, ap); va_end(ap); done (1); } - - -#ifdef MMDFMTS -/* - * err_abrt() is used by the mm_ routines - * do not, under *ANY* circumstances, remove it from post, - * or you will lose *BIG* - */ - -void -err_abrt (int code, char *fmt, ...) -{ - char buffer[BUFSIZ]; - va_list ap; - - snprintf (buffer, sizeof(buffer), "[%s]", rp_valstr (code)); - - va_start(ap, fmt); - advertise (buffer, NULL, fmt, ap); - va_end(ap); - - done (1); -} -#endif /* MMDFMTS */