X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/dc5d7a6edaba9fe7306e972b926aa4766f6b58ba..b335902294f1bb9b9fdab8c8917de07a1db3d4b1:/uip/post.c diff --git a/uip/post.c b/uip/post.c index 8cfcf651..43110f36 100644 --- a/uip/post.c +++ b/uip/post.c @@ -37,6 +37,12 @@ # define TLSminc(a) 0 #endif /* TLS_SUPPORT */ +#ifndef OAUTH_SUPPORT +# define OAUTHminc(a) (a) +#else /* OAUTH_SUPPORT */ +# define OAUTHminc(a) 0 +#endif /* OAUTH_SUPPORT */ + #define FCCS 10 /* max number of fccs allowed */ /* In the following array of structures, the numeric second field of the @@ -76,21 +82,28 @@ X("server host", 6, SERVSW) /* specify alternate SMTP server */ \ X("snoop", -5, SNOOPSW) /* snoop the SMTP transaction */ \ X("partno", -6, PARTSW) \ - X("queued", -6, QUEUESW) \ - X("sasl", SASLminc(-4), SASLSW) \ - X("nosasl", SASLminc(-6), NOSASLSW) \ - X("saslmaxssf", SASLminc(-10), SASLMXSSFSW) \ - X("saslmech", SASLminc(-5), SASLMECHSW) \ + X("sasl", SASLminc(4), SASLSW) \ + X("nosasl", SASLminc(6), NOSASLSW) \ + X("saslmaxssf", SASLminc(10), SASLMXSSFSW) \ + X("saslmech", SASLminc(5), SASLMECHSW) \ X("user", SASLminc(-4), USERSW) \ - X("port server port name/number", 4, PORTSW) \ + X("port server submission port name/number", 4, PORTSW) \ X("tls", TLSminc(-3), TLSSW) \ X("initialtls", TLSminc(-10), INITTLSSW) \ X("notls", TLSminc(-5), NTLSSW) \ X("fileproc", -4, FILEPROCSW) \ X("mhlproc", -3, MHLPROCSW) \ + X("sendmail program", 0, MTSSM) \ X("mts smtp|sendmail/smtp|sendmail/pipe", 2, MTSSW) \ X("credentials legacy|file:filename", 0, CREDENTIALSSW) \ X("messageid localname|random", 2, MESSAGEIDSW) \ + X("oauthcredfile", OAUTHminc(-7), OAUTHCREDFILESW) \ + X("oauthclientid", OAUTHminc(-12), OAUTHCLIDSW) \ + X("oauthclientsecret", OAUTHminc(-12), OAUTHCLSECSW) \ + X("oauthauthendpoint", OAUTHminc(-6), OAUTHAUTHENDSW) \ + X("oauthredirect", OAUTHminc(-6), OAUTHREDIRSW) \ + X("oauthtokenendpoint", OAUTHminc(-6), OAUTHTOKENDSW) \ + X("oauthscope", OAUTHminc(-6), OAUTHSCOPESW) \ #define X(sw, minchars, id) id, DEFINE_SWITCH_ENUM(POST); @@ -101,6 +114,25 @@ DEFINE_SWITCH_ARRAY(POST, switches); #undef X +/* + * Mapping between command-line switches and profile entries, communicated + * from 'send'. We use a service name of 'post' internally. + */ + +static struct oauth_profile { + const char *profname; + int switchnum; +} oauthswitches[] = { + { "oauth-post-credential-file", OAUTHCREDFILESW }, + { "oauth-post-client_id", OAUTHCLIDSW }, + { "oauth-post-client_secret", OAUTHCLSECSW }, + { "oauth-post-auth_endpoint", OAUTHAUTHENDSW }, + { "oauth-post-redirect_url", OAUTHREDIRSW }, + { "oauth-post-token_endpoint", OAUTHTOKENDSW }, + { "oauth-post-scope", OAUTHSCOPESW }, + { NULL, 0 } +}; + struct headers { char *value; unsigned int flags; @@ -201,8 +233,8 @@ static int sasl=0; /* Use SASL auth for SMTP */ static int saslssf=-1; /* Our maximum SSF for SASL */ 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 int tls=0; /* Use TLS for encryption */ +static char *port="submission"; /* Name of server port for SMTP submission */ +static int tls=-1; /* Use TLS for encryption */ static int fromcount=0; /* Count of addresses on From: header */ static int seensender=0; /* Have we seen a Sender: header? */ @@ -241,7 +273,6 @@ static char *serversw = NULL; static char prefix[] = "----- =_aaaaaaaaaa"; static char *partno = NULL; -static int queued = 0; /* * static prototypes @@ -258,14 +289,14 @@ static void anno (void); static int annoaux (struct mailname *); static void insert_fcc (struct headers *, char *); static void make_bcc_file (int); -static void verify_all_addresses (int, char *); +static void verify_all_addresses (int, char *, int); static void chkadr (void); static void sigon (void); static void sigoff (void); static void p_refile (char *); static void fcc (char *, char *); static void die (char *, char *, ...); -static void post (char *, int, int, char *); +static void post (char *, int, int, char *, int); static void do_text (char *file, int fd); static void do_an_address (struct mailname *, int); static void do_addresses (int, int); @@ -275,7 +306,7 @@ static int find_prefix (void); int main (int argc, char **argv) { - int state, compnum, dashstuff = 0; + int state, compnum, dashstuff = 0, swnum, oauth_flag = 0; char *cp, *msg = NULL, **argp, **arguments, *envelope; char buf[BUFSIZ], name[NAMESZ]; FILE *in, *out; @@ -289,7 +320,7 @@ main (int argc, char **argv) while ((cp = *argp++)) { if (*cp == '-') { - switch (smatch (++cp, switches)) { + switch ((swnum = smatch (++cp, switches))) { case AMBIGSW: ambigsw (cp, switches); done (1); @@ -422,10 +453,6 @@ main (int argc, char **argv) adios (NULL, "missing argument to %s", argp[-2]); continue; - case QUEUESW: - queued++; - continue; - case SASLSW: sasl++; continue; @@ -444,7 +471,36 @@ main (int argc, char **argv) if (!(saslmech = *argp++) || *saslmech == '-') adios (NULL, "missing argument to %s", argp[-2]); continue; - + + case OAUTHCREDFILESW: + case OAUTHCLIDSW: + case OAUTHCLSECSW: + case OAUTHAUTHENDSW: + case OAUTHREDIRSW: + case OAUTHTOKENDSW: + case OAUTHSCOPESW: + { + int i; + + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + + for (i = 0; oauthswitches[i].profname != NULL; i++) { + if (oauthswitches[i].switchnum == swnum) { + add_profile_entry(oauthswitches[i].profname, cp); + break; + } + } + + if (oauthswitches[i].profname == NULL) + adios (NULL, "internal error: cannot map switch %s " + "to profile entry", argp[-2]); + + oauth_flag++; + + continue; + } + case USERSW: if (!(user = *argp++) || *user == '-') adios (NULL, "missing argument to %s", argp[-2]); @@ -479,6 +535,12 @@ main (int argc, char **argv) mhlproc = cp; continue; + case MTSSM: + if (!(cp = *argp++) || *cp == '-') + adios (NULL, "missing argument to %s", argp[-2]); + sendmail = cp; + continue; + case MTSSW: if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); @@ -608,10 +670,25 @@ main (int argc, char **argv) envelope = from; } + if (tls == -1) { +#ifdef TLS_SUPPORT + /* + * The user didn't specify any of the tls switches. Try to + * help them by implying -initialtls if they're using port 465 + * (smtps, until IANA revoked that registration in 1998). + */ + tls = ! strcmp (port, "465") || ! strcasecmp (port, "smtps") + ? 2 + : 0; +#else /* ! TLS_SUPPORT */ + tls = 0; +#endif /* ! TLS_SUPPORT */ + } + /* If we are doing a "whom" check */ if (whomsw) { /* This won't work with MTS_SENDMAIL_PIPE. */ - verify_all_addresses (1, envelope); + verify_all_addresses (1, envelope, oauth_flag); done (0); } @@ -623,14 +700,14 @@ main (int argc, char **argv) verify_all_addresses with MTS_SENDMAIL_PIPE, but that might require running sendmail as root. Note that spost didn't verify addresses. */ - verify_all_addresses (verbose, envelope); + verify_all_addresses (verbose, envelope, oauth_flag); } - post (tmpfil, 0, verbose, envelope); + post (tmpfil, 0, verbose, envelope, oauth_flag); } - post (bccfil, 1, verbose, envelope); + post (bccfil, 1, verbose, envelope, oauth_flag); (void) m_unlink (bccfil); } else { - post (tmpfil, 0, isatty (1), envelope); + post (tmpfil, 0, isatty (1), envelope, oauth_flag); } p_refile (tmpfil); @@ -705,7 +782,7 @@ putfmt (char *name, char *str, FILE *out) if (hdr->flags & HFCC) { if ((cp = strrchr(str, '\n'))) *cp = 0; - for (cp = pp = str; (cp = strchr(pp, ',')); pp = cp) { + for (pp = str; (cp = strchr(pp, ',')); pp = cp) { *cp++ = 0; insert_fcc (hdr, pp); } @@ -1477,7 +1554,7 @@ do_addresses (int bccque, int talk) */ static void -post (char *file, int bccque, int talk, char *envelope) +post (char *file, int bccque, int talk, char *envelope, int oauth_flag) { int fd; int retval, i; @@ -1526,9 +1603,10 @@ post (char *file, int bccque, int talk, char *envelope) } } else { if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, - verbose, snoop, queued, sasl, - saslssf, saslmech, user, tls)) || - rp_isbad (retval = sm_winit (envelope))) + verbose, snoop, sasl, saslssf, + saslmech, user, + oauth_flag ? "post" : NULL, tls)) + || rp_isbad (retval = sm_winit (envelope))) die (NULL, "problem initializing server; %s", rp_string (retval)); do_addresses (bccque, talk && verbose); @@ -1557,7 +1635,7 @@ post (char *file, int bccque, int talk, char *envelope) /* Address Verification */ static void -verify_all_addresses (int talk, char *envelope) +verify_all_addresses (int talk, char *envelope, int oauth_flag) { int retval; struct mailname *lp; @@ -1566,8 +1644,9 @@ verify_all_addresses (int talk, char *envelope) if (!whomsw || checksw) if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, - verbose, snoop, queued, sasl, - saslssf, saslmech, user, tls)) + verbose, snoop, sasl, saslssf, + saslmech, user, + oauth_flag ? "post" : NULL, tls)) || rp_isbad (retval = sm_winit (envelope))) die (NULL, "problem initializing server; %s", rp_string (retval));