diff options
author | gshapiro <gshapiro@FreeBSD.org> | 2002-06-11 21:12:04 +0000 |
---|---|---|
committer | gshapiro <gshapiro@FreeBSD.org> | 2002-06-11 21:12:04 +0000 |
commit | faacdfb2c2946459651449cedf08a1bc29aee731 (patch) | |
tree | 546131e3b171104de8ab1498603b992a6971ec6a /contrib/sendmail/src/srvrsmtp.c | |
parent | e226f8e879ed5a8d2f5cc433067b698e07dce0b6 (diff) | |
download | FreeBSD-src-faacdfb2c2946459651449cedf08a1bc29aee731.zip FreeBSD-src-faacdfb2c2946459651449cedf08a1bc29aee731.tar.gz |
Import sendmail 8.12.4
Diffstat (limited to 'contrib/sendmail/src/srvrsmtp.c')
-rw-r--r-- | contrib/sendmail/src/srvrsmtp.c | 234 |
1 files changed, 217 insertions, 17 deletions
diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c index 1210ee8..bbcd31f 100644 --- a/contrib/sendmail/src/srvrsmtp.c +++ b/contrib/sendmail/src/srvrsmtp.c @@ -16,7 +16,7 @@ # include <libmilter/mfdef.h> #endif /* MILTER */ -SM_RCSID("@(#)$Id: srvrsmtp.c,v 1.1.1.10 2002/04/10 03:04:52 gshapiro Exp $") +SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.827 2002/05/28 14:29:57 ca Exp $") #if SASL || STARTTLS # include <sys/time.h> @@ -380,17 +380,24 @@ smtp(nullserver, d_flags, e) int result; volatile int authenticating; char *user; - char *in, *out, *out2; + char *in, *out2; +# if SASL >= 20000 + char *auth_id; + const char *out; + sasl_ssf_t ext_ssf; +# else /* SASL >= 20000 */ + char *out; const char *errstr; + sasl_external_properties_t ext_ssf; +# endif /* SASL >= 20000 */ + sasl_security_properties_t ssp; + sasl_ssf_t *ssf; unsigned int inlen, out2len; unsigned int outlen; char *volatile auth_type; char *mechlist; volatile unsigned int n_mechs; unsigned int len; - sasl_security_properties_t ssp; - sasl_external_properties_t ext_ssf; - sasl_ssf_t *ssf; #endif /* SASL */ #if STARTTLS int r; @@ -507,14 +514,17 @@ smtp(nullserver, d_flags, e) /* SASL server new connection */ if (sasl_ok) { -# if SASL > 10505 +# if SASL >= 20000 + result = sasl_server_new("smtp", hostname, NULL, NULL, NULL, + NULL, 0, &conn); +# elif SASL > 10505 /* use empty realm: only works in SASL > 1.5.5 */ result = sasl_server_new("smtp", hostname, "", NULL, 0, &conn); -# else /* SASL > 10505 */ +# else /* SASL >= 20000 */ /* use no realm -> realm is set to hostname by SASL lib */ result = sasl_server_new("smtp", hostname, NULL, NULL, 0, &conn); -# endif /* SASL > 10505 */ +# endif /* SASL >= 20000 */ sasl_ok = result == SASL_OK; if (!sasl_ok) { @@ -529,13 +539,59 @@ smtp(nullserver, d_flags, e) /* ** SASL set properties for sasl ** set local/remote IP - ** XXX only IPv4: Cyrus SASL doesn't support anything else + ** XXX Cyrus SASL v1 only supports IPv4 ** ** XXX where exactly are these used/required? ** Kerberos_v4 */ -# if NETINET +# if SASL >= 20000 +# if NETINET || NETINET6 + in = macvalue(macid("{daemon_family}"), e); + if (in != NULL && ( +# if NETINET6 + strcmp(in, "inet6") == 0 || +# endif /* NETINET6 */ + strcmp(in, "inet") == 0)) + { + SOCKADDR_LEN_T addrsize; + SOCKADDR saddr_l; + SOCKADDR saddr_r; + char localip[60], remoteip[60]; + + addrsize = sizeof(saddr_r); + if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD, + NULL), + (struct sockaddr *) &saddr_r, + &addrsize) == 0) + { + if (iptostring(&saddr_r, addrsize, + remoteip, sizeof remoteip)) + { + sasl_setprop(conn, SASL_IPREMOTEPORT, + remoteip); + } + addrsize = sizeof(saddr_l); + if (getsockname(sm_io_getinfo(InChannel, + SM_IO_WHAT_FD, + NULL), + (struct sockaddr *) &saddr_l, + &addrsize) == 0) + { + if (iptostring(&saddr_l, addrsize, + localip, + sizeof localip)) + { + sasl_setprop(conn, + SASL_IPLOCALPORT, + localip); + } + } + } + } +# endif /* NETINET || NETINET6 */ +# else /* SASL >= 20000 */ +# if NETINET in = macvalue(macid("{daemon_family}"), e); if (in != NULL && strcmp(in, "inet") == 0) { @@ -560,7 +616,8 @@ smtp(nullserver, d_flags, e) &saddr_l); } } -# endif /* NETINET */ +# endif /* NETINET */ +# endif /* SASL >= 20000 */ auth_type = NULL; mechlist = NULL; @@ -591,10 +648,19 @@ smtp(nullserver, d_flags, e) ** currently we have none so zero */ +# if SASL >= 20000 + ext_ssf = 0; + auth_id = NULL; + sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL, + &ext_ssf) == SASL_OK) && + (sasl_setprop(conn, SASL_AUTH_EXTERNAL, + auth_id) == SASL_OK)); +# else /* SASL >= 20000 */ ext_ssf.ssf = 0; ext_ssf.auth_id = NULL; sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL, &ext_ssf) == SASL_OK; +# endif /* SASL >= 20000 */ } if (sasl_ok) n_mechs = saslmechs(conn, &mechlist); @@ -866,8 +932,14 @@ smtp(nullserver, d_flags, e) } /* could this be shorter? XXX */ +# if SASL >= 20000 + in = xalloc(strlen(inp) + 1); + result = sasl_decode64(inp, strlen(inp), in, + strlen(inp), &inlen); +# else /* SASL >= 20000 */ out = xalloc(strlen(inp)); result = sasl_decode64(inp, strlen(inp), out, &outlen); +# endif /* SASL >= 20000 */ if (result != SASL_OK) { authenticating = SASL_NOT_AUTH; @@ -875,11 +947,20 @@ smtp(nullserver, d_flags, e) /* rfc 2254 4. */ message("501 5.5.4 cannot decode AUTH parameter %s", inp); +# if SASL >= 20000 + sm_free(in); +# endif /* SASL >= 20000 */ continue; } +# if SASL >= 20000 + result = sasl_server_step(conn, in, inlen, + &out, &outlen); + sm_free(in); +# else /* SASL >= 20000 */ result = sasl_server_step(conn, out, outlen, &out, &outlen, &errstr); +# endif /* SASL >= 20000 */ /* get an OK if we're done */ if (result == SASL_OK) @@ -890,6 +971,13 @@ smtp(nullserver, d_flags, e) macdefine(&BlankEnvelope.e_macro, A_TEMP, macid("{auth_type}"), auth_type); +# if SASL >= 20000 + user = macvalue(macid("{auth_authen}"), e); + + /* get security strength (features) */ + result = sasl_getprop(conn, SASL_SSF, + (const void **) &ssf); +# else /* SASL >= 20000 */ result = sasl_getprop(conn, SASL_USERNAME, (void **)&user); if (result != SASL_OK) @@ -914,6 +1002,7 @@ smtp(nullserver, d_flags, e) /* get security strength (features) */ result = sasl_getprop(conn, SASL_SSF, (void **) &ssf); +# endif /* SASL >= 20000 */ if (result != SASL_OK) { macdefine(&BlankEnvelope.e_macro, @@ -995,11 +1084,14 @@ smtp(nullserver, d_flags, e) sm_dprintf("AUTH continue: msg='%s' len=%u\n", out2, out2len); } +# if SASL >= 20000 + sm_free(out2); +# endif /* SASL >= 20000 */ } else { /* not SASL_OK or SASL_CONT */ - message("500 5.7.0 authentication failed"); + message("535 5.7.0 authentication failed"); if (LogLevel > 9) sm_syslog(LOG_WARNING, e->e_id, "AUTH failure (%s): %s (%d) %s", @@ -1007,7 +1099,11 @@ smtp(nullserver, d_flags, e) sasl_errstring(result, NULL, NULL), result, +# if SASL >= 20000 + sasl_errdetail(conn)); +# else /* SASL >= 20000 */ errstr == NULL ? "" : errstr); +# endif /* SASL >= 20000 */ authenticating = SASL_NOT_AUTH; } } @@ -1181,10 +1277,16 @@ smtp(nullserver, d_flags, e) } } + if (*p == '\0') + { + message("501 5.5.2 AUTH mechanism must be specified"); + break; + } + /* check whether mechanism is available */ if (iteminlist(p, mechlist, " ") == NULL) { - message("503 5.3.3 AUTH mechanism %.32s not available", + message("504 5.3.3 AUTH mechanism %.32s not available", p); break; } @@ -1192,9 +1294,15 @@ smtp(nullserver, d_flags, e) if (ismore) { /* could this be shorter? XXX */ +# if SASL >= 20000 + in = xalloc(strlen(q) + 1); + result = sasl_decode64(q, strlen(q), in, + strlen(q), &inlen); +# else /* SASL >= 20000 */ in = sm_rpool_malloc(e->e_rpool, strlen(q)); result = sasl_decode64(q, strlen(q), in, &inlen); +# endif /* SASL >= 20000 */ if (result != SASL_OK) { message("501 5.5.4 cannot BASE64 decode '%s'", @@ -1205,6 +1313,9 @@ smtp(nullserver, d_flags, e) result, q); /* start over? */ authenticating = SASL_NOT_AUTH; +# if SASL >= 20000 + sm_free(in); +# endif /* SASL >= 20000 */ in = NULL; inlen = 0; break; @@ -1217,12 +1328,19 @@ smtp(nullserver, d_flags, e) } /* see if that auth type exists */ +# if SASL >= 20000 + result = sasl_server_start(conn, p, in, inlen, + &out, &outlen); + if (in != NULL) + sm_free(in); +# else /* SASL >= 20000 */ result = sasl_server_start(conn, p, in, inlen, &out, &outlen, &errstr); +# endif /* SASL >= 20000 */ if (result != SASL_OK && result != SASL_CONTINUE) { - message("500 5.7.0 authentication failed"); + message("535 5.7.0 authentication failed"); if (LogLevel > 9) sm_syslog(LOG_ERR, e->e_id, "AUTH failure (%s): %s (%d) %s", @@ -1230,7 +1348,11 @@ smtp(nullserver, d_flags, e) sasl_errstring(result, NULL, NULL), result, +# if SASL >= 20000 + sasl_errdetail(conn)); +# else /* SASL >= 20000 */ errstr); +# endif /* SASL >= 20000 */ break; } auth_type = newstr(p); @@ -1264,6 +1386,9 @@ smtp(nullserver, d_flags, e) message("334 %s", out2); authenticating = SASL_PROC_AUTH; } +# if SASL >= 20000 + sm_free(out2); +# endif /* SASL >= 20000 */ break; #endif /* SASL */ @@ -1494,12 +1619,23 @@ smtp(nullserver, d_flags, e) char *s; s = macvalue(macid("{cipher_bits}"), e); +# if SASL >= 20000 + if (s != NULL && (ext_ssf = atoi(s)) > 0) + { + auth_id = macvalue(macid("{cert_subject}"), + e); + sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL, + &ext_ssf) == SASL_OK) && + (sasl_setprop(conn, SASL_AUTH_EXTERNAL, + auth_id) == SASL_OK)); +# else /* SASL >= 20000 */ if (s != NULL && (ext_ssf.ssf = atoi(s)) > 0) { ext_ssf.auth_id = macvalue(macid("{cert_subject}"), e); sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL, &ext_ssf) == SASL_OK; +# endif /* SASL >= 20000 */ mechlist = NULL; if (sasl_ok) n_mechs = saslmechs(conn, @@ -1591,6 +1727,7 @@ smtp(nullserver, d_flags, e) break; } + ok = true; for (q = p; *q != '\0'; q++) { if (!isascii(*q)) @@ -1600,13 +1737,16 @@ smtp(nullserver, d_flags, e) if (isspace(*q)) { *q = '\0'; + + /* only complain if strict check */ + ok = AllowBogusHELO; break; } if (strchr("[].-_#", *q) == NULL) break; } - if (*q == '\0') + if (*q == '\0' && ok) { q = "pleased to meet you"; sendinghost = sm_strdup_x(p); @@ -2254,7 +2394,7 @@ smtp(nullserver, d_flags, e) macdefine(&e->e_macro, A_PERM, macid("{rcpt_mailer}"), NULL); macdefine(&e->e_macro, A_PERM, - macid("{rcpt_relay}"), NULL); + macid("{rcpt_host}"), NULL); macdefine(&e->e_macro, A_PERM, macid("{rcpt_addr}"), NULL); macdefine(&e->e_macro, A_PERM, @@ -2588,7 +2728,8 @@ doquit: logsender(e, NULL); e->e_flags &= ~EF_LOGSENDER; - if (lognullconnection && LogLevel > 5) + if (lognullconnection && LogLevel > 5 && + nullserver == NULL) { char *d; @@ -2725,6 +2866,7 @@ smtp_data(smtp, e) ADDRESS *a; ENVELOPE *ee; char *id; + char *oldid; char buf[32]; SmtpPhase = "server DATA"; @@ -2945,8 +3087,13 @@ smtp_data(smtp, e) ee->e_to = NULL; } + /* put back id for SMTP logging in putoutmsg() */ + oldid = CurEnv->e_id; + CurEnv->e_id = id; + /* issue success message */ message("250 2.0.0 %s Message accepted for delivery", id); + CurEnv->e_id = oldid; /* if we just queued, poke it */ if (doublequeue) @@ -3726,9 +3873,15 @@ saslmechs(conn, mechlist) int len, num, result; /* "user" is currently unused */ +# if SASL >= 20000 + result = sasl_listmech(conn, NULL, + "", " ", "", (const char **) mechlist, + (unsigned int *)&len, (unsigned int *)&num); +# else /* SASL >= 20000 */ result = sasl_listmech(conn, "user", /* XXX */ "", " ", "", mechlist, (unsigned int *)&len, (unsigned int *)&num); +# endif /* SASL >= 20000 */ if (result != SASL_OK) { if (LogLevel > 9) @@ -3754,6 +3907,52 @@ saslmechs(conn, mechlist) } return num; } + +# if SASL >= 20000 +/* +** PROXY_POLICY -- define proxy policy for AUTH +** +** Parameters: +** conn -- unused. +** context -- unused. +** requested_user -- authorization identity. +** rlen -- authorization identity length. +** auth_identity -- authentication identity. +** alen -- authentication identity length. +** def_realm -- default user realm. +** urlen -- user realm length. +** propctx -- unused. +** +** Returns: +** ok? +** +** Side Effects: +** sets {auth_authen} macro. +*/ + +int +proxy_policy(conn, context, requested_user, rlen, auth_identity, alen, + def_realm, urlen, propctx) + sasl_conn_t *conn; + void *context; + const char *requested_user; + unsigned rlen; + const char *auth_identity; + unsigned alen; + const char *def_realm; + unsigned urlen; + struct propctx *propctx; +{ + if (auth_identity == NULL) + return SASL_FAIL; + + macdefine(&BlankEnvelope.e_macro, A_TEMP, + macid("{auth_authen}"), (char *) auth_identity); + + return SASL_OK; +} +# else /* SASL >= 20000 */ + /* ** PROXY_POLICY -- define proxy policy for AUTH ** @@ -3781,6 +3980,7 @@ proxy_policy(context, auth_identity, requested_user, user, errstr) *user = newstr(auth_identity); return SASL_OK; } +# endif /* SASL >= 20000 */ #endif /* SASL */ #if STARTTLS |