From: Earl Hood Date: Wed, 3 Feb 2010 05:56:56 +0000 (+0000) Subject: * mts/smtp/smtp.c: added SASL support if mts configuration X-Git-Tag: PRE_POSIX_CONVERSION~4 X-Git-Url: http://git.marmaro.de/?p=mmh;a=commitdiff_plain;h=352fe458a57061db81240c19fa4b356c7448463b * mts/smtp/smtp.c: added SASL support if mts configuration setting is set to "sendmail". This is useful if sendmail conf option is to a custom script that creates a proxy connection to an smtp server. * sbr/mts.c: added support for MHMTSCONF and MHMTSUSERCONF envvars. The former specifies an alternative system mts.conf to use. The later specifies a user-specific mts.conf to use. This one will be read after the system conf, so the user's conf only needs to set options they want to override. The MHMTSUSERCONF allows a user to set personal alternative mail submission methods w/o affecting other users on the system. * uip/whom.c: added SASL-based options so address checking can work against a server that requires SASL. --- diff --git a/ChangeLog b/ChangeLog index 38ba7e4..992f51c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2010-02-02 Earl Hood + * mts/smtp/smtp.c: added SASL support if mts configuration + setting is set to "sendmail". This is useful if sendmail + conf option is to a custom script that creates a proxy + connection to an smtp server. + + * sbr/mts.c: added support for MHMTSCONF and MHMTSUSERCONF + envvars. The former specifies an alternative system + mts.conf to use. The later specifies a user-specific + mts.conf to use. This one will be read after the system + conf, so the user's conf only needs to set options they + want to override. The MHMTSUSERCONF allows a user to set + personal alternative mail submission methods w/o affecting + other users on the system. + + * uip/whom.c: added SASL-based options so address checking + can work against a server that requires SASL. + 2009-12-29 David Levine * uip/mhlistsbr.c, uip/mhlsbr.c, uip/picksbr.c: cast diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c index 05e292f..ab70c24 100644 --- a/mts/smtp/smtp.c +++ b/mts/smtp/smtp.c @@ -128,7 +128,8 @@ char *EHLOkeys[MAXEHLO + 1]; */ static int smtp_init (char *, char *, char *, int, int, int, int, int, int, char *, char *); -static int sendmail_init (char *, char *, int, int, int, int, int); +static int sendmail_init (char *, char *, int, int, int, int, int, int, + char *, char *); static int rclient (char *, char *); static int sm_ierror (char *fmt, ...); @@ -165,13 +166,13 @@ sm_init (char *client, char *server, char *port, int watch, int verbose, debug, onex, queued, sasl, saslmech, user); else return sendmail_init (client, server, watch, verbose, - debug, onex, queued); + debug, onex, queued, sasl, saslmech, user); } static int smtp_init (char *client, char *server, char *port, int watch, int verbose, - int debug, int onex, int queued, int sasl, char *saslmech, - char *user) + int debug, int onex, int queued, + int sasl, char *saslmech, char *user) { #ifdef CYRUS_SASL char *server_mechs; @@ -299,8 +300,12 @@ send_options: ; int sendmail_init (char *client, char *server, int watch, int verbose, - int debug, int onex, int queued) + int debug, int onex, int queued, + int sasl, char *saslmech, char *user) { +#ifdef CYRUS_SASL + char *server_mechs; +#endif /* CYRUS_SASL */ int i, result, vecp; int pdi[2], pdo[2]; char *vec[15]; @@ -426,6 +431,35 @@ sendmail_init (char *client, char *server, int watch, int verbose, } } +#ifdef CYRUS_SASL + /* + * If the user asked for SASL, then check to see if the SMTP server + * supports it. Otherwise, error out (because the SMTP server + * might have been spoofed; we don't want to just silently not + * do authentication + */ + + if (sasl) { + if (! (server_mechs = EHLOset("AUTH"))) { + sm_end(NOTOK); + return sm_ierror("SMTP server does not support SASL"); + } + + if (saslmech && stringdex(saslmech, server_mechs) == -1) { + sm_end(NOTOK); + return sm_ierror("Requested SASL mech \"%s\" is not in the " + "list of supported mechanisms:\n%s", + saslmech, server_mechs); + } + + if (sm_auth_sasl(user, saslmech ? saslmech : server_mechs, + server) != RP_OK) { + sm_end(NOTOK); + return NOTOK; + } + } +#endif /* CYRUS_SASL */ + #ifndef ZMAILER if (onex) smtalk (SM_HELO, "ONEX"); @@ -454,7 +488,7 @@ rclient (char *server, char *service) int sm_winit (int mode, char *from) { - char *smtpcom; + char *smtpcom = NULL; switch (mode) { case S_MAIL: @@ -472,6 +506,10 @@ sm_winit (int mode, char *from) case S_SAML: smtpcom = "SAML"; break; + + default: + /* Hopefully, we do not get here. */ + break; } switch (smtalk (SM_MAIL, "%s FROM:<%s>", smtpcom, from)) { @@ -1173,7 +1211,7 @@ smhear (void) int i, code, cont, bc, rc, more; unsigned char *bp; char *rp; - char **ehlo, buffer[BUFSIZ]; + char **ehlo = NULL, buffer[BUFSIZ]; if (doingEHLO) { static int at_least_once = 0; diff --git a/sbr/mts.c b/sbr/mts.c index de7518c..7610cda 100644 --- a/sbr/mts.c +++ b/sbr/mts.c @@ -33,6 +33,9 @@ */ static char *tailor_value (unsigned char *); static void getuserinfo (void); +static const char *get_mtsconf_pathname(void); +static const char *get_mtsuserconf_pathname(void); +static void mts_read_conf_file (FILE *fp); /* * *mmdfldir and *uucpldir are the maildrop directories. If maildrops @@ -172,36 +175,22 @@ static struct bind binds[] = { void mts_init (char *name) { - unsigned char *bp; - char *cp, buffer[BUFSIZ]; - struct bind *b; + const char *cp; FILE *fp; static int inited = 0; - if (inited++ || (fp = fopen (mtsconf, "r")) == NULL) + if (inited++ || (fp = fopen (get_mtsconf_pathname(), "r")) == NULL) return; + mts_read_conf_file(fp); + fclose (fp); - while (fgets (buffer, sizeof(buffer), fp)) { - if (!(cp = strchr(buffer, '\n'))) - break; - *cp = 0; - if (*buffer == '#' || *buffer == '\0') - continue; - if (!(bp = strchr(buffer, ':'))) - break; - *bp++ = 0; - while (isspace (*bp)) - *bp++ = 0; - - for (b = binds; b->keyword; b++) - if (!strcmp (buffer, b->keyword)) - break; - if (b->keyword && (cp = tailor_value (bp))) - *b->value = cp; + cp = get_mtsuserconf_pathname(); + if (cp != NULL && + ((fp = fopen (get_mtsuserconf_pathname(), "r")) != NULL)) { + mts_read_conf_file(fp); + fclose (fp); } - fclose (fp); - Everyone = atoi (everyone); if (strstr(masquerade, "draft_from") != NULL) @@ -529,3 +518,50 @@ getuserinfo (void) return; } + +static const char* +get_mtsconf_pathname (void) +{ + const char *cp = getenv ( "MHMTSCONF "); + if (cp != NULL && *cp != '\0') { + return cp; + } + return mtsconf; +} + +static const char* +get_mtsuserconf_pathname (void) +{ + const char *cp = getenv ( "MHMTSUSERCONF" ); + if (cp != NULL && *cp != '\0') { + return cp; + } + return NULL; +} + +static void +mts_read_conf_file (FILE *fp) +{ + unsigned char *bp; + char *cp, buffer[BUFSIZ]; + struct bind *b; + + while (fgets (buffer, sizeof(buffer), fp)) { + if (!(cp = strchr(buffer, '\n'))) + break; + *cp = 0; + if (*buffer == '#' || *buffer == '\0') + continue; + if (!(bp = strchr(buffer, ':'))) + break; + *bp++ = 0; + while (isspace (*bp)) + *bp++ = 0; + + for (b = binds; b->keyword; b++) + if (!strcmp (buffer, b->keyword)) + break; + if (b->keyword && (cp = tailor_value (bp))) + *b->value = cp; + } +} diff --git a/uip/whom.c b/uip/whom.c index d04ef27..51ce5fe 100644 --- a/uip/whom.c +++ b/uip/whom.c @@ -13,6 +13,12 @@ #include #include +#ifndef CYRUS_SASL +# define SASLminc(a) (a) +#else /* CYRUS_SASL */ +# define SASLminc(a) 0 +#endif /* CYRUS_SASL */ + static struct swit switches[] = { #define ALIASW 0 { "alias aliasfile", 0 }, @@ -38,6 +44,14 @@ static struct swit switches[] = { { "server host", -6 }, #define SNOOPSW 11 { "snoop", -5 }, +#define SASLSW 12 + { "sasl", SASLminc(4) }, +#define SASLMECHSW 13 + { "saslmech mechanism", SASLminc(-5) }, +#define USERSW 14 + { "user username", SASLminc(-4) }, +#define PORTSW 15 + { "port server port name/number", 4 }, { NULL, 0 } }; @@ -88,6 +102,7 @@ main (int argc, char **argv) case CHKSW: case NOCHKSW: case SNOOPSW: + case SASLSW: vec[vecp++] = --cp; continue; @@ -117,6 +132,9 @@ main (int argc, char **argv) case ALIASW: case CLIESW: case SERVSW: + case USERSW: + case PORTSW: + case SASLMECHSW: vec[vecp++] = --cp; if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]);