diff options
author | Gregory Neil Shapiro <gshapiro@FreeBSD.org> | 2010-01-26 04:17:18 +0000 |
---|---|---|
committer | Gregory Neil Shapiro <gshapiro@FreeBSD.org> | 2010-01-26 04:17:18 +0000 |
commit | 09b16018d032d94de7fbaf59c4d6fc4a43c4d610 (patch) | |
tree | 25902a53d874255d42002dd157e36601e71e2df5 /src | |
parent | 7db286411e6127edcdd31f558ac20de5c63055b0 (diff) | |
download | src-test2-09b16018d032d94de7fbaf59c4d6fc4a43c4d610.tar.gz src-test2-09b16018d032d94de7fbaf59c4d6fc4a43c4d610.zip |
Notes
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.m4 | 2 | ||||
-rw-r--r-- | src/README | 5 | ||||
-rw-r--r-- | src/TRACEFLAGS | 3 | ||||
-rw-r--r-- | src/collect.c | 5 | ||||
-rw-r--r-- | src/conf.c | 62 | ||||
-rw-r--r-- | src/conf.h | 15 | ||||
-rw-r--r-- | src/daemon.c | 11 | ||||
-rw-r--r-- | src/deliver.c | 37 | ||||
-rw-r--r-- | src/envelope.c | 18 | ||||
-rw-r--r-- | src/headers.c | 17 | ||||
-rw-r--r-- | src/main.c | 35 | ||||
-rw-r--r-- | src/map.c | 42 | ||||
-rw-r--r-- | src/milter.c | 95 | ||||
-rw-r--r-- | src/queue.c | 83 | ||||
-rw-r--r-- | src/ratectrl.c | 52 | ||||
-rw-r--r-- | src/readcf.c | 165 | ||||
-rw-r--r-- | src/savemail.c | 4 | ||||
-rw-r--r-- | src/sendmail.0 | 4 | ||||
-rw-r--r-- | src/sendmail.8 | 6 | ||||
-rw-r--r-- | src/sendmail.h | 26 | ||||
-rw-r--r-- | src/sfsasl.c | 4 | ||||
-rw-r--r-- | src/srvrsmtp.c | 105 | ||||
-rw-r--r-- | src/tls.c | 80 | ||||
-rw-r--r-- | src/usersmtp.c | 13 | ||||
-rw-r--r-- | src/util.c | 8 | ||||
-rw-r--r-- | src/version.c | 6 |
26 files changed, 673 insertions, 230 deletions
diff --git a/src/Makefile.m4 b/src/Makefile.m4 index fd015b4937a3..0fa337467d49 100644 --- a/src/Makefile.m4 +++ b/src/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.115 2008/03/27 16:13:33 ca Exp $ +dnl $Id: Makefile.m4,v 8.121 2009/12/15 22:39:23 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/src/README b/src/README index 34313fc8506c..9c4628ffede4 100644 --- a/src/README +++ b/src/README @@ -9,7 +9,7 @@ # the sendmail distribution. # # -# $Id: README,v 8.391 2008/02/12 16:38:21 ca Exp $ +# $Id: README,v 8.392 2009/04/10 17:49:19 gshapiro Exp $ # This directory contains the source files for sendmail(TM). @@ -32,6 +32,7 @@ For detailed instructions, please read the document ../doc/op/op.me: cd ../doc/op ; make op.ps op.txt Sendmail is a trademark of Sendmail, Inc. +US Patent Numbers 6865671, 6986037. +-------------------+ @@ -1847,4 +1848,4 @@ util.c Some general purpose routines used by sendmail. version.c The version number and information about this version of sendmail. -(Version $Revision: 8.391 $, last update $Date: 2008/02/12 16:38:21 $ ) +(Version $Revision: 8.392 $, last update $Date: 2009/04/10 17:49:19 $ ) diff --git a/src/TRACEFLAGS b/src/TRACEFLAGS index a6249fd2c477..6fdfdd97df1d 100644 --- a/src/TRACEFLAGS +++ b/src/TRACEFLAGS @@ -1,4 +1,4 @@ -# $Id: TRACEFLAGS,v 8.47 2006/09/11 22:36:32 ca Exp $ +# $Id: TRACEFLAGS,v 8.48 2008/11/03 21:09:26 gshapiro Exp $ 0, 4 main.c main canonical name, UUCP node name, a.k.a.s 0, 15 main.c main print configuration 0, 44 util.c printav print address of each string @@ -86,6 +86,7 @@ 70 queue.c quarantining 71,>99 milter.c quarantine on errors 73 queue.c shared memory updates +74,>99 map.c LDAP map defer 80 content length 81 sun remote mode 83 collect.c timeout diff --git a/src/collect.c b/src/collect.c index 0a2cdaba83eb..f5d72477c510 100644 --- a/src/collect.c +++ b/src/collect.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: collect.c,v 8.282 2008/01/31 18:48:29 ca Exp $") +SM_RCSID("@(#)$Id: collect.c,v 8.284 2008/08/06 05:26:24 ca Exp $") static void eatfrom __P((char *volatile, ENVELOPE *)); static void collect_doheader __P((ENVELOPE *)); @@ -847,6 +847,9 @@ readerr: } /* Log collection information. */ + if (tTd(92, 2)) + sm_dprintf("collect: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4) { logsender(e, e->e_msgid); diff --git a/src/conf.c b/src/conf.c index bf9705712c44..8d8f9ed6b147 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: conf.c,v 8.1141 2008/04/14 02:09:35 ca Exp $") +SM_RCSID("@(#)$Id: conf.c,v 8.1153 2009/12/18 17:25:12 ca Exp $") #include <sm/sendmail.h> #include <sendmail/pathnames.h> @@ -392,6 +392,9 @@ setdefaults(e) #if REQUIRES_DIR_FSYNC RequiresDirfsync = true; #endif /* REQUIRES_DIR_FSYNC */ +#if _FFR_RCPTTHROTDELAY + BadRcptThrottleDelay = 1; +#endif /* _FFR_RCPTTHROTDELAY */ ConnectionRateWindowSize = 60; setupmaps(); setupqueues(); @@ -782,7 +785,7 @@ inithostmaps() else if (strcmp(maptype[i], "ldap") == 0 && stab("aliases.ldap", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "aliases.ldap ldap -b . -h localhost -k mail=%0 -v mailgroup", + (void) sm_strlcpy(buf, "aliases.ldap ldap -b . -h localhost -k mail=%0 -v mailgroup", sizeof buf); (void) makemapentry(buf); } @@ -968,7 +971,10 @@ switch_map_find(service, maptype, mapreturn) p = strpbrk(buf, "#\n"); if (p != NULL) *p = '\0'; - p = strpbrk(buf, " \t"); +#ifndef SM_NSSWITCH_DELIMS +# define SM_NSSWITCH_DELIMS " \t" +#endif /* SM_NSSWITCH_DELIMS */ + p = strpbrk(buf, SM_NSSWITCH_DELIMS); if (p != NULL) *p++ = '\0'; if (buf[0] == '\0') @@ -981,7 +987,7 @@ switch_map_find(service, maptype, mapreturn) buf); continue; } - while (isspace(*p)) + while (isascii(*p) && isspace(*p)) p++; if (*p == '\0') continue; @@ -1007,7 +1013,7 @@ switch_map_find(service, maptype, mapreturn) if (p == NULL) break; *p++ = '\0'; - while (isspace(*p)) + while (isascii(*p) && isspace(*p)) p++; } if (svcno < MAXMAPSTACK) @@ -2282,7 +2288,8 @@ refuseconnections(e, dn, active) # define MIN_DELAY_LOG 90 /* wait before logging this again */ # define D_MSG_LA "delaying connections on daemon %s: load average=%d >= %d" /* sleep to flatten out connection load */ - sm_setproctitle(true, e, D_MSG_LA, Daemons[dn].d_name, limit); + sm_setproctitle(true, e, D_MSG_LA, Daemons[dn].d_name, + CurrentLA, limit); if (LogLevel > 8 && (now = curtime()) > log_delay) { sm_syslog(LOG_INFO, NOQID, D_MSG_LA, @@ -3374,6 +3381,10 @@ enoughdiskspace(msize, e) { int i; +#if _FFR_TESTS + if (tTd(4, 101)) + return false; +#endif /* _FFR_TESTS */ if (MinBlocksFree <= 0 && msize <= 0) { if (tTd(4, 80)) @@ -4074,7 +4085,7 @@ strtol(nptr, endptr, base) */ do { c = *s++; - } while (isspace(c)); + } while (isascii(c) && isspace(c)); if (c == '-') { neg = 1; c = *s++; @@ -4110,9 +4121,9 @@ strtol(nptr, endptr, base) cutlim = cutoff % (unsigned long) base; cutoff /= (unsigned long) base; for (acc = 0, any = 0;; c = *s++) { - if (isdigit(c)) + if (isascii(c) && isdigit(c)) c -= '0'; - else if (isalpha(c)) + else if (isascii(c) && isalpha(c)) c -= isupper(c) ? 'A' - 10 : 'a' - 10; else break; @@ -6043,6 +6054,10 @@ char *FFRCompileOptions[] = /* Deal with MTAs that send a reply during the DATA phase. */ "_FFR_CATCH_BROKEN_MTAS", #endif /* _FFR_CATCH_BROKEN_MTAS */ +#if _FFR_CHECKCONFIG + /* New OpMode to check the configuration file */ + "_FFR_CHECKCONFIG", +#endif /* _FFR_CHECKCONFIG */ #if _FFR_CHK_QUEUE /* Stricter checks about queue directory permissions. */ "_FFR_CHK_QUEUE", @@ -6117,6 +6132,10 @@ char *FFRCompileOptions[] = /* EightBitAddrOK: allow 8-bit e-mail addresses */ "_FFR_EIGHT_BIT_ADDR_OK", #endif /* _FFR_EIGHT_BIT_ADDR_OK */ +#if _FFR_EXPDELAY + /* exponential queue delay */ + "_FFR_EXPDELAY", +#endif /* _FFR_EXPDELAY */ #if _FFR_EXTRA_MAP_CHECK /* perform extra checks on $( $) in R lines */ "_FFR_EXTRA_MAP_CHECK", @@ -6175,10 +6194,17 @@ char *FFRCompileOptions[] = /* Ignore extensions offered in response to HELO */ "_FFR_IGNORE_EXT_ON_HELO", #endif /* _FFR_IGNORE_EXT_ON_HELO */ +#if _FFR_LINUX_MHNL + /* Set MAXHOSTNAMELEN to 256 (Linux) */ + "_FFR_LINUX_MHNL", +#endif /* _FFR_LINUX_MHNL */ #if _FFR_LOCAL_DAEMON /* Local daemon mode (-bl) which only accepts loopback connections */ "_FFR_LOCAL_DAEMON", #endif /* _FFR_LOCAL_DAEMON */ +#if _FFR_MAIL_MACRO + "_FFR_MAIL_MACRO", +#endif /* _FFR_MAIL_MACRO */ #if _FFR_MAXDATASIZE /* ** It is possible that a header is larger than MILTER_CHUNK_SIZE, @@ -6199,6 +6225,10 @@ char *FFRCompileOptions[] = /* Limit sleep(2) time in libsm/clock.c */ "_FFR_MAX_SLEEP_TIME", #endif /* _FFR_MAX_SLEEP_TIME */ +#if _FFR_MDS_NEGOTIATE + /* MaxDataSize negotation with libmilter */ + "_FFR_MDS_NEGOTIATE", +#endif /* _FFR_MDS_NEGOTIATE */ #if _FFR_MEMSTAT /* Check free memory */ "_FFR_MEMSTAT", @@ -6232,6 +6262,10 @@ char *FFRCompileOptions[] = "_FFR_MILTER_CHECK_REJECTIONS_TOO", #endif /* _FFR_MILTER_CHECK_REJECTIONS_TOO */ +#if _FFR_MILTER_ENHSC + /* extract enhanced status code from milter replies for dsn= logging */ + "_FFR_MILTER_ENHSC", +#endif /* _FFR_MILTER_ENHSC */ #if _FFR_MIME7TO8_OLD /* Old mime7to8 code, the new is broken for at least one example. */ "_FFR_MIME7TO8_OLD", @@ -6285,6 +6319,10 @@ char *FFRCompileOptions[] = /* Debug output for the queue scheduler. */ "_FFR_QUEUE_SCHED_DBG", #endif /* _FFR_QUEUE_SCHED_DBG */ +#if _FFR_RCPTTHROTDELAY + /* configurable delay for BadRcptThrottle */ + "_FFR_RCPTTHROTDELAY" +#endif /* _FFR_RCPTTHROTDELAY */ #if _FFR_REDIRECTEMPTY /* ** envelope <> can't be sent to mailing lists, only owner- @@ -6361,6 +6399,10 @@ char *FFRCompileOptions[] = /* SuperSafe per DaemonPortOptions: 'T' (better letter?) */ "_FFR_SS_PER_DAEMON", #endif /* _FFR_SS_PER_DAEMON */ +#if _FFR_TESTS + /* enable some test code */ + "_FFR_TESTS", +#endif /* _FFR_TESTS */ #if _FFR_TIMERS /* Donated code (unused). */ "_FFR_TIMERS", diff --git a/src/conf.h b/src/conf.h index f1386c4b61f6..dff37ff99fee 100644 --- a/src/conf.h +++ b/src/conf.h @@ -10,7 +10,7 @@ * the sendmail distribution. * * - * $Id: conf.h,v 8.574 2006/11/29 00:36:06 ca Exp $ + * $Id: conf.h,v 8.575 2009/03/25 20:04:00 ca Exp $ */ /* @@ -123,9 +123,18 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ #define DATA_PROGRESS_TIMEOUT 300 /* how often to check DATA progress */ #define ENHSCLEN 10 /* max len of enhanced status code */ #define DEFAULT_MAX_RCPT 100 /* max number of RCPTs per envelope */ -#define MAXQUEUEGROUPS 50 /* max # of queue groups */ +#ifndef MAXQUEUEGROUPS +# define MAXQUEUEGROUPS 50 /* max # of queue groups */ /* must be less than BITMAPBITS for DoQueueRun */ -#define MAXWORKGROUPS 50 /* max # of work groups */ +#endif /* MAXQUEUEGROUPS */ +#if MAXQUEUEGROUPS >= BITMAPBITS + ERROR _MAXQUEUEGROUPS must be less than _BITMAPBITS +#endif /* MAXQUEUEGROUPS >= BITMAPBITS */ + +#ifndef MAXWORKGROUPS +# define MAXWORKGROUPS 50 /* max # of work groups */ +#endif /* MAXWORKGROUPS */ + #define MAXFILESYS BITMAPBITS /* max # of queue file systems * must be <= BITMAPBITS */ #ifndef FILESYS_UPDATE_INTERVAL diff --git a/src/daemon.c b/src/daemon.c index 06a36c7e6487..983ad2fe3ede 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2007, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include <sendmail.h> #include "map.h" -SM_RCSID("@(#)$Id: daemon.c,v 8.680 2008/02/14 00:20:26 ca Exp $") +SM_RCSID("@(#)$Id: daemon.c,v 8.683 2009/12/18 01:12:40 ca Exp $") #if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) # define USE_SOCK_STREAM 1 @@ -199,7 +199,7 @@ getrequests(e) if (tTd(15, 1)) { for (idx = 0; idx < NDaemons; idx++) - sm_dprintf("getrequests: daemon %s: %d\n", + sm_dprintf("getrequests: daemon %s: socket %d\n", Daemons[idx].d_name, Daemons[idx].d_socket); } @@ -2161,7 +2161,8 @@ makeconnection(host, port, mci, e, enough) case AF_INET: clt_addr.sin.sin_addr.s_addr = inet_addr(p); if (clt_addr.sin.sin_addr.s_addr != INADDR_NONE && - clt_addr.sin.sin_addr.s_addr != INADDR_LOOPBACK) + clt_addr.sin.sin_addr.s_addr != + htonl(INADDR_LOOPBACK)) { clt_bind = true; socksize = sizeof(struct sockaddr_in); @@ -2342,7 +2343,7 @@ makeconnection(host, port, mci, e, enough) } } gothostent: - if (hp == NULL) + if (hp == NULL || hp->h_addr == NULL) { #if NAMED_BIND /* check for name server timeouts */ diff --git a/src/deliver.c b/src/deliver.c index ed60e47a3c96..0322c956ef2b 100644 --- a/src/deliver.c +++ b/src/deliver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include <sendmail.h> #include <sm/time.h> -SM_RCSID("@(#)$Id: deliver.c,v 8.1015 2007/10/17 21:35:30 ca Exp $") +SM_RCSID("@(#)$Id: deliver.c,v 8.1020 2009/12/18 17:08:01 ca Exp $") #if HASSETUSERCONTEXT # include <login_cap.h> @@ -575,12 +575,12 @@ sendall(e, mode) #endif /* HASFLOCK */ if (e->e_nrcpts > 0) e->e_flags |= EF_INQUEUE; - dropenvelope(e, splitenv != NULL, true); + (void) dropenvelope(e, splitenv != NULL, true); for (ee = splitenv; ee != NULL; ee = ee->e_sibling) { if (ee->e_nrcpts > 0) ee->e_flags |= EF_INQUEUE; - dropenvelope(ee, false, true); + (void) dropenvelope(ee, false, true); } return; @@ -602,7 +602,7 @@ sendall(e, mode) /* now drop the envelope in the parent */ e->e_flags |= EF_INQUEUE; - dropenvelope(e, splitenv != NULL, false); + (void) dropenvelope(e, splitenv != NULL, false); /* arrange to reacquire lock after fork */ e->e_id = qid; @@ -615,7 +615,7 @@ sendall(e, mode) /* drop envelope in parent */ ee->e_flags |= EF_INQUEUE; - dropenvelope(ee, false, false); + (void) dropenvelope(ee, false, false); /* and save qid for reacquisition */ ee->e_id = qid; @@ -762,14 +762,14 @@ sendall(e, mode) } sendenvelope(e, mode); - dropenvelope(e, true, true); + (void) dropenvelope(e, true, true); for (ee = splitenv; ee != NULL; ee = ee->e_sibling) { CurEnv = ee; if (mode != SM_VERIFY) openxscript(ee); sendenvelope(ee, mode); - dropenvelope(ee, true, true); + (void) dropenvelope(ee, true, true); } CurEnv = e; @@ -1391,7 +1391,7 @@ deliver(e, firstto) else p = e->e_from.q_paddr; rpath = remotename(p, m, RF_SENDERADDR|RF_CANONICAL, &rcode, e); - if (strlen(rpath) > MAXSHORTSTR) + if (strlen(rpath) > MAXNAME) { rpath = shortenstring(rpath, MAXSHORTSTR); @@ -2978,7 +2978,7 @@ reconnect: /* after switching to an encrypted connection */ char *s; /* - ** TLS negotation failed, what to do? + ** TLS negotiation failed, what to do? ** fall back to unencrypted connection ** or abort? How to decide? ** set a macro and call a ruleset. @@ -3021,7 +3021,7 @@ reconnect: /* after switching to an encrypted connection */ /* ** rcode == EX_SOFTWARE is special: - ** the TLS negotation failed + ** the TLS negotiation failed ** we have to drop the connection no matter what ** However, we call tls_server to give it the chance ** to log the problem and return an appropriate @@ -6075,8 +6075,9 @@ initclttls(tls_ok) return false; if (clt_ctx != NULL) return true; /* already done */ - tls_ok_clt = inittls(&clt_ctx, TLS_I_CLT, false, CltCertFile, - CltKeyFile, CACertPath, CACertFile, DHParams); + tls_ok_clt = inittls(&clt_ctx, TLS_I_CLT, Clt_SSL_Options, false, + CltCertFile, CltKeyFile, + CACertPath, CACertFile, DHParams); return tls_ok_clt; } @@ -6108,6 +6109,16 @@ starttls(m, mci, e) if (clt_ctx == NULL && !initclttls(true)) return EX_TEMPFAIL; + +# if USE_OPENSSL_ENGINE + if (!SSL_set_engine(NULL)) + { + sm_syslog(LOG_ERR, NOQID, + "STARTTLS=client, SSL_set_engine=failed"); + return EX_TEMPFAIL; + } +# endif /* USE_OPENSSL_ENGINE */ + smtpmessage("STARTTLS", m, mci); /* get the reply */ diff --git a/src/envelope.c b/src/envelope.c index 641c621a416c..022c3ca8b2d6 100644 --- a/src/envelope.c +++ b/src/envelope.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: envelope.c,v 8.305 2008/03/31 16:32:13 ca Exp $") +SM_RCSID("@(#)$Id: envelope.c,v 8.310 2009/12/18 17:08:01 ca Exp $") /* ** CLRSESSENVELOPE -- clear session oriented data in an envelope @@ -163,14 +163,14 @@ newenvelope(e, parent, rpool) ** split -- if true, split by recipient if message is queued up ** ** Returns: -** none. +** EX_* status (currently: 0: success, EX_IOERR on panic) ** ** Side Effects: ** housekeeping necessary to dispose of an envelope. ** Unlocks this queue file. */ -void +int dropenvelope(e, fulldrop, split) register ENVELOPE *e; bool fulldrop; @@ -209,12 +209,15 @@ dropenvelope(e, fulldrop, split) /* we must have an id to remove disk files */ if (id == NULL) - return; + return EX_OK; /* if verify-only mode, we can skip most of this */ if (OpMode == MD_VERIFY) goto simpledrop; + if (tTd(92, 2)) + sm_dprintf("dropenvelope: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) logsender(e, NULL); e->e_flags &= ~EF_LOGSENDER; @@ -618,7 +621,11 @@ simpledrop: } e->e_id = NULL; e->e_flags &= ~EF_HAS_DF; + if (panic) + return EX_IOERR; + return EX_OK; } + /* ** CLEARENVELOPE -- clear an envelope without unlocking ** @@ -714,6 +721,9 @@ clearenvelope(e, fullclear, rpool) bh = bh->h_link; nhp = &(*nhp)->h_link; } +#if _FFR_MILTER_ENHSC + e->e_enhsc[0] = '\0'; +#endif /* _FFR_MILTER_ENHSC */ } /* ** INITSYS -- initialize instantiation of system diff --git a/src/headers.c b/src/headers.c index 8e70fed7618e..c4bdc8770025 100644 --- a/src/headers.c +++ b/src/headers.c @@ -14,7 +14,7 @@ #include <sendmail.h> #include <sm/sendmail.h> -SM_RCSID("@(#)$Id: headers.c,v 8.312 2007/06/19 18:52:11 ca Exp $") +SM_RCSID("@(#)$Id: headers.c,v 8.317 2008/08/27 20:11:55 gshapiro Exp $") static HDR *allocheader __P((char *, char *, int, SM_RPOOL_T *, bool)); static size_t fix_mime_header __P((HDR *, ENVELOPE *)); @@ -715,7 +715,16 @@ hvalue(field, header) { if (!bitset(H_DEFAULT, h->h_flags) && sm_strcasecmp(h->h_field, field) == 0) - return h->h_value; + { + char *s; + + s = h->h_value; + if (s == NULL) + return NULL; + while (isascii(*s) && isspace(*s)) + s++; + return s; + } } return NULL; } @@ -1065,6 +1074,10 @@ eatheader(e, full, log) ** Log collection information. */ + if (tTd(92, 2)) + sm_dprintf("eatheader: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d, log=%d\n", + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel, + log); if (log && bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4) { logsender(e, e->e_msgid); diff --git a/src/main.c b/src/main.c index d68d5b590d6b..1bbb070dace6 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2006, 2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -26,7 +26,7 @@ SM_UNUSED(static char copyright[]) = The Regents of the University of California. All rights reserved.\n"; #endif /* ! lint */ -SM_RCSID("@(#)$Id: main.c,v 8.967 2008/03/31 16:32:13 ca Exp $") +SM_RCSID("@(#)$Id: main.c,v 8.971 2009/12/18 17:08:01 ca Exp $") #if NETINET || NETINET6 @@ -129,7 +129,7 @@ int SyslogPrefixLen; /* estimated length of syslog prefix */ { \ if (extraprivs && \ OpMode != MD_DELIVER && OpMode != MD_SMTP && \ - OpMode != MD_ARPAFTP && \ + OpMode != MD_ARPAFTP && OpMode != MD_CHECKCONFIG && \ OpMode != MD_VERIFY && OpMode != MD_TEST) \ { \ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, \ @@ -401,6 +401,9 @@ main(argc, argv, envp) case MD_HOSTSTAT: case MD_PURGESTAT: case MD_ARPAFTP: +#if _FFR_CHECKCONFIG + case MD_CHECKCONFIG: +#endif /* _FFR_CHECKCONFIG */ OpMode = j; break; @@ -1192,7 +1195,7 @@ main(argc, argv, envp) } /* if we've had errors so far, exit now */ - if ((ExitStat != EX_OK && OpMode != MD_TEST) || + if ((ExitStat != EX_OK && OpMode != MD_TEST && OpMode != MD_CHECKCONFIG) || ExitStat == EX_OSERR) { finis(false, true, ExitStat); @@ -1566,6 +1569,7 @@ main(argc, argv, envp) break; case MD_TEST: + case MD_CHECKCONFIG: case MD_PRINT: case MD_PRINTNQE: case MD_FREEZE: @@ -1626,6 +1630,9 @@ main(argc, argv, envp) case MD_TEST: /* don't have persistent host status in test mode */ HostStatDir = NULL; + /* FALLTHROUGH */ + + case MD_CHECKCONFIG: if (Verbose == 0) Verbose = 2; BlankEnvelope.e_errormode = EM_PRINT; @@ -1933,8 +1940,8 @@ main(argc, argv, envp) } } - /* if we've had errors so far, exit now */ - if (ExitStat != EX_OK && OpMode != MD_TEST) + /* if checking config or have had errors so far, exit now */ + if (OpMode == MD_CHECKCONFIG || (ExitStat != EX_OK && OpMode != MD_TEST)) { finis(false, true, ExitStat); /* NOTREACHED */ @@ -1958,7 +1965,7 @@ main(argc, argv, envp) case MD_PRINT: /* print the queue */ HoldErrs = false; - dropenvelope(&BlankEnvelope, true, false); + (void) dropenvelope(&BlankEnvelope, true, false); (void) sm_signal(SIGPIPE, sigpipe); if (qgrp != NOQGRP) { @@ -1981,7 +1988,7 @@ main(argc, argv, envp) case MD_PRINTNQE: /* print number of entries in queue */ - dropenvelope(&BlankEnvelope, true, false); + (void) dropenvelope(&BlankEnvelope, true, false); (void) sm_signal(SIGPIPE, sigpipe); printnqe(smioout, NULL); finis(false, true, EX_OK); @@ -2133,8 +2140,8 @@ main(argc, argv, envp) else if (OpMode == MD_DAEMON || OpMode == MD_FGDAEMON || OpMode == MD_SMTP) { - /* check whether STARTTLS is turned off for the server */ - if (chkdaemonmodifiers(D_NOTLS)) + /* check whether STARTTLS is turned off */ + if (chkdaemonmodifiers(D_NOTLS) && chkclientmodifiers(D_NOTLS)) tls_ok = false; } else /* other modes don't need STARTTLS */ @@ -2530,7 +2537,7 @@ main(argc, argv, envp) } } } - dropenvelope(&MainEnvelope, true, false); + (void) dropenvelope(&MainEnvelope, true, false); #if STARTTLS /* init TLS for server, ignore result for now */ @@ -2952,7 +2959,11 @@ finis(drop, cleanup, exitstat) { if (CurEnv->e_id != NULL) { - dropenvelope(CurEnv, true, false); + int r; + + r = dropenvelope(CurEnv, true, false); + if (exitstat == EX_OK) + exitstat = r; sm_rpool_free(CurEnv->e_rpool); CurEnv->e_rpool = NULL; diff --git a/src/map.c b/src/map.c index 4248fd90f519..be88685babd9 100644 --- a/src/map.c +++ b/src/map.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1992, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: map.c,v 8.699 2007/10/10 00:06:45 ca Exp $") +SM_RCSID("@(#)$Id: map.c,v 8.705 2009/08/11 22:22:40 ca Exp $") #if LDAPMAP # include <sm/ldap.h> @@ -730,7 +730,7 @@ getcanonname(host, hbsize, trymx, pttl) int mapno; bool found = false; bool got_tempfail = false; - auto int status; + auto int status = EX_UNAVAILABLE; char *maptype[MAXMAPSTACK]; short mapreturn[MAXMAPACTIONS]; #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) @@ -1710,7 +1710,7 @@ lockdbm: { map->map_mflags |= MF_OPEN; map->map_pid = CurrentPid; - if ((omode && O_ACCMODE) == O_RDWR) + if ((omode & O_ACCMODE) == O_RDWR) map->map_mflags |= MF_WRITABLE; goto lockdbm; } @@ -2359,7 +2359,7 @@ db_map_lookup(map, name, av, statp) { map->map_mflags |= MF_OPEN; map->map_pid = CurrentPid; - if ((omode && O_ACCMODE) == O_RDWR) + if ((omode & O_ACCMODE) == O_RDWR) map->map_mflags |= MF_WRITABLE; db = (DB *) map->map_db2; goto lockdb; @@ -3415,6 +3415,18 @@ ldapmap_open(map, mode) else id = "localhost"; + if (tTd(74, 104)) + { + extern MAPCLASS NullMapClass; + + /* debug mode: don't actually open an LDAP connection */ + map->map_orgclass = map->map_class; + map->map_class = &NullMapClass; + map->map_mflags |= MF_OPEN; + map->map_pid = CurrentPid; + return true; + } + /* No connection yet, connect */ if (!sm_ldap_start(map->map_mname, lmap)) { @@ -3514,12 +3526,12 @@ sunet_id_hash(str) p_last = p; while (*p != '\0') { - if (islower(*p) || isdigit(*p)) + if (isascii(*p) && (islower(*p) || isdigit(*p))) { *p_last = *p; p_last++; } - else if (isupper(*p)) + else if (isascii(*p) && isupper(*p)) { *p_last = tolower(*p); p_last++; @@ -3967,6 +3979,10 @@ ldapmap_parseargs(map, args) map->map_coldelim = ' '; } +# if _FFR_LDAP_NETWORK_TIMEOUT + lmap->ldap_networktmo = 120; +# endif /* _FFR_LDAP_NETWORK_TIMEOUT */ + for (;;) { while (isascii(*p) && isspace(*p)) @@ -4066,7 +4082,7 @@ ldapmap_parseargs(map, args) case 'c': /* network (connect) timeout */ while (isascii(*++p) && isspace(*p)) continue; - lmap->ldap_networktmo.tv_sec = atoi(p); + lmap->ldap_networktmo = atoi(p); break; # endif /* _FFR_LDAP_NETWORK_TIMEOUT */ @@ -6687,6 +6703,13 @@ null_map_store(map, key, val) return; } +MAPCLASS NullMapClass = +{ + "null-map", NULL, 0, + NULL, null_map_lookup, null_map_store, + null_map_open, null_map_close, +}; + /* ** BOGUS stubs */ @@ -7325,7 +7348,8 @@ arith_map_lookup(map, name, av, statp) if (LogLevel > 10) sm_syslog(LOG_WARNING, NOQID, "arith_map: unknown operator %c", - isprint(*name) ? *name : '?'); + (isascii(*name) && isprint(*name)) ? + *name : '?'); return NULL; } if (boolres) diff --git a/src/milter.c b/src/milter.c index 816c7bf7d4ac..773dfa8f9c6d 100644 --- a/src/milter.c +++ b/src/milter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2006 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: milter.c,v 8.269 2007/06/06 17:26:12 ca Exp $") +SM_RCSID("@(#)$Id: milter.c,v 8.277 2009/11/06 00:57:06 ca Exp $") #if MILTER # include <sm/sendmail.h> @@ -514,7 +514,6 @@ milter_write(m, cmd, buf, len, to, e, where) ENVELOPE *e; const char *where; { - time_t writestart = (time_t) 0; ssize_t sl, i; int num_vectors; mi_int32 nl; @@ -532,12 +531,16 @@ milter_write(m, cmd, buf, len, to, e, where) if (len < 0 || len > MilterMaxDataSize) { if (tTd(64, 5)) - sm_dprintf("milter_write(%s): length %ld out of range\n", - m->mf_name, (long) len); + { + sm_dprintf("milter_write(%s): length %ld out of range, cmd=%c\n", + m->mf_name, (long) len, command); + sm_dprintf("milter_write(%s): buf=%s\n", + m->mf_name, str2prt(buf)); + } if (MilterLogLevel > 0) sm_syslog(LOG_ERR, e->e_id, - "milter_write(%s): length %ld out of range", - m->mf_name, (long) len); + "milter_write(%s): length %ld out of range, cmd=%c", + m->mf_name, (long) len, command); milter_error(m, e); return NULL; } @@ -594,10 +597,7 @@ milter_write(m, cmd, buf, len, to, e, where) } if (to > 0) - { - writestart = curtime(); MILTER_TIMEOUT("write", to, true, started, where); - } /* write the vector(s) */ i = writev(m->mf_sock, vector, num_vectors); @@ -1572,10 +1572,10 @@ static struct milteropt # define MO_LOGLEVEL 0x07 { "loglevel", MO_LOGLEVEL }, -# if _FFR_MAXDATASIZE +# if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE # define MO_MAXDATASIZE 0x08 { "maxdatasize", MO_MAXDATASIZE }, -# endif /* _FFR_MAXDATASIZE */ +# endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */ { NULL, (unsigned char)-1 }, }; @@ -1631,11 +1631,29 @@ milter_set_option(name, val, sticky) MilterLogLevel = atoi(val); break; -#if _FFR_MAXDATASIZE +# if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE case MO_MAXDATASIZE: +# if _FFR_MDS_NEGOTIATE MilterMaxDataSize = (size_t)atol(val); + if (MilterMaxDataSize != MILTER_MDS_64K && + MilterMaxDataSize != MILTER_MDS_256K && + MilterMaxDataSize != MILTER_MDS_1M) + { + sm_syslog(LOG_WARNING, NOQID, + "WARNING: Milter.%s=%d, allowed are only %d, %d, and %d", + name, MilterMaxDataSize, + MILTER_MDS_64K, MILTER_MDS_256K, + MILTER_MDS_1M); + if (MilterMaxDataSize < MILTER_MDS_64K) + MilterMaxDataSize = MILTER_MDS_64K; + else if (MilterMaxDataSize < MILTER_MDS_256K) + MilterMaxDataSize = MILTER_MDS_256K; + else + MilterMaxDataSize = MILTER_MDS_1M; + } +# endif /* _FFR_MDS_NEGOTIATE */ break; -#endif /* _FFR_MAXDATASIZE */ +# endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */ case MO_MACROS_CONNECT: if (macros == NULL) @@ -2411,6 +2429,12 @@ milter_negotiate(m, e, milters) mta_prot_flags = SMFI_CURR_PROT; mta_actions = SMFI_CURR_ACTS; #endif /* _FFR_MILTER_CHECK */ +#if _FFR_MDS_NEGOTIATE + if (MilterMaxDataSize == MILTER_MDS_256K) + mta_prot_flags |= SMFIP_MDS_256K; + else if (MilterMaxDataSize == MILTER_MDS_1M) + mta_prot_flags |= SMFIP_MDS_1M; +#endif /* _FFR_MDS_NEGOTIATE */ fvers = htonl(mta_prot_vers); pflags = htonl(mta_prot_flags); @@ -2525,6 +2549,39 @@ milter_negotiate(m, e, milters) goto error; } +#if _FFR_MDS_NEGOTIATE + /* use a table instead of sequence? */ + if (bitset(SMFIP_MDS_1M, m->mf_pflags)) + { + if (MilterMaxDataSize != MILTER_MDS_1M) + { + /* this should not happen... */ + sm_syslog(LOG_WARNING, NOQID, + "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d", + MilterMaxDataSize, MILTER_MDS_1M); + MilterMaxDataSize = MILTER_MDS_1M; + } + } + else if (bitset(SMFIP_MDS_256K, m->mf_pflags)) + { + if (MilterMaxDataSize != MILTER_MDS_256K) + { + sm_syslog(LOG_WARNING, NOQID, + "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d", + MilterMaxDataSize, MILTER_MDS_256K); + MilterMaxDataSize = MILTER_MDS_256K; + } + } + else if (MilterMaxDataSize != MILTER_MDS_64K) + { + sm_syslog(LOG_WARNING, NOQID, + "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d", + MilterMaxDataSize, MILTER_MDS_64K); + MilterMaxDataSize = MILTER_MDS_64K; + } + m->mf_pflags &= ~SMFI_INTERNAL; +#endif /* _FFR_MDS_NEGOTIATE */ + /* check for protocol feature mismatch */ if ((m->mf_pflags & mta_prot_flags) != m->mf_pflags) { @@ -2976,7 +3033,7 @@ milter_addheader(m, response, rlen, e) h->h_value = mh_value; else { - h->h_value = addleadingspace (mh_value, e->e_rpool); + h->h_value = addleadingspace(mh_value, e->e_rpool); SM_FREE(mh_value); } h->h_flags |= H_USER; @@ -3277,7 +3334,7 @@ milter_changeheader(m, response, rlen, e) h->h_value = mh_value; else { - h->h_value = addleadingspace (mh_value, e->e_rpool); + h->h_value = addleadingspace(mh_value, e->e_rpool); SM_FREE(mh_value); } h->h_flags |= H_USER; @@ -3330,7 +3387,7 @@ milter_split_response(response, rlen, pargc) return NULL; /* last entry is only for the name */ - s = (char **)malloc(nelem * (sizeof(*s))); + s = (char **)malloc((nelem + 1) * (sizeof(*s))); if (s == NULL) return NULL; s[0] = response; @@ -3813,7 +3870,7 @@ milter_init(e, state, milters) m->mf_sock < 0 ? "open" : "negotiate"); - /* if negotation failure, close socket */ + /* if negotiation failure, close socket */ milter_error(m, e); MILTER_CHECK_ERROR(true, continue); continue; @@ -4383,7 +4440,7 @@ milter_data(e, state) response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e, - "body"); + "eom"); if (m->mf_state == SMFS_ERROR) break; diff --git a/src/queue.c b/src/queue.c index d4c6369d0e6a..194f5250d663 100644 --- a/src/queue.c +++ b/src/queue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include <sendmail.h> #include <sm/sem.h> -SM_RCSID("@(#)$Id: queue.c,v 8.977 2008/02/15 23:19:58 ca Exp $") +SM_RCSID("@(#)$Id: queue.c,v 8.987 2009/12/18 17:08:01 ca Exp $") #include <dirent.h> @@ -134,7 +134,7 @@ static const char EmptyString[] = ""; static void grow_wlist __P((int, int)); static int multiqueue_cache __P((char *, int, QUEUEGRP *, int, unsigned int *)); -static int gatherq __P((int, int, bool, bool *, bool *)); +static int gatherq __P((int, int, bool, bool *, bool *, int *)); static int sortq __P((int)); static void printctladdr __P((ADDRESS *, SM_FILE_T *)); static bool readqf __P((ENVELOPE *, bool)); @@ -2106,7 +2106,7 @@ run_work_group(wgrp, flags) for (i = 0; i < Queue[qgrp]->qg_numqueues; i++) { - h = gatherq(qgrp, qdir, false, &full, &more); + (void) gatherq(qgrp, qdir, false, &full, &more, &h); #if SM_CONF_SHM if (ShmId != SM_SHM_NO_ID) QSHM_ENTRIES(Queue[qgrp]->qg_qpaths[qdir].qp_idx) = h; @@ -2450,6 +2450,7 @@ runqueueevent(ignore) ** full -- (optional) to be set 'true' if WorkList is full ** more -- (optional) to be set 'true' if there are still more ** messages in this queue not added to WorkList +** pnentries -- (optional) total nuber of entries in queue ** ** Returns: ** The number of request in the queue (not necessarily @@ -2472,25 +2473,26 @@ static int WorkListSize = 0; /* current max size of WorkList */ static int WorkListCount = 0; /* # of work items in WorkList */ static int -gatherq(qgrp, qdir, doall, full, more) +gatherq(qgrp, qdir, doall, full, more, pnentries) int qgrp; int qdir; bool doall; bool *full; bool *more; + int *pnentries; { register struct dirent *d; register WORK *w; register char *p; DIR *f; - int i, num_ent; - int wn; + int i, num_ent, wn, nentries; QUEUE_CHAR *check; char qd[MAXPATHLEN]; char qf[MAXPATHLEN]; wn = WorkListCount - 1; num_ent = 0; + nentries = 0; if (qdir == NOQDIR) (void) sm_strlcpy(qd, ".", sizeof(qd)); else @@ -2600,6 +2602,7 @@ gatherq(qgrp, qdir, doall, full, more) continue; } + ++nentries; check = QueueLimitId; while (check != NULL) { @@ -2855,6 +2858,21 @@ gatherq(qgrp, qdir, doall, full, more) break; case 'K': +#if _FFR_EXPDELAY + if (MaxQueueAge > 0) + { + time_t lasttry, delay; + + lasttry = (time_t) atol(&lbuf[1]); + delay = MIN(lasttry - w->w_ctime, + MaxQueueAge); + age = curtime() - lasttry; + if (age < delay) + w->w_tooyoung = true; + break; + } +#endif /* _FFR_EXPDELAY */ + age = curtime() - (time_t) atol(&lbuf[1]); if (age >= 0 && MinQueueAge > 0 && age < MinQueueAge) @@ -2900,6 +2918,8 @@ gatherq(qgrp, qdir, doall, full, more) *full = (wn >= MaxQueueRun && MaxQueueRun > 0) || (WorkList == NULL && wn > 0); + if (pnentries != NULL) + *pnentries = nentries; return i; } /* @@ -3331,8 +3351,8 @@ workcmpf4(a, b) ** WORKCMPF5 -- compare based on assigned random number ** ** Parameters: -** a -- the first argument (ignored). -** b -- the second argument (ignored). +** a -- the first argument. +** b -- the second argument. ** ** Returns: ** randomly 1/-1 @@ -3682,7 +3702,7 @@ dowork(qgrp, qdir, id, forkflag, requeueflag, e) finis(true, true, ExitStat); else { - dropenvelope(e, true, false); + (void) dropenvelope(e, true, false); sm_rpool_free(rpool); e->e_rpool = NULL; } @@ -3859,7 +3879,7 @@ doworklist(el, forkflag, requeueflag) /* do the delivery */ sendall(&e, SM_DELIVER); - dropenvelope(&e, true, false); + (void) dropenvelope(&e, true, false); } else { @@ -4834,7 +4854,7 @@ print_single_queue(qgrp, qdir) ** Read and order the queue. */ - nrequests = gatherq(qgrp, qdir, true, NULL, NULL); + nrequests = gatherq(qgrp, qdir, true, NULL, NULL, NULL); (void) sortq(Queue[qgrp]->qg_maxlist); /* @@ -5332,31 +5352,31 @@ static const char QueueIdChars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh */ # define queuenextid() CurrentPid - +#define QIC_LEN_SQR (QIC_LEN * QIC_LEN) void assign_queueid(e) register ENVELOPE *e; { pid_t pid = queuenextid(); - static int cX = 0; - static long random_offset; + static unsigned int cX = 0; + static unsigned int random_offset; struct tm *tm; char idbuf[MAXQFNAME - 2]; - int seq; + unsigned int seq; if (e->e_id != NULL) return; /* see if we need to get a new base time/pid */ - if (cX >= QIC_LEN * QIC_LEN || LastQueueTime == 0 || - LastQueuePid != pid) + if (cX >= QIC_LEN_SQR || LastQueueTime == 0 || LastQueuePid != pid) { time_t then = LastQueueTime; /* if the first time through, pick a random offset */ if (LastQueueTime == 0) - random_offset = get_random(); + random_offset = ((unsigned int)get_random()) + % QIC_LEN_SQR; while ((LastQueueTime = curtime()) == then && LastQueuePid == pid) @@ -5368,16 +5388,16 @@ assign_queueid(e) } /* - ** Generate a new sequence number between 0 and QIC_LEN*QIC_LEN-1. - ** This lets us generate up to QIC_LEN*QIC_LEN unique queue ids + ** Generate a new sequence number between 0 and QIC_LEN_SQR-1. + ** This lets us generate up to QIC_LEN_SQR unique queue ids ** per second, per process. With envelope splitting, ** a single message can consume many queue ids. */ - seq = (int)((cX + random_offset) % (QIC_LEN * QIC_LEN)); + seq = (cX + random_offset) % QIC_LEN_SQR; ++cX; if (tTd(7, 50)) - sm_dprintf("assign_queueid: random_offset = %ld (%d)\n", + sm_dprintf("assign_queueid: random_offset=%u (%u)\n", random_offset, seq); tm = gmtime(&LastQueueTime); @@ -5430,6 +5450,7 @@ sync_queue_time() { #if FAST_PID_RECYCLE if (OpMode != MD_TEST && + OpMode != MD_CHECKCONFIG && OpMode != MD_VERIFY && LastQueueTime > 0 && LastQueuePid == CurrentPid && @@ -5740,6 +5761,10 @@ pickqdir(qg, fsize, e) else qdir = get_rand_mod(qg->qg_numqueues); +#if _FFR_TESTS + if (tTd(4, 101)) + return NOQDIR; +#endif /* _FFR_TESTS */ if (MinBlocksFree <= 0 && fsize <= 0) return qdir; @@ -6600,6 +6625,16 @@ init_sem(owner) (long) SemKey, SemId, sm_errstring(-SemId)); return; } + if (owner && RunAsUid != 0) + { + int r; + + r = sm_semsetowner(SemId, RunAsUid, RunAsGid, 0660); + if (r != 0) + sm_syslog(LOG_ERR, NOQID, + "key=%ld, sm_semsetowner=%d, RunAsUid=%d, RunAsGid=%d", + (long) SemKey, r, RunAsUid, RunAsGid); + } #endif /* SM_CONF_SEM */ #endif /* _FFR_USE_SEM_LOCKING */ return; @@ -8826,7 +8861,7 @@ quarantine_queue(reason, qgrplimit) if (StopRequest) stop_sendmail(); - nrequests = gatherq(qgrp, qdir, true, NULL, NULL); + nrequests = gatherq(qgrp, qdir, true, NULL, NULL, NULL); /* first see if there is anything */ if (nrequests <= 0) diff --git a/src/ratectrl.c b/src/ratectrl.c index 8b95b3753df0..773955a6db0f 100644 --- a/src/ratectrl.c +++ b/src/ratectrl.c @@ -45,7 +45,7 @@ */ #include <sendmail.h> -SM_RCSID("@(#)$Id: ratectrl.c,v 8.12 2008/02/11 22:56:05 ca Exp $") +SM_RCSID("@(#)$Id: ratectrl.c,v 8.13 2009/05/05 23:19:34 ca Exp $") /* ** stuff included - given some warnings (inet_ntoa) @@ -69,9 +69,6 @@ SM_RCSID("@(#)$Id: ratectrl.c,v 8.12 2008/02/11 22:56:05 ca Exp $") /* forward declarations */ static int client_rate __P((time_t, SOCKADDR *, bool)); static int total_rate __P((time_t, bool)); -#if 0 -static int sockaddrcmp __P((SOCKADDR *, SOCKADDR *)); -#endif /* 0 */ /* ** CONNECTION_RATE_CHECK - updates connection history data @@ -485,50 +482,3 @@ total_rate(now, update) return cnt; } - -#if 0 -/* -** SOCKADDRCMP - compare two SOCKADDR structures -** this function may be used to compare SOCKADDR -** structures when using bsearch and qsort functions -** in the same way we do with strcmp -** -** Parameters: -** a, b - addresses -** -** Returns: -** 1 if a > b -** -1 if a < b -** 0 if a = b -** -** OBS: This call isn't used at the moment, it will -** be used when code will be extended to work with IPV6 -*/ - -static int -sockaddrcmp(a, b) - SOCKADDR *a; - SOCKADDR *b; -{ - if (a->sa.sa_family > b->sa.sa_family) - return 1; - if (a->sa.sa_family < b->sa.sa_family) - return -1; - - switch (a->sa.sa_family) - { - case AF_INET: - if (a->sin.sin_addr.s_addr > b->sin.sin_addr.s_addr) - return 1; - if (a->sin.sin_addr.s_addr < b->sin.sin_addr.s_addr) - return -1; - return 0; - break; - - case AF_INET6: - /* TO BE DONE */ - break; - } - return 0; -} -#endif /* 0 */ diff --git a/src/readcf.c b/src/readcf.c index 445df9e10686..c6d48a8cfea6 100644 --- a/src/readcf.c +++ b/src/readcf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2006, 2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include <sendmail.h> #include <sm/sendmail.h> -SM_RCSID("@(#)$Id: readcf.c,v 8.666 2008/02/14 17:25:14 ca Exp $") +SM_RCSID("@(#)$Id: readcf.c,v 8.674 2009/10/26 17:47:00 ca Exp $") #if NETINET || NETINET6 # include <arpa/inet.h> @@ -113,6 +113,9 @@ readcf(cfname, safe, e) FileName = cfname; LineNumber = 0; +#if STARTTLS + Srv_SSL_Options = Clt_SSL_Options = SSL_OP_ALL; +#endif /* STARTTLS */ if (DontLockReadFiles) sff |= SFF_NOLOCK; cf = safefopen(cfname, O_RDONLY, 0444, sff); @@ -136,7 +139,7 @@ readcf(cfname, safe, e) if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode)) { - if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS) + if (OpMode == MD_DAEMON || OpMode == MD_INITALIAS || OpMode == MD_CHECKCONFIG) (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s: WARNING: dangerous write permissions\n", FileName); @@ -462,7 +465,7 @@ readcf(cfname, safe, e) rwp = RewriteRules[ruleset]; if (rwp != NULL) { - if (OpMode == MD_TEST) + if (OpMode == MD_TEST || OpMode == MD_CHECKCONFIG) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "WARNING: Ruleset %s has multiple definitions\n", @@ -534,7 +537,6 @@ readcf(cfname, safe, e) p++; while (isascii(*p) && isspace(*p)) p++; - file = p; } else optional = false; @@ -2255,10 +2257,101 @@ static struct optioninfo # define O_RCPTSHUTDG 0xe2 { "BadRcptShutdownGood", O_RCPTSHUTDG, OI_SAFE }, #endif /* _FFR_BADRCPT_SHUTDOWN */ +#if STARTTLS && _FFR_TLS_1 +# define O_SRV_SSL_OPTIONS 0xe3 + { "ServerSSLOptions", O_SRV_SSL_OPTIONS, OI_NONE }, +# define O_CLT_SSL_OPTIONS 0xe4 + { "ClientSSLOptions", O_CLT_SSL_OPTIONS, OI_NONE }, +#endif /* STARTTLS && _FFR_TLS_1 */ +#if _FFR_EXPDELAY +# define O_MAX_QUEUE_AGE 0xe5 + { "MaxQueueAge", O_MAX_QUEUE_AGE, OI_NONE }, +#endif /* _FFR_EXPDELAY */ +#if _FFR_RCPTTHROTDELAY +# define O_RCPTTHROTDELAY 0xe6 + { "BadRcptThrottleDelay", O_RCPTTHROTDELAY, OI_SAFE }, +#endif /* _FFR_RCPTTHROTDELAY */ { NULL, '\0', OI_NONE } }; +#if STARTTLS && _FFR_TLS_1 +static struct ssl_options +{ + const char *sslopt_name; /* name of the flag */ + long sslopt_bits; /* bits to set/clear */ +} SSL_Option[] = +{ +/* these are turned on by default */ +#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG + { "SSL_OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG }, +#endif /* SSL_OP_MICROSOFT_SESS_ID_BUG */ +#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG + { "SSL_OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG }, +#endif /* SSL_OP_NETSCAPE_CHALLENGE_BUG */ +#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG + { "SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG }, +#endif /* SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG */ +#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG + { "SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG }, +#endif /* SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG */ +#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER + { "SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER }, +#endif /* SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER */ +#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING + { "SSL_OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING }, +#endif /* SSL_OP_MSIE_SSLV2_RSA_PADDING */ +#ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG + { "SSL_OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG }, +#endif /* SSL_OP_SSLEAY_080_CLIENT_DH_BUG */ +#ifdef SSL_OP_TLS_D5_BUG + { "SSL_OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG }, +#endif /* SSL_OP_TLS_D5_BUG */ +#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG + { "SSL_OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG }, +#endif /* SSL_OP_TLS_BLOCK_PADDING_BUG */ +#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + { "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS }, +#endif /* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */ + { "SSL_OP_ALL", SSL_OP_ALL }, +#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + { "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION }, +#endif /* SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION */ +#ifdef SSL_OP_EPHEMERAL_RSA + { "SSL_OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA }, +#endif /* SSL_OP_EPHEMERAL_RSA */ +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE + { "SSL_OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE }, +#endif /* SSL_OP_CIPHER_SERVER_PREFERENCE */ +#ifdef SSL_OP_TLS_ROLLBACK_BUG + { "SSL_OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG }, +#endif /* SSL_OP_TLS_ROLLBACK_BUG */ +#ifdef SSL_OP_NO_SSLv2 + { "SSL_OP_NO_SSLv2", SSL_OP_NO_SSLv2 }, +#endif /* SSL_OP_NO_SSLv2 */ +#ifdef SSL_OP_NO_SSLv3 + { "SSL_OP_NO_SSLv3", SSL_OP_NO_SSLv3 }, +#endif /* SSL_OP_NO_SSLv3 */ +#ifdef SSL_OP_NO_TLSv1 + { "SSL_OP_NO_TLSv1", SSL_OP_NO_TLSv1 }, +#endif /* SSL_OP_NO_TLSv1 */ +#ifdef SSL_OP_PKCS1_CHECK_1 + { "SSL_OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1 }, +#endif /* SSL_OP_PKCS1_CHECK_1 */ +#ifdef SSL_OP_PKCS1_CHECK_2 + { "SSL_OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2 }, +#endif /* SSL_OP_PKCS1_CHECK_2 */ +#ifdef SSL_OP_NETSCAPE_CA_DN_BUG + { "SSL_OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG }, +#endif /* SSL_OP_NETSCAPE_CA_DN_BUG */ +#ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG + { "SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG }, +#endif /* SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG */ + { NULL, 0 } +}; +#endif /* STARTTLS && _FFR_TLS_1 */ + + # define CANONIFY(val) # define SET_OPT_DEFAULT(opt, val) opt = val @@ -2299,6 +2392,9 @@ setoption(opt, val, safe, sticky, e) char *newval; char exbuf[MAXLINE]; #endif /* STARTTLS || SM_CONF_SHM */ +#if STARTTLS && _FFR_TLS_1 + long *pssloptions = NULL; +#endif /* STARTTLS && _FFR_TLS_1 */ errno = 0; if (opt == ' ') @@ -2995,6 +3091,12 @@ setoption(opt, val, safe, sticky, e) MinQueueAge = convtime(val, 'm'); break; +#if _FFR_EXPDELAY + case O_MAX_QUEUE_AGE: + MaxQueueAge = convtime(val, 'm'); + break; +#endif /* _FFR_EXPDELAY */ + case O_DEFCHARSET: /* default character set for mimefying */ DefaultCharSet = newstr(denlstring(val, true, true)); break; @@ -3317,6 +3419,12 @@ setoption(opt, val, safe, sticky, e) BadRcptThrottle = atoi(val); break; +#if _FFR_RCPTTHROTDELAY + case O_RCPTTHROTDELAY: + BadRcptThrottleDelay = atoi(val); + break; +#endif /* _FFR_RCPTTHROTDELAY */ + case O_DEADLETTER: CANONIFY(val); PSTRSET(DeadLetterDrop, val); @@ -3578,7 +3686,51 @@ setoption(opt, val, safe, sticky, e) SET_STRING_EXP(DHParams5); case O_CIPHERLIST: SET_STRING_EXP(CipherList); + case O_SRV_SSL_OPTIONS: + pssloptions = &Srv_SSL_Options; + case O_CLT_SSL_OPTIONS: + if (pssloptions == NULL) + pssloptions = &Clt_SSL_Options; + for (p = val; *p != 0; ) + { + bool clearmode; + char *q; + struct ssl_options *sslopts; + + while (*p == ' ') + p++; + if (*p == '\0') + break; + clearmode = false; + if (*p == '-' || *p == '+') + clearmode = *p++ == '-'; + q = p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + for (sslopts = SSL_Option; + sslopts->sslopt_name != NULL; sslopts++) + { + if (sm_strcasecmp(q, sslopts->sslopt_name) == 0) + break; + } + if (sslopts->sslopt_name == NULL) + { + errno = 0; + syserr("readcf: %s option value %s unrecognized", + o->o_name, q); + } + else if (clearmode) + *pssloptions &= ~sslopts->sslopt_bits; + else + *pssloptions |= sslopts->sslopt_bits; + } + pssloptions = NULL; + break; + # endif /* _FFR_TLS_1 */ + case O_CRLFILE: # if OPENSSL_VERSION_NUMBER > 0x00907000L SET_STRING_EXP(CRLFile); @@ -4026,8 +4178,7 @@ strtorwset(p, endp, stabmode) char *q = NULL; q = p; - while (*p != '\0' && isascii(*p) && - (isalnum(*p) || *p == '_')) + while (*p != '\0' && isascii(*p) && (isalnum(*p) || *p == '_')) p++; if (q == p || !(isascii(*q) && isalpha(*q))) { diff --git a/src/savemail.c b/src/savemail.c index cf72e8d497ef..4178245cc5a3 100644 --- a/src/savemail.c +++ b/src/savemail.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: savemail.c,v 8.313 2006/11/29 00:20:41 ca Exp $") +SM_RCSID("@(#)$Id: savemail.c,v 8.314 2009/12/18 17:08:01 ca Exp $") static bool errbody __P((MCI *, ENVELOPE *, char *)); static bool pruneroute __P((char *)); @@ -705,7 +705,7 @@ returntosender(msg, returnq, flags, e) sendall(ee, SM_DELIVER); /* restore state */ - dropenvelope(ee, true, false); + (void) dropenvelope(ee, true, false); sm_rpool_free(ee->e_rpool); CurEnv = oldcur; returndepth--; diff --git a/src/sendmail.0 b/src/sendmail.0 index 060ed242f616..ccf9ad945ff8 100644 --- a/src/sendmail.0 +++ b/src/sendmail.0 @@ -457,9 +457,11 @@ SSEEEE AALLSSOO http://www.sendmail.org/ + US Patent Numbers 6865671, 6986037. + HHIISSTTOORRYY The sseennddmmaaiill command appeared in 4.2BSD. - $Date: 2007/08/02 05:42:33 $ SENDMAIL(8) + $Date: 2009/04/10 17:49:19 $ SENDMAIL(8) diff --git a/src/sendmail.8 b/src/sendmail.8 index 27b44d62eab7..691fa74a5090 100644 --- a/src/sendmail.8 +++ b/src/sendmail.8 @@ -9,9 +9,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: sendmail.8,v 8.58 2007/08/02 05:42:33 ca Exp $ +.\" $Id: sendmail.8,v 8.59 2009/04/10 17:49:19 gshapiro Exp $ .\" -.TH SENDMAIL 8 "$Date: 2007/08/02 05:42:33 $" +.TH SENDMAIL 8 "$Date: 2009/04/10 17:49:19 $" .SH NAME sendmail \- an electronic mail transport agent @@ -741,6 +741,8 @@ Internet Request For Comments No. 8, SMM. .PP http://www.sendmail.org/ +.PP +US Patent Numbers 6865671, 6986037. .SH HISTORY The .B sendmail diff --git a/src/sendmail.h b/src/sendmail.h index b6b231d844ef..b170c2bbb3d7 100644 --- a/src/sendmail.h +++ b/src/sendmail.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -52,7 +52,7 @@ #ifdef _DEFINE # ifndef lint -SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1059 2008/02/15 23:19:58 ca Exp $"; +SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1068 2009/12/18 17:08:01 ca Exp $"; # endif /* ! lint */ #endif /* _DEFINE */ @@ -607,7 +607,7 @@ extern bool filesys_free __P((long)); ERROR: change SASL_SEC_MASK_ notify sendmail.org! # endif /* SASL_SEC_NOPLAINTEXT & SASL_SEC_MASK) == 0 ... */ # endif /* SASL >= 20101 */ -# define MAXOUTLEN 8192 /* length of output buffer */ +# define MAXOUTLEN 8192 /* length of output buffer, should be 2^n */ /* functions */ extern char *intersect __P((char *, char *, SM_RPOOL_T *)); @@ -931,6 +931,10 @@ struct envelope int e_dlvr_flag; /* deliver by flag */ SM_RPOOL_T *e_rpool; /* resource pool for this envelope */ unsigned int e_features; /* server features */ +#if _FFR_MILTER_ENHSC +#define ENHSC_LEN 11 + char e_enhsc[ENHSC_LEN]; /* enhanced status code */ +#endif /* _FFR_MILTER_ENHSC */ }; /* values for e_flags */ @@ -982,7 +986,7 @@ extern ENVELOPE BlankEnvelope; /* functions */ extern void clearenvelope __P((ENVELOPE *, bool, SM_RPOOL_T *)); -extern void dropenvelope __P((ENVELOPE *, bool, bool)); +extern int dropenvelope __P((ENVELOPE *, bool, bool)); extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *, SM_RPOOL_T *)); extern void clrsessenvelope __P((ENVELOPE *)); extern void printenvflags __P((ENVELOPE *)); @@ -1561,6 +1565,7 @@ extern void stabapply __P((void (*)(STAB *, int), int)); #define MD_HOSTSTAT 'h' /* print persistent host stat info */ #define MD_PURGESTAT 'H' /* purge persistent host stat info */ #define MD_QUEUERUN 'q' /* queue run */ +#define MD_CHECKCONFIG 'C' /* check configuration file */ #if _FFR_LOCAL_DAEMON EXTERN bool LocalDaemon; @@ -1880,7 +1885,7 @@ struct termescape /* functions */ extern bool init_tls_library __P((void)); -extern bool inittls __P((SSL_CTX **, unsigned long, bool, char *, char *, char *, char *, char *)); +extern bool inittls __P((SSL_CTX **, unsigned long, long, bool, char *, char *, char *, char *, char *)); extern bool initclttls __P((bool)); extern void setclttls __P((bool)); extern bool initsrvtls __P((bool)); @@ -1906,6 +1911,7 @@ EXTERN char *CRLFile; /* file CRLs */ EXTERN char *CRLPath; /* path to CRLs (dir. with hashes) */ #endif /* _FFR_CRLPATH */ EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ +EXTERN long Srv_SSL_Options, Clt_SSL_Options; /* SSL options */ #endif /* STARTTLS */ /* @@ -1986,6 +1992,9 @@ EXTERN int QueueFileMode; /* mode on files in mail queue */ EXTERN int QueueMode; /* which queue items to act upon */ EXTERN int QueueSortOrder; /* queue sorting order algorithm */ EXTERN time_t MinQueueAge; /* min delivery interval */ +#if _FFR_EXPDELAY +EXTERN time_t MaxQueueAge; /* max delivery interval */ +#endif /* _FFR_EXPDELAY */ EXTERN time_t QueueIntvl; /* intervals between running the queue */ EXTERN char *QueueDir; /* location of queue directory */ EXTERN QUEUE_CHAR *QueueLimitId; /* limit queue run to id */ @@ -2235,11 +2244,16 @@ EXTERN bool UseNameServer; /* using DNS -- interpret h_errno & MX RRs */ EXTERN char InetMode; /* default network for daemon mode */ EXTERN char OpMode; /* operation mode, see below */ EXTERN char SpaceSub; /* substitution for <lwsp> */ -EXTERN int BadRcptThrottle; /* Throttle rejected RCPTs per SMTP message */ #if _FFR_BADRCPT_SHUTDOWN EXTERN int BadRcptShutdown; /* Shutdown connection for rejected RCPTs */ EXTERN int BadRcptShutdownGood; /* above even when there are good RCPTs */ #endif /* _FFR_BADRCPT_SHUTDOWN */ +EXTERN int BadRcptThrottle; /* Throttle rejected RCPTs per SMTP message */ +#if _FFR_RCPTTHROTDELAY +EXTERN unsigned int BadRcptThrottleDelay; /* delay for BadRcptThrottle */ +#else +# define BadRcptThrottleDelay 1 +#endif /* _FFR_RCPTTHROTDELAY */ EXTERN int CheckpointInterval; /* queue file checkpoint interval */ EXTERN int ConfigLevel; /* config file level */ EXTERN int ConnRateThrottle; /* throttle for SMTP connection rate */ diff --git a/src/sfsasl.c b/src/sfsasl.c index 67e919f34df3..cad16db1686a 100644 --- a/src/sfsasl.c +++ b/src/sfsasl.c @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Id: sfsasl.c,v 8.117 2008/01/31 18:48:29 ca Exp $") +SM_RCSID("@(#)$Id: sfsasl.c,v 8.118 2008/07/22 15:12:48 ca Exp $") #include <stdlib.h> #include <sendmail.h> #include <sm/time.h> @@ -296,7 +296,7 @@ sasl_write(fp, buf, size) /* ** Fetch the maximum input buffer size for sasl_encode(). ** This can be less than the size set in attemptauth() - ** due to a negotation with the other side, e.g., + ** due to a negotiation with the other side, e.g., ** Cyrus IMAP lmtp program sets maxbuf=4096, ** digestmd5 substracts 25 and hence we'll get 4071 ** instead of 8192 (MAXOUTLEN). diff --git a/src/srvrsmtp.c b/src/srvrsmtp.c index fffcd0d37ab7..49016e4572b5 100644 --- a/src/srvrsmtp.c +++ b/src/srvrsmtp.c @@ -17,7 +17,7 @@ # include <libmilter/mfdef.h> #endif /* MILTER */ -SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.975 2008/03/31 16:32:13 ca Exp $") +SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.989 2009/12/18 17:08:01 ca Exp $") #include <sm/time.h> #include <sm/fdset.h> @@ -479,6 +479,9 @@ do \ e->e_sendqueue = NULL; \ e->e_flags |= EF_CLRQUEUE; \ \ + if (tTd(92, 2)) \ + sm_dprintf("CLEAR_STATE: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",\ + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel);\ if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) \ logsender(e, NULL); \ e->e_flags &= ~EF_LOGSENDER; \ @@ -486,7 +489,7 @@ do \ /* clean up a bit */ \ smtp.sm_gotmail = false; \ SuprErrs = true; \ - dropenvelope(e, true, false); \ + (void) dropenvelope(e, true, false); \ sm_rpool_free(e->e_rpool); \ e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \ CurEnv = e; \ @@ -906,6 +909,16 @@ smtp(nullserver, d_flags, e) #endif /* SASL */ #if STARTTLS +# if USE_OPENSSL_ENGINE + if (tls_ok_srv && bitset(SRV_OFFER_TLS, features) && + !SSL_set_engine(NULL)) + { + sm_syslog(LOG_ERR, NOQID, + "STARTTLS=server, SSL_set_engine=failed"); + tls_ok_srv = false; + } +# endif /* USE_OPENSSL_ENGINE */ + set_tls_rd_tmo(TimeOuts.to_nextcommand); #endif /* STARTTLS */ @@ -1272,7 +1285,8 @@ smtp(nullserver, d_flags, e) { if (++np_log < 3) sm_syslog(LOG_INFO, NOQID, - "unauthorized PIPELINING, sleeping"); + "unauthorized PIPELINING, sleeping, relay=%.100s", + CurSmtpClient); sleep(1); } @@ -1447,8 +1461,9 @@ smtp(nullserver, d_flags, e) message("454 4.5.4 Internal error: unable to encode64"); if (LogLevel > 5) sm_syslog(LOG_WARNING, e->e_id, - "AUTH encode64 error [%d for \"%s\"]", - result, out); + "AUTH encode64 error [%d for \"%s\"], relay=%.100s", + result, out, + CurSmtpClient); /* start over? */ authenticating = SASL_NOT_AUTH; } @@ -1469,16 +1484,17 @@ smtp(nullserver, d_flags, e) message("535 5.7.0 authentication failed"); if (LogLevel > 9) sm_syslog(LOG_WARNING, e->e_id, - "AUTH failure (%s): %s (%d) %s", + "AUTH failure (%s): %s (%d) %s, relay=%.100s", auth_type, sasl_errstring(result, NULL, NULL), result, # if SASL >= 20000 - sasl_errdetail(conn)); + sasl_errdetail(conn), # else /* SASL >= 20000 */ - errstr == NULL ? "" : errstr); + errstr == NULL ? "" : errstr, # endif /* SASL >= 20000 */ + CurSmtpClient); RESET_SASLCONN; authenticating = SASL_NOT_AUTH; } @@ -1700,8 +1716,9 @@ smtp(nullserver, d_flags, e) q); if (LogLevel > 5) sm_syslog(LOG_WARNING, e->e_id, - "AUTH decode64 error [%d for \"%s\"]", - result, q); + "AUTH decode64 error [%d for \"%s\"], relay=%.100s", + result, q, + CurSmtpClient); /* start over? */ authenticating = SASL_NOT_AUTH; # if SASL >= 20000 @@ -1734,16 +1751,17 @@ smtp(nullserver, d_flags, e) message("535 5.7.0 authentication failed"); if (LogLevel > 9) sm_syslog(LOG_ERR, e->e_id, - "AUTH failure (%s): %s (%d) %s", + "AUTH failure (%s): %s (%d) %s, relay=%.100s", p, sasl_errstring(result, NULL, NULL), result, # if SASL >= 20000 - sasl_errdetail(conn)); + sasl_errdetail(conn), # else /* SASL >= 20000 */ - errstr); + errstr, # endif /* SASL >= 20000 */ + CurSmtpClient); RESET_SASLCONN; break; } @@ -1893,8 +1911,9 @@ smtp(nullserver, d_flags, e) if (LogLevel > 5) { sm_syslog(LOG_WARNING, NOQID, - "STARTTLS=server, error: accept failed=%d, SSL_error=%d, errno=%d, retry=%d", - r, ssl_err, errno, i); + "STARTTLS=server, error: accept failed=%d, SSL_error=%d, errno=%d, retry=%d, relay=%.100s", + r, ssl_err, errno, i, + CurSmtpClient); if (LogLevel > 8) tlslogerr("server"); } @@ -2532,7 +2551,7 @@ smtp(nullserver, d_flags, e) #if _FFR_BADRCPT_SHUTDOWN /* ** hack to deal with hack, see below: - ** n_badrcpts is increased is limit is reached. + ** n_badrcpts is increased if limit is reached. */ n_badrcpts_adj = (BadRcptThrottle > 0 && @@ -2576,12 +2595,12 @@ smtp(nullserver, d_flags, e) /* ** Don't use exponential backoff for now. - ** Some servers will open more connections + ** Some systems will open more connections ** and actually overload the receiver even ** more. */ - (void) sleep(1); + (void) sleep(BadRcptThrottleDelay); } if (!smtp.sm_gotmail) { @@ -3147,6 +3166,11 @@ doquit: milter_quit(e); #endif /* MILTER */ + if (tTd(92, 2)) + sm_dprintf("QUIT: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", + e->e_id, + bitset(EF_LOGSENDER, e->e_flags), + LogLevel); if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) logsender(e, NULL); e->e_flags &= ~EF_LOGSENDER; @@ -3358,6 +3382,11 @@ smtp_data(smtp, e) response); LogUsrErrs = false; } +#if _FFR_MILTER_ENHSC + if (ISSMTPCODE(response)) + (void) extenhsc(response + 4, ' ', e->e_enhsc); +#endif /* _FFR_MILTER_ENHSC */ + usrerr(response); if (strncmp(response, "421 ", 4) == 0 || strncmp(response, "421-", 4) == 0) @@ -3374,6 +3403,10 @@ smtp_data(smtp, e) "Milter: cmd=data, reject=550 5.7.1 Command rejected"); LogUsrErrs = false; } +#if _FFR_MILTER_ENHSC + (void) sm_strlcpy(e->e_enhsc, "5.7.1", + sizeof(e->e_enhsc)); +#endif /* _FFR_MILTER_ENHSC */ usrerr("550 5.7.1 Command rejected"); return true; @@ -3392,6 +3425,9 @@ smtp_data(smtp, e) MSG_TEMPFAIL); LogUsrErrs = false; } +#if _FFR_MILTER_ENHSC + (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc); +#endif /* _FFR_MILTER_ENHSC */ usrerr(MSG_TEMPFAIL); return true; @@ -3467,7 +3503,14 @@ smtp_data(smtp, e) "Milter: data, reject=%s", response); milteraccept = false; +#if _FFR_MILTER_ENHSC + if (ISSMTPCODE(response)) + (void) extenhsc(response + 4, ' ', e->e_enhsc); +#endif /* _FFR_MILTER_ENHSC */ usrerr(response); + if (strncmp(response, "421 ", 4) == 0 + || strncmp(response, "421-", 4) == 0) + rv = false; break; case SMFIR_REJECT: @@ -3492,6 +3535,9 @@ smtp_data(smtp, e) "Milter: data, reject=%s", MSG_TEMPFAIL); milteraccept = false; +#if _FFR_MILTER_ENHSC + (void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc); +#endif /* _FFR_MILTER_ENHSC */ usrerr(MSG_TEMPFAIL); break; @@ -3782,6 +3828,9 @@ smtp_data(smtp, e) } abortmessage: + if (tTd(92, 2)) + sm_dprintf("abortmessage: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", + e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags)) logsender(e, NULL); e->e_flags &= ~EF_LOGSENDER; @@ -3795,7 +3844,7 @@ smtp_data(smtp, e) */ if (aborting || bitset(EF_DISCARD, e->e_flags)) - dropenvelope(e, true, false); + (void) dropenvelope(e, true, false); else { for (ee = e; ee != NULL; ee = ee->e_sibling) @@ -3804,11 +3853,11 @@ smtp_data(smtp, e) QueueMode != QM_QUARANTINE && ee->e_quarmsg != NULL) { - dropenvelope(ee, true, false); + (void) dropenvelope(ee, true, false); continue; } if (WILL_BE_QUEUED(ee->e_sendmode)) - dropenvelope(ee, true, false); + (void) dropenvelope(ee, true, false); } } @@ -3870,8 +3919,13 @@ logundelrcpts(e, msg, level, all) if (!QS_IS_UNDELIVERED(a->q_state) && !all) continue; e->e_to = a->q_paddr; - logdelivery(NULL, NULL, a->q_status, msg, NULL, - (time_t) 0, e); + logdelivery(NULL, NULL, +#if _FFR_MILTER_ENHSC + (a->q_status == NULL && e->e_enhsc[0] != '\0') + ? e->e_enhsc : +#endif /* _FFR_MILTER_ENHSC */ + a->q_status, + msg, NULL, (time_t) 0, e); } e->e_to = NULL; } @@ -4692,8 +4746,9 @@ initsrvtls(tls_ok) return false; /* do NOT remove assignment */ - tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, true, SrvCertFile, - SrvKeyFile, CACertPath, CACertFile, DHParams); + tls_ok_srv = inittls(&srv_ctx, TLS_Srv_Opts, Srv_SSL_Options, true, + SrvCertFile, SrvKeyFile, + CACertPath, CACertFile, DHParams); return tls_ok_srv; } #endif /* STARTTLS */ diff --git a/src/tls.c b/src/tls.c index 1a213cab68ee..70319944950c 100644 --- a/src/tls.c +++ b/src/tls.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2006 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: tls.c,v 8.107 2006/10/12 21:35:11 ca Exp $") +SM_RCSID("@(#)$Id: tls.c,v 8.114 2009/08/10 15:11:09 ca Exp $") #if STARTTLS # include <openssl/err.h> @@ -486,6 +486,7 @@ tls_safe_f(var, sff, srv) ** Parameters: ** ctx -- pointer to context ** req -- requirements for initialization (see sendmail.h) +** options -- options ** srv -- server side? ** certfile -- filename of certificate ** keyfile -- filename of private key @@ -514,9 +515,10 @@ static char server_session_id_context[] = "sendmail8"; #endif bool -inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) +inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) SSL_CTX **ctx; unsigned long req; + long options; bool srv; char *certfile, *keyfile, *cacertpath, *cacertfile, *dhparam; { @@ -525,7 +527,7 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) # endif /* !NO_DH */ int r; bool ok; - long sff, status, options; + long sff, status; char *who; # if _FFR_TLS_1 char *cf2, *kf2; @@ -643,7 +645,10 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) } } if (dhparam == NULL) + { dhparam = srv ? "1" : "5"; + req |= (srv ? TLS_I_DH1024 : TLS_I_DH512); + } else if (*dhparam == '/') { TLS_OK_F(dhparam, "DHParameters", @@ -913,7 +918,6 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) /* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */ - options = SSL_OP_ALL; /* bug compatibility? */ #if SM_SSL_OP_TLS_BLOCK_PADDING_BUG /* @@ -1196,23 +1200,62 @@ tls_get_info(ssl, srv, host, mac, certreq) if (cert != NULL) { unsigned int n; + X509_NAME *subj, *issuer; unsigned char md[EVP_MAX_MD_SIZE]; char buf[MAXNAME]; - X509_NAME_oneline(X509_get_subject_name(cert), - buf, sizeof(buf)); + subj = X509_get_subject_name(cert); + issuer = X509_get_issuer_name(cert); + X509_NAME_oneline(subj, buf, sizeof(buf)); macdefine(mac, A_TEMP, macid("{cert_subject}"), xtextify(buf, "<>\")")); - X509_NAME_oneline(X509_get_issuer_name(cert), - buf, sizeof(buf)); + X509_NAME_oneline(issuer, buf, sizeof(buf)); macdefine(mac, A_TEMP, macid("{cert_issuer}"), xtextify(buf, "<>\")")); - X509_NAME_get_text_by_NID(X509_get_subject_name(cert), - NID_commonName, buf, sizeof(buf)); + +#define CHECK_X509_NAME(which) \ + do { \ + if (r == -1) \ + { \ + sm_strlcpy(buf, "BadCertificateUnknown", sizeof(buf)); \ + if (LogLevel > 7) \ + sm_syslog(LOG_INFO, NOQID, \ + "STARTTLS=%s, relay=%.100s, field=%s, status=failed to extract CN", \ + who, \ + host == NULL ? "local" : host, \ + which); \ + } \ + else if ((size_t)r >= sizeof(buf) - 1) \ + { \ + sm_strlcpy(buf, "BadCertificateTooLong", sizeof(buf)); \ + if (LogLevel > 7) \ + sm_syslog(LOG_INFO, NOQID, \ + "STARTTLS=%s, relay=%.100s, field=%s, status=CN too long", \ + who, \ + host == NULL ? "local" : host, \ + which); \ + } \ + else if ((size_t)r > strlen(buf)) \ + { \ + sm_strlcpy(buf, "BadCertificateContainsNUL", \ + sizeof(buf)); \ + if (LogLevel > 7) \ + sm_syslog(LOG_INFO, NOQID, \ + "STARTTLS=%s, relay=%.100s, field=%s, status=CN contains NUL", \ + who, \ + host == NULL ? "local" : host, \ + which); \ + } \ + } while (0) + + r = X509_NAME_get_text_by_NID(subj, NID_commonName, buf, + sizeof buf); + CHECK_X509_NAME("cn_subject"); macdefine(mac, A_TEMP, macid("{cn_subject}"), xtextify(buf, "<>\")")); - X509_NAME_get_text_by_NID(X509_get_issuer_name(cert), - NID_commonName, buf, sizeof(buf)); + r = X509_NAME_get_text_by_NID(issuer, NID_commonName, buf, + sizeof buf); + CHECK_X509_NAME("cn_issuer"); macdefine(mac, A_TEMP, macid("{cn_issuer}"), xtextify(buf, "<>\")")); n = 0; @@ -1596,14 +1639,19 @@ tls_verify_cb(ctx, unused) { int ok; + /* + ** man SSL_CTX_set_cert_verify_callback(): + ** callback should return 1 to indicate verification success + ** and 0 to indicate verification failure. + */ + ok = X509_verify_cert(ctx); - if (ok == 0) + if (ok <= 0) { if (LogLevel > 13) return tls_verify_log(ok, ctx, "TLS"); - return 1; /* override it */ } - return ok; + return 1; } /* ** TLSLOGERR -- log the errors from the TLS error stack diff --git a/src/usersmtp.c b/src/usersmtp.c index b29495c3ae7f..23278b0b59d7 100644 --- a/src/usersmtp.c +++ b/src/usersmtp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2006, 2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2006, 2008, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: usersmtp.c,v 8.472 2008/01/31 18:48:29 ca Exp $") +SM_RCSID("@(#)$Id: usersmtp.c,v 8.473 2009/06/17 17:26:51 ca Exp $") #include <sysexits.h> @@ -1568,7 +1568,9 @@ attemptauth(m, mci, e, sai) sasl_interact_t *client_interact = NULL; char *mechusing; sasl_security_properties_t ssp; - char in64[MAXOUTLEN]; + + /* MUST NOT be a multiple of 4: bug in some sasl_encode64() versions */ + char in64[MAXOUTLEN + 1]; #if NETINET || (NETINET6 && SASL >= 20000) extern SOCKADDR CurHostAddr; #endif /* NETINET || (NETINET6 && SASL >= 20000) */ @@ -1770,7 +1772,8 @@ attemptauth(m, mci, e, sai) } else { - saslresult = sasl_encode64(out, outlen, in64, MAXOUTLEN, NULL); + saslresult = sasl_encode64(out, outlen, in64, sizeof(in64), + NULL); if (saslresult != SASL_OK) /* internal error */ { if (LogLevel > 8) @@ -1837,7 +1840,7 @@ attemptauth(m, mci, e, sai) if (outlen > 0) { saslresult = sasl_encode64(out, outlen, in64, - MAXOUTLEN, NULL); + sizeof(in64), NULL); if (saslresult != SASL_OK) { /* give an error reply to the other side! */ diff --git a/src/util.c b/src/util.c index dab596130500..ab491fbfe52b 100644 --- a/src/util.c +++ b/src/util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2007, 2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Id: util.c,v 8.414 2007/11/02 17:30:38 ca Exp $") +SM_RCSID("@(#)$Id: util.c,v 8.416 2009/12/18 17:05:26 ca Exp $") #include <sm/sendmail.h> #include <sysexits.h> @@ -868,7 +868,7 @@ xputs(fp, s) c &= 0177; } printchar: - if (isprint(c)) + if (isascii(c) && isprint(c)) { (void) sm_io_putc(fp, SM_TIME_DEFAULT, c); continue; @@ -895,7 +895,7 @@ xputs(fp, s) TermEscape.te_rv_on); shiftout = true; } - if (isprint(c)) + if (isascii(c) && isprint(c)) { (void) sm_io_putc(fp, SM_TIME_DEFAULT, '\\'); (void) sm_io_putc(fp, SM_TIME_DEFAULT, c); diff --git a/src/version.c b/src/version.c index 3e5ee8e6fdcc..cb94d0f2c574 100644 --- a/src/version.c +++ b/src/version.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2009 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,6 +13,6 @@ #include <sm/gen.h> -SM_RCSID("@(#)$Id: version.c,v 8.208 2008/04/17 17:04:30 ca Exp $") +SM_RCSID("@(#)$Id: version.c,v 8.218 2009/12/23 04:43:09 ca Exp $") -char Version[] = "8.14.3"; +char Version[] = "8.14.4"; |