summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src')
-rw-r--r--contrib/sendmail/src/README10
-rw-r--r--contrib/sendmail/src/TRACEFLAGS6
-rw-r--r--contrib/sendmail/src/TUNING13
-rw-r--r--contrib/sendmail/src/bf.c3
-rw-r--r--contrib/sendmail/src/collect.c14
-rw-r--r--contrib/sendmail/src/conf.c529
-rw-r--r--contrib/sendmail/src/daemon.c98
-rw-r--r--contrib/sendmail/src/deliver.c135
-rw-r--r--contrib/sendmail/src/envelope.c20
-rw-r--r--contrib/sendmail/src/err.c122
-rw-r--r--contrib/sendmail/src/headers.c32
-rw-r--r--contrib/sendmail/src/main.c67
-rw-r--r--contrib/sendmail/src/map.c40
-rw-r--r--contrib/sendmail/src/mci.c1
-rw-r--r--contrib/sendmail/src/milter.c39
-rw-r--r--contrib/sendmail/src/parseaddr.c36
-rw-r--r--contrib/sendmail/src/queue.c139
-rw-r--r--contrib/sendmail/src/readcf.c866
-rw-r--r--contrib/sendmail/src/recipient.c70
-rw-r--r--contrib/sendmail/src/savemail.c15
-rw-r--r--contrib/sendmail/src/sendmail.83
-rw-r--r--contrib/sendmail/src/sendmail.h138
-rw-r--r--contrib/sendmail/src/sfsasl.c22
-rw-r--r--contrib/sendmail/src/sm_resolve.c2
-rw-r--r--contrib/sendmail/src/srvrsmtp.c430
-rw-r--r--contrib/sendmail/src/tls.c407
-rw-r--r--contrib/sendmail/src/usersmtp.c65
-rw-r--r--contrib/sendmail/src/util.c146
-rw-r--r--contrib/sendmail/src/version.c6
29 files changed, 2586 insertions, 888 deletions
diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README
index c437b1e..fddce9d 100644
--- a/contrib/sendmail/src/README
+++ b/contrib/sendmail/src/README
@@ -189,10 +189,11 @@ replies are text based and encoded as netstrings. The socket map
uses the same syntax as milters the specify the remote endpoint,
e.g.:
-Ksocket mySocketMap inet:12345@127.0.0.1
+KmySocketMap socket inet:12345@127.0.0.1
See doc/op/op.me for details.
+
+---------------+
| COMPILE FLAGS |
+---------------+
@@ -630,8 +631,7 @@ EGD Define this if your system has EGD installed, see
http://egd.sourceforge.net/ . It should be used to
seed the PRNG for STARTTLS if HASURANDOMDEV is not defined.
STARTTLS Enables SMTP STARTTLS (RFC 2487). This requires OpenSSL
- (http://www.OpenSSL.org/); use OpenSSL 0.9.5a or later
- (if compatible with this version), do not use 0.9.3.
+ (http://www.OpenSSL.org/); use OpenSSL 0.9.8zc or later.
See STARTTLS COMPILATION AND CONFIGURATION for further
information.
TLS_NO_RSA Turn off support for RSA algorithms in STARTTLS.
@@ -653,6 +653,9 @@ REQUIRES_DIR_FSYNC Turn on support for file systems that require to
chattr +S on Linux.
DBMMODE The default file permissions to use when creating new
database files for maps and aliases. Defaults to 0640.
+IPV6_FULL Use uncompressed IPv6 addresses (set by default). This
+ permits a zero subnet to have a more specific match,
+ such as different map entries for IPv6:0:0 vs IPv6:0.
Generic notice: If you enable a compile time option that needs
libraries or include files that don't come with sendmail or are
@@ -1733,6 +1736,7 @@ Fedora Core 5, 64 bit version
Problem noted by Daniel Krones, solution suggested by
Anthony Howe.
+
+--------------+
| MANUAL PAGES |
+--------------+
diff --git a/contrib/sendmail/src/TRACEFLAGS b/contrib/sendmail/src/TRACEFLAGS
index e73ed10..06efaa9 100644
--- a/contrib/sendmail/src/TRACEFLAGS
+++ b/contrib/sendmail/src/TRACEFLAGS
@@ -87,11 +87,17 @@
71,>99 milter.c quarantine on errors
73 queue.c shared memory updates
74,>99 map.c LDAP map defer
+#if _FFR_XCNCT
+75 debug FFR_XC*
+#endif /* _FFR_XCNCT */
80 content length
81 sun remote mode
83 collect.c timeout
84 deliver.c timeout
85 map.c dprintf map
+#if _FFR_PROXY
+87 srvrsmtp.c proxy mode
+#endif
89 conf.c >=8 use sm_dprintf() instead of syslog()
91 mci.c syslogging of MCI cache information
93,>99 * Prevent daemon connection fork for profiling/debugging
diff --git a/contrib/sendmail/src/TUNING b/contrib/sendmail/src/TUNING
index 77c3f64..8df5803 100644
--- a/contrib/sendmail/src/TUNING
+++ b/contrib/sendmail/src/TUNING
@@ -1,4 +1,4 @@
-# Copyright (c) 2001-2003 Proofpoint, Inc. and its suppliers.
+# Copyright (c) 2001-2003, 2014 Proofpoint, Inc. and its suppliers.
# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
@@ -135,6 +135,17 @@ to send e-mail then either the -G option should be used or
should be added to the .mc file.
+Note: starting with 8.15, sendmail will not ignore temporary map
+lookup failures during header rewriting, which means that DNS lookup
+problems even for headers will cause messages to stay in the queue.
+Hence it is strongly suggested to use the nocanonify feature;
+at least turning it on for the MTA, but maybe disabling it for the
+MSA, i.e., use Modifiers for DaemonPortOptions accordingly.
+As a last resort, it is possible to override the host map to ignore
+temporary failures, e.g.,
+Khost host -t
+However, this can cause inconsistent header rewriting.
+
* Mailing Lists and Large Aliases (1-n Mailing)
-----------------------------------------------
diff --git a/contrib/sendmail/src/bf.c b/contrib/sendmail/src/bf.c
index 7d90856..0f2c9c0 100644
--- a/contrib/sendmail/src/bf.c
+++ b/contrib/sendmail/src/bf.c
@@ -695,7 +695,8 @@ sm_bfcommit(fp)
sm_dprintf("bfcommit(%s): to disk\n", bfp->bf_filename);
if (tTd(58, 32))
sm_dprintf("bfcommit(): filemode %o flags %ld\n",
- bfp->bf_filemode, bfp->bf_flags);
+ (unsigned int) bfp->bf_filemode,
+ bfp->bf_flags);
}
if (stat(bfp->bf_filename, &st) == 0)
diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c
index 8d90acb..5f090b2 100644
--- a/contrib/sendmail/src/collect.c
+++ b/contrib/sendmail/src/collect.c
@@ -59,7 +59,7 @@ collect_eoh(e, numhdrs, hdrslen)
sm_dprintf("collect: rscheck(\"check_eoh\", \"%s $| %s\")\n",
hnum, hsize);
(void) rscheck("check_eoh", hnum, hsize, e, RSF_UNSTRUCTURED|RSF_COUNT,
- 3, NULL, e->e_id, NULL);
+ 3, NULL, e->e_id, NULL, NULL);
/*
** Process the header,
@@ -297,6 +297,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
int hdrslen;
int numhdrs;
int afd;
+ int old_rd_tmo;
unsigned char *pbp;
unsigned char peekbuf[8];
char bufbuf[MAXLINE];
@@ -311,7 +312,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
dbto = smtpmode ? ((int) TimeOuts.to_datablock * 1000)
: SM_TIME_FOREVER;
sm_io_setinfo(fp, SM_IO_WHAT_TIMEOUT, &dbto);
- set_tls_rd_tmo(TimeOuts.to_datablock);
+ old_rd_tmo = set_tls_rd_tmo(TimeOuts.to_datablock);
c = SM_IO_EOF;
inputerr = false;
headeronly = hdrp != NULL;
@@ -720,7 +721,7 @@ readerr:
}
if (headeronly)
- return;
+ goto end;
if (mstate != MS_BODY)
{
@@ -940,6 +941,9 @@ readerr:
+ e->e_nrcpts * WkRecipFact;
markstats(e, (ADDRESS *) NULL, STATS_NORMAL);
}
+
+ end:
+ (void) set_tls_rd_tmo(old_rd_tmo);
}
/*
@@ -1026,8 +1030,8 @@ dferror(df, msg, e)
#endif /* 0 */
}
else
- syserr("421 4.3.0 collect: Cannot write %s (%s, uid=%d, gid=%d)",
- dfname, msg, (int) geteuid(), (int) getegid());
+ syserr("421 4.3.0 collect: Cannot write %s (%s, uid=%ld, gid=%ld)",
+ dfname, msg, (long) geteuid(), (long) getegid());
if (sm_io_reopen(SmFtStdio, SM_TIME_DEFAULT, SM_PATH_DEVNULL,
SM_IO_WRONLY, NULL, df) == NULL)
sm_syslog(LOG_ERR, e->e_id,
diff --git a/contrib/sendmail/src/conf.c b/contrib/sendmail/src/conf.c
index b64f3c7..c73334e 100644
--- a/contrib/sendmail/src/conf.c
+++ b/contrib/sendmail/src/conf.c
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: conf.c,v 8.1191 2014-01-08 17:03:14 ca Exp $")
+SM_RCSID("@(#)$Id: conf.c,v 8.1192 2014-01-27 18:23:21 ca Exp $")
#include <sm/sendmail.h>
#include <sendmail/pathnames.h>
@@ -229,10 +229,8 @@ struct dbsval DontBlameSendmailValues[] =
{ "worldwritableforwardfile", DBS_WORLDWRITABLEFORWARDFILE },
{ "worldwritableincludefile", DBS_WORLDWRITABLEINCLUDEFILE },
{ "groupreadablekeyfile", DBS_GROUPREADABLEKEYFILE },
-#if _FFR_GROUPREADABLEAUTHINFOFILE
- { "groupreadableadefaultauthinfofile",
+ { "groupreadabledefaultauthinfofile",
DBS_GROUPREADABLEAUTHINFOFILE },
-#endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
{ NULL, 0 }
};
@@ -304,9 +302,9 @@ setdefaults(e)
}
TrustedUid = 0;
if (tTd(37, 4))
- sm_dprintf("setdefaults: DefUser=%s, DefUid=%d, DefGid=%d\n",
+ sm_dprintf("setdefaults: DefUser=%s, DefUid=%ld, DefGid=%ld\n",
DefUser != NULL ? DefUser : "<1:1>",
- (int) DefUid, (int) DefGid);
+ (long) DefUid, (long) DefGid);
CheckpointInterval = 10; /* option C */
MaxHopCount = 25; /* option h */
set_delivery_mode(SM_FORK, e); /* option d */
@@ -365,6 +363,8 @@ setdefaults(e)
#endif /* SASL */
#if STARTTLS
TLS_Srv_Opts = TLS_I_SRV;
+ if (NULL == EVP_digest)
+ EVP_digest = EVP_md5();
#endif /* STARTTLS */
#ifdef HESIOD_INIT
HesiodContext = NULL;
@@ -379,6 +379,9 @@ setdefaults(e)
}
else
InetMode = AF_INET;
+#if !IPV6_FULL
+ UseCompressedIPv6Addresses = true;
+#endif
#else /* NETINET6 */
InetMode = AF_INET;
#endif /* NETINET6 */
@@ -399,6 +402,9 @@ setdefaults(e)
BadRcptThrottleDelay = 1;
#endif /* _FFR_RCPTTHROTDELAY */
ConnectionRateWindowSize = 60;
+#if _FFR_BOUNCE_QUEUE
+ BounceQueue = NOQGRP;
+#endif /* _FFR_BOUNCE_QUEUE */
setupmaps();
setupqueues();
setupmailers();
@@ -423,8 +429,8 @@ setdefuser()
? "nobody" : defpwent->pw_name,
sizeof(defuserbuf));
if (tTd(37, 4))
- sm_dprintf("setdefuser: DefUid=%d, DefUser=%s\n",
- (int) DefUid, DefUser);
+ sm_dprintf("setdefuser: DefUid=%ld, DefUser=%s\n",
+ (long) DefUid, DefUser);
}
/*
** SETUPQUEUES -- initialize default queues
@@ -665,12 +671,10 @@ setupmaps()
dequote_init, null_map_open, null_map_close,
arith_map_lookup, null_map_store);
-#if _FFR_ARPA_MAP
/* "arpa" map -- IP -> arpa */
MAPDEF("arpa", NULL, 0,
dequote_init, null_map_open, null_map_close,
arpa_map_lookup, null_map_store);
-#endif /* _FFR_ARPA_MAP */
#if SOCKETMAP
/* arbitrary daemons */
@@ -2299,7 +2303,7 @@ refuseconnections(e, dn, active)
# 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,
- CurrentLA, limit);
+ CurrentLA, limit);
if (LogLevel > 8 && (now = curtime()) > log_delay)
{
sm_syslog(LOG_INFO, NOQID, D_MSG_LA,
@@ -2780,7 +2784,7 @@ reapchild(sig)
return SIGFUNC_RETURN;
}
/*
-** GETDTABLESIZE -- return number of file descriptors
+** GETDTSIZE -- return number of file descriptors
**
** Only on non-BSD systems
**
@@ -3601,8 +3605,8 @@ lockfile(fd, filename, ext, type)
uid_t euid = geteuid();
errno = save_errno;
- syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
- filename, ext, fd, type, omode, euid);
+ syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%ld)",
+ filename, ext, fd, type, omode, (long) euid);
dumpfd(fd, true, true);
}
# else /* !HASFLOCK */
@@ -3631,8 +3635,8 @@ lockfile(fd, filename, ext, type)
uid_t euid = geteuid();
errno = save_errno;
- syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
- filename, ext, fd, type, omode, euid);
+ syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%ld)",
+ filename, ext, fd, type, omode, (long) euid);
dumpfd(fd, true, true);
}
# endif /* !HASFLOCK */
@@ -4009,8 +4013,8 @@ validate_connection(sap, hostname, e)
hostname, anynet_ntoa(sap));
connection_rate_check(sap, e);
- if (rscheck("check_relay", hostname, anynet_ntoa(sap),
- e, RSF_RMCOMM|RSF_COUNT, 3, NULL, NOQID, NULL) != EX_OK)
+ if (rscheck("check_relay", hostname, anynet_ntoa(sap), e,
+ RSF_RMCOMM|RSF_COUNT, 3, NULL, NOQID, NULL, NULL) != EX_OK)
{
static char reject[BUFSIZ*2];
extern char MsgBuf[];
@@ -5406,7 +5410,7 @@ sm_syslog(level, id, fmt, va_alist)
SM_VA_START(ap, fmt);
n = sm_vsnprintf(buf, bufsize, fmt, ap);
SM_VA_END(ap);
- SM_ASSERT(n > 0);
+ SM_ASSERT(n >= 0);
if (n < bufsize)
break;
@@ -5736,148 +5740,155 @@ char *CompileOptions[] =
{
#if ALLOW_255
"ALLOW_255",
-#endif /* ALLOW_255 */
+#endif
#if NAMED_BIND
# if DNSMAP
"DNSMAP",
-# endif /* DNSMAP */
-#endif /* NAMED_BIND */
+# endif
+#endif
#if EGD
"EGD",
-#endif /* EGD */
+#endif
#if HESIOD
"HESIOD",
-#endif /* HESIOD */
+#endif
+#if HESIOD_ALLOW_NUMERIC_LOGIN
+ "HESIOD_ALLOW_NUMERIC_LOGIN",
+#endif
#if HES_GETMAILHOST
"HES_GETMAILHOST",
-#endif /* HES_GETMAILHOST */
+#endif
+#if IPV6_FULL
+ /* Use uncompressed IPv6 address format (no "::") by default */
+ "IPV6_FULL",
+#endif
#if LDAPMAP
"LDAPMAP",
-#endif /* LDAPMAP */
+#endif
#if LDAP_REFERRALS
"LDAP_REFERRALS",
-#endif /* LDAP_REFERRALS */
+#endif
#if LOG
"LOG",
-#endif /* LOG */
+#endif
#if MAP_NSD
"MAP_NSD",
-#endif /* MAP_NSD */
+#endif
#if MAP_REGEX
"MAP_REGEX",
-#endif /* MAP_REGEX */
+#endif
#if MATCHGECOS
"MATCHGECOS",
-#endif /* MATCHGECOS */
+#endif
#if MILTER
"MILTER",
-#endif /* MILTER */
+#endif
#if MIME7TO8
"MIME7TO8",
-#endif /* MIME7TO8 */
+#endif
#if MIME7TO8_OLD
"MIME7TO8_OLD",
-#endif /* MIME7TO8_OLD */
+#endif
#if MIME8TO7
"MIME8TO7",
-#endif /* MIME8TO7 */
+#endif
#if NAMED_BIND
"NAMED_BIND",
-#endif /* NAMED_BIND */
+#endif
#if NDBM
"NDBM",
-#endif /* NDBM */
+#endif
#if NETINET
"NETINET",
-#endif /* NETINET */
+#endif
#if NETINET6
"NETINET6",
-#endif /* NETINET6 */
+#endif
#if NETINFO
"NETINFO",
-#endif /* NETINFO */
+#endif
#if NETISO
"NETISO",
-#endif /* NETISO */
+#endif
#if NETNS
"NETNS",
-#endif /* NETNS */
+#endif
#if NETUNIX
"NETUNIX",
-#endif /* NETUNIX */
+#endif
#if NETX25
"NETX25",
-#endif /* NETX25 */
+#endif
#if NEWDB
"NEWDB",
-#endif /* NEWDB */
+#endif
#if NIS
"NIS",
-#endif /* NIS */
+#endif
#if NISPLUS
"NISPLUS",
-#endif /* NISPLUS */
+#endif
#if NO_DH
"NO_DH",
-#endif /* NO_DH */
+#endif
#if PH_MAP
"PH_MAP",
-#endif /* PH_MAP */
+#endif
#ifdef PICKY_HELO_CHECK
"PICKY_HELO_CHECK",
-#endif /* PICKY_HELO_CHECK */
+#endif
#if PIPELINING
"PIPELINING",
-#endif /* PIPELINING */
+#endif
#if SASL
# if SASL >= 20000
"SASLv2",
# else /* SASL >= 20000 */
"SASL",
-# endif /* SASL >= 20000 */
-#endif /* SASL */
+# endif
+#endif
#if SCANF
"SCANF",
-#endif /* SCANF */
+#endif
#if SM_LDAP_ERROR_ON_MISSING_ARGS
"SM_LDAP_ERROR_ON_MISSING_ARGS",
-#endif /* SM_LDAP_ERROR_ON_MISSING_ARGS */
+#endif
#if SMTPDEBUG
"SMTPDEBUG",
-#endif /* SMTPDEBUG */
+#endif
#if SOCKETMAP
"SOCKETMAP",
-#endif /* SOCKETMAP */
+#endif
#if STARTTLS
"STARTTLS",
-#endif /* STARTTLS */
+#endif
#if SUID_ROOT_FILES_OK
"SUID_ROOT_FILES_OK",
-#endif /* SUID_ROOT_FILES_OK */
+#endif
#if TCPWRAPPERS
"TCPWRAPPERS",
-#endif /* TCPWRAPPERS */
+#endif
#if TLS_NO_RSA
"TLS_NO_RSA",
-#endif /* TLS_NO_RSA */
+#endif
#if TLS_VRFY_PER_CTX
"TLS_VRFY_PER_CTX",
-#endif /* TLS_VRFY_PER_CTX */
+#endif
#if USERDB
"USERDB",
-#endif /* USERDB */
+#endif
#if USE_LDAP_INIT
"USE_LDAP_INIT",
-#endif /* USE_LDAP_INIT */
+#endif
#if USE_TTYPATH
"USE_TTYPATH",
-#endif /* USE_TTYPATH */
+#endif
#if XDEBUG
"XDEBUG",
-#endif /* XDEBUG */
+#endif
#if XLA
"XLA",
-#endif /* XLA */
+#endif
NULL
};
@@ -5890,169 +5901,169 @@ char *OsCompileOptions[] =
{
#if ADDRCONFIG_IS_BROKEN
"ADDRCONFIG_IS_BROKEN",
-#endif /* ADDRCONFIG_IS_BROKEN */
+#endif
#ifdef AUTO_NETINFO_HOSTS
"AUTO_NETINFO_HOSTS",
-#endif /* AUTO_NETINFO_HOSTS */
+#endif
#ifdef AUTO_NIS_ALIASES
"AUTO_NIS_ALIASES",
-#endif /* AUTO_NIS_ALIASES */
+#endif
#if BROKEN_RES_SEARCH
"BROKEN_RES_SEARCH",
-#endif /* BROKEN_RES_SEARCH */
+#endif
#ifdef BSD4_4_SOCKADDR
"BSD4_4_SOCKADDR",
-#endif /* BSD4_4_SOCKADDR */
+#endif
#if BOGUS_O_EXCL
"BOGUS_O_EXCL",
-#endif /* BOGUS_O_EXCL */
+#endif
#if DEC_OSF_BROKEN_GETPWENT
"DEC_OSF_BROKEN_GETPWENT",
-#endif /* DEC_OSF_BROKEN_GETPWENT */
+#endif
#if FAST_PID_RECYCLE
"FAST_PID_RECYCLE",
-#endif /* FAST_PID_RECYCLE */
+#endif
#if HASCLOSEFROM
"HASCLOSEFROM",
-#endif /* HASCLOSEFROM */
+#endif
#if HASFCHOWN
"HASFCHOWN",
-#endif /* HASFCHOWN */
+#endif
#if HASFCHMOD
"HASFCHMOD",
-#endif /* HASFCHMOD */
+#endif
#if HASFDWALK
"HASFDWALK",
-#endif /* HASFDWALK */
+#endif
#if HASFLOCK
"HASFLOCK",
-#endif /* HASFLOCK */
+#endif
#if HASGETDTABLESIZE
"HASGETDTABLESIZE",
-#endif /* HASGETDTABLESIZE */
+#endif
#if HASGETUSERSHELL
"HASGETUSERSHELL",
-#endif /* HASGETUSERSHELL */
+#endif
#if HASINITGROUPS
"HASINITGROUPS",
-#endif /* HASINITGROUPS */
+#endif
#if HASLDAPGETALIASBYNAME
"HASLDAPGETALIASBYNAME",
-#endif /* HASLDAPGETALIASBYNAME */
+#endif
#if HASLSTAT
"HASLSTAT",
-#endif /* HASLSTAT */
+#endif
#if HASNICE
"HASNICE",
-#endif /* HASNICE */
+#endif
#if HASRANDOM
"HASRANDOM",
-#endif /* HASRANDOM */
+#endif
#if HASRRESVPORT
"HASRRESVPORT",
-#endif /* HASRRESVPORT */
+#endif
#if HASSETEGID
"HASSETEGID",
-#endif /* HASSETEGID */
+#endif
#if HASSETLOGIN
"HASSETLOGIN",
-#endif /* HASSETLOGIN */
+#endif
#if HASSETREGID
"HASSETREGID",
-#endif /* HASSETREGID */
+#endif
#if HASSETRESGID
"HASSETRESGID",
-#endif /* HASSETRESGID */
+#endif
#if HASSETREUID
"HASSETREUID",
-#endif /* HASSETREUID */
+#endif
#if HASSETRLIMIT
"HASSETRLIMIT",
-#endif /* HASSETRLIMIT */
+#endif
#if HASSETSID
"HASSETSID",
-#endif /* HASSETSID */
+#endif
#if HASSETUSERCONTEXT
"HASSETUSERCONTEXT",
-#endif /* HASSETUSERCONTEXT */
+#endif
#if HASSETVBUF
"HASSETVBUF",
-#endif /* HASSETVBUF */
+#endif
#if HAS_ST_GEN
"HAS_ST_GEN",
-#endif /* HAS_ST_GEN */
+#endif
#if HASSRANDOMDEV
"HASSRANDOMDEV",
-#endif /* HASSRANDOMDEV */
+#endif
#if HASURANDOMDEV
"HASURANDOMDEV",
-#endif /* HASURANDOMDEV */
+#endif
#if HASSTRERROR
"HASSTRERROR",
-#endif /* HASSTRERROR */
+#endif
#if HASULIMIT
"HASULIMIT",
-#endif /* HASULIMIT */
+#endif
#if HASUNAME
"HASUNAME",
-#endif /* HASUNAME */
+#endif
#if HASUNSETENV
"HASUNSETENV",
-#endif /* HASUNSETENV */
+#endif
#if HASWAITPID
"HASWAITPID",
-#endif /* HASWAITPID */
+#endif
#if HAVE_NANOSLEEP
"HAVE_NANOSLEEP",
-#endif /* HAVE_NANOSLEEP */
+#endif
#if IDENTPROTO
"IDENTPROTO",
-#endif /* IDENTPROTO */
+#endif
#if IP_SRCROUTE
"IP_SRCROUTE",
-#endif /* IP_SRCROUTE */
+#endif
#if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
"LOCK_ON_OPEN",
-#endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
+#endif
#if MILTER_NO_NAGLE
"MILTER_NO_NAGLE ",
-#endif /* MILTER_NO_NAGLE */
+#endif
#if NEEDFSYNC
"NEEDFSYNC",
-#endif /* NEEDFSYNC */
+#endif
#if NEEDLINK
"NEEDLINK",
-#endif /* NEEDLINK */
+#endif
#if NEEDLOCAL_HOSTNAME_LENGTH
"NEEDLOCAL_HOSTNAME_LENGTH",
-#endif /* NEEDLOCAL_HOSTNAME_LENGTH */
+#endif
#if NEEDSGETIPNODE
"NEEDSGETIPNODE",
-#endif /* NEEDSGETIPNODE */
+#endif
#if NEEDSTRSTR
"NEEDSTRSTR",
-#endif /* NEEDSTRSTR */
+#endif
#if NEEDSTRTOL
"NEEDSTRTOL",
-#endif /* NEEDSTRTOL */
+#endif
#ifdef NO_GETSERVBYNAME
"NO_GETSERVBYNAME",
-#endif /* NO_GETSERVBYNAME */
+#endif
#if NOFTRUNCATE
"NOFTRUNCATE",
-#endif /* NOFTRUNCATE */
+#endif
#if REQUIRES_DIR_FSYNC
"REQUIRES_DIR_FSYNC",
-#endif /* REQUIRES_DIR_FSYNC */
+#endif
#if RLIMIT_NEEDS_SYS_TIME_H
"RLIMIT_NEEDS_SYS_TIME_H",
-#endif /* RLIMIT_NEEDS_SYS_TIME_H */
+#endif
#if SAFENFSPATHCONF
"SAFENFSPATHCONF",
-#endif /* SAFENFSPATHCONF */
+#endif
#if SECUREWARE
"SECUREWARE",
-#endif /* SECUREWARE */
+#endif
#if SFS_TYPE == SFS_4ARGS
"SFS_4ARGS",
#elif SFS_TYPE == SFS_MOUNT
@@ -6072,55 +6083,55 @@ char *OsCompileOptions[] =
#endif
#if SHARE_V1
"SHARE_V1",
-#endif /* SHARE_V1 */
+#endif
#if SIOCGIFCONF_IS_BROKEN
"SIOCGIFCONF_IS_BROKEN",
-#endif /* SIOCGIFCONF_IS_BROKEN */
+#endif
#if SIOCGIFNUM_IS_BROKEN
"SIOCGIFNUM_IS_BROKEN",
-#endif /* SIOCGIFNUM_IS_BROKEN */
+#endif
#if SNPRINTF_IS_BROKEN
"SNPRINTF_IS_BROKEN",
-#endif /* SNPRINTF_IS_BROKEN */
+#endif
#if SO_REUSEADDR_IS_BROKEN
"SO_REUSEADDR_IS_BROKEN",
-#endif /* SO_REUSEADDR_IS_BROKEN */
+#endif
#if SYS5SETPGRP
"SYS5SETPGRP",
-#endif /* SYS5SETPGRP */
+#endif
#if SYSTEM5
"SYSTEM5",
-#endif /* SYSTEM5 */
+#endif
#if USE_DOUBLE_FORK
"USE_DOUBLE_FORK",
-#endif /* USE_DOUBLE_FORK */
+#endif
#if USE_ENVIRON
"USE_ENVIRON",
-#endif /* USE_ENVIRON */
+#endif
#if USE_SA_SIGACTION
"USE_SA_SIGACTION",
-#endif /* USE_SA_SIGACTION */
+#endif
#if USE_SIGLONGJMP
"USE_SIGLONGJMP",
-#endif /* USE_SIGLONGJMP */
+#endif
#if USEGETCONFATTR
"USEGETCONFATTR",
-#endif /* USEGETCONFATTR */
+#endif
#if USESETEUID
"USESETEUID",
-#endif /* USESETEUID */
+#endif
#ifdef USESYSCTL
"USESYSCTL",
-#endif /* USESYSCTL */
+#endif
#if USE_OPENSSL_ENGINE
"USE_OPENSSL_ENGINE",
-#endif /* USE_OPENSSL_ENGINE */
+#endif
#if USING_NETSCAPE_LDAP
"USING_NETSCAPE_LDAP",
-#endif /* USING_NETSCAPE_LDAP */
+#endif
#ifdef WAITUNION
"WAITUNION",
-#endif /* WAITUNION */
+#endif
NULL
};
@@ -6130,77 +6141,73 @@ char *OsCompileOptions[] =
char *FFRCompileOptions[] =
{
+#if _FFR_ADD_BCC
+ "_FFR_ADD_BCC",
+#endif
#if _FFR_ADDR_TYPE_MODES
/* more info in {addr_type}, requires m4 changes! */
"_FFR_ADDR_TYPE_MODES",
-#endif /* _FFR_ADDR_TYPE_MODES */
+#endif
+#if _FFR_ALIAS_DETAIL
+ /* try to handle +detail for aliases */
+ "_FFR_ALIAS_DETAIL",
+#endif
#if _FFR_ALLOW_SASLINFO
/* DefaultAuthInfo can be specified by user. */
/* DefaultAuthInfo doesn't really work in 8.13 anymore. */
"_FFR_ALLOW_SASLINFO",
-#endif /* _FFR_ALLOW_SASLINFO */
-#if _FFR_ARPA_MAP
- /* arpa map to reverse an IPv(4,6) address */
- "_FFR_ARPA_MAP",
-#endif /* _FFR_ARPA_MAP */
+#endif
#if _FFR_BADRCPT_SHUTDOWN
/* shut down connection (421) if there are too many bad RCPTs */
"_FFR_BADRCPT_SHUTDOWN",
-#endif /* _FFR_BADRCPT_SHUTDOWN */
+#endif
#if _FFR_BESTMX_BETTER_TRUNCATION
/* Better truncation of list of MX records for dns map. */
"_FFR_BESTMX_BETTER_TRUNCATION",
-#endif /* _FFR_BESTMX_BETTER_TRUNCATION */
+#endif
+#if _FFR_BOUNCE_QUEUE
+ /* Separate, unprocessed queue for DSNs */
+ /* John Gardiner Myers of Proofpoint */
+ "_FFR_BOUNCE_QUEUE",
+#endif
#if _FFR_CATCH_BROKEN_MTAS
/* 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 */
+#endif
#if _FFR_CHK_QUEUE
/* Stricter checks about queue directory permissions. */
"_FFR_CHK_QUEUE",
-#endif /* _FFR_CHK_QUEUE */
+#endif
#if _FFR_CLIENT_SIZE
/* Don't try to send mail if its size exceeds SIZE= of server. */
"_FFR_CLIENT_SIZE",
-#endif /* _FFR_CLIENT_SIZE */
+#endif
#if _FFR_CRLPATH
/* CRLPath; needs documentation; Al Smith */
"_FFR_CRLPATH",
-#endif /* _FFR_CRLPATH */
-#if _FFR_DAEMON_NETUNIX
- /* Allow local (not just TCP) socket connection to server. */
- "_FFR_DAEMON_NETUNIX",
-#endif /* _FFR_DAEMON_NETUNIX */
-#if _FFR_DEPRECATE_MAILER_FLAG_I
- /* What it says :-) */
- "_FFR_DEPRECATE_MAILER_FLAG_I",
-#endif /* _FFR_DEPRECATE_MAILER_FLAG_I */
+#endif
#if _FFR_DM_ONE
/* deliver first TA in background, then queue */
"_FFR_DM_ONE",
-#endif /* _FFR_DM_ONE */
+#endif
#if _FFR_DIGUNIX_SAFECHOWN
/* Properly set SAFECHOWN (include/sm/conf.h) for Digital UNIX */
/* Problem noted by Anne Bennett of Concordia University */
"_FFR_DIGUNIX_SAFECHOWN",
-#endif /* _FFR_DIGUNIX_SAFECHOWN */
+#endif
#if _FFR_DNSMAP_ALIASABLE
/* Allow dns map type to be used for aliases. */
/* Don Lewis of TDK */
"_FFR_DNSMAP_ALIASABLE",
-#endif /* _FFR_DNSMAP_ALIASABLE */
+#endif
#if _FFR_DONTLOCKFILESFORREAD_OPTION
/* Enable DontLockFilesForRead option. */
"_FFR_DONTLOCKFILESFORREAD_OPTION",
-#endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
+#endif
#if _FFR_DOTTED_USERNAMES
/* Allow usernames with '.' */
"_FFR_DOTTED_USERNAMES",
-#endif /* _FFR_DOTTED_USERNAMES */
+#endif
#if _FFR_DPO_CS
/*
** Make DaemonPortOptions case sensitive.
@@ -6215,11 +6222,11 @@ char *FFRCompileOptions[] =
*/
"_FFR_DPO_CS",
-#endif /* _FFR_DPO_CS */
+#endif
#if _FFR_DPRINTF_MAP
/* dprintf map for logging */
"_FFR_DPRINTF_MAP",
-#endif /* _FFR_DPRINTF_MAP */
+#endif
#if _FFR_DROP_TRUSTUSER_WARNING
/*
** Don't issue this warning:
@@ -6228,24 +6235,20 @@ char *FFRCompileOptions[] =
*/
"_FFR_DROP_TRUSTUSER_WARNING",
-#endif /* _FFR_DROP_TRUSTUSER_WARNING */
+#endif
#if _FFR_EIGHT_BIT_ADDR_OK
/* 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 */
+#endif
#if _FFR_EXTRA_MAP_CHECK
/* perform extra checks on $( $) in R lines */
"_FFR_EXTRA_MAP_CHECK",
-#endif /* _FFR_EXTRA_MAP_CHECK */
+#endif
#if _FFR_GETHBN_ExFILE
/*
** According to Motonori Nakamura some gethostbyname()
** implementations (TurboLinux?) may (temporarily) fail
- ** due to a lack of file discriptors. Enabling this FFR
+ ** due to a lack of file descriptors. Enabling this FFR
** will check errno for EMFILE and ENFILE and in case of a match
** cause a temporary error instead of a permanent error.
** The right solution is of course to file a bug against those
@@ -6253,11 +6256,11 @@ char *FFRCompileOptions[] =
*/
"_FFR_GETHBN_ExFILE",
-#endif /* _FFR_GETHBN_ExFILE */
+#endif
#if _FFR_FIPSMODE
/* FIPSMode (if supported by OpenSSL library) */
"_FFR_FIPSMODE",
-#endif /* _FFR_FIPSMODE */
+#endif
#if _FFR_FIX_DASHT
/*
** If using -t, force not sending to argv recipients, even
@@ -6265,55 +6268,66 @@ char *FFRCompileOptions[] =
*/
"_FFR_FIX_DASHT",
-#endif /* _FFR_FIX_DASHT */
+#endif
#if _FFR_FORWARD_SYSERR
/* Cause a "syserr" if forward file isn't "safe". */
"_FFR_FORWARD_SYSERR",
-#endif /* _FFR_FORWARD_SYSERR */
+#endif
#if _FFR_GEN_ORCPT
/* Generate a ORCPT DSN arg if not already provided */
"_FFR_GEN_ORCPT",
-#endif /* _FFR_GEN_ORCPT */
-#if _FFR_GROUPREADABLEAUTHINFOFILE
- /* Allow group readable DefaultAuthInfo file. */
- "_FFR_GROUPREADABLEAUTHINFOFILE",
-#endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
+#endif
#if _FFR_HANDLE_ISO8859_GECOS
/*
** Allow ISO 8859 characters in GECOS field: replace them
- ** ith ASCII "equivalent".
+ ** with ASCII "equivalent".
*/
/* Peter Eriksson of Linkopings universitet */
"_FFR_HANDLE_ISO8859_GECOS",
-#endif /* _FFR_HANDLE_ISO8859_GECOS */
+#endif
+#if _FFR_HANDLE_HDR_RW_TEMPFAIL
+ /*
+ ** Temporary header rewriting problems from remotename() etc
+ ** are not "sticky" for mci (e.g., during queue runs).
+ */
+
+ "_FFR_HANDLE_HDR_RW_TEMPFAIL",
+#endif
#if _FFR_HPUX_NSSWITCH
/* Use nsswitch on HP-UX */
"_FFR_HPUX_NSSWITCH",
-#endif /* _FFR_HPUX_NSSWITCH */
+#endif
#if _FFR_IGNORE_BOGUS_ADDR
/* Ignore addresses for which prescan() failed */
"_FFR_IGNORE_BOGUS_ADDR",
-#endif /* _FFR_IGNORE_BOGUS_ADDR */
+#endif
#if _FFR_IGNORE_EXT_ON_HELO
/* Ignore extensions offered in response to HELO */
"_FFR_IGNORE_EXT_ON_HELO",
-#endif /* _FFR_IGNORE_EXT_ON_HELO */
-#if _FFR_IPV6_FULL
- /* Use uncompressed IPv6 address format (no "::") */
- "_FFR_IPV6_FULL",
-#endif /* _FFR_IPV6_FULL */
+#endif
#if _FFR_LINUX_MHNL
/* Set MAXHOSTNAMELEN to 256 (Linux) */
"_FFR_LINUX_MHNL",
-#endif /* _FFR_LINUX_MHNL */
+#endif
#if _FFR_LOCAL_DAEMON
/* Local daemon mode (-bl) which only accepts loopback connections */
"_FFR_LOCAL_DAEMON",
-#endif /* _FFR_LOCAL_DAEMON */
+#endif
+#if _FFR_LOG_MORE1
+ /* log some TLS/AUTH info in from= too */
+ "_FFR_LOG_MORE1",
+#endif
+#if _FFR_LOG_MORE2
+ /* log some TLS info in to= too */
+ "_FFR_LOG_MORE2",
+#endif
+#if _FFR_LOGREPLY
+ "_FFR_LOGREPLY",
+#endif
#if _FFR_MAIL_MACRO
"_FFR_MAIL_MACRO",
-#endif /* _FFR_MAIL_MACRO */
+#endif
#if _FFR_MAXDATASIZE
/*
** It is possible that a header is larger than MILTER_CHUNK_SIZE,
@@ -6323,28 +6337,33 @@ char *FFRCompileOptions[] =
*/
"_FFR_MAXDATASIZE",
-#endif /* _FFR_MAXDATASIZE */
+#endif
#if _FFR_MAX_FORWARD_ENTRIES
/* Try to limit number of .forward entries */
/* (doesn't work) */
/* Randall S. Winchester of the University of Maryland */
"_FFR_MAX_FORWARD_ENTRIES",
-#endif /* _FFR_MAX_FORWARD_ENTRIES */
+#endif
#if _FFR_MAX_SLEEP_TIME
/* Limit sleep(2) time in libsm/clock.c */
"_FFR_MAX_SLEEP_TIME",
-#endif /* _FFR_MAX_SLEEP_TIME */
+#endif
#if _FFR_MDS_NEGOTIATE
/* MaxDataSize negotation with libmilter */
"_FFR_MDS_NEGOTIATE",
-#endif /* _FFR_MDS_NEGOTIATE */
+#endif
#if _FFR_MEMSTAT
/* Check free memory */
"_FFR_MEMSTAT",
-#endif /* _FFR_MEMSTAT */
+#endif
#if _FFR_MILTER_CHECK
"_FFR_MILTER_CHECK",
-#endif /* _FFR_MILTER_CHECK */
+#endif
+#if _FFR_MILTER_CONNECT_REPLYCODE
+ /* milter: propagate replycode returned by connect commands */
+ /* John Gardiner Myers of Proofpoint */
+ "_FFR_MILTER_CONNECT_REPLYCODE ",
+#endif
#if _FFR_MILTER_CONVERT_ALL_LF_TO_CRLF
/*
** milter_body() uses the same conversion algorithm as putbody()
@@ -6362,7 +6381,7 @@ char *FFRCompileOptions[] =
*/
"_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF",
-#endif /* _FFR_MILTER_CONVERT_ALL_LF_TO_CRLF */
+#endif
#if _FFR_MILTER_CHECK_REJECTIONS_TOO
/*
** Also send RCPTs that are rejected by check_rcpt to a milter
@@ -6370,68 +6389,71 @@ char *FFRCompileOptions[] =
*/
"_FFR_MILTER_CHECK_REJECTIONS_TOO",
-#endif /* _FFR_MILTER_CHECK_REJECTIONS_TOO */
+#endif
#if _FFR_MILTER_ENHSC
/* extract enhanced status code from milter replies for dsn= logging */
"_FFR_MILTER_ENHSC",
-#endif /* _FFR_MILTER_ENHSC */
+#endif
#if _FFR_MIME7TO8_OLD
/* Old mime7to8 code, the new is broken for at least one example. */
"_FFR_MIME7TO8_OLD",
-#endif /* _FFR_MAX_SLEEP_TIME */
+#endif
#if _FFR_MORE_MACROS
/* allow more long macro names ("unprintable" characters). */
"_FFR_MORE_MACROS",
-#endif /* _FFR_MORE_MACROS */
+#endif
#if _FFR_MSG_ACCEPT
/* allow to override "Message accepted for delivery" */
"_FFR_MSG_ACCEPT",
-#endif /* _FFR_MSG_ACCEPT */
+#endif
#if _FFR_NODELAYDSN_ON_HOLD
/* Do not issue a DELAY DSN for mailers that use the hold flag. */
/* Steven Pitzl */
"_FFR_NODELAYDSN_ON_HOLD",
-#endif /* _FFR_NODELAYDSN_ON_HOLD */
+#endif
#if _FFR_NO_PIPE
/* Disable PIPELINING, delay client if used. */
"_FFR_NO_PIPE",
-#endif /* _FFR_NO_PIPE */
+#endif
#if _FFR_LDAP_NETWORK_TIMEOUT
/* set LDAP_OPT_NETWORK_TIMEOUT if available (-c) */
"_FFR_LDAP_NETWORK_TIMEOUT",
-#endif /* _FFR_LDAP_NETWORK_TIMEOUT */
+#endif
#if _FFR_LOG_NTRIES
/* log ntries=, from Nik Clayton of FreeBSD */
"_FFR_LOG_NTRIES",
-#endif /* _FFR_LOG_NTRIES */
+#endif
+#if _FFR_PROXY
+ /* "proxy" (synchronous) delivery mode */
+ "_FFR_PROXY",
+#endif
#if _FFR_QF_PARANOIA
"_FFR_QF_PARANOIA",
-#endif /* _FFR_QF_PARANOIA */
-#if _FFR_QUEUEDELAY
- /* Exponential queue delay; disabled in 8.13 since it isn't used. */
- "_FFR_QUEUEDELAY",
-#endif /* _FFR_QUEUEDELAY */
+#endif
#if _FFR_QUEUE_GROUP_SORTORDER
/* Allow QueueSortOrder per queue group. */
/* XXX: Still need to actually use qgrp->qg_sortorder */
"_FFR_QUEUE_GROUP_SORTORDER",
-#endif /* _FFR_QUEUE_GROUP_SORTORDER */
+#endif
#if _FFR_QUEUE_MACRO
/* Define {queue} macro. */
"_FFR_QUEUE_MACRO",
-#endif /* _FFR_QUEUE_MACRO */
+#endif
#if _FFR_QUEUE_RUN_PARANOIA
/* Additional checks when doing queue runs; interval of checks */
"_FFR_QUEUE_RUN_PARANOIA",
-#endif /* _FFR_QUEUE_RUN_PARANOIA */
+#endif
#if _FFR_QUEUE_SCHED_DBG
/* Debug output for the queue scheduler. */
"_FFR_QUEUE_SCHED_DBG",
-#endif /* _FFR_QUEUE_SCHED_DBG */
+#endif
+#if _FFR_RCPTFLAGS
+ "_FFR_RCPTFLAGS",
+#endif
#if _FFR_RCPTTHROTDELAY
/* configurable delay for BadRcptThrottle */
"_FFR_RCPTTHROTDELAY",
-#endif /* _FFR_RCPTTHROTDELAY */
+#endif
#if _FFR_REDIRECTEMPTY
/*
** envelope <> can't be sent to mailing lists, only owner-
@@ -6440,19 +6462,19 @@ char *FFRCompileOptions[] =
*/
"_FFR_REDIRECTEMPTY",
-#endif /* _FFR_REDIRECTEMPTY */
+#endif
#if _FFR_REJECT_NUL_BYTE
/* reject NUL bytes in body */
"_FFR_REJECT_NUL_BYTE",
-#endif /* _FFR_REJECT_NUL_BYTE */
+#endif
#if _FFR_RESET_MACRO_GLOBALS
/* Allow macro 'j' to be set dynamically via rulesets. */
"_FFR_RESET_MACRO_GLOBALS",
-#endif /* _FFR_RESET_MACRO_GLOBALS */
+#endif
#if _FFR_RHS
/* Random shuffle for queue sorting. */
"_FFR_RHS",
-#endif /* _FFR_RHS */
+#endif
#if _FFR_RUNPQG
/*
** allow -qGqueue_group -qp to work, i.e.,
@@ -6460,15 +6482,15 @@ char *FFRCompileOptions[] =
*/
"_FFR_RUNPQG",
-#endif /* _FFR_RUNPQG */
+#endif
#if _FFR_SESSID
/* session id (for logging) */
"_FFR_SESSID",
-#endif /* _FFR_SESSID */
+#endif
#if _FFR_SHM_STATUS
/* Donated code (unused). */
"_FFR_SHM_STATUS",
-#endif /* _FFR_SHM_STATUS */
+#endif
#if _FFR_LDAP_SINGLEDN
/*
** The LDAP database map code in Sendmail 8.12.10, when
@@ -6487,15 +6509,15 @@ char *FFRCompileOptions[] =
*/
"_FFR_LDAP_SINGLEDN",
-#endif /* _FFR_LDAP_SINGLEDN */
+#endif
#if _FFR_SKIP_DOMAINS
/* process every N'th domain instead of every N'th message */
"_FFR_SKIP_DOMAINS",
-#endif /* _FFR_SKIP_DOMAINS */
+#endif
#if _FFR_SLEEP_USE_SELECT
/* Use select(2) in libsm/clock.c to emulate sleep(2) */
"_FFR_SLEEP_USE_SELECT ",
-#endif /* _FFR_SLEEP_USE_SELECT */
+#endif
#if _FFR_SPT_ALIGN
/*
** It looks like the Compaq Tru64 5.1A now aligns argv and envp to 64
@@ -6507,26 +6529,34 @@ char *FFRCompileOptions[] =
/* Chris Adams of HiWAAY Informations Services */
"_FFR_SPT_ALIGN",
-#endif /* _FFR_SPT_ALIGN */
+#endif
#if _FFR_SS_PER_DAEMON
/* SuperSafe per DaemonPortOptions: 'T' (better letter?) */
"_FFR_SS_PER_DAEMON",
-#endif /* _FFR_SS_PER_DAEMON */
+#endif
#if _FFR_TESTS
/* enable some test code */
"_FFR_TESTS",
-#endif /* _FFR_TESTS */
+#endif
#if _FFR_TIMERS
/* Donated code (unused). */
"_FFR_TIMERS",
-#endif /* _FFR_TIMERS */
-#if _FFR_TLS_1
- /* More STARTTLS options, e.g., secondary certs. */
- "_FFR_TLS_1",
-#endif /* _FFR_TLS_1 */
+#endif
#if _FFR_TLS_EC
"_FFR_TLS_EC",
-#endif /* _FFR_TLS_EC */
+#endif
+#if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE
+ /*
+ ** Use SSL_CTX_use_certificate_chain_file()
+ ** instead of SSL_CTX_use_certificate_file()
+ */
+
+ "_FFR_TLS_USE_CERTIFICATE_CHAIN_FILE",
+#endif
+#if _FFR_TLS_SE_OPTS
+ /* TLS session options */
+ "_FFR_TLS_SE_OPTS",
+#endif
#if _FFR_TRUSTED_QF
/*
** If we don't own the file mark it as unsafe.
@@ -6535,7 +6565,7 @@ char *FFRCompileOptions[] =
*/
"_FFR_TRUSTED_QF",
-#endif /* _FFR_TRUSTED_QF */
+#endif
#if _FFR_USE_GETPWNAM_ERRNO
/*
** See libsm/mbdb.c: only enable this on OSs
@@ -6545,15 +6575,18 @@ char *FFRCompileOptions[] =
*/
"_FFR_USE_GETPWNAM_ERRNO",
-#endif /* _FFR_USE_GETPWNAM_ERRNO */
+#endif
#if _FFR_USE_SEM_LOCKING
"_FFR_USE_SEM_LOCKING",
-#endif /* _FFR_USE_SEM_LOCKING */
+#endif
#if _FFR_USE_SETLOGIN
/* Use setlogin() */
/* Peter Philipp */
"_FFR_USE_SETLOGIN",
-#endif /* _FFR_USE_SETLOGIN */
+#endif
+#if _FFR_XCNCT
+ "_FFR_XCNCT",
+#endif
NULL
};
diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c
index d6b3f49..4288365 100644
--- a/contrib/sendmail/src/daemon.c
+++ b/contrib/sendmail/src/daemon.c
@@ -32,7 +32,7 @@ SM_RCSID("@(#)$Id: daemon.c,v 8.698 2013-11-22 20:51:55 ca Exp $")
#endif /* defined(USE_SOCK_STREAM) */
#if STARTTLS
-# include <openssl/rand.h>
+# include <openssl/rand.h>
#endif /* STARTTLS */
#include <sm/time.h>
@@ -517,14 +517,12 @@ getrequests(e)
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_family}"), "unspec");
break;
-#if _FFR_DAEMON_NETUNIX
-# if NETUNIX
+#if NETUNIX
case AF_UNIX:
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_family}"), "local");
break;
-# endif /* NETUNIX */
-#endif /* _FFR_DAEMON_NETUNIX */
+#endif /* NETUNIX */
#if NETINET
case AF_INET:
macdefine(&BlankEnvelope.e_macro, A_PERM,
@@ -827,6 +825,17 @@ getrequests(e)
OutChannel = outchannel;
DisConnected = false;
+#if _FFR_XCNCT
+ t = xconnect(inchannel);
+ if (t <= 0)
+ {
+ clrbitn(D_XCNCT, Daemons[curdaemon].d_flags);
+ clrbitn(D_XCNCT_M, Daemons[curdaemon].d_flags);
+ }
+ else
+ setbitn(t, Daemons[curdaemon].d_flags);
+
+#endif /* _FFR_XCNCT */
#if XLA
if (!xla_host_ok(RealHostName))
@@ -1060,8 +1069,7 @@ opendaemonsocket(d, firsttime)
(void) sleep(5);
if (firsttime || d->d_socket < 0)
{
-#if _FFR_DAEMON_NETUNIX
-# if NETUNIX
+#if NETUNIX
if (d->d_addr.sa.sa_family == AF_UNIX)
{
int rval;
@@ -1084,8 +1092,7 @@ opendaemonsocket(d, firsttime)
/* Don't try to overtake an existing socket */
(void) unlink(d->d_addr.sunix.sun_path);
}
-# endif /* NETUNIX */
-#endif /* _FFR_DOMAIN_NETUNIX */
+#endif /* NETUNIX */
d->d_socket = socket(d->d_addr.sa.sa_family,
SOCK_STREAM, 0);
if (d->d_socket < 0)
@@ -1113,7 +1120,7 @@ opendaemonsocket(d, firsttime)
continue;
}
- if (SM_FD_SETSIZE > 0 && d->d_socket >= SM_FD_SETSIZE)
+ if (!SM_FD_OK_SELECT(d->d_socket))
{
save_errno = EINVAL;
syserr("opendaemonsocket: daemon %s: server SMTP socket (%d) too large",
@@ -1168,13 +1175,11 @@ opendaemonsocket(d, firsttime)
switch (d->d_addr.sa.sa_family)
{
-#if _FFR_DAEMON_NETUNIX
-# ifdef NETUNIX
+#ifdef NETUNIX
case AF_UNIX:
socksize = sizeof(d->d_addr.sunix);
break;
-# endif /* NETUNIX */
-#endif /* _FFR_DAEMON_NETUNIX */
+#endif /* NETUNIX */
#if NETINET
case AF_INET:
socksize = sizeof(d->d_addr.sin);
@@ -1493,6 +1498,9 @@ setsockaddroptions(p, d)
case SM_DEFER:
case SM_DELIVER:
case SM_FORK:
+#if _FFR_PROXY
+ case SM_PROXY_REQ:
+#endif /* _FFR_PROXY */
d->d_dm = *v;
break;
default:
@@ -1512,13 +1520,11 @@ setsockaddroptions(p, d)
#endif /* !_FFR_DPO_CS */
if (isascii(*v) && isdigit(*v))
d->d_addr.sa.sa_family = atoi(v);
-#if _FFR_DAEMON_NETUNIX
-# ifdef NETUNIX
+#ifdef NETUNIX
else if (sm_strcasecmp(v, "unix") == 0 ||
sm_strcasecmp(v, "local") == 0)
d->d_addr.sa.sa_family = AF_UNIX;
-# endif /* NETUNIX */
-#endif /* _FFR_DAEMON_NETUNIX */
+#endif /* NETUNIX */
#if NETINET
else if (sm_strcasecmp(v, "inet") == 0)
d->d_addr.sa.sa_family = AF_INET;
@@ -1628,14 +1634,14 @@ setsockaddroptions(p, d)
{
switch (d->d_addr.sa.sa_family)
{
-#if _FFR_DAEMON_NETUNIX
-# if NETUNIX
+#if NETUNIX
case AF_UNIX:
if (strlen(addr) >= sizeof(d->d_addr.sunix.sun_path))
{
errno = ENAMETOOLONG;
- syserr("setsockaddroptions: domain socket name too long: %s > %d",
- addr, sizeof(d->d_addr.sunix.sun_path));
+ syserr("setsockaddroptions: domain socket name too long: %s > %ld",
+ addr,
+ (long) sizeof(d->d_addr.sunix.sun_path));
break;
}
@@ -1646,8 +1652,7 @@ setsockaddroptions(p, d)
addr,
sizeof(d->d_addr.sunix.sun_path));
break;
-# endif /* NETUNIX */
-#endif /* _FFR_DAEMON_NETUNIX */
+#endif /* NETUNIX */
#if NETINET
case AF_INET:
if (!isascii(*addr) || !isdigit(*addr) ||
@@ -1998,16 +2003,14 @@ addr_family(addr)
return AF_INET6;
}
#endif /* NETINET6 */
-#if _FFR_DAEMON_NETUNIX
-# if NETUNIX
+#if NETUNIX
if (*addr == '/')
{
if (tTd(16, 9))
sm_dprintf("addr_family(%s): LOCAL\n", addr);
return AF_UNIX;
}
-# endif /* NETUNIX */
-#endif /* _FFR_DAEMON_NETUNIX */
+#endif /* NETUNIX */
if (tTd(16, 9))
sm_dprintf("addr_family(%s): UNSPEC\n", addr);
return AF_UNSPEC;
@@ -2045,7 +2048,7 @@ chkclientmodifiers(flag)
#if MILTER
/*
-** SETUP_DAEMON_FILTERS -- Parse per-socket filters
+** SETUP_DAEMON_MILTERS -- Parse per-socket filters
**
** Parameters:
** none
@@ -3047,8 +3050,7 @@ shutdown_daemon()
(void) close(Daemons[i].d_socket);
Daemons[i].d_socket = -1;
-#if _FFR_DAEMON_NETUNIX
-# if NETUNIX
+#if NETUNIX
/* Remove named sockets */
if (Daemons[i].d_addr.sa.sa_family == AF_UNIX)
{
@@ -3070,8 +3072,7 @@ shutdown_daemon()
sm_errstring(errno));
}
}
-# endif /* NETUNIX */
-#endif /* _FFR_DAEMON_NETUNIX */
+#endif /* NETUNIX */
}
}
@@ -3413,7 +3414,7 @@ getauthinfo(fd, may_be_forged)
char ibuf[MAXNAME + 1];
static char hbuf[MAXNAME + MAXAUTHINFO + 11];
- *may_be_forged = false;
+ *may_be_forged = true;
falen = sizeof(RealHostAddr);
if (isatty(fd) || (i = getpeername(fd, &RealHostAddr.sa, &falen)) < 0 ||
falen <= 0 || RealHostAddr.sa.sa_family == 0)
@@ -3430,6 +3431,8 @@ getauthinfo(fd, may_be_forged)
return NULL;
errno = 0;
}
+
+ *may_be_forged = false;
(void) sm_strlcpyn(hbuf, sizeof(hbuf), 2, RealUserName,
"@localhost");
if (tTd(9, 1))
@@ -3446,8 +3449,10 @@ getauthinfo(fd, may_be_forged)
}
/* cross check RealHostName with forward DNS lookup */
- if (anynet_ntoa(&RealHostAddr)[0] != '[' &&
- RealHostName[0] != '[')
+ if (anynet_ntoa(&RealHostAddr)[0] == '[' ||
+ RealHostName[0] == '[')
+ *may_be_forged = false;
+ else
{
int family;
@@ -3473,19 +3478,16 @@ getauthinfo(fd, may_be_forged)
/* try to match the reverse against the forward lookup */
hp = sm_gethostbyname(RealHostName, family);
- if (hp == NULL)
- {
- /* XXX: Could be a temporary error on forward lookup */
- *may_be_forged = true;
- }
- else
+ if (hp != NULL)
{
for (ha = hp->h_addr_list; *ha != NULL; ha++)
{
if (addrcmp(hp, *ha, &RealHostAddr) == 0)
+ {
+ *may_be_forged = false;
break;
+ }
}
- *may_be_forged = *ha == NULL;
#if NETINET6
freehostent(hp);
hp = NULL;
@@ -4259,12 +4261,10 @@ anynet_ntop(s6a, dst, dst_len)
return NULL;
dst += sz;
dst_len -= sz;
-# if _FFR_IPV6_FULL
- ap = sm_inet6_ntop(s6a, dst, dst_len);
-# else /* _FFR_IPV6_FULL */
- ap = (char *) inet_ntop(AF_INET6, s6a, dst, dst_len);
-# endif /* _FFR_IPV6_FULL */
-
+ if (UseCompressedIPv6Addresses)
+ ap = (char *) inet_ntop(AF_INET6, s6a, dst, dst_len);
+ else
+ ap = sm_inet6_ntop(s6a, dst, dst_len);
/* Restore pointer to beginning of string */
if (ap != NULL)
ap = d;
diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c
index 39c484c..62d02b1 100644
--- a/contrib/sendmail/src/deliver.c
+++ b/contrib/sendmail/src/deliver.c
@@ -37,7 +37,7 @@ static void sendenvelope __P((ENVELOPE *, int));
static int coloncmp __P((const char *, const char *));
#if STARTTLS
-# include <openssl/err.h>
+# include <openssl/err.h>
static int starttls __P((MAILER *, MCI *, ENVELOPE *));
static int endtlsclt __P((MCI *));
#endif /* STARTTLS */
@@ -1223,6 +1223,7 @@ should_try_fbsh(e, tried_fallbacksmarthost, hostbuf, hbsz, status)
}
return false;
}
+
/*
** DELIVER -- Deliver a message to a list of addresses.
**
@@ -1392,6 +1393,8 @@ deliver(e, firstto)
else
p = e->e_from.q_paddr;
rpath = remotename(p, m, RF_SENDERADDR|RF_CANONICAL, &rcode, e);
+ if (rcode != EX_OK && bitnset(M_xSMTP, m->m_flags))
+ goto cleanup;
if (strlen(rpath) > MAXNAME)
{
rpath = shortenstring(rpath, MAXSHORTSTR);
@@ -1468,6 +1471,7 @@ deliver(e, firstto)
/* running LMTP or SMTP */
clever = true;
*pvp = NULL;
+ setbitn(M_xSMTP, m->m_flags);
}
else if (bitnset(M_LMTP, m->m_flags))
{
@@ -1600,7 +1604,7 @@ deliver(e, firstto)
quarantine = (e->e_quarmsg != NULL);
rcode = rscheck("check_compat", e->e_from.q_paddr, to->q_paddr,
e, RSF_RMCOMM|RSF_COUNT, 3, NULL,
- e->e_id, NULL);
+ e->e_id, NULL, NULL);
if (rcode == EX_OK)
{
/* do in-code checking if not discarding */
@@ -2465,8 +2469,8 @@ tryhost:
ctladdr->q_gid) == -1
&& suidwarn)
{
- syserr("openmailer: initgroups(%s, %d) failed",
- user, ctladdr->q_gid);
+ syserr("openmailer: initgroups(%s, %ld) failed",
+ user, (long) ctladdr->q_gid);
exit(EX_TEMPFAIL);
}
}
@@ -2492,8 +2496,8 @@ tryhost:
if (initgroups(DefUser, DefGid) == -1 &&
suidwarn)
{
- syserr("openmailer: initgroups(%s, %d) failed",
- DefUser, DefGid);
+ syserr("openmailer: initgroups(%s, %ld) failed",
+ DefUser, (long) DefGid);
exit(EX_TEMPFAIL);
}
}
@@ -2522,9 +2526,9 @@ tryhost:
new_gid != getegid())
{
/* Only root can change the gid */
- syserr("openmailer: insufficient privileges to change gid, RunAsUid=%d, new_gid=%d, gid=%d, egid=%d",
- (int) RunAsUid, (int) new_gid,
- (int) getgid(), (int) getegid());
+ syserr("openmailer: insufficient privileges to change gid, RunAsUid=%ld, new_gid=%ld, gid=%ld, egid=%ld",
+ (long) RunAsUid, (long) new_gid,
+ (long) getgid(), (long) getegid());
exit(EX_TEMPFAIL);
}
@@ -2619,8 +2623,8 @@ tryhost:
if (RunAsUid != 0 && new_euid != RunAsUid)
{
/* Only root can change the uid */
- syserr("openmailer: insufficient privileges to change uid, new_euid=%d, RunAsUid=%d",
- (int) new_euid, (int) RunAsUid);
+ syserr("openmailer: insufficient privileges to change uid, new_euid=%ld, RunAsUid=%ld",
+ (long) new_euid, (long) RunAsUid);
exit(EX_TEMPFAIL);
}
@@ -2662,9 +2666,9 @@ tryhost:
}
if (tTd(11, 2))
- sm_dprintf("openmailer: running as r/euid=%d/%d, r/egid=%d/%d\n",
- (int) getuid(), (int) geteuid(),
- (int) getgid(), (int) getegid());
+ sm_dprintf("openmailer: running as r/euid=%ld/%ld, r/egid=%ld/%ld\n",
+ (long) getuid(), (long) geteuid(),
+ (long) getgid(), (long) getegid());
/* move into some "safe" directory */
if (m->m_execdir != NULL)
@@ -2964,8 +2968,8 @@ reconnect: /* after switching to an encrypted connection */
QuickAbort = false;
SuprErrs = true;
if (rscheck("try_tls", host, NULL, e,
- RSF_RMCOMM, 7, host, NOQID, NULL)
- != EX_OK
+ RSF_RMCOMM, 7, host, NOQID, NULL,
+ NULL) != EX_OK
|| Errors > olderrors)
{
usetls = false;
@@ -3039,7 +3043,7 @@ reconnect: /* after switching to an encrypted connection */
if (rscheck("tls_server",
macvalue(macid("{verify}"), e),
NULL, e, RSF_RMCOMM|RSF_COUNT, 5,
- host, NOQID, NULL) != EX_OK ||
+ host, NOQID, NULL, NULL) != EX_OK ||
Errors > olderrors ||
rcode == EX_SOFTWARE)
{
@@ -3364,7 +3368,7 @@ do_transfer:
# if STARTTLS
i = rscheck("tls_rcpt", to->q_user, NULL, e,
RSF_RMCOMM|RSF_COUNT, 3,
- mci->mci_host, e->e_id, NULL);
+ mci->mci_host, e->e_id, NULL, NULL);
if (i != EX_OK)
{
markfailure(e, to, mci, i, false);
@@ -3590,7 +3594,7 @@ do_transfer:
if (tobuf[0] != '\0')
{
- giveresponse(rcode, NULL, m, mci, ctladdr, xstart, e, tochain);
+ giveresponse(rcode, NULL, m, mci, ctladdr, xstart, e, NULL);
#if 0
/*
** This code is disabled for now because I am not
@@ -4166,14 +4170,13 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
/*
** Final cleanup.
- ** Log a record of the transaction. Compute the new
- ** ExitStat -- if we already had an error, stick with
- ** that.
+ ** Log a record of the transaction. Compute the new ExitStat
+ ** -- if we already had an error, stick with that.
*/
if (OpMode != MD_VERIFY && !bitset(EF_VRFYONLY, e->e_flags) &&
LogLevel > ((status == EX_TEMPFAIL) ? 8 : (status == EX_OK) ? 7 : 6))
- logdelivery(m, mci, dsn, statmsg + off, ctladdr, xstart, e);
+ logdelivery(m, mci, dsn, statmsg + off, ctladdr, xstart, e, to, status);
if (tTd(11, 2))
sm_dprintf("giveresponse: status=%d, dsn=%s, e->e_message=%s, errnum=%d\n",
@@ -4215,6 +4218,8 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
** xstart -- the transaction start time, used for
** computing transaction delay.
** e -- the current envelope.
+** to -- the current recipient (NULL if none).
+** rcode -- status code
**
** Returns:
** none
@@ -4224,7 +4229,7 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
*/
void
-logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
+logdelivery(m, mci, dsn, status, ctladdr, xstart, e, to, rcode)
MAILER *m;
register MCI *mci;
char *dsn;
@@ -4232,6 +4237,8 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
ADDRESS *ctladdr;
time_t xstart;
register ENVELOPE *e;
+ ADDRESS *to;
+ int rcode;
{
register char *bp;
register char *p;
@@ -4276,6 +4283,16 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
bp += strlen(bp);
}
+# if _FFR_LOG_MORE2
+# if STARTTLS
+ p = macvalue(macid("{verify}"), e);
+ if (p == NULL || *p == '\0')
+ p = "NONE";
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp), ", tls_verify=%.20s", p);
+ bp += strlen(bp);
+# endif /* STARTTLS */
+# endif /* _FFR_LOG_MORE2 */
+
/* pri: changes with each delivery attempt */
(void) sm_snprintf(bp, SPACELEFT(buf, bp), ", pri=%ld",
PRT_NONNEGL(e->e_msgpriority));
@@ -4342,6 +4359,43 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
# define STATLEN 203
# endif /* (STATLEN) > 203 */
+#if _FFR_LOGREPLY
+ /*
+ ** Notes:
+ ** per-rcpt status: to->q_rstatus
+ ** global status: e->e_text
+ **
+ ** We (re)use STATLEN here, is that a good choice?
+ **
+ ** stat=Deferred: ...
+ ** has sometimes the same text?
+ **
+ ** Note: this doesn't show the stage at which the error happened.
+ ** can/should we log that?
+ ** XS_* in reply() basically encodes the state.
+ */
+
+ /* only show errors */
+ if (rcode != EX_OK && to != NULL && to->q_rstatus != NULL &&
+ *to->q_rstatus != '\0')
+ {
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp),
+ ", reply=%s",
+ shortenstring(to->q_rstatus, STATLEN));
+ bp += strlen(bp);
+ }
+ else if (rcode != EX_OK && e->e_text != NULL)
+ {
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp),
+ ", reply=%d %s%s%s",
+ e->e_rcode,
+ e->e_renhsc,
+ (e->e_renhsc[0] != '\0') ? " " : "",
+ shortenstring(e->e_text, STATLEN));
+ bp += strlen(bp);
+ }
+#endif
+
/* stat: max 210 bytes */
if ((bp - buf) > (sizeof(buf) - ((STATLEN) + 20)))
{
@@ -4368,6 +4422,7 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e)
for (q = p + l; q > p; q--)
{
+ /* XXX a comma in an address will break this! */
if (*q == ',')
break;
}
@@ -5327,8 +5382,8 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
if (RunAsUid != 0 && RealUid != RunAsUid)
{
/* Only root can change the uid */
- syserr("mailfile: insufficient privileges to change uid, RunAsUid=%d, RealUid=%d",
- (int) RunAsUid, (int) RealUid);
+ syserr("mailfile: insufficient privileges to change uid, RunAsUid=%ld, RealUid=%ld",
+ (long) RunAsUid, (long) RealUid);
RETURN(EX_TEMPFAIL);
}
}
@@ -5368,9 +5423,9 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
RealGid != getegid()))
{
/* Only root can change the gid */
- syserr("mailfile: insufficient privileges to change gid, RealGid=%d, RunAsUid=%d, gid=%d, egid=%d",
- (int) RealGid, (int) RunAsUid,
- (int) getgid(), (int) getegid());
+ syserr("mailfile: insufficient privileges to change gid, RealGid=%ld, RunAsUid=%ld, gid=%ld, egid=%ld",
+ (long) RealGid, (long) RunAsUid,
+ (long) getgid(), (long) getegid());
RETURN(EX_TEMPFAIL);
}
}
@@ -5411,8 +5466,8 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
{
if (initgroups(RealUserName, RealGid) == -1 && suidwarn)
{
- syserr("mailfile: initgroups(%s, %d) failed",
- RealUserName, RealGid);
+ syserr("mailfile: initgroups(%s, %ld) failed",
+ RealUserName, (long) RealGid);
RETURN(EX_TEMPFAIL);
}
}
@@ -5474,9 +5529,9 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
}
if (tTd(11, 2))
- sm_dprintf("mailfile: running as r/euid=%d/%d, r/egid=%d/%d\n",
- (int) getuid(), (int) geteuid(),
- (int) getgid(), (int) getegid());
+ sm_dprintf("mailfile: running as r/euid=%ld/%ld, r/egid=%ld/%ld\n",
+ (long) getuid(), (long) geteuid(),
+ (long) getgid(), (long) getegid());
/* move into some "safe" directory */
@@ -6163,11 +6218,18 @@ starttls(m, mci, e)
}
return EX_SOFTWARE;
}
+ /* SSL_clear(clt_ssl); ? */
+
+ if (get_tls_se_options(e, clt_ssl, false) != 0)
+ {
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=client, get_tls_se_options=fail");
+ return EX_SOFTWARE;
+ }
rfd = sm_io_getinfo(mci->mci_in, SM_IO_WHAT_FD, NULL);
wfd = sm_io_getinfo(mci->mci_out, SM_IO_WHAT_FD, NULL);
- /* SSL_clear(clt_ssl); ? */
if (rfd < 0 || wfd < 0 ||
(result = SSL_set_rfd(clt_ssl, rfd)) != 1 ||
(result = SSL_set_wfd(clt_ssl, wfd)) != 1)
@@ -6189,6 +6251,7 @@ ssl_retry:
if ((result = SSL_connect(clt_ssl)) <= 0)
{
int i, ssl_err;
+ int save_errno = errno;
ssl_err = SSL_get_error(clt_ssl, result);
i = tls_retry(clt_ssl, rfd, wfd, tlsstart,
@@ -6206,7 +6269,7 @@ ssl_retry:
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=client, error: connect failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d",
result, sr == NULL ? "unknown" : sr, ssl_err,
- errno, i);
+ save_errno, i);
if (LogLevel > 9)
tlslogerr(LOG_WARNING, "client");
}
diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c
index df6c5c7..bae6b00 100644
--- a/contrib/sendmail/src/envelope.c
+++ b/contrib/sendmail/src/envelope.c
@@ -42,11 +42,9 @@ clrsessenvelope(e)
macdefine(&e->e_macro, A_PERM, macid("{cipher}"), "");
macdefine(&e->e_macro, A_PERM, macid("{tls_version}"), "");
macdefine(&e->e_macro, A_PERM, macid("{verify}"), "");
-# if _FFR_TLS_1
macdefine(&e->e_macro, A_PERM, macid("{alg_bits}"), "");
macdefine(&e->e_macro, A_PERM, macid("{cn_issuer}"), "");
macdefine(&e->e_macro, A_PERM, macid("{cn_subject}"), "");
-# endif /* _FFR_TLS_1 */
#endif /* STARTTLS */
}
@@ -246,6 +244,16 @@ dropenvelope(e, fulldrop, split)
e->e_flags |= EF_FATALERRS|EF_CLRQUEUE;
}
+#if _FFR_PROXY
+ if (tTd(87, 2))
+ {
+ q = e->e_sendqueue;
+ sm_dprintf("dropenvelope: mode=%c, e=%p, sibling=%p, nrcpts=%d, sendqueue=%p, next=%p, state=%d\n",
+ e->e_sendmode, e, e->e_sibling, e->e_nrcpts, q,
+ (q == NULL) ? (void *)0 : q->q_next,
+ (q == NULL) ? -1 : q->q_state);
+ }
+#endif /* _FFR_PROXY */
e->e_flags &= ~EF_QUEUERUN;
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
@@ -253,6 +261,10 @@ dropenvelope(e, fulldrop, split)
if (QS_IS_UNDELIVERED(q->q_state))
queueit = true;
+#if _FFR_PROXY
+ if (queueit && e->e_sendmode == SM_PROXY)
+ queueit = false;
+#endif /* _FFR_PROXY */
/* see if a notification is needed */
if (bitset(QPINGONFAILURE, q->q_flags) &&
@@ -577,9 +589,9 @@ simpledrop:
if (!split_by_recipient(e) &&
bitset(EF_FATALERRS, e->e_flags))
{
- syserr("!dropenvelope(%s): cannot commit data file %s, uid=%d",
+ syserr("!dropenvelope(%s): cannot commit data file %s, uid=%ld",
e->e_id, queuename(e, DATAFL_LETTER),
- (int) geteuid());
+ (long) geteuid());
}
for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling)
queueup(ee, false, true);
diff --git a/contrib/sendmail/src/err.c b/contrib/sendmail/src/err.c
index 835fa4b..0594eb9 100644
--- a/contrib/sendmail/src/err.c
+++ b/contrib/sendmail/src/err.c
@@ -94,7 +94,7 @@ fatal_error(exc)
** reply code defaults to 451 or 554, depending on errno.
**
** Parameters:
-** fmt -- the format string. An optional '!' or '@',
+** fmt -- the format string. An optional '!', '@', or '+',
** followed by an optional three-digit SMTP
** reply code, followed by message text.
** (others) -- parameters
@@ -127,8 +127,7 @@ syserr(fmt, va_alist)
{
register char *p;
int save_errno = errno;
- bool panic;
- bool exiting;
+ bool panic, exiting, keep;
char *user;
char *enhsc;
char *errtxt;
@@ -136,21 +135,22 @@ syserr(fmt, va_alist)
char ubuf[80];
SM_VA_LOCAL_DECL
+ panic = exiting = keep = false;
switch (*fmt)
{
case '!':
++fmt;
- panic = true;
- exiting = true;
+ panic = exiting = true;
break;
case '@':
++fmt;
- panic = false;
exiting = true;
break;
+ case '+':
+ ++fmt;
+ keep = true;
+ break;
default:
- panic = false;
- exiting = false;
break;
}
@@ -182,7 +182,7 @@ syserr(fmt, va_alist)
puterrmsg(MsgBuf);
/* save this message for mailq printing */
- if (!panic && CurEnv != NULL)
+ if (!panic && CurEnv != NULL && (!keep || CurEnv->e_message == NULL))
{
char *nmsg = sm_rpool_strdup_x(CurEnv->e_rpool, errtxt);
@@ -479,6 +479,108 @@ message(msg, va_alist)
}
}
+#if _FFR_PROXY
+/*
+** EMESSAGE -- print message (not necessarily an error)
+** (same as message() but requires reply code and enhanced status code)
+**
+** Parameters:
+** replycode -- SMTP reply code.
+** enhsc -- enhanced status code.
+** msg -- the message (sm_io_printf fmt) -- it can begin with
+** an SMTP reply code. If not, 050 is assumed.
+** (others) -- sm_io_printf arguments
+**
+** Returns:
+** none
+**
+** Side Effects:
+** none.
+*/
+
+/*VARARGS3*/
+void
+# ifdef __STDC__
+emessage(const char *replycode, const char *enhsc, const char *msg, ...)
+# else /* __STDC__ */
+emessage(replycode, enhsc, msg, va_alist)
+ const char *replycode;
+ const char *enhsc;
+ const char *msg;
+ va_dcl
+# endif /* __STDC__ */
+{
+ char *errtxt;
+ SM_VA_LOCAL_DECL
+
+ errno = 0;
+ SM_VA_START(ap, msg);
+ errtxt = fmtmsg(MsgBuf, CurEnv->e_to, replycode, enhsc, 0, msg, ap);
+ SM_VA_END(ap);
+ putoutmsg(MsgBuf, false, false);
+
+ /* save this message for mailq printing */
+ switch (MsgBuf[0])
+ {
+ case '4':
+ case '8':
+ if (CurEnv->e_message != NULL)
+ break;
+ /* FALLTHROUGH */
+
+ case '5':
+ if (CurEnv->e_rpool == NULL && CurEnv->e_message != NULL)
+ sm_free(CurEnv->e_message);
+ CurEnv->e_message = sm_rpool_strdup_x(CurEnv->e_rpool, errtxt);
+ break;
+ }
+}
+
+/*
+** EXTSC -- check and extract a status codes
+**
+** Parameters:
+** msg -- string with possible enhanced status code.
+** delim -- delim for enhanced status code.
+** replycode -- pointer to storage for SMTP reply code;
+** must be != NULL and have space for at least
+** 4 characters.
+** enhsc -- pointer to storage for enhanced status code;
+** must be != NULL and have space for at least
+** 10 characters ([245].[0-9]{1,3}.[0-9]{1,3})
+**
+** Returns:
+** -1 -- no SMTP reply code.
+** >=3 -- offset of error text in msg.
+** (<=4 -- no enhanced status code)
+*/
+
+int
+extsc(msg, delim, replycode, enhsc)
+ const char *msg;
+ int delim;
+ char *replycode;
+ char *enhsc;
+{
+ int offset;
+
+ SM_REQUIRE(replycode != NULL);
+ SM_REQUIRE(enhsc != NULL);
+ replycode[0] = '\0';
+ enhsc[0] = '\0';
+ if (msg == NULL)
+ return -1;
+ if (!ISSMTPREPLY(msg))
+ return -1;
+ sm_strlcpy(replycode, msg, 4);
+ if (msg[3] == '\0')
+ return 3;
+ offset = 4;
+ if (isenhsc(msg + 4, delim))
+ offset = extenhsc(msg + 4, delim, enhsc) + 4;
+ return offset;
+}
+#endif /* _FFR_PROXY */
/*
** NMESSAGE -- print message (not necessarily an error)
@@ -1138,7 +1240,7 @@ sm_errstring(errnum)
}
#if LDAPMAP
- if (errnum >= E_LDAPBASE)
+ if (errnum >= E_LDAPBASE - E_LDAP_SHIM)
return ldap_err2string(errnum - E_LDAPBASE);
#endif /* LDAPMAP */
diff --git a/contrib/sendmail/src/headers.c b/contrib/sendmail/src/headers.c
index 3c59a40..0af7243 100644
--- a/contrib/sendmail/src/headers.c
+++ b/contrib/sendmail/src/headers.c
@@ -360,7 +360,7 @@ hse:
macdefine(&e->e_macro, A_PERM,
macid("{addr_type}"), "h");
(void) rscheck(rs, fvalue, NULL, e, rscheckflags, 3,
- NULL, e->e_id, NULL);
+ NULL, e->e_id, NULL, NULL);
}
}
@@ -415,7 +415,7 @@ hse:
** the RCPT mailer.
*/
- if (bitnset(M_NOMHHACK,
+ if (bitnset(M_NOMHHACK,
e->e_from.q_mailer->m_flags))
{
h->h_flags &= ~H_CHECK;
@@ -1194,6 +1194,22 @@ logsender(e, msgid)
", daemon=%.20s", p);
sbp += strlen(sbp);
}
+# if _FFR_LOG_MORE1
+# if STARTTLS
+ p = macvalue(macid("{verify}"), e);
+ if (p == NULL || *p == '\0')
+ p = "NONE";
+ (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), ", tls_verify=%.20s", p);
+ sbp += strlen(sbp);
+# endif /* STARTTLS */
+# if SASL
+ p = macvalue(macid("{auth_type}"), e);
+ if (p == NULL || *p == '\0')
+ p = "NONE";
+ (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), ", auth=%.20s", p);
+ sbp += strlen(sbp);
+# endif /* SASL */
+# endif /* _FFR_LOG_MORE1 */
sm_syslog(LOG_INFO, e->e_id, "%.850s, relay=%s", sbuf, name);
#else /* (SYSLOG_BUFSIZE) >= 256 */
@@ -1892,8 +1908,10 @@ putheader(mci, hdr, e, flags)
if (bitset(H_FROM, h->h_flags))
oldstyle = false;
- commaize(h, p, oldstyle, mci, e,
- PXLF_HEADER | PXLF_STRIPMQUOTE);
+ if (!commaize(h, p, oldstyle, mci, e,
+ PXLF_HEADER | PXLF_STRIPMQUOTE)
+ && bitnset(M_xSMTP, mci->mci_mailer->m_flags))
+ goto writeerr;
}
else
{
@@ -2169,6 +2187,12 @@ commaize(h, p, oldstyle, mci, e, putflags)
#endif /* USERDB */
status = EX_OK;
name = remotename(name, mci->mci_mailer, flags, &status, e);
+ if (status != EX_OK && bitnset(M_xSMTP, mci->mci_mailer->m_flags))
+ {
+ if (status == EX_TEMPFAIL)
+ mci->mci_flags |= MCIF_NOTSTICKY;
+ goto writeerr;
+ }
if (*name == '\0')
{
*p = savechar;
diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c
index 511eb02..38eebbf 100644
--- a/contrib/sendmail/src/main.c
+++ b/contrib/sendmail/src/main.c
@@ -406,9 +406,7 @@ 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;
@@ -645,6 +643,17 @@ main(argc, argv, envp)
sm_printoptions(FFRCompileOptions);
}
+#if STARTTLS
+ if (tTd(0, 14))
+ {
+ /* exit(EX_CONFIG) if different? */
+ sm_dprintf(" OpenSSL: compiled 0x%08x\n",
+ (uint) OPENSSL_VERSION_NUMBER);
+ sm_dprintf(" OpenSSL: linked 0x%08x\n",
+ (uint) SSLeay());
+ }
+#endif /* STARTTLS */
+
/* clear sendmail's environment */
ExternalEnviron = environ;
emptyenviron[0] = NULL;
@@ -2566,6 +2575,38 @@ main(argc, argv, envp)
** Set _ macro in BlankEnvelope before calling newenvelope().
*/
+#if _FFR_XCNCT
+ if (bitnset(D_XCNCT, *p_flags) || bitnset(D_XCNCT_M, *p_flags))
+ {
+ /* copied from getauthinfo() */
+ if (RealHostName == NULL)
+ {
+ RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr));
+ if (strlen(RealHostName) > MAXNAME)
+ RealHostName[MAXNAME] = '\0'; /* XXX - 1 ? */
+ }
+ snprintf(buf, sizeof(buf), "%s [%s]",
+ RealHostName, anynet_ntoa(&RealHostAddr));
+
+ forged = bitnset(D_XCNCT_M, *p_flags);
+ if (forged)
+ {
+ (void) sm_strlcat(buf, " (may be forged)",
+ sizeof(buf));
+ macdefine(&BlankEnvelope.e_macro, A_PERM,
+ macid("{client_resolve}"), "FORGED");
+ }
+
+ /* HACK! variable used only two times right below */
+ authinfo = buf;
+ if (tTd(75, 9))
+ sm_syslog(LOG_INFO, NOQID,
+ "main: where=not_calling_getauthinfo, RealHostAddr=%s",
+ anynet_ntoa(&RealHostAddr));
+ }
+ else
+ /* WARNING: "non-braced" else */
+#endif /* _FFR_XCNCT */
authinfo = getauthinfo(sm_io_getinfo(InChannel, SM_IO_WHAT_FD,
NULL), &forged);
macdefine(&BlankEnvelope.e_macro, A_TEMP, '_', authinfo);
@@ -2622,13 +2663,13 @@ main(argc, argv, envp)
#if NETINET
case AF_INET:
(void) sm_snprintf(pbuf, sizeof(pbuf), "%d",
- RealHostAddr.sin.sin_port);
+ ntohs(RealHostAddr.sin.sin_port));
break;
#endif /* NETINET */
#if NETINET6
case AF_INET6:
(void) sm_snprintf(pbuf, sizeof(pbuf), "%d",
- RealHostAddr.sin6.sin6_port);
+ ntohs(RealHostAddr.sin6.sin6_port));
break;
#endif /* NETINET6 */
default:
@@ -3696,12 +3737,12 @@ drop_privileges(to_real_uid)
GIDSET_T emptygidset[1];
if (tTd(47, 1))
- sm_dprintf("drop_privileges(%d): Real[UG]id=%d:%d, get[ug]id=%d:%d, gete[ug]id=%d:%d, RunAs[UG]id=%d:%d\n",
+ sm_dprintf("drop_privileges(%d): Real[UG]id=%ld:%ld, get[ug]id=%ld:%ld, gete[ug]id=%ld:%ld, RunAs[UG]id=%ld:%ld\n",
(int) to_real_uid,
- (int) RealUid, (int) RealGid,
- (int) getuid(), (int) getgid(),
- (int) geteuid(), (int) getegid(),
- (int) RunAsUid, (int) RunAsGid);
+ (long) RealUid, (long) RealGid,
+ (long) getuid(), (long) getgid(),
+ (long) geteuid(), (long) getegid(),
+ (long) RunAsUid, (long) RunAsGid);
if (to_real_uid)
{
@@ -3776,15 +3817,15 @@ drop_privileges(to_real_uid)
{
if (setgid(RunAsGid) < 0 && (!UseMSP || getegid() != RunAsGid))
{
- syserr("drop_privileges: setgid(%d) failed",
- (int) RunAsGid);
+ syserr("drop_privileges: setgid(%ld) failed",
+ (long) RunAsGid);
rval = EX_OSERR;
}
errno = 0;
if (rval == EX_OK && getegid() != RunAsGid)
{
- syserr("drop_privileges: Unable to set effective gid=%d to RunAsGid=%d",
- (int) getegid(), (int) RunAsGid);
+ syserr("drop_privileges: Unable to set effective gid=%ld to RunAsGid=%ld",
+ (long) getegid(), (long) RunAsGid);
rval = EX_OSERR;
}
}
diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c
index b79f591..2cc283e 100644
--- a/contrib/sendmail/src/map.c
+++ b/contrib/sendmail/src/map.c
@@ -204,6 +204,20 @@ map_parseargs(map, ap)
map->map_app = ++p;
break;
+ case 'd':
+ {
+ char *h;
+
+ ++p;
+ h = strchr(p, ' ');
+ if (h != NULL)
+ *h = '\0';
+ map->map_timeout = convtime(p, 's');
+ if (h != NULL)
+ *h = ' ';
+ }
+ break;
+
case 'T':
map->map_tapp = ++p;
break;
@@ -1826,7 +1840,7 @@ ndbm_map_store(map, lhs, rhs)
data.dptr = buf;
if (tTd(38, 9))
sm_dprintf("ndbm_map_store append=%s\n",
- data.dptr);
+ (char *)data.dptr);
}
}
status = dbm_store((DBM *) map->map_db1,
@@ -7366,7 +7380,6 @@ arith_map_lookup(map, name, av, statp)
return NULL;
}
-#if _FFR_ARPA_MAP
char *
arpa_map_lookup(map, name, av, statp)
MAP *map;
@@ -7419,7 +7432,7 @@ arpa_map_lookup(map, name, av, statp)
{
struct in_addr in_addr;
- r = anynet_pton(AF_INET, name, &in_addr);
+ r = inet_pton(AF_INET, name, &in_addr);
if (r == 1)
{
unsigned char *src;
@@ -7445,7 +7458,6 @@ arpa_map_lookup(map, name, av, statp)
}
return rval;
}
-#endif /* _FFR_ARPA_MAP */
#if SOCKETMAP
@@ -7466,6 +7478,7 @@ socket_map_open(map, mode)
{
STAB *s;
int sock = 0;
+ int tmo;
SOCKADDR_LEN_T addrlen = 0;
int addrno = 0;
int save_errno;
@@ -7865,6 +7878,13 @@ socket_map_open(map, mode)
return false;
}
+ tmo = map->map_timeout;
+ if (tmo == 0)
+ tmo = 30000; /* default: 30s */
+ else
+ tmo *= 1000; /* s -> ms */
+ sm_io_setinfo(map->map_db1, SM_IO_WHAT_TIMEOUT, &tmo);
+
/* Save connection for reuse */
s->s_socketmap = map;
return true;
@@ -7999,8 +8019,16 @@ socket_map_lookup(map, name, av, statp)
if (sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen) != 1)
{
- syserr("451 4.3.0 socket_map_lookup(%s): failed to read length parameter of reply",
- map->map_mname);
+ if (errno == EAGAIN)
+ {
+ syserr("451 4.3.0 socket_map_lookup(%s): read timeout",
+ map->map_mname);
+ }
+ else
+ {
+ syserr("451 4.3.0 socket_map_lookup(%s): failed to read length parameter of reply %d",
+ map->map_mname, errno);
+ }
*statp = EX_TEMPFAIL;
goto errcl;
}
diff --git a/contrib/sendmail/src/mci.c b/contrib/sendmail/src/mci.c
index 773eb16..c3f925f 100644
--- a/contrib/sendmail/src/mci.c
+++ b/contrib/sendmail/src/mci.c
@@ -352,6 +352,7 @@ mci_get(host, m)
#if PIPELINING
mci->mci_okrcpts = 0;
#endif /* PIPELINING */
+ mci->mci_flags &= ~MCIF_NOTSTICKY;
if (mci->mci_rpool == NULL)
mci->mci_rpool = sm_rpool_new_x(NULL);
diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c
index cbc4d35..9b3667d 100644
--- a/contrib/sendmail/src/milter.c
+++ b/contrib/sendmail/src/milter.c
@@ -204,7 +204,7 @@ static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE;
fd_set fds; \
struct timeval tv; \
\
- if (SM_FD_SETSIZE > 0 && m->mf_sock >= SM_FD_SETSIZE) \
+ if (!SM_FD_OK_SELECT(m->mf_sock)) \
{ \
if (tTd(64, 5)) \
sm_dprintf("milter_%s(%s): socket %d is larger than FD_SETSIZE %d\n", \
@@ -1642,8 +1642,8 @@ milter_set_option(name, val, sticky)
MilterMaxDataSize != MILTER_MDS_1M)
{
sm_syslog(LOG_WARNING, NOQID,
- "WARNING: Milter.%s=%d, allowed are only %d, %d, and %d",
- name, MilterMaxDataSize,
+ "WARNING: Milter.%s=%lu, allowed are only %d, %d, and %d",
+ name, (unsigned long) MilterMaxDataSize,
MILTER_MDS_64K, MILTER_MDS_256K,
MILTER_MDS_1M);
if (MilterMaxDataSize < MILTER_MDS_64K)
@@ -2317,6 +2317,8 @@ milter_getsymlist(m, buf, rlen, offset)
offset += MILTER_LEN_BYTES;
macros = NULL;
+#define SM_M_MACRO_NAME(i) (((i) < SM_ARRAY_SIZE(MilterOptTab) && (i) >= 0) \
+ ? MilterOptTab[i].mo_name : "?")
switch (i)
{
case SMFIM_CONNECT:
@@ -2330,23 +2332,23 @@ milter_getsymlist(m, buf, rlen, offset)
macros = MilterMacros[i][m->mf_idx];
m->mf_lflags |= MI_LFLAGS_SYM(i);
len = strlen(buf + offset);
- if (len > 0)
+ if (len >= 0)
{
r = milter_set_macros(m->mf_name, macros,
buf + offset, nummac);
if (r >= 0)
nummac = r;
if (tTd(64, 5))
- sm_dprintf("milter_getsymlist(%s, %s)=%d\n",
- m->mf_name, buf + offset, r);
+ sm_dprintf("milter_getsymlist(%s, %s, \"%s\")=%d\n",
+ m->mf_name,
+ SM_M_MACRO_NAME(i),
+ buf + offset, r);
}
break;
default:
return -1;
}
- if (len == 0)
- return -1;
offset += len + 1;
}
@@ -2421,7 +2423,9 @@ milter_negotiate(m, e, milters)
if (tTd(64, 5))
sm_dprintf("milter_negotiate(%s): send: version %lu, fflags 0x%lx, pflags 0x%lx\n",
- m->mf_name, ntohl(fvers), ntohl(fflags), ntohl(pflags));
+ m->mf_name, (unsigned long) ntohl(fvers),
+ (unsigned long) ntohl(fflags),
+ (unsigned long) ntohl(pflags));
response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e,
"negotiate");
@@ -2526,8 +2530,9 @@ milter_negotiate(m, e, milters)
{
/* this should not happen... */
sm_syslog(LOG_WARNING, NOQID,
- "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d",
- MilterMaxDataSize, MILTER_MDS_1M);
+ "WARNING: Milter.maxdatasize: configured=%lu, set by libmilter=%d",
+ (unsigned long) MilterMaxDataSize,
+ MILTER_MDS_1M);
MilterMaxDataSize = MILTER_MDS_1M;
}
}
@@ -2536,16 +2541,18 @@ milter_negotiate(m, e, milters)
if (MilterMaxDataSize != MILTER_MDS_256K)
{
sm_syslog(LOG_WARNING, NOQID,
- "WARNING: Milter.maxdatasize: configured=%d, set by libmilter=%d",
- MilterMaxDataSize, MILTER_MDS_256K);
+ "WARNING: Milter.maxdatasize: configured=%lu, set by libmilter=%d",
+ (unsigned long) 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);
+ "WARNING: Milter.maxdatasize: configured=%lu, set by libmilter=%d",
+ (unsigned long) MilterMaxDataSize,
+ MILTER_MDS_64K);
MilterMaxDataSize = MILTER_MDS_64K;
}
m->mf_pflags &= ~SMFI_INTERNAL;
@@ -3976,6 +3983,7 @@ milter_connect(hostname, addr, e, state)
else
milter_per_connection_check(e);
+#if !_FFR_MILTER_CONNECT_REPLYCODE
/*
** SMFIR_REPLYCODE can't work with connect due to
** the requirements of SMTP. Therefore, ignore the
@@ -4000,6 +4008,7 @@ milter_connect(hostname, addr, e, state)
response = NULL;
}
}
+#endif /* !_FFR_MILTER_CONNECT_REPLYCODE */
return response;
}
diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c
index 4c78720..2adb39c 100644
--- a/contrib/sendmail/src/parseaddr.c
+++ b/contrib/sendmail/src/parseaddr.c
@@ -2204,8 +2204,9 @@ badaddr:
** use entire pvp.
** buf -- buffer to build the string into.
** sz -- size of buf.
-** spacesub -- the space separator character; if '\0',
-** use SpaceSub.
+** spacesub -- the space separator character;
+** '\0': SpaceSub.
+** NOSPACESEP: no separator
** external -- convert to external form?
** (no metacharacters; METAQUOTEs removed, see below)
**
@@ -2268,7 +2269,7 @@ cataddr(pvp, evp, buf, sz, spacesub, external)
char *q;
natomtok = (IntTokenTab[**pvp & 0xff] == ATM);
- if (oatomtok && natomtok)
+ if (oatomtok && natomtok && spacesub != NOSPACESEP)
{
*p++ = spacesub;
if (--sz <= 0)
@@ -2362,6 +2363,10 @@ sameaddr(a, b)
if (strcmp(a->q_user, b->q_user) != 0)
return false;
+ /* do the required flags match? */
+ if (!ADDR_FLAGS_MATCH(a, b))
+ return false;
+
/* if we have good uids for both but they differ, these are different */
if (a->q_mailer == ProgMailer)
{
@@ -2409,6 +2414,7 @@ struct qflags
unsigned long qf_bit;
};
+/* :'a,.s;^#define \(Q[A-Z]*\) .*; { "\1", \1 },; */
static struct qflags AddressFlags[] =
{
{ "QGOODUID", QGOODUID },
@@ -2426,6 +2432,12 @@ static struct qflags AddressFlags[] =
{ "QDELIVERED", QDELIVERED },
{ "QDELAYED", QDELAYED },
{ "QTHISPASS", QTHISPASS },
+ { "QALIAS", QALIAS },
+ { "QBYTRACE", QBYTRACE },
+ { "QBYNDELAY", QBYNDELAY },
+ { "QBYNRELAY", QBYNRELAY },
+ { "QINTBCC", QINTBCC },
+ { "QDYNMAILER", QDYNMAILER },
{ "QRCPTOK", QRCPTOK },
{ NULL, 0 }
};
@@ -2789,7 +2801,7 @@ remotename(name, m, flags, pstat, e)
{
sm_dprintf("remotename => `");
xputs(sm_debug_file(), buf);
- sm_dprintf("'\n");
+ sm_dprintf("', stat=%d\n", *pstat);
}
return buf;
}
@@ -3060,6 +3072,8 @@ dequote_map(map, name, av, statp)
** logid -- id for sm_syslog.
** addr -- if not NULL and ruleset returns $#error:
** store mailer triple here.
+** addrstr -- if not NULL and ruleset does not return $#:
+** address string
**
** Returns:
** EX_OK -- if the rwset doesn't resolve to $#error
@@ -3067,7 +3081,7 @@ dequote_map(map, name, av, statp)
*/
int
-rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr)
+rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr, addrstr)
char *rwset;
char *p1;
char *p2;
@@ -3077,6 +3091,7 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr)
char *host;
char *logid;
ADDRESS *addr;
+ char **addrstr;
{
char *volatile buf;
size_t bufsize;
@@ -3150,6 +3165,17 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr)
(void) REWRITE(pvp, rsno, e);
if (bitset(RSF_UNSTRUCTURED, flags))
SuprErrs = saveSuprErrs;
+
+ if (pvp[0] != NULL && (pvp[0][0] & 0377) != CANONNET &&
+ bitset(RSF_ADDR, flags) && addrstr != NULL)
+ {
+ cataddr(&(pvp[0]), NULL, ubuf, sizeof(ubuf),
+ bitset(RSF_STRING, flags) ? NOSPACESEP : ' ',
+ true);
+ *addrstr = sm_rpool_strdup_x(e->e_rpool, ubuf);
+ goto finis;
+ }
+
if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET ||
pvp[1] == NULL || (strcmp(pvp[1], "error") != 0 &&
strcmp(pvp[1], "discard") != 0))
diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c
index db339f2..a323301 100644
--- a/contrib/sendmail/src/queue.c
+++ b/contrib/sendmail/src/queue.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2009, 2011, 2012 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 1998-2009, 2011, 2012, 2014 Proofpoint, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -125,13 +125,6 @@ static SM_DEBUG_T DebugLeakQ = SM_DEBUG_INITIALIZER("leak_q",
"@(#)$Debug: leak_q - trace memory leaks during queue processing $");
#endif /* SM_HEAP_CHECK */
-/*
-** We use EmptyString instead of "" to avoid
-** 'zero-length format string' warnings from gcc
-*/
-
-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 *, int *));
@@ -304,7 +297,7 @@ hash_q(p, h)
** d data file directory name (added in 8.12)
** E error recipient
** F flag bits
-** G free (was: queue delay algorithm if _FFR_QUEUEDELAY)
+** G free
** H header
** I data file's inode number
** K time of last delivery attempt
@@ -320,7 +313,7 @@ hash_q(p, h)
** T init time
** V queue file version
** X free (was: character set if _FFR_SAVE_CHARSET)
-** Y free (was: current delay if _FFR_QUEUEDELAY)
+** Y free
** Z original envelope id from ESMTP
** ! deliver by (added in 8.12)
** $ define macro
@@ -404,8 +397,8 @@ queueup(e, announce, msync)
printopenfds(true);
errno = save_errno;
- syserr("!queueup: cannot create queue file %s, euid=%d, fd=%d, fp=%p",
- tf, (int) geteuid(), tfd, tfp);
+ syserr("!queueup: cannot create queue file %s, euid=%ld, fd=%d, fp=%p",
+ tf, (long) geteuid(), tfd, tfp);
/* NOTREACHED */
}
e->e_lockfp = tfp;
@@ -427,8 +420,8 @@ queueup(e, announce, msync)
break;
if (LogLevel > 0 && (i % 32) == 0)
sm_syslog(LOG_ALERT, e->e_id,
- "queueup: cannot create %s, euid=%d: %s",
- tf, (int) geteuid(),
+ "queueup: cannot create %s, euid=%ld: %s",
+ tf, (long) geteuid(),
sm_errstring(errno));
}
#if SM_OPEN_EXLOCK
@@ -473,8 +466,8 @@ queueup(e, announce, msync)
printopenfds(true);
errno = save_errno;
- syserr("!queueup: cannot create queue temp file %s, uid=%d",
- tf, (int) geteuid());
+ syserr("!queueup: cannot create queue temp file %s, uid=%ld",
+ tf, (long) geteuid());
}
}
@@ -518,8 +511,8 @@ queueup(e, announce, msync)
sm_io_setinfo(e->e_dfp, SM_BF_COMMIT, NULL) < 0 &&
errno != EINVAL)
{
- syserr("!queueup: cannot commit data file %s, uid=%d",
- queuename(e, DATAFL_LETTER), (int) geteuid());
+ syserr("!queueup: cannot commit data file %s, uid=%ld",
+ queuename(e, DATAFL_LETTER), (long) geteuid());
}
if (e->e_dfp != NULL &&
SuperSafe == SAFE_INTERACTIVE && msync)
@@ -560,8 +553,8 @@ queueup(e, announce, msync)
if (dfd < 0 || (dfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
(void *) &dfd, SM_IO_WRONLY_B,
NULL)) == NULL)
- syserr("!queueup: cannot create data temp file %s, uid=%d",
- df, (int) geteuid());
+ syserr("!queueup: cannot create data temp file %s, uid=%ld",
+ df, (long) geteuid());
if (fstat(dfd, &stbuf) < 0)
e->e_dfino = -1;
else
@@ -595,8 +588,8 @@ queueup(e, announce, msync)
}
if (sm_io_close(dfp, SM_TIME_DEFAULT) < 0)
- syserr("!queueup: cannot save data temp file %s, uid=%d",
- df, (int) geteuid());
+ syserr("!queueup: cannot save data temp file %s, uid=%ld",
+ df, (long) geteuid());
e->e_putbody = putbody;
}
@@ -733,9 +726,15 @@ queueup(e, announce, msync)
(void) sm_io_putc(tfp, SM_TIME_DEFAULT, 'F');
if (bitset(QPINGONDELAY, q->q_flags))
(void) sm_io_putc(tfp, SM_TIME_DEFAULT, 'D');
+ if (bitset(QINTBCC, q->q_flags))
+ (void) sm_io_putc(tfp, SM_TIME_DEFAULT, 'B');
if (q->q_alias != NULL &&
bitset(QALIAS, q->q_alias->q_flags))
(void) sm_io_putc(tfp, SM_TIME_DEFAULT, 'A');
+
+ /* _FFR_RCPTFLAGS */
+ if (bitset(QDYNMAILER, q->q_flags))
+ (void) sm_io_putc(tfp, SM_TIME_DEFAULT, QDYNMAILFLG);
(void) sm_io_putc(tfp, SM_TIME_DEFAULT, ':');
(void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "%s\n",
denlstring(q->q_paddr, true, false));
@@ -747,10 +746,10 @@ queueup(e, announce, msync)
tag = "quarantined";
e->e_to = q->q_paddr;
- message(tag);
+ message("%s", tag);
if (LogLevel > 8)
logdelivery(q->q_mailer, NULL, q->q_status,
- tag, NULL, (time_t) 0, e);
+ tag, NULL, (time_t) 0, e, q, EX_OK);
e->e_to = NULL;
}
if (tTd(40, 1))
@@ -888,8 +887,8 @@ queueup(e, announce, msync)
(void) sm_strlcpy(qf, queuename(e, ANYQFL_LETTER),
sizeof(qf));
if (rename(tf, qf) < 0)
- syserr("cannot rename(%s, %s), uid=%d",
- tf, qf, (int) geteuid());
+ syserr("cannot rename(%s, %s), uid=%ld",
+ tf, qf, (long) geteuid());
else
{
/*
@@ -1785,7 +1784,7 @@ runner_work(e, sequenceno, didfork, skip, njobs)
if (shouldqueue(w->w_pri, w->w_ctime))
{
if (Verbose)
- message(EmptyString);
+ message("%s", "");
if (QueueSortOrder == QSO_BYPRIORITY)
{
if (Verbose)
@@ -1813,7 +1812,7 @@ runner_work(e, sequenceno, didfork, skip, njobs)
{
if (Verbose)
{
- message(EmptyString);
+ message("%s", "");
message("Running %s/%s (sequence %d of %d)",
qid_printqueue(w->w_qgrp, w->w_qdir),
w->w_name + 2, sequenceno, njobs);
@@ -2042,9 +2041,7 @@ run_work_group(wgrp, flags)
{
IgnoreHostStatus = true;
MinQueueAge = 0;
-#if _FFR_EXPDELAY
MaxQueueAge = 0;
-#endif /* _FFR_EXPDELAY */
}
/*
@@ -2871,7 +2868,6 @@ gatherq(qgrp, qdir, doall, full, more, pnentries)
break;
case 'K':
-#if _FFR_EXPDELAY
if (MaxQueueAge > 0)
{
time_t lasttry, delay;
@@ -2884,7 +2880,6 @@ gatherq(qgrp, qdir, doall, full, more, pnentries)
w->w_tooyoung = true;
break;
}
-#endif /* _FFR_EXPDELAY */
age = curtime() - (time_t) atol(&lbuf[1]);
if (age >= 0 && MinQueueAge > 0 &&
@@ -4096,8 +4091,9 @@ readqf(e, openonly)
if (LogLevel > 0)
{
sm_syslog(LOG_ALERT, e->e_id,
- "bogus queue file, uid=%d, gid=%d, mode=%o",
- st.st_uid, st.st_gid, st.st_mode);
+ "bogus queue file, uid=%ld, gid=%ld, mode=%o",
+ (long) st.st_uid, (long) st.st_gid,
+ (unsigned int) st.st_mode);
}
if (tTd(40, 8))
sm_dprintf("readqf(%s): bogus file\n", qf);
@@ -4418,6 +4414,14 @@ readqf(e, openonly)
ctladdr->q_flags |= QALIAS;
break;
+ case 'B':
+ qflags |= QINTBCC;
+ break;
+
+ case QDYNMAILFLG:
+ qflags |= QDYNMAILER;
+ break;
+
default: /* ignore or complain? */
break;
}
@@ -4426,7 +4430,7 @@ readqf(e, openonly)
else
qflags |= QPRIMARY;
macdefine(&e->e_macro, A_PERM, macid("{addr_type}"),
- "e r");
+ ((qflags & QINTBCC) != 0) ? "e b" : "e r");
if (*p != '\0')
q = parseaddr(++p, NULLADDR, RF_COPYALL, '\0',
NULL, e, true);
@@ -4443,6 +4447,10 @@ readqf(e, openonly)
q->q_flags |= qflags;
q->q_finalrcpt = frcpt;
q->q_orcpt = orcpt;
+#if _FFR_RCPTFLAGS
+ if (bitset(QDYNMAILER, qflags))
+ newmodmailer(q, QDYNMAILFLG);
+#endif
(void) recipient(q, &e->e_sendqueue, 0, e);
}
frcpt = NULL;
@@ -4500,24 +4508,6 @@ readqf(e, openonly)
nomore = true;
break;
-#if _FFR_QUEUEDELAY
- case 'G':
- case 'Y':
-
- /*
- ** Maintain backward compatibility for
- ** users who defined _FFR_QUEUEDELAY in
- ** previous releases. Remove this
- ** code in 8.14 or 8.15.
- */
-
- if (qfver == 5 || qfver == 7)
- break;
-
- /* If not qfver 5 or 7, then 'G' or 'Y' is invalid */
- /* FALLTHROUGH */
-#endif /* _FFR_QUEUEDELAY */
-
default:
syserr("readqf: %s: line %d: bad line \"%s\"",
qf, LineNumber, shortenstring(bp, MAXSHORTSTR));
@@ -4635,6 +4625,14 @@ readqf(e, openonly)
static void prtstr __P((char *, int));
+#if _FFR_BOUNCE_QUEUE
+# define SKIP_BOUNCE_QUEUE \
+ if (i == BounceQueue) \
+ continue;
+#else
+# define SKIP_BOUNCE_QUEUE
+#endif
+
static void
prtstr(s, ml)
char *s;
@@ -4698,6 +4696,7 @@ printnqe(out, prefix)
{
int j;
+ SKIP_BOUNCE_QUEUE
k++;
for (j = 0; j < Queue[i]->qg_numqueues; j++)
{
@@ -5643,8 +5642,8 @@ loseqfile(e, why)
{
p = queuename(e, LOSEQF_LETTER);
if (rename(buf, p) < 0)
- syserr("cannot rename(%s, %s), uid=%d",
- buf, p, (int) geteuid());
+ syserr("cannot rename(%s, %s), uid=%ld",
+ buf, p, (long) geteuid());
else if (LogLevel > 0)
sm_syslog(LOG_ALERT, e->e_id,
"Losing %s: %s", buf, why);
@@ -6656,8 +6655,8 @@ init_sem(owner)
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);
+ "key=%ld, sm_semsetowner=%d, RunAsUid=%ld, RunAsGid=%ld",
+ (long) SemKey, r, (long) RunAsUid, (long) RunAsGid);
}
#endif /* SM_CONF_SEM */
#endif /* _FFR_USE_SEM_LOCKING */
@@ -6734,11 +6733,12 @@ upd_qs(e, count, space, where)
if (QSHM_ENTRIES(idx) >= 0 && count != 0)
{
# if _FFR_USE_SEM_LOCKING
- r = sm_sem_acq(SemId, 0, 1);
+ if (SemId >= 0)
+ r = sm_sem_acq(SemId, 0, 1);
# endif /* _FFR_USE_SEM_LOCKING */
QSHM_ENTRIES(idx) += count;
# if _FFR_USE_SEM_LOCKING
- if (r >= 0)
+ if (SemId >= 0 && r >= 0)
r = sm_sem_rel(SemId, 0, 1);
# endif /* _FFR_USE_SEM_LOCKING */
}
@@ -6815,8 +6815,8 @@ write_key_file(keypath, key)
int err = errno;
sm_syslog(LOG_ALERT, NOQID,
- "ownership change on %s to %d failed: %s",
- keypath, RunAsUid, sm_errstring(err));
+ "ownership change on %s to %ld failed: %s",
+ keypath, (long) RunAsUid, sm_errstring(err));
}
# endif /* HASFCHOWN */
}
@@ -6966,8 +6966,8 @@ init_shm(qn, owner, hash)
i = sm_shmsetowner(ShmId, RunAsUid, RunAsGid, 0660);
if (i != 0)
sm_syslog(LOG_ERR, NOQID,
- "key=%ld, sm_shmsetowner=%d, RunAsUid=%d, RunAsGid=%d",
- (long) ShmKey, i, RunAsUid, RunAsGid);
+ "key=%ld, sm_shmsetowner=%d, RunAsUid=%ld, RunAsGid=%ld",
+ (long) ShmKey, i, (long) RunAsUid, (long) RunAsGid);
}
p = (int *) Pshm;
if (owner)
@@ -7155,19 +7155,19 @@ setup_queues(owner)
safefile(" ", RunAsUid, RunAsGid, RunAsUserName, sff,
QueueFileMode, NULL) != 0)
{
- syserr("can not write to queue directory %s (RunAsGid=%d, required=%d)",
- basedir, (int) RunAsGid, (int) st.st_gid);
+ syserr("can not write to queue directory %s (RunAsGid=%ld, required=%ld)",
+ basedir, (long) RunAsGid, (long) st.st_gid);
}
if (bitset(S_IWOTH|S_IXOTH, st.st_mode))
{
#if _FFR_MSP_PARANOIA
syserr("dangerous permissions=%o on queue directory %s",
- (int) st.st_mode, basedir);
+ (unsigned int) st.st_mode, basedir);
#else /* _FFR_MSP_PARANOIA */
if (LogLevel > 0)
sm_syslog(LOG_ERR, NOQID,
"dangerous permissions=%o on queue directory %s",
- (int) st.st_mode, basedir);
+ (unsigned int) st.st_mode, basedir);
#endif /* _FFR_MSP_PARANOIA */
}
#if _FFR_MSP_PARANOIA
@@ -7619,7 +7619,7 @@ cmpidx(a, b)
}
/*
-** MAKEWORKGROUP -- balance queue groups into work groups per MaxQueueChildren
+** MAKEWORKGROUPS -- balance queue groups into work groups per MaxQueueChildren
**
** Take the now defined queue groups and assign them to work groups.
** This is done to balance out the number of concurrently active
@@ -7691,6 +7691,7 @@ makeworkgroups()
NumWorkGroups = 0;
for (i = 0; i < NumQueue; i++)
{
+ SKIP_BOUNCE_QUEUE
total_runners += si[i].sg_maxqrun;
if (MaxQueueChildren <= 0 || total_runners <= MaxQueueChildren)
NumWorkGroups++;
@@ -7716,6 +7717,8 @@ makeworkgroups()
dir = 1;
for (i = 0; i < NumQueue; i++)
{
+ SKIP_BOUNCE_QUEUE
+
/* a to-and-fro packing scheme, continue from last position */
if (j >= NumWorkGroups)
{
diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c
index fc3bb90..2b0fbf7 100644
--- a/contrib/sendmail/src/readcf.c
+++ b/contrib/sendmail/src/readcf.c
@@ -33,6 +33,51 @@ static void toomany __P((int, int));
static char *extrquotstr __P((char *, char **, char *, bool *));
static void parse_class_words __P((int, char *));
+
+#if _FFR_BOUNCE_QUEUE
+static char *bouncequeue = NULL;
+static void initbouncequeue __P((void));
+
+/*
+** INITBOUNCEQUEUE -- determine BounceQueue if option is set.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** sets BounceQueue
+*/
+
+static void
+initbouncequeue()
+{
+ STAB *s;
+
+ BounceQueue = NOQGRP;
+ if (bouncequeue == NULL || bouncequeue[0] == '\0')
+ return;
+
+ s = stab(bouncequeue, ST_QUEUE, ST_FIND);
+ if (s == NULL)
+ {
+ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
+ "Warning: option BounceQueue: unknown queue group %s\n",
+ bouncequeue);
+ }
+ else
+ BounceQueue = s->s_quegrp->qg_index;
+}
+#endif /* _FFR_BOUNCE_QUEUE */
+
+#if _FFR_RCPTFLAGS
+void setupdynmailers __P((void));
+#else
+#define setupdynmailers()
+#endif
+
/*
** READCF -- read configuration file.
**
@@ -117,12 +162,12 @@ readcf(cfname, safe, e)
#if STARTTLS
Srv_SSL_Options = SSL_OP_ALL;
Clt_SSL_Options = SSL_OP_ALL
-#ifdef SSL_OP_NO_SSLv2
+# ifdef SSL_OP_NO_SSLv2
| SSL_OP_NO_SSLv2
-#endif
-#ifdef SSL_OP_NO_TICKET
+# endif
+# ifdef SSL_OP_NO_TICKET
| SSL_OP_NO_TICKET
-#endif
+# endif
;
# ifdef SSL_OP_TLSEXT_PADDING
/* SSL_OP_TLSEXT_PADDING breaks compatibility with some sites */
@@ -730,6 +775,10 @@ readcf(cfname, safe, e)
(void) sm_io_close(cf, SM_TIME_DEFAULT);
FileName = NULL;
+#if _FFR_BOUNCE_QUEUE
+ initbouncequeue();
+#endif
+
/* initialize host maps from local service tables */
inithostmaps();
@@ -756,6 +805,7 @@ readcf(cfname, safe, e)
}
}
}
+ setupdynmailers();
}
/*
@@ -1175,6 +1225,125 @@ fileclass(class, filename, fmt, ismap, safe, optional)
if (pid > 0)
(void) waitfor(pid);
}
+
+#if _FFR_RCPTFLAGS
+/* first character for dynamically created mailers */
+static char dynmailerp = ' ';
+
+/* list of first characters for cf defined mailers */
+static char frst[MAXMAILERS + 1];
+
+/*
+** SETUPDYNMAILERS -- find a char that isn't used as first element of any
+** mailer name.
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+**
+** Note: space is not valid in cf defined mailers hence the function
+** will always find a char. It's not nice, but this is for
+** internal names only.
+*/
+
+void
+setupdynmailers()
+{
+ int i;
+ char pp[] = "YXZ0123456789ABCDEFGHIJKLMNOPQRSTUVWyxzabcfghijkmnoqtuvw ";
+
+ frst[MAXMAILERS] = '\0';
+ for (i = 0; i < strlen(pp); i++)
+ {
+ if (strchr(frst, pp[i]) == NULL)
+ {
+ dynmailerp = pp[i];
+ if (tTd(25, 8))
+ sm_dprintf("dynmailerp=%c\n", dynmailerp);
+ return;
+ }
+ }
+
+ /* NOTREACHED */
+ SM_ASSERT(0);
+}
+
+/*
+** NEWMODMAILER -- Create a new mailer with modifications
+**
+** Parameters:
+** rcpt -- current RCPT
+** fl -- flag to set
+**
+** Returns:
+** true iff successful.
+**
+** Note: this creates a copy of the mailer for the rcpt and
+** modifies exactly one flag. It does not work
+** for multiple flags!
+*/
+
+bool
+newmodmailer(rcpt, fl)
+ ADDRESS *rcpt;
+ int fl;
+{
+ int idx;
+ struct mailer *m;
+ STAB *s;
+ char mname[256];
+
+ SM_REQUIRE(rcpt != NULL);
+ if (rcpt->q_mailer == NULL)
+ return false;
+ if (tTd(25, 8))
+ sm_dprintf("newmodmailer: rcpt=%s\n", rcpt->q_paddr);
+ SM_REQUIRE(rcpt->q_mailer->m_name != NULL);
+ SM_REQUIRE(rcpt->q_mailer->m_name[0] != '\0');
+ sm_strlcpy(mname, rcpt->q_mailer->m_name, sizeof(mname));
+ mname[0] = dynmailerp;
+ if (tTd(25, 8))
+ sm_dprintf("newmodmailer: name=%s\n", mname);
+ s = stab(mname, ST_MAILER, ST_ENTER);
+ if (s->s_mailer != NULL)
+ {
+ idx = s->s_mailer->m_mno;
+ if (tTd(25, 6))
+ sm_dprintf("newmodmailer: found idx=%d\n", idx);
+ }
+ else
+ {
+ idx = rcpt->q_mailer->m_mno;
+ idx += MAXMAILERS;
+ if (tTd(25, 6))
+ sm_dprintf("newmodmailer: idx=%d\n", idx);
+ if (idx > SM_ARRAY_SIZE(Mailer))
+ return false;
+ }
+
+ m = Mailer[idx];
+ if (m == NULL)
+ m = (struct mailer *) xalloc(sizeof(*m));
+ memset((char *) m, '\0', sizeof(*m));
+ STRUCTCOPY(*rcpt->q_mailer, *m);
+ Mailer[idx] = m;
+
+ /* "modify" the mailer */
+ setbitn(bitidx(fl), m->m_flags);
+ rcpt->q_mailer = m;
+ m->m_mno = idx;
+ m->m_name = newstr(mname);
+ if (tTd(25, 1))
+ sm_dprintf("newmodmailer: mailer[%d]=%s %p\n",
+ idx, Mailer[idx]->m_name, Mailer[idx]);
+
+ return true;
+}
+
+#endif /* _FFR_RCPTFLAGS */
+
/*
** MAKEMAILER -- define a new mailer.
**
@@ -1208,6 +1377,7 @@ fileclass(class, filename, fmt, ismap, safe, optional)
** enters the mailer into the mailer table.
*/
+
void
makemailer(line)
char *line;
@@ -1238,6 +1408,9 @@ makemailer(line)
return;
}
m->m_name = newstr(line);
+#if _FFR_RCPTFLAGS
+ frst[nextmailer] = line[0];
+#endif
m->m_qgrp = NOQGRP;
m->m_uid = NO_UID;
m->m_gid = NO_GID;
@@ -1279,12 +1452,10 @@ makemailer(line)
{
if (!(isascii(*p) && isspace(*p)))
{
-#if _FFR_DEPRECATE_MAILER_FLAG_I
if (*p == M_INTERNAL)
sm_syslog(LOG_WARNING, NOQID,
"WARNING: mailer=%s, flag=%c deprecated",
m->m_name, *p);
-#endif /* _FFR_DEPRECATE_MAILER_FLAG_I */
setbitn(bitidx(*p), m->m_flags);
}
}
@@ -1416,7 +1587,11 @@ makemailer(line)
struct passwd *pw;
while (*p != '\0' && isascii(*p) &&
+# if _FFR_DOTTED_USERNAMES
+ (isalnum(*p) || strchr(SM_PWN_CHARS, *p) != NULL))
+# else /* _FFR_DOTTED_USERNAMES */
(isalnum(*p) || strchr("-_", *p) != NULL))
+# endif /* _FFR_DOTTED_USERNAMES */
p++;
while (isascii(*p) && isspace(*p))
*p++ = '\0';
@@ -1460,7 +1635,8 @@ makemailer(line)
char *q = p;
struct group *gr;
- while (isascii(*p) && isalnum(*p))
+ while (isascii(*p) &&
+ (isalnum(*p) || strchr(SM_PWN_CHARS, *p) != NULL))
p++;
*p++ = '\0';
if (*q == '\0')
@@ -1939,6 +2115,439 @@ printmailer(fp, m)
}
(void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\n");
}
+
+#if STARTTLS
+static struct ssl_options
+{
+ const char *sslopt_name; /* name of the flag */
+ long sslopt_bits; /* bits to set/clear */
+} SSL_Option[] =
+{
+/* Workaround for bugs are turned on by default (as well as some others) */
+#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
+ { "SSL_OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG },
+#endif
+#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
+ { "SSL_OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG },
+#endif
+#ifdef SSL_OP_LEGACY_SERVER_CONNECT
+ { "SSL_OP_LEGACY_SERVER_CONNECT", SSL_OP_LEGACY_SERVER_CONNECT },
+#endif
+#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+ { "SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG },
+#endif
+#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
+ { "SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG },
+#endif
+#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+ { "SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER },
+#endif
+#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
+ { "SSL_OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING },
+#endif
+#ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+ { "SSL_OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG },
+#endif
+#ifdef SSL_OP_TLS_D5_BUG
+ { "SSL_OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG },
+#endif
+#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
+ { "SSL_OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG },
+#endif
+#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+ { "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS },
+#endif
+#ifdef SSL_OP_ALL
+ { "SSL_OP_ALL", SSL_OP_ALL },
+#endif
+#ifdef SSL_OP_NO_QUERY_MTU
+ { "SSL_OP_NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU },
+#endif
+#ifdef SSL_OP_COOKIE_EXCHANGE
+ { "SSL_OP_COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE },
+#endif
+#ifdef SSL_OP_NO_TICKET
+ { "SSL_OP_NO_TICKET", SSL_OP_NO_TICKET },
+#endif
+#ifdef SSL_OP_CISCO_ANYCONNECT
+ { "SSL_OP_CISCO_ANYCONNECT", SSL_OP_CISCO_ANYCONNECT },
+#endif
+#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+ { "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION },
+#endif
+#ifdef SSL_OP_NO_COMPRESSION
+ { "SSL_OP_NO_COMPRESSION", SSL_OP_NO_COMPRESSION },
+#endif
+#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
+ { "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION },
+#endif
+#ifdef SSL_OP_SINGLE_ECDH_USE
+ { "SSL_OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE },
+#endif
+#ifdef SSL_OP_SINGLE_DH_USE
+ { "SSL_OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE },
+#endif
+#ifdef SSL_OP_EPHEMERAL_RSA
+ { "SSL_OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA },
+#endif
+#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
+ { "SSL_OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE },
+#endif
+#ifdef SSL_OP_TLS_ROLLBACK_BUG
+ { "SSL_OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG },
+#endif
+#ifdef SSL_OP_NO_SSLv2
+ { "SSL_OP_NO_SSLv2", SSL_OP_NO_SSLv2 },
+#endif
+#ifdef SSL_OP_NO_SSLv3
+ { "SSL_OP_NO_SSLv3", SSL_OP_NO_SSLv3 },
+#endif
+#ifdef SSL_OP_NO_TLSv1
+ { "SSL_OP_NO_TLSv1", SSL_OP_NO_TLSv1 },
+#endif
+#ifdef SSL_OP_NO_TLSv1_2
+ { "SSL_OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2 },
+#endif
+#ifdef SSL_OP_NO_TLSv1_1
+ { "SSL_OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1 },
+#endif
+#ifdef SSL_OP_PKCS1_CHECK_1
+ { "SSL_OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1 },
+#endif
+#ifdef SSL_OP_PKCS1_CHECK_2
+ { "SSL_OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2 },
+#endif
+#ifdef SSL_OP_NETSCAPE_CA_DN_BUG
+ { "SSL_OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG },
+#endif
+#ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
+ { "SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG },
+#endif
+#ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
+ { "SSL_OP_CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG },
+#endif
+#ifdef SSL_OP_TLSEXT_PADDING
+ { "SSL_OP_TLSEXT_PADDING", SSL_OP_TLSEXT_PADDING },
+#endif
+ { NULL, 0 }
+};
+
+/*
+** READSSLOPTIONS -- read SSL_OP_* values
+**
+** Parameters:
+** opt -- name of option (can be NULL)
+** val -- string with SSL_OP_* values or hex value
+** delim -- end of string (e.g., '\0' or ';')
+** pssloptions -- return value (output)
+**
+** Returns:
+** 0 on success.
+*/
+
+#define SSLOPERR_NAN 1
+#define SSLOPERR_NOTFOUND 2
+#define SM_ISSPACE(c) (isascii(c) && isspace(c))
+
+static int
+readssloptions(opt, val, pssloptions, delim)
+ char *opt;
+ char *val;
+ unsigned long *pssloptions;
+ int delim;
+{
+ char *p;
+ int ret;
+
+ ret = 0;
+ for (p = val; *p != '\0' && *p != delim; )
+ {
+ bool clearmode;
+ char *q;
+ unsigned long sslopt_val;
+ struct ssl_options *sslopts;
+
+ while (*p == ' ')
+ p++;
+ if (*p == '\0')
+ break;
+ clearmode = false;
+ if (*p == '-' || *p == '+')
+ clearmode = *p++ == '-';
+ q = p;
+ while (*p != '\0' && !(SM_ISSPACE(*p)) && *p != ',')
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+ sslopt_val = 0;
+ if (isdigit(*q))
+ {
+ char *end;
+
+ sslopt_val = strtoul(q, &end, 0);
+
+ /* not a complete "syntax" check but good enough */
+ if (end == q)
+ {
+ errno = 0;
+ ret = SSLOPERR_NAN;
+ if (opt != NULL)
+ syserr("readcf: %s option value %s not a number",
+ opt, q);
+ sslopt_val = 0;
+ }
+ }
+ else
+ {
+ for (sslopts = SSL_Option;
+ sslopts->sslopt_name != NULL; sslopts++)
+ {
+ if (sm_strcasecmp(q, sslopts->sslopt_name) == 0)
+ {
+ sslopt_val = sslopts->sslopt_bits;
+ break;
+ }
+ }
+ if (sslopts->sslopt_name == NULL)
+ {
+ errno = 0;
+ ret = SSLOPERR_NOTFOUND;
+ if (opt != NULL)
+ syserr("readcf: %s option value %s unrecognized",
+ opt, q);
+ }
+ }
+ if (sslopt_val != 0)
+ {
+ if (clearmode)
+ *pssloptions &= ~sslopt_val;
+ else
+ *pssloptions |= sslopt_val;
+ }
+ }
+ return ret;
+}
+
+# if _FFR_TLS_SE_OPTS
+/*
+** GET_TLS_SE_OPTIONS -- get TLS session options (from ruleset)
+**
+** Parameters:
+** e -- envelope
+** ssl -- TLS session context
+** srv -- server?
+**
+** Returns:
+** 0 on success.
+*/
+
+int
+get_tls_se_options(e, ssl, srv)
+ ENVELOPE *e;
+ SSL *ssl;
+ bool srv;
+{
+ bool saveQuickAbort, saveSuprErrs, ok;
+ char *optionlist, *opt, *val;
+ char *keyfile, *certfile;
+ size_t len, i;
+ int ret;
+
+# define who (srv ? "server" : "client")
+# define NAME_C_S macvalue(macid(srv ? "{client_name}" : "{server_name}"), e)
+# define ADDR_C_S macvalue(macid(srv ? "{client_addr}" : "{server_addr}"), e)
+# define WHICH srv ? "srv" : "clt"
+
+ ret = 0;
+ keyfile = certfile = opt = val = NULL;
+ saveQuickAbort = QuickAbort;
+ saveSuprErrs = SuprErrs;
+ SuprErrs = true;
+ QuickAbort = false;
+
+ optionlist = NULL;
+ ok = rscheck(srv ? "tls_srv_features" : "tls_clt_features",
+ NAME_C_S, ADDR_C_S, e,
+ RSF_RMCOMM|RSF_ADDR|RSF_STRING,
+ 5, NULL, NOQID, NULL, &optionlist) == EX_OK;
+ if (!ok && LogLevel > 8)
+ {
+ sm_syslog(LOG_NOTICE, NOQID,
+ "rscheck(tls_%s_features)=failed, relay=%s [%s], errors=%d",
+ WHICH, NAME_C_S, ADDR_C_S,
+ Errors);
+ }
+ QuickAbort = saveQuickAbort;
+ SuprErrs = saveSuprErrs;
+ if (ok && LogLevel > 9)
+ {
+ sm_syslog(LOG_INFO, NOQID,
+ "tls_%s_features=%s, relay=%s [%s]",
+ WHICH, optionlist, NAME_C_S, ADDR_C_S);
+ }
+ if (!ok || optionlist == NULL || (len = strlen(optionlist)) < 2)
+ {
+ if (LogLevel > 9)
+ sm_syslog(LOG_INFO, NOQID,
+ "tls_%s_features=empty, relay=%s [%s]",
+ WHICH, NAME_C_S, ADDR_C_S);
+
+ return ok ? 0 : 1;
+ }
+
+ i = 0;
+ if (optionlist[0] == '"' && optionlist[len - 1] == '"')
+ {
+ optionlist[0] = ' ';
+ optionlist[--len] = '\0';
+ if (len <= 2)
+ {
+ if (LogLevel > 9 && len > 1)
+ sm_syslog(LOG_INFO, NOQID,
+ "tls_%s_features=too_short, relay=%s [%s]",
+ WHICH, NAME_C_S, ADDR_C_S);
+
+ /* this is not treated as error! */
+ return 0;
+ }
+ i = 1;
+ }
+
+# define INVALIDSYNTAX \
+ do { \
+ if (LogLevel > 7) \
+ sm_syslog(LOG_INFO, NOQID, \
+ "tls_%s_features=invalid_syntax, opt=%s, relay=%s [%s]", \
+ WHICH, opt, NAME_C_S, ADDR_C_S); \
+ return -1; \
+ } while (0)
+
+# define CHECKLEN \
+ do { \
+ if (i >= len) \
+ INVALIDSYNTAX; \
+ } while (0)
+
+# define SKIPWS \
+ do { \
+ while (i < len && SM_ISSPACE(optionlist[i])) \
+ ++i; \
+ CHECKLEN; \
+ } while (0)
+
+ /* parse and handle opt=val; */
+ do {
+ char sep;
+
+ SKIPWS;
+ opt = optionlist + i;
+ sep = '=';
+ while (i < len && optionlist[i] != sep
+ && optionlist[i] != '\0' && !SM_ISSPACE(optionlist[i]))
+ ++i;
+ CHECKLEN;
+ while (i < len && SM_ISSPACE(optionlist[i]))
+ optionlist[i++] = '\0';
+ CHECKLEN;
+ if (optionlist[i] != sep)
+ INVALIDSYNTAX;
+ optionlist[i++] = '\0';
+
+ SKIPWS;
+ val = optionlist + i;
+ sep = ';';
+ while (i < len && optionlist[i] != sep && optionlist[i] != '\0')
+ ++i;
+ if (optionlist[i] != '\0')
+ {
+ CHECKLEN;
+ optionlist[i++] = '\0';
+ }
+
+ if (LogLevel > 13)
+ sm_syslog(LOG_DEBUG, NOQID,
+ "tls_%s_features=parsed, %s=%s, relay=%s [%s]",
+ WHICH, opt, val, NAME_C_S, ADDR_C_S);
+
+ if (sm_strcasecmp(opt, "options") == 0)
+ {
+ unsigned long ssloptions;
+
+ ssloptions = 0;
+ ret = readssloptions(NULL, val, &ssloptions, ';');
+ if (ret == 0)
+ (void) SSL_set_options(ssl, (long) ssloptions);
+ else if (LogLevel > 8)
+ {
+ sm_syslog(LOG_WARNING, NOQID,
+ "tls_%s_features=%s, error=%s, relay=%s [%s]",
+ WHICH, val,
+ (ret == SSLOPERR_NAN) ? "not a number" :
+ ((ret == SSLOPERR_NOTFOUND) ? "SSL_OP not found" :
+ "unknown"),
+ NAME_C_S, ADDR_C_S);
+ }
+ }
+ else if (sm_strcasecmp(opt, "cipherlist") == 0)
+ {
+ if (SSL_set_cipher_list(ssl, val) <= 0)
+ {
+ ret = 1;
+ if (LogLevel > 7)
+ {
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: SSL_set_cipher_list(%s) failed",
+ who, val);
+
+ if (LogLevel > 9)
+ tlslogerr(LOG_WARNING, who);
+ }
+ }
+ }
+ else if (sm_strcasecmp(opt, "keyfile") == 0)
+ keyfile = val;
+ else if (sm_strcasecmp(opt, "certfile") == 0)
+ certfile = val;
+ else
+ {
+ ret = 1;
+ if (LogLevel > 7)
+ {
+ sm_syslog(LOG_INFO, NOQID,
+ "tls_%s_features=unknown_option, opt=%s, relay=%s [%s]",
+ WHICH, opt, NAME_C_S, ADDR_C_S);
+ }
+ }
+
+ } while (optionlist[i] != '\0' && i < len);
+
+ /* need cert and key before we can use the options */
+ /* does not implement the "," hack for 2nd cert/key pair */
+ if (keyfile != NULL && certfile != NULL)
+ {
+ load_certkey(ssl, srv, certfile, keyfile);
+ keyfile = certfile = NULL;
+ }
+ else if (keyfile != NULL || certfile != NULL)
+ {
+ ret = 1;
+ if (LogLevel > 7)
+ {
+ sm_syslog(LOG_INFO, NOQID,
+ "tls_%s_features=only_one_of_CertFile/KeyFile_specified, relay=%s [%s]",
+ WHICH, NAME_C_S, ADDR_C_S);
+ }
+ }
+
+ return ret;
+# undef who
+# undef NAME_C_S
+# undef ADDR_C_S
+# undef WHICH
+}
+# endif /* _FFR_TLS_SE_OPTS */
+#endif /* STARTTLS */
+
/*
** SETOPTION -- set global processing option
**
@@ -2180,12 +2789,10 @@ static struct optioninfo
{ "AuthOptions", O_SASLOPTS, OI_NONE },
#define O_QUEUE_FILE_MODE 0xbe
{ "QueueFileMode", O_QUEUE_FILE_MODE, OI_NONE },
-#if _FFR_TLS_1
-# define O_DHPARAMS5 0xbf
- { "DHParameters512", O_DHPARAMS5, OI_NONE },
-# define O_CIPHERLIST 0xc0
+#define O_DIG_ALG 0xbf
+ { "CertFingerprintAlgorithm", O_DIG_ALG, OI_NONE },
+#define O_CIPHERLIST 0xc0
{ "CipherList", O_CIPHERLIST, OI_NONE },
-#endif /* _FFR_TLS_1 */
#define O_RANDFILE 0xc1
{ "RandFile", O_RANDFILE, OI_NONE },
#define O_TLS_SRV_OPTS 0xc2
@@ -2271,16 +2878,12 @@ 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
+#define O_SRV_SSL_OPTIONS 0xe3
{ "ServerSSLOptions", O_SRV_SSL_OPTIONS, OI_NONE },
-# define O_CLT_SSL_OPTIONS 0xe4
+#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
+#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 },
@@ -2297,128 +2900,20 @@ static struct optioninfo
# define O_REJECTNUL 0xe9
{ "RejectNUL", O_REJECTNUL, OI_SAFE },
#endif /* _FFR_REJECT_NUL_BYTE */
+#if _FFR_BOUNCE_QUEUE
+# define O_BOUNCEQUEUE 0xea
+ { "BounceQueue", O_BOUNCEQUEUE, OI_NONE },
+#endif /* _FFR_BOUNCE_QUEUE */
+#if _FFR_ADD_BCC
+# define O_ADDBCC 0xeb
+ { "AddBcc", O_ADDBCC, OI_NONE },
+#endif
+#define O_USECOMPRESSEDIPV6ADDRESSES 0xec
+ { "UseCompressedIPv6Addresses", O_USECOMPRESSEDIPV6ADDRESSES, OI_NONE },
{ 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[] =
-{
-/* Workaround for bugs are turned on by default (as well as some others) */
-#ifdef SSL_OP_MICROSOFT_SESS_ID_BUG
- { "SSL_OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG },
-#endif
-#ifdef SSL_OP_NETSCAPE_CHALLENGE_BUG
- { "SSL_OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG },
-#endif
-#ifdef SSL_OP_LEGACY_SERVER_CONNECT
- { "SSL_OP_LEGACY_SERVER_CONNECT", SSL_OP_LEGACY_SERVER_CONNECT },
-#endif
-#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
- { "SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG },
-#endif
-#ifdef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
- { "SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG },
-#endif
-#ifdef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
- { "SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER },
-#endif
-#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
- { "SSL_OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING },
-#endif
-#ifdef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
- { "SSL_OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG },
-#endif
-#ifdef SSL_OP_TLS_D5_BUG
- { "SSL_OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG },
-#endif
-#ifdef SSL_OP_TLS_BLOCK_PADDING_BUG
- { "SSL_OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG },
-#endif
-#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
- { "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS },
-#endif
-#ifdef SSL_OP_ALL
- { "SSL_OP_ALL", SSL_OP_ALL },
-#endif
-#ifdef SSL_OP_NO_QUERY_MTU
- { "SSL_OP_NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU },
-#endif
-#ifdef SSL_OP_COOKIE_EXCHANGE
- { "SSL_OP_COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE },
-#endif
-#ifdef SSL_OP_NO_TICKET
- { "SSL_OP_NO_TICKET", SSL_OP_NO_TICKET },
-#endif
-#ifdef SSL_OP_CISCO_ANYCONNECT
- { "SSL_OP_CISCO_ANYCONNECT", SSL_OP_CISCO_ANYCONNECT },
-#endif
-#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
- { "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION },
-#endif
-#ifdef SSL_OP_NO_COMPRESSION
- { "SSL_OP_NO_COMPRESSION", SSL_OP_NO_COMPRESSION },
-#endif
-#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
- { "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION },
-#endif
-#ifdef SSL_OP_SINGLE_ECDH_USE
- { "SSL_OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE },
-#endif
-#ifdef SSL_OP_SINGLE_DH_USE
- { "SSL_OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE },
-#endif
-#ifdef SSL_OP_EPHEMERAL_RSA
- { "SSL_OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA },
-#endif
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
- { "SSL_OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE },
-#endif
-#ifdef SSL_OP_TLS_ROLLBACK_BUG
- { "SSL_OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG },
-#endif
-#ifdef SSL_OP_NO_SSLv2
- { "SSL_OP_NO_SSLv2", SSL_OP_NO_SSLv2 },
-#endif
-#ifdef SSL_OP_NO_SSLv3
- { "SSL_OP_NO_SSLv3", SSL_OP_NO_SSLv3 },
-#endif
-#ifdef SSL_OP_NO_TLSv1
- { "SSL_OP_NO_TLSv1", SSL_OP_NO_TLSv1 },
-#endif
-#ifdef SSL_OP_NO_TLSv1_2
- { "SSL_OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2 },
-#endif
-#ifdef SSL_OP_NO_TLSv1_1
- { "SSL_OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1 },
-#endif
-#ifdef SSL_OP_PKCS1_CHECK_1
- { "SSL_OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1 },
-#endif
-#ifdef SSL_OP_PKCS1_CHECK_2
- { "SSL_OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2 },
-#endif
-#ifdef SSL_OP_NETSCAPE_CA_DN_BUG
- { "SSL_OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG },
-#endif
-#ifdef SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
- { "SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG },
-#endif
-#ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
- { "SSL_OP_CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG },
-#endif
-#ifdef SSL_OP_TLSEXT_PADDING
- { "SSL_OP_TLSEXT_PADDING", SSL_OP_TLSEXT_PADDING },
-#endif
- { NULL, 0 }
-};
-#endif /* STARTTLS && _FFR_TLS_1 */
-
-
# define CANONIFY(val)
# define SET_OPT_DEFAULT(opt, val) opt = val
@@ -2459,9 +2954,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 */
+#if STARTTLS
+ unsigned long *pssloptions = NULL;
+#endif
errno = 0;
if (opt == ' ')
@@ -2706,6 +3201,11 @@ setoption(opt, val, safe, sticky, e)
set_delivery_mode(*val, e);
break;
+#if _FFR_PROXY
+ case SM_PROXY_REQ:
+ set_delivery_mode(*val, e);
+ break;
+#endif /* _FFR_PROXY */
default:
syserr("Unknown delivery mode %c", *val);
@@ -3159,11 +3659,9 @@ 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));
@@ -3378,9 +3876,9 @@ setoption(opt, val, safe, sticky, e)
RunAsGid = pw->pw_gid;
else if (UseMSP && *p == '\0')
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
- "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n",
- (int) EffGid,
- (int) pw->pw_gid);
+ "WARNING: RunAsUser for MSP ignored, check group ids (egid=%ld, want=%ld)\n",
+ (long) EffGid,
+ (long) pw->pw_gid);
}
# ifdef UID_MAX
if (RunAsUid > UID_MAX)
@@ -3402,9 +3900,9 @@ setoption(opt, val, safe, sticky, e)
else if (UseMSP)
(void) sm_io_fprintf(smioout,
SM_TIME_DEFAULT,
- "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n",
- (int) EffGid,
- (int) runasgid);
+ "WARNING: RunAsUser for MSP ignored, check group ids (egid=%ld, want=%ld)\n",
+ (long) EffGid,
+ (long) runasgid);
}
else
{
@@ -3419,9 +3917,9 @@ setoption(opt, val, safe, sticky, e)
else if (UseMSP)
(void) sm_io_fprintf(smioout,
SM_TIME_DEFAULT,
- "WARNING: RunAsUser for MSP ignored, check group ids (egid=%d, want=%d)\n",
- (int) EffGid,
- (int) gr->gr_gid);
+ "WARNING: RunAsUser for MSP ignored, check group ids (egid=%ld, want=%ld)\n",
+ (long) EffGid,
+ (long) gr->gr_gid);
}
}
if (tTd(47, 5))
@@ -3749,56 +4247,22 @@ setoption(opt, val, safe, sticky, e)
SET_STRING_EXP(CACertPath);
case O_DHPARAMS:
SET_STRING_EXP(DHParams);
-# if _FFR_TLS_1
- case O_DHPARAMS5:
- SET_STRING_EXP(DHParams5);
case O_CIPHERLIST:
SET_STRING_EXP(CipherList);
+ case O_DIG_ALG:
+ SET_STRING_EXP(CertFingerprintAlgorithm);
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;
+ (void) readssloptions(o->o_name, val, pssloptions, '\0');
+ if (tTd(37, 8))
+ sm_dprintf("ssloptions=%#lx\n", *pssloptions);
- 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);
@@ -3839,7 +4303,6 @@ setoption(opt, val, safe, sticky, e)
case 'V':
TLS_Srv_Opts |= TLS_I_NO_VRFY;
break;
-# if _FFR_TLS_1
/*
** Server without a cert? That works only if
** AnonDH is enabled as cipher, which is not in the
@@ -3851,7 +4314,6 @@ setoption(opt, val, safe, sticky, e)
case 'C':
TLS_Srv_Opts &= ~TLS_I_SRV_CERT;
break;
-# endif /* _FFR_TLS_1 */
case ' ': /* ignore */
case '\t': /* ignore */
case ',': /* ignore */
@@ -3884,10 +4346,9 @@ setoption(opt, val, safe, sticky, e)
case O_CACERTFILE:
case O_CACERTPATH:
case O_DHPARAMS:
-# if _FFR_TLS_1
- case O_DHPARAMS5:
+ case O_SRV_SSL_OPTIONS:
+ case O_CLT_SSL_OPTIONS:
case O_CIPHERLIST:
-# endif /* _FFR_TLS_1 */
case O_CRLFILE:
# if _FFR_CRLPATH
case O_CRLPATH:
@@ -4064,6 +4525,21 @@ setoption(opt, val, safe, sticky, e)
break;
#endif /* _FFR_REJECT_NUL_BYTE */
+#if _FFR_BOUNCE_QUEUE
+ case O_BOUNCEQUEUE:
+ bouncequeue = newstr(val);
+ break;
+#endif /* _FFR_BOUNCE_QUEUE */
+
+#if _FFR_ADD_BCC
+ case O_ADDBCC:
+ AddBcc = atobool(val);
+ break;
+#endif
+ case O_USECOMPRESSEDIPV6ADDRESSES:
+ UseCompressedIPv6Addresses = atobool(val);
+ break;
+
default:
if (tTd(37, 1))
{
diff --git a/contrib/sendmail/src/recipient.c b/contrib/sendmail/src/recipient.c
index ff3a3b9..3fad957 100644
--- a/contrib/sendmail/src/recipient.c
+++ b/contrib/sendmail/src/recipient.c
@@ -667,8 +667,8 @@ recipient(new, sendq, aliaslevel, e)
new->q_status = "5.7.1";
if (new->q_alias->q_ruser == NULL)
usrerrenh(new->q_status,
- "550 UID %d is an unknown user: cannot mail to programs",
- new->q_alias->q_uid);
+ "550 UID %ld is an unknown user: cannot mail to programs",
+ (long) new->q_alias->q_uid);
else
usrerrenh(new->q_status,
"550 User %s@%s doesn't have a valid shell for mailing to programs",
@@ -890,8 +890,8 @@ recipient(new, sendq, aliaslevel, e)
new->q_status = "5.7.1";
if (new->q_alias->q_ruser == NULL)
usrerrenh(new->q_status,
- "550 UID %d is an unknown user: cannot mail to files",
- new->q_alias->q_uid);
+ "550 UID %ld is an unknown user: cannot mail to files",
+ (long) new->q_alias->q_uid);
else
usrerrenh(new->q_status,
"550 User %s@%s doesn't have a valid shell for mailing to files",
@@ -1174,7 +1174,7 @@ finduser(name, fuzzyp, user)
*fuzzyp = false;
-#if HESIOD
+#if HESIOD && !HESIOD_ALLOW_NUMERIC_LOGIN
/* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */
for (p = name; *p != '\0'; p++)
if (!isascii(*p) || !isdigit(*p))
@@ -1185,7 +1185,7 @@ finduser(name, fuzzyp, user)
sm_dprintf("failed (numeric input)\n");
return EX_NOUSER;
}
-#endif /* HESIOD */
+#endif /* HESIOD && !HESIOD_ALLOW_NUMERIC_LOGIN */
/* look up this login name using fast path */
status = sm_mbdb_lookup(name, user);
@@ -1446,8 +1446,8 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
if (tTd(27, 2))
sm_dprintf("include(%s)\n", fname);
if (tTd(27, 4))
- sm_dprintf(" ruid=%d euid=%d\n",
- (int) getuid(), (int) geteuid());
+ sm_dprintf(" ruid=%ld euid=%ld\n",
+ (long) getuid(), (long) geteuid());
if (tTd(27, 14))
{
sm_dprintf("ctladdr ");
@@ -1455,8 +1455,8 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
}
if (tTd(27, 9))
- sm_dprintf("include: old uid = %d/%d\n",
- (int) getuid(), (int) geteuid());
+ sm_dprintf("include: old uid = %ld/%ld\n",
+ (long) getuid(), (long) geteuid());
if (forwarding)
{
@@ -1483,8 +1483,8 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
!bitnset(DBS_NONROOTSAFEADDR, DontBlameSendmail))
{
if (tTd(27, 4))
- sm_dprintf("include: not safe (euid=%d, RunAsUid=%d)\n",
- (int) geteuid(), (int) RunAsUid);
+ sm_dprintf("include: not safe (euid=%ld, RunAsUid=%ld)\n",
+ (long) geteuid(), (long) RunAsUid);
ctladdr->q_flags |= QUNSAFEADDR;
}
@@ -1512,8 +1512,8 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
if (initgroups(user, gid) == -1)
{
rval = EAGAIN;
- syserr("include: initgroups(%s, %d) failed",
- user, gid);
+ syserr("include: initgroups(%s, %ld) failed",
+ user, (long) gid);
goto resetuid;
}
}
@@ -1533,7 +1533,7 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
if (gid != 0 && setgid(gid) < -1)
{
rval = EAGAIN;
- syserr("setgid(%d) failure", gid);
+ syserr("setgid(%ld) failure", (long) gid);
goto resetuid;
}
if (uid != 0)
@@ -1542,8 +1542,8 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
if (seteuid(uid) < 0)
{
rval = EAGAIN;
- syserr("seteuid(%d) failure (real=%d, eff=%d)",
- uid, (int) getuid(), (int) geteuid());
+ syserr("seteuid(%ld) failure (real=%ld, eff=%ld)",
+ (long) uid, (long) getuid(), (long) geteuid());
goto resetuid;
}
# endif /* MAILER_SETUID_METHOD == USE_SETEUID */
@@ -1551,8 +1551,8 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
if (setreuid(0, uid) < 0)
{
rval = EAGAIN;
- syserr("setreuid(0, %d) failure (real=%d, eff=%d)",
- uid, (int) getuid(), (int) geteuid());
+ syserr("setreuid(0, %ld) failure (real=%ld, eff=%ld)",
+ (long) uid, (long) getuid(), (long) geteuid());
goto resetuid;
}
# endif /* MAILER_SETUID_METHOD == USE_SETREUID */
@@ -1561,8 +1561,8 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
#endif /* MAILER_SETUID_METHOD != USE_SETUID */
if (tTd(27, 9))
- sm_dprintf("include: new uid = %d/%d\n",
- (int) getuid(), (int) geteuid());
+ sm_dprintf("include: new uid = %ld/%ld\n",
+ (long) getuid(), (long) geteuid());
/*
** If home directory is remote mounted but server is down,
@@ -1655,8 +1655,8 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
{
/* don't use this :include: file */
if (tTd(27, 4))
- sm_dprintf("include: not safe (uid=%d): %s\n",
- (int) uid, sm_errstring(rval));
+ sm_dprintf("include: not safe (uid=%ld): %s\n",
+ (long) uid, sm_errstring(rval));
}
else if ((fp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, fname,
SM_IO_RDONLY, NULL)) == NULL)
@@ -1683,28 +1683,28 @@ resetuid:
{
# if USESETEUID
if (seteuid(0) < 0)
- syserr("!seteuid(0) failure (real=%d, eff=%d)",
- (int) getuid(), (int) geteuid());
+ syserr("!seteuid(0) failure (real=%ld, eff=%ld)",
+ (long) getuid(), (long) geteuid());
# else /* USESETEUID */
if (setreuid(-1, 0) < 0)
- syserr("!setreuid(-1, 0) failure (real=%d, eff=%d)",
- (int) getuid(), (int) geteuid());
+ syserr("!setreuid(-1, 0) failure (real=%ld, eff=%ld)",
+ (long) getuid(), (long) geteuid());
if (setreuid(RealUid, 0) < 0)
- syserr("!setreuid(%d, 0) failure (real=%d, eff=%d)",
- (int) RealUid, (int) getuid(),
- (int) geteuid());
+ syserr("!setreuid(%ld, 0) failure (real=%ld, eff=%ld)",
+ (long) RealUid, (long) getuid(),
+ (long) geteuid());
# endif /* USESETEUID */
}
if (setgid(savedgid) < 0)
- syserr("!setgid(%d) failure (real=%d eff=%d)",
- (int) savedgid, (int) getgid(),
- (int) getegid());
+ syserr("!setgid(%ld) failure (real=%ld eff=%ld)",
+ (long) savedgid, (long) getgid(),
+ (long) getegid());
}
#endif /* HASSETREUID || USESETEUID */
if (tTd(27, 9))
- sm_dprintf("include: reset uid = %d/%d\n",
- (int) getuid(), (int) geteuid());
+ sm_dprintf("include: reset uid = %ld/%ld\n",
+ (long) getuid(), (long) geteuid());
if (rval == E_SM_OPENTIMEOUT)
usrerr("451 4.4.1 open timeout on %s", fname);
diff --git a/contrib/sendmail/src/savemail.c b/contrib/sendmail/src/savemail.c
index 07c3c90..6de8f2f 100644
--- a/contrib/sendmail/src/savemail.c
+++ b/contrib/sendmail/src/savemail.c
@@ -581,6 +581,10 @@ returntosender(msg, returnq, flags, e)
else
ee->e_flags |= EF_NO_BODY_RETN;
+#if _FFR_BOUNCE_QUEUE
+ if (BounceQueue != NOQGRP)
+ ee->e_qgrp = ee->e_dfqgrp = BounceQueue;
+#endif /* _FFR_BOUNCE_QUEUE */
if (!setnewqueue(ee))
{
syserr("554 5.3.0 returntosender: cannot select queue for %s",
@@ -702,8 +706,15 @@ returntosender(msg, returnq, flags, e)
/* mark statistics */
markstats(ee, NULLADDR, STATS_NORMAL);
- /* actually deliver the error message */
- sendall(ee, SM_DELIVER);
+#if _FFR_BOUNCE_QUEUE
+ if (BounceQueue == NOQGRP)
+ {
+#endif
+ /* actually deliver the error message */
+ sendall(ee, SM_DELIVER);
+#if _FFR_BOUNCE_QUEUE
+ }
+#endif
(void) dropenvelope(ee, true, false);
/* check for delivery errors */
diff --git a/contrib/sendmail/src/sendmail.8 b/contrib/sendmail/src/sendmail.8
index a6c47fe..f525c3e 100644
--- a/contrib/sendmail/src/sendmail.8
+++ b/contrib/sendmail/src/sendmail.8
@@ -92,6 +92,9 @@ Also,
the ``From:'' and ``Sender:''
fields are examined for the name of the sender.
.TP
+.B \-bC
+Check the configuration file.
+.TP
.B \-bd
Run as a daemon.
.B Sendmail
diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h
index 07a58e9..b2d0211 100644
--- a/contrib/sendmail/src/sendmail.h
+++ b/contrib/sendmail/src/sendmail.h
@@ -122,7 +122,7 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1104 2013-11-22 20:5
# endif /* HESIOD */
#if STARTTLS
-# include <openssl/ssl.h>
+# include <openssl/ssl.h>
# if !TLS_NO_RSA
# if _FFR_FIPSMODE
# define RSA_KEYLENGTH 1024
@@ -199,10 +199,19 @@ typedef int (*sasl_callback_ft)(void);
# define INADDR_NONE 0xffffffff
#endif /* ! INADDR_NONE */
+/* By default use uncompressed IPv6 address format (no "::") */
+#ifndef IPV6_FULL
+# define IPV6_FULL 1
+#endif
/* (f)open() modes for queue files */
-# define QF_O_EXTRA 0
+#define QF_O_EXTRA 0
+
+#if _FFR_PROXY || _FFR_LOGREPLY
+# define _FFR_ERRCODE 1
+#endif
+#define SM_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
/*
** An 'argument class' describes the storage allocation status
@@ -283,11 +292,23 @@ typedef struct address ADDRESS;
#define QBYTRACE 0x00008000 /* DeliverBy: trace */
#define QBYNDELAY 0x00010000 /* DeliverBy: notify, delay */
#define QBYNRELAY 0x00020000 /* DeliverBy: notify, relayed */
+#define QINTBCC 0x00040000 /* internal Bcc */
+#define QDYNMAILER 0x00080000 /* "dynamic mailer" */
#define QTHISPASS 0x40000000 /* temp: address set this pass */
#define QRCPTOK 0x80000000 /* recipient() processed address */
+#define QDYNMAILFLG 'Y'
+
#define Q_PINGFLAGS (QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY)
+#if _FFR_RCPTFLAGS
+# define QMATCHFLAGS (QINTBCC|QDYNMAILER)
+# define QMATCH_FLAG(a) ((a)->q_flags & QMATCHFLAGS)
+# define ADDR_FLAGS_MATCH(a, b) (QMATCH_FLAG(a) == QMATCH_FLAG(b))
+#else
+# define ADDR_FLAGS_MATCH(a, b) true
+#endif
+
/* values for q_state */
#define QS_OK 0 /* address ok (for now)/not yet tried */
#define QS_SENT 1 /* good address, delivery complete */
@@ -342,6 +363,9 @@ typedef struct address ADDRESS;
extern ADDRESS NullAddress; /* a null (template) address [main.c] */
+/* for cataddr() */
+#define NOSPACESEP 256
+
/* functions */
extern void cataddr __P((char **, char **, char *, int, int, bool));
extern char *crackaddr __P((char *, ENVELOPE *));
@@ -422,6 +446,7 @@ struct mailer
};
/* bits for m_flags */
+#define M_xSMTP 0x01 /* internal: {ES,S,L}MTP */
#define M_ESMTP 'a' /* run Extended SMTP */
#define M_ALIASABLE 'A' /* user can be LHS of an alias */
#define M_BLANKEND 'b' /* ensure blank line at end of message */
@@ -449,6 +474,7 @@ struct mailer
#define M_NHDR 'n' /* don't insert From line */
#define M_MANYSTATUS 'N' /* MAIL11V3: DATA returns multi-status */
#define M_RUNASRCPT 'o' /* always run mailer as recipient */
+ /* 'O' free? */
#define M_FROMPATH 'p' /* use reverse-path in MAIL FROM: */
/* 'P' CF: include Return-Path: */
#define M_VRFY250 'q' /* VRFY command returns 250 instead of 252 */
@@ -464,11 +490,14 @@ struct mailer
#define M_NOHOSTSTAT 'W' /* ignore long term host status information */
/* 'x' CF: include Full-Name: */
#define M_XDOT 'X' /* use hidden-dot algorithm */
+ /* 'y' free? */
+ /* 'Y' free? */
#define M_LMTP 'z' /* run Local Mail Transport Protocol */
#define M_DIALDELAY 'Z' /* apply dial delay sleeptime */
#define M_NOMX '0' /* turn off MX lookups */
#define M_NONULLS '1' /* don't send null bytes */
#define M_FSMTP '2' /* force SMTP (no ESMTP even if offered) */
+ /* '4' free? */
#define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */
#define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */
#define M_7BITHDRS '6' /* strip headers to 7 bits even in 8 bit path */
@@ -498,7 +527,11 @@ EXTERN MAILER *FileMailer; /* ptr to *file* mailer */
EXTERN MAILER *InclMailer; /* ptr to *include* mailer */
EXTERN MAILER *LocalMailer; /* ptr to local mailer */
EXTERN MAILER *ProgMailer; /* ptr to program mailer */
+#if _FFR_RCPTFLAGS
+EXTERN MAILER *Mailer[MAXMAILERS * 2 + 1];
+#else
EXTERN MAILER *Mailer[MAXMAILERS + 1];
+#endif
/*
** Queue group definition structure.
@@ -742,6 +775,12 @@ MCI
#define MCIF_INLONGLINE 0x01000000 /* in the middle of a long line */
#define MCIF_AUTH2 0x02000000 /* got 2 AUTH lines */
#define MCIF_ONLY_EHLO 0x10000000 /* use only EHLO in smtpinit */
+#if _FFR_HANDLE_HDR_RW_TEMPFAIL
+/* an error is not sticky (if put{header,body}() etc fail) */
+# define MCIF_NOTSTICKY 0x20000000
+#else
+# define MCIF_NOTSTICKY 0
+#endif
#define MCIF_EXTENS (MCIF_EXPN | MCIF_SIZE | MCIF_8BITMIME | MCIF_DSN | MCIF_8BITOK | MCIF_AUTH | MCIF_ENHSTAT | MCIF_TLS | MCIF_AUTH2)
@@ -945,10 +984,16 @@ 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
+#if _FFR_MILTER_ENHSC
char e_enhsc[ENHSC_LEN]; /* enhanced status code */
#endif /* _FFR_MILTER_ENHSC */
+#if _FFR_ERRCODE
+ /* smtp error codes during delivery */
+ int e_rcode; /* reply code */
+ char e_renhsc[ENHSC_LEN]; /* enhanced status code */
+ char *e_text; /* reply text */
+#endif /* _FFR_ERRCODE */
};
#define PRT_NONNEGL(v) ((v) < 0 ? LONG_MAX : (v))
@@ -1141,7 +1186,7 @@ extern int macid_parse __P((char *, char **));
#define macid(name) macid_parse(name, NULL)
extern char *macname __P((int));
extern char *macvalue __P((int, ENVELOPE *));
-extern int rscheck __P((char *, char *, char *, ENVELOPE *, int, int, char *, char *, ADDRESS *));
+extern int rscheck __P((char *, char *, char *, ENVELOPE *, int, int, char *, char *, ADDRESS *, char **));
extern int rscap __P((char *, char *, char *, ENVELOPE *, char ***, char *, int));
extern void setclass __P((int, char *));
extern int strtorwset __P((char *, char **, int));
@@ -1305,15 +1350,6 @@ MAP
#define MA_UNAVAIL 1 /* member map is not available */
#define MA_TRYAGAIN 2 /* member map returns temp failure */
-/* macros to handle MapTempFail */
-#define BIT_IS_MTP 0x01 /* temp.failure occurred */
-#define BIT_ASK_MTP 0x02 /* do we care about MapTempFail? */
-#define RESET_MAPTEMPFAIL MapTempFail = 0
-#define INIT_MAPTEMPFAIL MapTempFail = BIT_ASK_MTP
-#define SET_MAPTEMPFAIL MapTempFail |= BIT_IS_MTP
-#define IS_MAPTEMPFAIL bitset(BIT_IS_MTP, MapTempFail)
-#define ASK_MAPTEMPFAIL bitset(BIT_ASK_MTP, MapTempFail)
-
/*
** The class of a map -- essentially the functions to call
*/
@@ -1633,6 +1669,10 @@ EXTERN bool V6LoopbackAddrFound; /* found an IPv6 loopback address */
/* values for e_sendmode -- send modes */
#define SM_DELIVER 'i' /* interactive delivery */
+#if _FFR_PROXY
+#define SM_PROXY_REQ 's' /* synchronous mode requested */
+#define SM_PROXY 'S' /* synchronous mode activated */
+#endif /* _FFR_PROXY */
#define SM_FORK 'b' /* deliver in background */
#if _FFR_DM_ONE
#define SM_DM_ONE 'o' /* deliver first TA in background, then queue */
@@ -1641,7 +1681,11 @@ EXTERN bool V6LoopbackAddrFound; /* found an IPv6 loopback address */
#define SM_DEFER 'd' /* defer map lookups as well as queue */
#define SM_VERIFY 'v' /* verify only (used internally) */
#define DM_NOTSET (-1) /* DeliveryMode (per daemon) option not set */
+#if _FFR_PROXY
+# define SM_IS_INTERACTIVE(m) ((m) == SM_DELIVER || (m) == SM_PROXY_REQ || (m) == SM_PROXY)
+#else /* _FFR_PROXY */
# define SM_IS_INTERACTIVE(m) ((m) == SM_DELIVER)
+#endif /* _FFR_PROXY */
#define WILL_BE_QUEUED(m) ((m) == SM_QUEUE || (m) == SM_DEFER)
@@ -1736,6 +1780,8 @@ EXTERN unsigned long PrivacyFlags; /* privacy flags */
#define RSF_RMCOMM 0x0001 /* strip comments */
#define RSF_UNSTRUCTURED 0x0002 /* unstructured, ignore syntax errors */
#define RSF_COUNT 0x0004 /* count rejections (statistics)? */
+#define RSF_ADDR 0x0008 /* reassemble address */
+#define RSF_STRING 0x0010 /* reassemble address as string */
/*
** Flags passed to mime8to7 and putheader.
@@ -1893,6 +1939,10 @@ struct termescape
#define D_OPTIONAL 'O' /* optional socket */
#define D_DISABLE ((char)0x02) /* optional socket disabled */
#define D_ISSET ((char)0x03) /* this client struct is set */
+#if _FFR_XCNCT
+#define D_XCNCT ((char)0x04) /* X-Connect was used */
+#define D_XCNCT_M ((char)0x05) /* X-Connect was used + "forged" */
+#endif /* _FFR_XCNCT */
#if STARTTLS
/*
@@ -1926,6 +1976,7 @@ struct termescape
#define TLS_I_KEY_OUNR 0x00400000 /* Key must be other unreadable */
#define TLS_I_CRLF_EX 0x00800000 /* CRL file must exist */
#define TLS_I_CRLF_UNR 0x01000000 /* CRL file must be g/o unreadable */
+#define TLS_I_DHFIXED 0x02000000 /* use fixed DH param */
/* require server cert */
#define TLS_I_SRV_CERT (TLS_I_CERT_EX | TLS_I_KEY_EX | \
@@ -1935,8 +1986,7 @@ struct termescape
/* server requirements */
#define TLS_I_SRV (TLS_I_SRV_CERT | TLS_I_RSA_TMP | TLS_I_VRFY_PATH | \
- TLS_I_VRFY_LOC | TLS_I_TRY_DH | TLS_I_DH1024 | \
- TLS_I_CACHE)
+ TLS_I_VRFY_LOC | TLS_I_TRY_DH | TLS_I_CACHE)
/* client requirements */
#define TLS_I_CLT (TLS_I_KEY_UNR | TLS_I_KEY_OUNR)
@@ -1947,7 +1997,7 @@ struct termescape
/* functions */
extern bool init_tls_library __P((bool _fipsmode));
-extern bool inittls __P((SSL_CTX **, unsigned long, long, bool, char *, char *, char *, char *, char *));
+extern bool inittls __P((SSL_CTX **, unsigned long, unsigned long, bool, char *, char *, char *, char *, char *));
extern bool initclttls __P((bool));
extern void setclttls __P((bool));
extern bool initsrvtls __P((bool));
@@ -1960,10 +2010,9 @@ EXTERN char *CACertPath; /* path to CA certificates (dir. with hashes) */
EXTERN char *CACertFile; /* file with CA certificate */
EXTERN char *CltCertFile; /* file with client certificate */
EXTERN char *CltKeyFile; /* file with client private key */
-# if _FFR_TLS_1
EXTERN char *CipherList; /* list of ciphers */
-EXTERN char *DHParams5; /* file with DH parameters (512) */
-# endif /* _FFR_TLS_1 */
+EXTERN char *CertFingerprintAlgorithm; /* name of fingerprint alg */
+EXTERN const EVP_MD *EVP_digest; /* digest for cert fp */
EXTERN char *DHParams; /* file with DH parameters */
EXTERN char *RandFile; /* source of random data */
EXTERN char *SrvCertFile; /* file with server certificate */
@@ -1973,7 +2022,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 */
+EXTERN unsigned long Srv_SSL_Options, Clt_SSL_Options; /* SSL options */
#endif /* STARTTLS */
/*
@@ -2054,9 +2103,7 @@ 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 */
@@ -2064,6 +2111,9 @@ EXTERN QUEUE_CHAR *QueueLimitQuarantine; /* limit queue run to quarantine reason
EXTERN QUEUE_CHAR *QueueLimitRecipient; /* limit queue run to rcpt */
EXTERN QUEUE_CHAR *QueueLimitSender; /* limit queue run to sender */
EXTERN QUEUEGRP *Queue[MAXQUEUEGROUPS + 1]; /* queue groups */
+#if _FFR_BOUNCE_QUEUE
+EXTERN int BounceQueue;
+#endif
/* functions */
extern void assign_queueid __P((ENVELOPE *));
@@ -2265,7 +2315,7 @@ extern unsigned char tTdvect[100]; /* trace vector */
} while (0)
/* reply types (text in SmtpMsgBuffer) */
-#define XS_DEFAULT 0
+#define XS_DEFAULT 0 /* other commands, e.g., RSET */
#define XS_STARTTLS 1
#define XS_AUTH 2
#define XS_GREET 3
@@ -2274,14 +2324,16 @@ extern unsigned char tTdvect[100]; /* trace vector */
#define XS_RCPT 6
#define XS_DATA 7
#define XS_EOM 8
-#define XS_DATA2 9
-#define XS_RCPT2 10
-#define XS_QUIT 15
+#define XS_DATA2 9 /* LMTP */
+#define XS_QUIT 10
/*
** Global variables.
*/
+#if _FFR_ADD_BCC
+EXTERN bool AddBcc;
+#endif
#if _FFR_ADDR_TYPE_MODES
EXTERN bool AddrTypeModes; /* addr_type: extra "mode" information */
#endif /* _FFR_ADDR_TYPE_MODES */
@@ -2337,6 +2389,7 @@ EXTERN bool UseMSP; /* mail submission: group writable queue ok? */
EXTERN bool WorkAroundBrokenAAAA; /* some nameservers return SERVFAIL on AAAA queries */
EXTERN bool UseErrorsTo; /* use Errors-To: header (back compat) */
EXTERN bool UseNameServer; /* using DNS -- interpret h_errno & MX RRs */
+EXTERN bool UseCompressedIPv6Addresses; /* for more specific zero-subnet matches */
EXTERN char InetMode; /* default network for daemon mode */
EXTERN char OpMode; /* operation mode, see below */
EXTERN char SpaceSub; /* substitution for <lwsp> */
@@ -2504,6 +2557,10 @@ extern void buffer_errors __P((void));
extern void flush_errors __P((bool));
extern void PRINTFLIKE(1, 2) message __P((const char *, ...));
extern void PRINTFLIKE(1, 2) nmessage __P((const char *, ...));
+#if _FFR_PROXY
+extern void PRINTFLIKE(3, 4) emessage __P((const char *, const char *, const char *, ...));
+extern int extsc __P((const char *, int, char *, char *));
+#endif /* _FFR_PROXY */
extern void PRINTFLIKE(1, 2) syserr __P((const char *, ...));
extern void PRINTFLIKE(2, 3) usrerrenh __P((char *, const char *, ...));
extern void PRINTFLIKE(1, 2) usrerr __P((const char *, ...));
@@ -2519,7 +2576,7 @@ extern bool rebuildaliases __P((MAP *, bool));
extern void setalias __P((char *));
/* logging */
-extern void logdelivery __P((MAILER *, MCI *, char *, const char *, ADDRESS *, time_t, ENVELOPE *));
+extern void logdelivery __P((MAILER *, MCI *, char *, const char *, ADDRESS *, time_t, ENVELOPE *, ADDRESS *, int));
extern void logsender __P((ENVELOPE *, char *));
extern void PRINTFLIKE(3, 4) sm_syslog __P((int, const char *, const char *, ...));
@@ -2656,6 +2713,14 @@ extern int getla __P((void));
extern char *getmodifiers __P((char *, BITMAP256));
extern BITMAP256 *getrequests __P((ENVELOPE *));
extern char *getvendor __P((int));
+#if _FFR_TLS_SE_OPTS && STARTTLS
+# ifndef TLS_VRFY_PER_CTX
+# define TLS_VRFY_PER_CTX 1
+# endif
+extern int get_tls_se_options __P((ENVELOPE *, SSL *, bool));
+#else
+# define get_tls_se_options(e, s, w) 0
+#endif
extern void help __P((char *, ENVELOPE *));
extern void init_md __P((int, char **));
extern void initdaemon __P((void));
@@ -2666,6 +2731,9 @@ extern void init_vendor_macros __P((ENVELOPE *));
extern SIGFUNC_DECL intsig __P((int));
extern bool isatom __P((const char *));
extern bool isloopback __P((SOCKADDR sa));
+#if _FFR_TLS_SE_OPTS && STARTTLS
+extern bool load_certkey __P((SSL *, bool, char *, char *));
+#endif
extern void load_if_names __P((void));
extern bool lockfile __P((int, char *, char *, int));
extern void log_sendmail_pid __P((ENVELOPE *));
@@ -2719,10 +2787,10 @@ extern sigfunc_t setsignal __P((int, sigfunc_t));
extern void sm_setuserenv __P((const char *, const char *));
extern void settime __P((ENVELOPE *));
#if STARTTLS
-extern void set_tls_rd_tmo __P((int));
-#else /* STARTTLS */
-#define set_tls_rd_tmo(rd_tmo)
-#endif /* STARTTLS */
+extern int set_tls_rd_tmo __P((int));
+#else
+# define set_tls_rd_tmo(rd_tmo) 0
+#endif
extern char *sfgets __P((char *, int, SM_FILE_T *, time_t, char *));
extern char *shortenstring __P((const char *, size_t));
extern char *shorten_hostname __P((char []));
@@ -2774,16 +2842,22 @@ extern int waitfor __P((pid_t));
extern bool writable __P((char *, ADDRESS *, long));
#if SM_HEAP_CHECK
# define xalloc(size) xalloc_tagged(size, __FILE__, __LINE__)
-extern char *xalloc_tagged __P((int, char*, int));
+extern char *xalloc_tagged __P((int, char *, int));
#else /* SM_HEAP_CHECK */
extern char *xalloc __P((int));
#endif /* SM_HEAP_CHECK */
+#if _FFR_XCNCT
+extern int xconnect __P((SM_FILE_T *));
+#endif /* _FFR_XCNCT */
extern void xputs __P((SM_FILE_T *, const char *));
extern char *xtextify __P((char *, char *));
extern bool xtextok __P((char *));
extern int xunlink __P((char *));
extern char *xuntextify __P((char *));
+#if _FFR_RCPTFLAGS
+extern bool newmodmailer __P((ADDRESS *, int));
+#endif
#undef EXTERN
#endif /* ! _SENDMAIL_H */
diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c
index 0593a25..5209dfa 100644
--- a/contrib/sendmail/src/sfsasl.c
+++ b/contrib/sendmail/src/sfsasl.c
@@ -13,6 +13,7 @@ SM_RCSID("@(#)$Id: sfsasl.c,v 8.121 2013-11-22 20:51:56 ca Exp $")
#include <stdlib.h>
#include <sendmail.h>
#include <sm/time.h>
+#include <sm/fdset.h>
#include <errno.h>
/* allow to disable error handling code just in case... */
@@ -415,7 +416,7 @@ sfdcsasl(fin, fout, conn, tmo)
#if STARTTLS
# include "sfsasl.h"
-# include <openssl/err.h>
+# include <openssl/err.h>
/* Structure used by the "tls" file type */
struct tls_obj
@@ -618,17 +619,16 @@ tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
where, rfd, wfd, err);
}
- if (FD_SETSIZE > 0 &&
- ((err == SSL_ERROR_WANT_READ && rfd >= FD_SETSIZE) ||
- (err == SSL_ERROR_WANT_WRITE && wfd >= FD_SETSIZE)))
+ if ((err == SSL_ERROR_WANT_READ && !SM_FD_OK_SELECT(rfd)) ||
+ (err == SSL_ERROR_WANT_WRITE && !SM_FD_OK_SELECT(wfd)))
{
if (LogLevel > 5)
{
sm_syslog(LOG_ERR, NOQID,
"STARTTLS=%s, error: fd %d/%d too large",
where, rfd, wfd);
- if (LogLevel > 8)
- tlslogerr(LOG_WARNING, where);
+ if (LogLevel > 8)
+ tlslogerr(LOG_WARNING, where);
}
errno = EINVAL;
}
@@ -685,17 +685,21 @@ tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
** rd_tmo -- read timeout
**
** Results:
-** none
+** previous read timeout
** This is a hack: there is no way to pass it in
*/
static int tls_rd_tmo = -1;
-void
+int
set_tls_rd_tmo(rd_tmo)
int rd_tmo;
{
+ int old_rd_tmo;
+
+ old_rd_tmo = tls_rd_tmo;
tls_rd_tmo = rd_tmo;
+ return old_rd_tmo;
}
/*
@@ -820,7 +824,7 @@ tls_read(fp, buf, size)
}
else if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS: read error=%s (%d), retry=%d, ssl_err=%d",
+ "STARTTLS: read error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
err, r, errno, try, ssl_err);
errno = save_errno;
}
diff --git a/contrib/sendmail/src/sm_resolve.c b/contrib/sendmail/src/sm_resolve.c
index 662eaa5..8ec2cb6 100644
--- a/contrib/sendmail/src/sm_resolve.c
+++ b/contrib/sendmail/src/sm_resolve.c
@@ -235,7 +235,7 @@ parse_dns_reply(data, len)
if (LogLevel > 5)
sm_syslog(LOG_WARNING, NOQID,
"ERROR: DNS RDLENGTH=%d > data len=%d",
- size, len - (p - data));
+ size, len - (int)(p - data));
dns_free_data(r);
return NULL;
}
diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c
index 1a53567..b05348d 100644
--- a/contrib/sendmail/src/srvrsmtp.c
+++ b/contrib/sendmail/src/srvrsmtp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2010, 2012, 2013 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 1998-2010, 2012-2014 Proofpoint, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -30,7 +30,7 @@ SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.1016 2013-11-22 20:51:56 ca Exp $")
static int saslmechs __P((sasl_conn_t *, char **));
#endif /* SASL */
#if STARTTLS
-# include <openssl/err.h>
+# include <openssl/err.h>
# include <sysexits.h>
static SSL_CTX *srv_ctx = NULL; /* TLS server context */
@@ -204,6 +204,174 @@ parse_esmtp_args(e, addr_st, p, delimptr, which, args, esmtp_args)
args[argno] = NULL;
}
+#if _FFR_ADD_BCC
+
+/*
+** ADDRCPT -- Add a rcpt to sendq list
+**
+** Parameters:
+** rcpt -- rcpt
+** sendq -- a pointer to the head of a queue to put
+** these people into.
+** e -- the envelope in which to add these recipients.
+**
+** Returns:
+** The number of addresses added to the list.
+*/
+
+static int
+addrcpt(rcpt, sendq, e)
+ char *rcpt;
+ ADDRESS **sendq;
+ ENVELOPE *e;
+{
+ int r;
+ char *oldto;
+ ADDRESS *a;
+
+ SM_REQUIRE(rcpt != NULL);
+ SM_REQUIRE(sendq != NULL);
+ SM_REQUIRE(e != NULL);
+ oldto = e->e_to;
+ if (tTd(25, 1))
+ sm_dprintf("addrcpt: rcpt=%s\n", rcpt);
+ r = Errors;
+ a = NULL;
+ SM_TRY
+ {
+ macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e b");
+ a = parseaddr(rcpt, NULLADDR, RF_COPYALL, ' ', NULL, e, true);
+ if (a == NULL)
+ return 0;
+
+ a->q_flags &= ~Q_PINGFLAGS;
+ a->q_flags |= QINTBCC;
+ a->q_owner = "<>";
+
+ /* disable alias expansion? */
+ a = recipient(a, sendq, 0, e);
+ }
+ SM_FINALLY
+ {
+ e->e_to = oldto;
+ macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), NULL);
+ }
+ SM_END_TRY
+ if (tTd(25, 1))
+ sm_dprintf("addrcpt: rcpt=%s, flags=%#lx\n", rcpt,
+ a != NULL ? a->q_flags : 0);
+ Errors = r;
+ return 1;
+}
+
+/*
+** ADDBCC -- Maybe create a copy of an e-mail
+**
+** Parameters:
+** a -- current RCPT
+** e -- the envelope.
+**
+** Returns:
+** nothing
+**
+** Side Effects:
+** rscheck() can trigger an "exception"
+*/
+
+static void
+addbcc(a, e)
+ ADDRESS *a;
+ ENVELOPE *e;
+{
+ int nobcc;
+ char *newrcpt, empty[1];
+
+ if (!AddBcc)
+ return;
+
+ nobcc = false;
+ empty[0] = '\0';
+ newrcpt = empty;
+
+ nobcc = rscheck("bcc", a->q_paddr, NULL, e, RSF_ADDR, 12, NULL, NOQID,
+ NULL, &newrcpt);
+ if (tTd(25, 1))
+ sm_dprintf("addbcc: nobcc=%d, Errors=%d, newrcpt=<%s>\n", nobcc, Errors, newrcpt);
+ if (nobcc != EX_OK || Errors > 0 || *newrcpt == '\0')
+ return;
+
+ (void) addrcpt(newrcpt, &e->e_sendqueue, e);
+ return;
+}
+#else /* _FFR_ADD_BCC */
+# define addbcc(a, e)
+#endif /* _FFR_ADD_BCC */
+
+#if _FFR_RCPTFLAGS
+/*
+** RCPTMODS -- Perform rcpt modifications if requested
+**
+** Parameters:
+** rcpt -- current RCPT
+** e -- the envelope.
+**
+** Returns:
+** nothing.
+*/
+
+void
+rcptmods(rcpt, e)
+ ADDRESS *rcpt;
+ ENVELOPE *e;
+{
+ char *fl;
+
+ SM_REQUIRE(rcpt != NULL);
+ SM_REQUIRE(e != NULL);
+
+ fl = macvalue(macid("{rcpt_flags}"), e);
+ if (fl == NULL || *fl == '\0')
+ return;
+ if (tTd(25, 1))
+ sm_dprintf("rcptmods: rcpt=%s, flags=%s\n", rcpt->q_paddr, fl);
+
+ /* parse flags */
+ for ( ; *fl != '\0'; ++fl)
+ {
+ switch (*fl)
+ {
+ case 'n':
+ rcpt->q_flags &= ~Q_PINGFLAGS;
+ rcpt->q_flags |= QINTBCC;
+ rcpt->q_owner = "<>";
+ break;
+
+ case 'N':
+ rcpt->q_flags &= ~Q_PINGFLAGS;
+ rcpt->q_owner = "<>";
+ break;
+
+ case QDYNMAILFLG:
+ rcpt->q_flags |= QDYNMAILER;
+ newmodmailer(rcpt, *fl);
+ break;
+
+ default:
+ sm_syslog(LOG_INFO, e->e_id,
+ "rcpt=%s, rcpt_flags=%s, status=unknown",
+ rcpt->q_paddr, fl);
+ break;
+ }
+ }
+
+ /* reset macro to avoid confusion later on */
+ macdefine(&e->e_macro, A_PERM, macid("{rcpt_flags}"), NULL);
+
+}
+#else /* _FFR_RCPTFLAGS */
+# define rcptmods(a, e)
+#endif /* _FFR_RCPTFLAGS */
+
/*
** SMTP -- run the SMTP protocol.
**
@@ -541,6 +709,24 @@ do \
qid_printname(e), CurSmtpClient, inp); \
}
+/*
+** Determine the correct protocol keyword to use in the
+** Received: header, following RFC 3848.
+*/
+
+#if !STARTTLS
+# define tls_active false
+#endif
+#if SASL
+# define auth_active (authenticating == SASL_IS_AUTH)
+#else
+# define auth_active false
+#endif
+#define GET_PROTOCOL() \
+ (auth_active \
+ ? (tls_active ? "ESMTPSA" : "ESMTPA") \
+ : (tls_active ? "ESMTPS" : "ESMTP"))
+
static bool SevenBitInput_Saved; /* saved version of SevenBitInput */
void
@@ -577,6 +763,7 @@ smtp(nullserver, d_flags, e)
SMTP_T smtp;
char *addr;
char *greetcode = "220";
+ const char *greetmsg = "not accepting messages";
char *hostname; /* my hostname ($j) */
QUEUE_CHAR *new;
char *args[MAXSMTPARGS];
@@ -907,11 +1094,7 @@ smtp(nullserver, d_flags, e)
}
#endif /* SASL */
-#if STARTTLS
-
-
- set_tls_rd_tmo(TimeOuts.to_nextcommand);
-#endif /* STARTTLS */
+ (void) set_tls_rd_tmo(TimeOuts.to_nextcommand);
#if MILTER
if (smtp.sm_milterize)
@@ -968,7 +1151,73 @@ smtp(nullserver, d_flags, e)
response = milter_connect(q, RealHostAddr, e, &state);
switch (state)
{
+#if _FFR_MILTER_CONNECT_REPLYCODE
+ case SMFIR_REPLYCODE:
+ if (*response == '5')
+ {
+ if (MilterLogLevel > 3)
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter: connect: host=%s, addr=%s, reject=%s",
+ peerhostname,
+ anynet_ntoa(&RealHostAddr),
+ response);
+ greetcode = "554"; /* Required by 2821 3.1 */
+ nullserver = newstr(response);
+ if (strlen(nullserver) > 4)
+ {
+ int skip;
+
+ greetmsg = nullserver + 4;
+
+ /* skip over enhanced status code */
+ skip = isenhsc(greetmsg, ' ');
+ if (skip > 0)
+ greetmsg += skip + 1;
+ }
+ smtp.sm_milterize = false;
+ break;
+ }
+ else if (strncmp(response, "421 ", 4) == 0)
+ {
+ int skip;
+ const char *msg = response + 4;
+
+ if (MilterLogLevel > 3)
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter: connect: host=%s, addr=%s, shutdown=%s",
+ peerhostname,
+ anynet_ntoa(&RealHostAddr),
+ response);
+ tempfail = true;
+ smtp.sm_milterize = false;
+
+ /* skip over enhanced status code */
+ skip = isenhsc(msg, ' ');
+ if (skip > 0)
+ msg += skip + 1;
+ message("421 %s %s", MyHostName, msg);
+
+ /* arrange to ignore send list */
+ e->e_sendqueue = NULL;
+ goto doquit;
+ }
+ else
+ {
+ if (MilterLogLevel > 3)
+ sm_syslog(LOG_INFO, e->e_id,
+ "Milter: connect: host=%s, addr=%s, temp failing commands=%s",
+ peerhostname,
+ anynet_ntoa(&RealHostAddr),
+ response);
+ /*tempfail = true;*/
+ smtp.sm_milterize = false;
+ nullserver = newstr(response);
+ break;
+ }
+
+#else /* _FFR_MILTER_CONNECT_REPLYCODE */
case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */
+#endif /* _FFR_MILTER_CONNECT_REPLYCODE */
case SMFIR_REJECT:
if (MilterLogLevel > 3)
sm_syslog(LOG_INFO, e->e_id,
@@ -1006,7 +1255,7 @@ smtp(nullserver, d_flags, e)
goto doquit;
}
if (response != NULL)
- sm_free(response); /* XXX */
+ sm_free(response);
}
#endif /* MILTER */
@@ -1097,8 +1346,8 @@ smtp(nullserver, d_flags, e)
/* output the first line, inserting "ESMTP" as second word */
if (*greetcode == '5')
- (void) sm_snprintf(inp, sizeof(inp),
- "%s not accepting messages", hostname);
+ (void) sm_snprintf(inp, sizeof(inp), "%s %s", hostname,
+ greetmsg);
else
expand(SmtpGreeting, inp, sizeof(inp), e);
@@ -1400,6 +1649,8 @@ smtp(nullserver, d_flags, e)
*ssf);
}
+ protocol = GET_PROTOCOL();
+
/*
** Only switch to encrypted connection
** if a security layer has been negotiated
@@ -1868,6 +2119,14 @@ smtp(nullserver, d_flags, e)
goto tls_done;
}
+ if (get_tls_se_options(e, srv_ssl, true) != 0)
+ {
+ message("454 4.3.3 TLS not available: error setting options");
+ SSL_free(srv_ssl);
+ srv_ssl = NULL;
+ goto tls_done;
+ }
+
# if !TLS_VRFY_PER_CTX
/*
** this could be used if it were possible to set
@@ -1898,13 +2157,12 @@ smtp(nullserver, d_flags, e)
SSL_set_accept_state(srv_ssl);
-# define SSL_ACC(s) SSL_accept(s)
-
tlsstart = curtime();
ssl_retry:
- if ((r = SSL_ACC(srv_ssl)) <= 0)
+ if ((r = SSL_accept(srv_ssl)) <= 0)
{
int i, ssl_err;
+ int save_errno = errno;
ssl_err = SSL_get_error(srv_ssl, r);
i = tls_retry(srv_ssl, rfd, wfd, tlsstart,
@@ -1924,7 +2182,7 @@ smtp(nullserver, d_flags, e)
"STARTTLS=server, error: accept failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d, relay=%.100s",
r, sr == NULL ? "unknown"
: sr,
- ssl_err, errno, i,
+ ssl_err, save_errno, i,
CurSmtpClient);
if (LogLevel > 9)
tlslogerr(LOG_WARNING, "server");
@@ -1962,7 +2220,7 @@ smtp(nullserver, d_flags, e)
macvalue(macid("{verify}"), e),
"STARTTLS", e,
RSF_RMCOMM|RSF_COUNT,
- 5, NULL, NOQID, NULL) != EX_OK ||
+ 5, NULL, NOQID, NULL, NULL) != EX_OK ||
Errors > 0)
{
extern char MsgBuf[];
@@ -2052,7 +2310,7 @@ smtp(nullserver, d_flags, e)
DELAY_CONN("EHLO");
if (c->cmd_code == CMDEHLO)
{
- protocol = "ESMTP";
+ protocol = GET_PROTOCOL();
SmtpPhase = "server EHLO";
}
else
@@ -2468,7 +2726,7 @@ smtp(nullserver, d_flags, e)
#endif /* _FFR_MAIL_MACRO */
if (rscheck("check_mail", addr,
NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
- NULL, e->e_id, NULL) != EX_OK ||
+ NULL, e->e_id, NULL, NULL) != EX_OK ||
Errors > 0)
sm_exc_raisenew_x(&EtypeQuickAbort, 1);
macdefine(&e->e_macro, A_PERM,
@@ -2731,7 +2989,7 @@ smtp(nullserver, d_flags, e)
macid("{addr_type}"), "e r");
if (rscheck("check_rcpt", addr,
NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
- NULL, e->e_id, p_addr_st) != EX_OK ||
+ NULL, e->e_id, p_addr_st, NULL) != EX_OK ||
Errors > 0)
goto rcpt_done;
macdefine(&e->e_macro, A_PERM,
@@ -2744,6 +3002,9 @@ smtp(nullserver, d_flags, e)
milter_cmd_safe = true;
#endif
+ addbcc(a, e);
+ rcptmods(a, e);
+
/* save in recipient list after ESMTP mods */
a = recipient(a, &e->e_sendqueue, 0, e);
/* may trigger exception... */
@@ -2821,6 +3082,7 @@ smtp(nullserver, d_flags, e)
#if !MILTER
rcpt_done:
#endif /* !MILTER */
+
macdefine(&e->e_macro, A_PERM,
macid("{rcpt_mailer}"), NULL);
macdefine(&e->e_macro, A_PERM,
@@ -2974,8 +3236,8 @@ smtp(nullserver, d_flags, e)
{
/* do config file checking of the address */
if (rscheck(vrfy ? "check_vrfy" : "check_expn",
- p, NULL, e, RSF_RMCOMM,
- 3, NULL, NOQID, NULL) != EX_OK ||
+ p, NULL, e, RSF_RMCOMM, 3, NULL,
+ NOQID, NULL, NULL) != EX_OK ||
Errors > 0)
sm_exc_raisenew_x(&EtypeQuickAbort, 1);
(void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e);
@@ -3070,9 +3332,8 @@ smtp(nullserver, d_flags, e)
** available to make a decision.
*/
- if (rscheck("check_etrn", p, NULL, e,
- RSF_RMCOMM, 3, NULL, NOQID, NULL)
- != EX_OK ||
+ if (rscheck("check_etrn", p, NULL, e, RSF_RMCOMM, 3,
+ NULL, NOQID, NULL, NULL) != EX_OK ||
Errors > 0)
break;
@@ -3371,7 +3632,7 @@ smtp_data(smtp, e)
(void) sm_snprintf(buf, sizeof(buf), "%u", smtp->sm_nrcpts);
if (rscheck("check_data", buf, NULL, e,
RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL,
- e->e_id, NULL) != EX_OK)
+ e->e_id, NULL, NULL) != EX_OK)
return true;
#if MILTER && SMFI_VERSION > 3
@@ -3494,7 +3755,7 @@ smtp_data(smtp, e)
/* rscheck() will set Errors or EF_DISCARD if it trips */
(void) rscheck("check_eom", buf, NULL, e, RSF_UNSTRUCTURED|RSF_COUNT,
- 3, NULL, e->e_id, NULL);
+ 3, NULL, e->e_id, NULL, NULL);
#if MILTER
milteraccept = true;
@@ -3735,6 +3996,38 @@ smtp_data(smtp, e)
_res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
#endif /* NAMED_BIND */
+#if _FFR_PROXY
+ if (SM_PROXY_REQ == e->e_sendmode)
+ {
+ /* is proxy mode possible? */
+ if (e->e_sibling == NULL && e->e_nrcpts == 1
+ && smtp->sm_nrcpts == 1
+ && (a = e->e_sendqueue) != NULL && a->q_next == NULL)
+ {
+ a->q_flags &= ~(QPINGONFAILURE|QPINGONSUCCESS|
+ QPINGONDELAY);
+ e->e_errormode = EM_QUIET;
+ e->e_sendmode = SM_PROXY;
+ }
+ else
+ {
+ if (tTd(87, 2))
+ {
+ a = e->e_sendqueue;
+ sm_dprintf("srv: mode=%c, e=%p, sibling=%p, nrcpts=%d, sm_nrcpts=%d, sendqueue=%p, next=%p\n",
+ e->e_sendmode, e, e->e_sibling, e->e_nrcpts,
+ smtp->sm_nrcpts, a,
+ (a == NULL) ? (void *)0 : a->q_next);
+ }
+
+ /* switch to interactive mode */
+ e->e_sendmode = SM_DELIVER;
+ if (LogLevel > 9)
+ sm_syslog(LOG_DEBUG, e->e_id,
+ "proxy mode requested but not possible");
+ }
+ }
+#endif /* _FFR_PROXY */
for (ee = e; ee != NULL; ee = ee->e_sibling)
{
@@ -3779,6 +4072,84 @@ smtp_data(smtp, e)
oldid = CurEnv->e_id;
CurEnv->e_id = id;
+#if _FFR_PROXY
+ a = e->e_sendqueue;
+ if (tTd(87, 1))
+ {
+ sm_dprintf("srv: mode=%c, e=%p, sibling=%p, nrcpts=%d, msg=%s, sendqueue=%p, next=%p, state=%d, SmtpError=%s, rcode=%d, renhsc=%s, text=%s\n",
+ e->e_sendmode, e, e->e_sibling, e->e_nrcpts, e->e_message, a,
+ (a == NULL) ? (void *)0 : a->q_next,
+ (a == NULL) ? -1 : a->q_state, SmtpError, e->e_rcode,
+ e->e_renhsc, e->e_text);
+ }
+
+ if (SM_PROXY == e->e_sendmode && a->q_state != QS_SENT &&
+ a->q_state != QS_VERIFIED) /* discarded! */
+ {
+ char *m, *errtext;
+ char replycode[4];
+ char enhsc[10];
+ int offset;
+
+#define NN_MSG(e) (((e)->e_message != NULL) ? (e)->e_message : "")
+ m = e->e_message;
+#define SM_MSG_DEFERRED "Deferred: "
+ if (m != NULL && strncmp(SM_MSG_DEFERRED, m,
+ sizeof(SM_MSG_DEFERRED) - 1) == 0)
+ m += sizeof(SM_MSG_DEFERRED) - 1;
+ offset = extsc(m, ' ', replycode, enhsc);
+
+ if (tTd(87, 2))
+ {
+ sm_dprintf("srv: SmtpError=%s, rcode=%d, renhsc=%s, replycode=%s, enhsc=%s, offset=%d\n",
+ SmtpError, e->e_rcode, e->e_renhsc,
+ replycode, enhsc, offset);
+ }
+
+#define DIG2CHAR(d) ((d) + '0')
+ if (e->e_rcode != 0 && (replycode[0] == '\0' ||
+ replycode[0] == DIG2CHAR(REPLYTYPE(e->e_rcode))))
+ {
+ replycode[0] = DIG2CHAR(REPLYTYPE(e->e_rcode));
+ replycode[1] = DIG2CHAR(REPLYCLASS(e->e_rcode));
+ replycode[2] = DIG2CHAR(REPLYMINOR(e->e_rcode));
+ replycode[3] = '\0';
+ if (e->e_renhsc[0] == replycode[0])
+ sm_strlcpy(enhsc, e->e_renhsc, sizeof(enhsc));
+ if (offset < 0)
+ offset = 0;
+ }
+ if (e->e_text != NULL)
+ {
+ (void) strreplnonprt(e->e_text, '_');
+ errtext = e->e_text;
+ }
+ else
+ errtext = m + offset;
+
+ if (replycode[0] != '\0' && enhsc[0] != '\0')
+ emessage(replycode, enhsc, "%s", errtext);
+ else if (replycode[0] != '\0')
+ emessage(replycode, smtptodsn(atoi(replycode)),
+ "%s", errtext);
+ else if (QS_IS_TEMPFAIL(a->q_state))
+ {
+ if (m != NULL)
+ message("450 4.5.1 %s", m);
+ else
+ message("450 4.5.1 Temporary error");
+ }
+ else
+ {
+ if (m != NULL)
+ message("550 5.5.1 %s", m);
+ else
+ message("550 5.0.0 Permanent error");
+ }
+ }
+ else
+ {
+#endif /* _FFR_PROXY */
/* issue success message */
#if _FFR_MSG_ACCEPT
if (MessageAccept != NULL && *MessageAccept != '\0')
@@ -3791,6 +4162,9 @@ smtp_data(smtp, e)
else
#endif /* _FFR_MSG_ACCEPT */
message("250 2.0.0 %s Message accepted for delivery", id);
+#if _FFR_PROXY
+ }
+#endif /* _FFR_PROXY */
CurEnv->e_id = oldid;
/* if we just queued, poke it */
@@ -3937,7 +4311,7 @@ logundelrcpts(e, msg, level, all)
? e->e_enhsc :
#endif /* _FFR_MILTER_ENHSC */
a->q_status,
- msg, NULL, (time_t) 0, e);
+ msg, NULL, (time_t) 0, e, a, EX_OK /* ??? */);
}
e->e_to = NULL;
}
@@ -4339,8 +4713,8 @@ mail_esmtp_args(a, kp, vp, e)
SuprErrs = true;
QuickAbort = false;
if (strcmp(auth_param, "<>") != 0 &&
- (rscheck("trust_auth", auth_param, NULL, e, RSF_RMCOMM,
- 9, NULL, NOQID, NULL) != EX_OK || Errors > 0))
+ (rscheck("trust_auth", auth_param, NULL, e, RSF_RMCOMM, 9,
+ NULL, NOQID, NULL, NULL) != EX_OK || Errors > 0))
{
if (tTd(95, 8))
{
diff --git a/contrib/sendmail/src/tls.c b/contrib/sendmail/src/tls.c
index ca93ee8..6b0ea25 100644
--- a/contrib/sendmail/src/tls.c
+++ b/contrib/sendmail/src/tls.c
@@ -13,21 +13,21 @@
SM_RCSID("@(#)$Id: tls.c,v 8.127 2013-11-27 02:51:11 gshapiro Exp $")
#if STARTTLS
-# include <openssl/err.h>
-# include <openssl/bio.h>
-# include <openssl/pem.h>
-# ifndef HASURANDOMDEV
-# include <openssl/rand.h>
-# endif /* ! HASURANDOMDEV */
+# include <openssl/err.h>
+# include <openssl/bio.h>
+# include <openssl/pem.h>
+# ifndef HASURANDOMDEV
+# include <openssl/rand.h>
+# endif /* ! HASURANDOMDEV */
# if !TLS_NO_RSA
static RSA *rsa_tmp = NULL; /* temporary RSA key */
static RSA *tmp_rsa_key __P((SSL *, int, int));
# endif /* !TLS_NO_RSA */
-# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
+# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
static int tls_verify_cb __P((X509_STORE_CTX *));
-# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
static int tls_verify_cb __P((X509_STORE_CTX *, void *));
-# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
# if OPENSSL_VERSION_NUMBER > 0x00907000L
static int x509_verify_cb __P((int, X509_STORE_CTX *));
@@ -41,7 +41,7 @@ static int x509_verify_cb __P((int, X509_STORE_CTX *));
static void apps_ssl_info_cb __P((CONST097 SSL *, int , int));
static bool tls_ok_f __P((char *, char *, int));
static bool tls_safe_f __P((char *, long, bool));
-static int tls_verify_log __P((int, X509_STORE_CTX *, char *));
+static int tls_verify_log __P((int, X509_STORE_CTX *, const char *));
# if !NO_DH
static DH *get_dh512 __P((void));
@@ -73,6 +73,62 @@ get_dh512()
return NULL;
return dh;
}
+
+# if 0
+
+This is the data from which the C code has been generated:
+
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEArDcgcLpxEksQHPlolRKCUJ2szKRziseWV9cUSQNZGxoGw7KkROz4
+HF9QSbg5axyNIG+QbZYtx0jp3l6/GWq1dLOj27yZkgYgaYgFrvKPiZ2jJ5xETQVH
+UpZwbjRcyjyWkWYJVsx1aF4F/iY4kT0n/+iGEoimI3C9V3KXTJ2S6jIkyJ6M/CrN
+EtrDynMlUMGlc7S1ouXVOTrtKeqy3S2L9eBLxVI+sChEijGIfELupdVeXihK006p
+MgnABPDbkTx6OOtYmSZaGQX+OLW2FPmwvcrzgCz9t9cAsuUcBZv1LeHEqZZttyLU
+oK0jjSXgFyeU4/NfyA+zuNeWzUL6bHmigwIBAg==
+-----END DH PARAMETERS-----
+# endif /* 0 */
+
+static DH *
+get_dh2048()
+{
+ static unsigned char dh2048_p[]={
+ 0xAC,0x37,0x20,0x70,0xBA,0x71,0x12,0x4B,0x10,0x1C,0xF9,0x68,
+ 0x95,0x12,0x82,0x50,0x9D,0xAC,0xCC,0xA4,0x73,0x8A,0xC7,0x96,
+ 0x57,0xD7,0x14,0x49,0x03,0x59,0x1B,0x1A,0x06,0xC3,0xB2,0xA4,
+ 0x44,0xEC,0xF8,0x1C,0x5F,0x50,0x49,0xB8,0x39,0x6B,0x1C,0x8D,
+ 0x20,0x6F,0x90,0x6D,0x96,0x2D,0xC7,0x48,0xE9,0xDE,0x5E,0xBF,
+ 0x19,0x6A,0xB5,0x74,0xB3,0xA3,0xDB,0xBC,0x99,0x92,0x06,0x20,
+ 0x69,0x88,0x05,0xAE,0xF2,0x8F,0x89,0x9D,0xA3,0x27,0x9C,0x44,
+ 0x4D,0x05,0x47,0x52,0x96,0x70,0x6E,0x34,0x5C,0xCA,0x3C,0x96,
+ 0x91,0x66,0x09,0x56,0xCC,0x75,0x68,0x5E,0x05,0xFE,0x26,0x38,
+ 0x91,0x3D,0x27,0xFF,0xE8,0x86,0x12,0x88,0xA6,0x23,0x70,0xBD,
+ 0x57,0x72,0x97,0x4C,0x9D,0x92,0xEA,0x32,0x24,0xC8,0x9E,0x8C,
+ 0xFC,0x2A,0xCD,0x12,0xDA,0xC3,0xCA,0x73,0x25,0x50,0xC1,0xA5,
+ 0x73,0xB4,0xB5,0xA2,0xE5,0xD5,0x39,0x3A,0xED,0x29,0xEA,0xB2,
+ 0xDD,0x2D,0x8B,0xF5,0xE0,0x4B,0xC5,0x52,0x3E,0xB0,0x28,0x44,
+ 0x8A,0x31,0x88,0x7C,0x42,0xEE,0xA5,0xD5,0x5E,0x5E,0x28,0x4A,
+ 0xD3,0x4E,0xA9,0x32,0x09,0xC0,0x04,0xF0,0xDB,0x91,0x3C,0x7A,
+ 0x38,0xEB,0x58,0x99,0x26,0x5A,0x19,0x05,0xFE,0x38,0xB5,0xB6,
+ 0x14,0xF9,0xB0,0xBD,0xCA,0xF3,0x80,0x2C,0xFD,0xB7,0xD7,0x00,
+ 0xB2,0xE5,0x1C,0x05,0x9B,0xF5,0x2D,0xE1,0xC4,0xA9,0x96,0x6D,
+ 0xB7,0x22,0xD4,0xA0,0xAD,0x23,0x8D,0x25,0xE0,0x17,0x27,0x94,
+ 0xE3,0xF3,0x5F,0xC8,0x0F,0xB3,0xB8,0xD7,0x96,0xCD,0x42,0xFA,
+ 0x6C,0x79,0xA2,0x83,
+ };
+ static unsigned char dh2048_g[]={ 0x02, };
+ DH *dh;
+
+ if ((dh=DH_new()) == NULL)
+ return(NULL);
+ dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
+ dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
+ if ((dh->p == NULL) || (dh->g == NULL))
+ {
+ DH_free(dh);
+ return(NULL);
+ }
+ return(dh);
+}
# endif /* !NO_DH */
@@ -311,15 +367,32 @@ init_tls_library(fipsmode)
}
}
#endif /* _FFR_FIPSMODE */
+ if (bv && CertFingerprintAlgorithm != NULL)
+ {
+ const EVP_MD *md;
+
+ md = EVP_get_digestbyname(CertFingerprintAlgorithm);
+ if (NULL == md)
+ {
+ bv = false;
+ if (LogLevel > 0)
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=init, CertFingerprintAlgorithm=%s, status=invalid"
+ , CertFingerprintAlgorithm);
+ }
+ else
+ EVP_digest = md;
+ }
return bv;
}
+
/*
** TLS_SET_VERIFY -- request client certificate?
**
** Parameters:
** ctx -- TLS context
** ssl -- TLS structure
-** vrfy -- require certificate?
+** vrfy -- request certificate?
**
** Returns:
** none.
@@ -369,12 +442,10 @@ tls_set_verify(ctx, ssl, vrfy)
# define TLS_S_CRLF_EX 0x00000100 /* CRL file exists */
# define TLS_S_CRLF_OK 0x00000200 /* CRL file is ok */
-# if _FFR_TLS_1
-# define TLS_S_CERT2_EX 0x00001000 /* 2nd cert file exists */
-# define TLS_S_CERT2_OK 0x00002000 /* 2nd cert file is ok */
-# define TLS_S_KEY2_EX 0x00004000 /* 2nd key file exists */
-# define TLS_S_KEY2_OK 0x00008000 /* 2nd key file is ok */
-# endif /* _FFR_TLS_1 */
+# define TLS_S_CERT2_EX 0x00001000 /* 2nd cert file exists */
+# define TLS_S_CERT2_OK 0x00002000 /* 2nd cert file is ok */
+# define TLS_S_KEY2_EX 0x00004000 /* 2nd key file exists */
+# define TLS_S_KEY2_OK 0x00008000 /* 2nd key file is ok */
# define TLS_S_DH_OK 0x00200000 /* DH cert is ok */
# define TLS_S_DHPAR_EX 0x00400000 /* DH param file exists */
@@ -507,6 +578,109 @@ tls_safe_f(var, sff, srv)
ok = false; \
}
+# if _FFR_TLS_SE_OPTS
+/*
+** LOAD_CERTKEY -- load cert/key for TLS session
+**
+** Parameters:
+** ssl -- TLS session context
+** certfile -- filename of certificate
+** keyfile -- filename of private key
+**
+** Returns:
+** succeeded?
+*/
+
+bool
+load_certkey(ssl, srv, certfile, keyfile)
+ SSL *ssl;
+ bool srv;
+ char *certfile;
+ char *keyfile;
+{
+ bool ok;
+ int r;
+ long sff, status;
+ unsigned long req;
+ char *who;
+
+ ok = true;
+ who = srv ? "server" : "client";
+ status = TLS_S_NONE;
+ req = TLS_I_CERT_EX|TLS_I_KEY_EX;
+ TLS_OK_F(certfile, "CertFile", bitset(TLS_I_CERT_EX, req),
+ TLS_S_CERT_EX, srv ? TLS_T_SRV : TLS_T_CLT);
+ TLS_OK_F(keyfile, "KeyFile", bitset(TLS_I_KEY_EX, req),
+ TLS_S_KEY_EX, srv ? TLS_T_SRV : TLS_T_CLT);
+
+ /* certfile etc. must be "safe". */
+ sff = SFF_REGONLY | SFF_SAFEDIRPATH | SFF_NOWLINK
+ | SFF_NOGWFILES | SFF_NOWWFILES
+ | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
+ if (DontLockReadFiles)
+ sff |= SFF_NOLOCK;
+
+ TLS_SAFE_F(certfile, sff | TLS_UNR(TLS_I_CERT_UNR, req),
+ bitset(TLS_I_CERT_EX, req),
+ bitset(TLS_S_CERT_EX, status), TLS_S_CERT_OK, srv);
+ TLS_SAFE_F(keyfile, sff | TLS_KEYSFF(req),
+ bitset(TLS_I_KEY_EX, req),
+ bitset(TLS_S_KEY_EX, status), TLS_S_KEY_OK, srv);
+
+# define SSL_use_cert(ssl, certfile) \
+ SSL_use_certificate_file(ssl, certfile, SSL_FILETYPE_PEM)
+# define SSL_USE_CERT "SSL_use_certificate_file"
+
+ if (bitset(TLS_S_CERT_OK, status) &&
+ SSL_use_cert(ssl, certfile) <= 0)
+ {
+ if (LogLevel > 7)
+ {
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: %s(%s) failed",
+ who, SSL_USE_CERT, certfile);
+ if (LogLevel > 9)
+ tlslogerr(LOG_WARNING, who);
+ }
+ if (bitset(TLS_I_USE_CERT, req))
+ return false;
+ }
+ if (bitset(TLS_S_KEY_OK, status) &&
+ SSL_use_PrivateKey_file(ssl, keyfile, SSL_FILETYPE_PEM) <= 0)
+ {
+ if (LogLevel > 7)
+ {
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: SSL_use_PrivateKey_file(%s) failed",
+ who, keyfile);
+ if (LogLevel > 9)
+ tlslogerr(LOG_WARNING, who);
+ }
+ if (bitset(TLS_I_USE_KEY, req))
+ return false;
+ }
+
+ /* check the private key */
+ if (bitset(TLS_S_KEY_OK, status) &&
+ (r = SSL_check_private_key(ssl)) <= 0)
+ {
+ /* Private key does not match the certificate public key */
+ if (LogLevel > 5)
+ {
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: SSL_check_private_key failed(%s): %d",
+ who, keyfile, r);
+ if (LogLevel > 9)
+ tlslogerr(LOG_WARNING, who);
+ }
+ if (bitset(TLS_I_USE_KEY, req))
+ return false;
+ }
+
+ return true;
+}
+# endif /* _FFR_TLS_SE_OPTS */
+
/*
** INITTLS -- initialize TLS
**
@@ -545,7 +719,7 @@ bool
inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
SSL_CTX **ctx;
unsigned long req;
- long options;
+ unsigned long options;
bool srv;
char *certfile, *keyfile, *cacertpath, *cacertfile, *dhparam;
{
@@ -556,12 +730,10 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
bool ok;
long sff, status;
char *who;
-# if _FFR_TLS_1
char *cf2, *kf2;
-# endif /* _FFR_TLS_1 */
-# if SM_CONF_SHM
+# if SM_CONF_SHM
extern int ShmId;
-# endif /* SM_CONF_SHM */
+# endif /* SM_CONF_SHM */
# if OPENSSL_VERSION_NUMBER > 0x00907000L
BIO *crl_file;
X509_CRL *crl;
@@ -586,7 +758,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
return true;
ok = true;
-# if _FFR_TLS_1
/*
** look for a second filename: it must be separated by a ','
** no blanks allowed (they won't be skipped).
@@ -605,7 +776,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
if (keyfile != NULL && (kf2 = strchr(keyfile, ',')) != NULL)
*kf2++ = '\0';
}
-# endif /* _FFR_TLS_1 */
/*
** Check whether files/paths are defined
@@ -625,7 +795,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
TLS_S_CRLF_EX, TLS_T_OTHER);
# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
-# if _FFR_TLS_1
/*
** if the second file is specified it must exist
** XXX: it is possible here to define only one of those files
@@ -641,18 +810,23 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
TLS_OK_F(kf2, "KeyFile", bitset(TLS_I_KEY_EX, req),
TLS_S_KEY2_EX, srv ? TLS_T_SRV : TLS_T_CLT);
}
-# endif /* _FFR_TLS_1 */
/*
** valid values for dhparam are (only the first char is checked)
** none no parameters: don't use DH
+ ** i use precomputed 2048 bit parameters
** 512 use precomputed 512 bit parameters
** 1024 generate 1024 bit parameters
** 2048 generate 2048 bit parameters
** /file/name read parameters from /file/name
- ** default is: 1024
*/
+#define SET_DH_DFL \
+ do { \
+ dhparam = "I"; \
+ req |= TLS_I_DHFIXED; \
+ } while (0)
+
if (bitset(TLS_I_TRY_DH, req))
{
if (dhparam != NULL)
@@ -661,24 +835,25 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
if (c == '1')
req |= TLS_I_DH1024;
+ else if (c == 'I' || c == 'i')
+ req |= TLS_I_DHFIXED;
else if (c == '2')
req |= TLS_I_DH2048;
else if (c == '5')
req |= TLS_I_DH512;
- else if (c != 'n' && c != 'N' && c != '/')
+ else if (c == 'n' || c == 'N')
+ req &= ~TLS_I_TRY_DH;
+ else if (c != '/')
{
if (LogLevel > 12)
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=%s, error: illegal value '%s' for DHParam",
+ "STARTTLS=%s, error: illegal value '%s' for DHParameters",
who, dhparam);
dhparam = NULL;
}
}
if (dhparam == NULL)
- {
- dhparam = "1";
- req |= TLS_I_DH1024;
- }
+ SET_DH_DFL;
else if (*dhparam == '/')
{
TLS_OK_F(dhparam, "DHParameters",
@@ -705,9 +880,14 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
TLS_SAFE_F(cacertfile, sff | TLS_UNR(TLS_I_CERTF_UNR, req),
bitset(TLS_I_CERTF_EX, req),
bitset(TLS_S_CERTF_EX, status), TLS_S_CERTF_OK, srv);
- TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req),
- bitset(TLS_I_DHPAR_EX, req),
- bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK, srv);
+ if (dhparam != NULL && *dhparam == '/')
+ {
+ TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req),
+ bitset(TLS_I_DHPAR_EX, req),
+ bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK, srv);
+ if (!bitset(TLS_S_DHPAR_OK, status))
+ SET_DH_DFL;
+ }
# if OPENSSL_VERSION_NUMBER > 0x00907000L
TLS_SAFE_F(CRLFile, sff | TLS_UNR(TLS_I_CRLF_UNR, req),
bitset(TLS_I_CRLF_EX, req),
@@ -715,7 +895,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
if (!ok)
return ok;
-# if _FFR_TLS_1
if (cf2 != NULL)
{
TLS_SAFE_F(cf2, sff | TLS_UNR(TLS_I_CERT_UNR, req),
@@ -728,7 +907,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
bitset(TLS_I_KEY_EX, req),
bitset(TLS_S_KEY2_EX, status), TLS_S_KEY2_OK, srv);
}
-# endif /* _FFR_TLS_1 */
/* create a method and a new context */
if ((*ctx = SSL_CTX_new(srv ? SSLv23_server_method() :
@@ -823,13 +1001,13 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
*/
if (bitset(TLS_I_RSA_TMP, req)
-# if SM_CONF_SHM
+# if SM_CONF_SHM
&& ShmId != SM_SHM_NO_ID &&
(rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL,
NULL)) == NULL
-# else /* SM_CONF_SHM */
+# else /* SM_CONF_SHM */
&& 0 /* no shared memory: no need to generate key now */
-# endif /* SM_CONF_SHM */
+# endif /* SM_CONF_SHM */
)
{
if (LogLevel > 7)
@@ -865,16 +1043,25 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
return false;
}
+#if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE
+# define SSL_CTX_use_cert(ssl_ctx, certfile) \
+ SSL_CTX_use_certificate_chain_file(ssl_ctx, certfile)
+# define SSL_CTX_USE_CERT "SSL_CTX_use_certificate_chain_file"
+#else
+# define SSL_CTX_use_cert(ssl_ctx, certfile) \
+ SSL_CTX_use_certificate_file(ssl_ctx, certfile, SSL_FILETYPE_PEM)
+# define SSL_CTX_USE_CERT "SSL_CTX_use_certificate_file"
+#endif
+
/* get the certificate file */
if (bitset(TLS_S_CERT_OK, status) &&
- SSL_CTX_use_certificate_file(*ctx, certfile,
- SSL_FILETYPE_PEM) <= 0)
+ SSL_CTX_use_cert(*ctx, certfile) <= 0)
{
if (LogLevel > 7)
{
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=%s, error: SSL_CTX_use_certificate_file(%s) failed",
- who, certfile);
+ "STARTTLS=%s, error: %s(%s) failed",
+ who, SSL_CTX_USE_CERT, certfile);
if (LogLevel > 9)
tlslogerr(LOG_WARNING, who);
}
@@ -899,7 +1086,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
return false;
}
-# if _FFR_TLS_1
/* XXX this code is pretty much duplicated from above! */
/* load private key */
@@ -918,13 +1104,13 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
/* get the certificate file */
if (bitset(TLS_S_CERT2_OK, status) &&
- SSL_CTX_use_certificate_file(*ctx, cf2, SSL_FILETYPE_PEM) <= 0)
+ SSL_CTX_use_cert(*ctx, cf2) <= 0)
{
if (LogLevel > 7)
{
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=%s, error: SSL_CTX_use_certificate_file(%s) failed",
- who, cf2);
+ "STARTTLS=%s, error: %s(%s) failed",
+ who, SSL_CTX_USE_CERT, cf2);
if (LogLevel > 9)
tlslogerr(LOG_WARNING, who);
}
@@ -944,7 +1130,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
tlslogerr(LOG_WARNING, who);
}
}
-# endif /* _FFR_TLS_1 */
/* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */
@@ -968,7 +1153,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
options &= ~SSL_OP_TLS_BLOCK_PADDING_BUG;
}
#endif
- SSL_CTX_set_options(*ctx, options);
+ SSL_CTX_set_options(*ctx, (long) options);
# if !NO_DH
/* Diffie-Hellman initialization */
@@ -977,6 +1162,10 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
#if _FFR_TLS_EC
EC_KEY *ecdh;
#endif /* _FFR_TLS_EC */
+
+ if (tTd(96, 8))
+ sm_dprintf("inittls: req=%#lx, status=%#lx\n",
+ req, status);
if (bitset(TLS_S_DHPAR_OK, status))
{
BIO *bio;
@@ -996,6 +1185,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
ERR_error_string(err, NULL));
if (LogLevel > 9)
tlslogerr(LOG_WARNING, who);
+ SET_DH_DFL;
}
}
else
@@ -1025,8 +1215,13 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
dh = DSA_dup_DH(dsa);
DSA_free(dsa);
}
- else
- if (dh == NULL && bitset(TLS_I_DH512, req))
+ else if (dh == NULL && bitset(TLS_I_DHFIXED, req))
+ {
+ if (tTd(96, 2))
+ sm_dprintf("inittls: Using precomputed 2048 bit DH parameters\n");
+ dh = get_dh2048();
+ }
+ else if (dh == NULL && bitset(TLS_I_DH512, req))
{
if (tTd(96, 2))
sm_dprintf("inittls: Using precomputed 512 bit DH parameters\n");
@@ -1153,7 +1348,6 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
if (tTd(96, 9))
SSL_CTX_set_info_callback(*ctx, apps_ssl_info_cb);
-# if _FFR_TLS_1
/* install our own cipher list */
if (CipherList != NULL && *CipherList != '\0')
{
@@ -1171,29 +1365,73 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
/* failure if setting to this list is required? */
}
}
-# endif /* _FFR_TLS_1 */
+
if (LogLevel > 12)
sm_syslog(LOG_INFO, NOQID, "STARTTLS=%s, init=%d", who, ok);
-# if _FFR_TLS_1
-# if 0
+# if 0
/*
** this label is required if we want to have a "clean" exit
** see the comments above at the initialization of cf2
*/
endinittls:
-# endif /* 0 */
+# endif /* 0 */
/* undo damage to global variables */
if (cf2 != NULL)
*--cf2 = ',';
if (kf2 != NULL)
*--kf2 = ',';
-# endif /* _FFR_TLS_1 */
return ok;
}
+
+/*
+** CERT_FP -- get cert fingerprint
+**
+** Parameters:
+** cert -- TLS cert
+** mac -- macro storage
+** macro -- where to store cert fp
+**
+** Returns:
+** <=0: cert fp calculation failed
+** >0: cert fp calculation ok
+*/
+
+static int
+cert_fp(cert, evp_digest, mac, macro)
+ X509 *cert;
+ const EVP_MD *evp_digest;
+ MACROS_T *mac;
+ char *macro;
+{
+ unsigned int n;
+ int r;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ char md5h[EVP_MAX_MD_SIZE * 3];
+ static const char hexcodes[] = "0123456789ABCDEF";
+
+ n = 0;
+ if (X509_digest(cert, EVP_digest, md, &n) == 0 || n <= 0)
+ {
+ macdefine(mac, A_TEMP, macid(macro), "");
+ return 0;
+ }
+
+ SM_ASSERT((n * 3) + 2 < sizeof(md5h));
+ for (r = 0; r < (int) n; r++)
+ {
+ md5h[r * 3] = hexcodes[(md[r] & 0xf0) >> 4];
+ md5h[(r * 3) + 1] = hexcodes[(md[r] & 0x0f)];
+ md5h[(r * 3) + 2] = ':';
+ }
+ md5h[(n * 3) - 1] = '\0';
+ macdefine(mac, A_TEMP, macid(macro), md5h);
+ return 1;
+}
+
/*
** TLS_GET_INFO -- get information about TLS connection
**
@@ -1208,9 +1446,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
** result of authentication.
**
** Side Effects:
-** sets macros: {cipher}, {tls_version}, {verify},
-** {cipher_bits}, {alg_bits}, {cert}, {cert_subject},
-** {cert_issuer}, {cn_subject}, {cn_issuer}
+** sets various TLS related macros.
*/
int
@@ -1238,7 +1474,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
macdefine(mac, A_TEMP, macid("{cipher_bits}"), bitstr);
(void) sm_snprintf(bitstr, sizeof(bitstr), "%d", r);
macdefine(mac, A_TEMP, macid("{alg_bits}"), bitstr);
- s = SSL_CIPHER_get_version(c);
+ s = (char *) SSL_get_version(ssl);
if (s == NULL)
s = "UNKNOWN";
macdefine(mac, A_TEMP, macid("{tls_version}"), s);
@@ -1252,9 +1488,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
who, verifyok, (unsigned long) cert);
if (cert != NULL)
{
- unsigned int n;
X509_NAME *subj, *issuer;
- unsigned char md[EVP_MAX_MD_SIZE];
char buf[MAXNAME];
subj = X509_get_subject_name(cert);
@@ -1268,6 +1502,8 @@ tls_get_info(ssl, srv, host, mac, certreq)
# define LL_BADCERT 8
+#define CERTFPMACRO (CertFingerprintAlgorithm != NULL ? "{cert_fp}" : "{cert_md5}")
+
#define CHECK_X509_NAME(which) \
do { \
if (r == -1) \
@@ -1313,24 +1549,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
CHECK_X509_NAME("cn_issuer");
macdefine(mac, A_TEMP, macid("{cn_issuer}"),
xtextify(buf, "<>\")"));
- n = 0;
- if (X509_digest(cert, EVP_md5(), md, &n) != 0 && n > 0)
- {
- char md5h[EVP_MAX_MD_SIZE * 3];
- static const char hexcodes[] = "0123456789ABCDEF";
-
- SM_ASSERT((n * 3) + 2 < sizeof(md5h));
- for (r = 0; r < (int) n; r++)
- {
- md5h[r * 3] = hexcodes[(md[r] & 0xf0) >> 4];
- md5h[(r * 3) + 1] = hexcodes[(md[r] & 0x0f)];
- md5h[(r * 3) + 2] = ':';
- }
- md5h[(n * 3) - 1] = '\0';
- macdefine(mac, A_TEMP, macid("{cert_md5}"), md5h);
- }
- else
- macdefine(mac, A_TEMP, macid("{cert_md5}"), "");
+ (void) cert_fp(cert, EVP_digest, mac, CERTFPMACRO);
}
else
{
@@ -1338,7 +1557,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
macdefine(mac, A_PERM, macid("{cert_issuer}"), "");
macdefine(mac, A_PERM, macid("{cn_subject}"), "");
macdefine(mac, A_PERM, macid("{cn_issuer}"), "");
- macdefine(mac, A_TEMP, macid("{cert_md5}"), "");
+ macdefine(mac, A_TEMP, macid(CERTFPMACRO), "");
}
switch (verifyok)
{
@@ -1633,9 +1852,9 @@ apps_ssl_info_cb(s, where, ret)
** Parameters:
** ok -- verify ok?
** ctx -- x509 context
+** name -- from where is this called?
**
** Returns:
-** 0 -- fatal error
** 1 -- ok
*/
@@ -1643,9 +1862,8 @@ static int
tls_verify_log(ok, ctx, name)
int ok;
X509_STORE_CTX *ctx;
- char *name;
+ const char *name;
{
- SSL *ssl;
X509 *cert;
int reason, depth;
char buf[512];
@@ -1653,17 +1871,6 @@ tls_verify_log(ok, ctx, name)
cert = X509_STORE_CTX_get_current_cert(ctx);
reason = X509_STORE_CTX_get_error(ctx);
depth = X509_STORE_CTX_get_error_depth(ctx);
- ssl = (SSL *) X509_STORE_CTX_get_ex_data(ctx,
- SSL_get_ex_data_X509_STORE_CTX_idx());
-
- if (ssl == NULL)
- {
- /* internal error */
- sm_syslog(LOG_ERR, NOQID,
- "STARTTLS: internal error: tls_verify_cb: ssl == NULL");
- return 0;
- }
-
X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
sm_syslog(LOG_INFO, NOQID,
"STARTTLS: %s cert verify: depth=%d %s, state=%d, reason=%s",
@@ -1729,10 +1936,10 @@ tlslogerr(level, who)
unsigned long es;
char *file, *data;
char buf[256];
-# define CP (const char **)
es = CRYPTO_thread_id();
- while ((l = ERR_get_error_line_data(CP &file, &line, CP &data, &flags))
+ while ((l = ERR_get_error_line_data((const char **) &file, &line,
+ (const char **) &data, &flags))
!= 0)
{
sm_syslog(level, NOQID,
diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c
index f3ddcf2..24d38ee 100644
--- a/contrib/sendmail/src/usersmtp.c
+++ b/contrib/sendmail/src/usersmtp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2006, 2008-2010 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 1998-2006, 2008-2010, 2014 Proofpoint, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -92,6 +92,11 @@ smtpinit(m, mci, e, onlyhelo)
CurHostName = MyHostName;
SmtpNeedIntro = true;
state = mci->mci_state;
+#if _FFR_ERRCODE
+ e->e_rcode = 0;
+ e->e_renhsc[0] = '\0';
+ e->e_text = NULL;
+#endif /* _FFR_ERRCODE */
switch (state)
{
case MCIS_MAIL:
@@ -227,10 +232,7 @@ tryhelo:
*/
if ((UseMSP && Verbose && bitset(MCIF_VERB, mci->mci_flags))
-# if !_FFR_DEPRECATE_MAILER_FLAG_I
- || bitnset(M_INTERNAL, m->m_flags)
-# endif /* !_FFR_DEPRECATE_MAILER_FLAG_I */
- )
+ || bitnset(M_INTERNAL, m->m_flags))
{
/* tell it to be verbose */
smtpmessage("VERB", m, mci);
@@ -768,9 +770,7 @@ readauth(filename, safe, sai, rpool)
pid = -1;
sff = SFF_REGONLY|SFF_SAFEDIRPATH|SFF_NOWLINK
|SFF_NOGWFILES|SFF_NOWWFILES|SFF_NOWRFILES;
-# if _FFR_GROUPREADABLEAUTHINFOFILE
if (!bitnset(DBS_GROUPREADABLEAUTHINFOFILE, DontBlameSendmail))
-# endif /* _FFR_GROUPREADABLEAUTHINFOFILE */
sff |= SFF_NOGRFILES;
if (DontLockReadFiles)
sff |= SFF_NOLOCK;
@@ -2770,7 +2770,10 @@ smtpdata(m, mci, e, ctladdr, xstart)
writeerr:
mci->mci_errno = errno;
mci->mci_state = MCIS_ERROR;
- mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL);
+ mci_setstat(mci, bitset(MCIF_NOTSTICKY, mci->mci_flags)
+ ? EX_NOTSTICKY: EX_TEMPFAIL,
+ "4.4.2", NULL);
+ mci->mci_flags &= ~MCIF_NOTSTICKY;
/*
** If putbody() couldn't finish due to a timeout,
@@ -2782,7 +2785,7 @@ smtpdata(m, mci, e, ctladdr, xstart)
(void) bfrewind(e->e_dfp);
errno = mci->mci_errno;
- syserr("451 4.4.1 timeout writing message to %s", CurHostName);
+ syserr("+451 4.4.1 timeout writing message to %s", CurHostName);
smtpquit(m, mci, e);
return EX_TEMPFAIL;
}
@@ -3085,7 +3088,7 @@ reply(m, mci, e, timeout, pfunc, enhstat, rtype)
*/
bufp = SmtpReplyBuffer;
- set_tls_rd_tmo(timeout);
+ (void) set_tls_rd_tmo(timeout);
for (;;)
{
register char *p;
@@ -3247,6 +3250,48 @@ reply(m, mci, e, timeout, pfunc, enhstat, rtype)
firstline = false;
continue;
}
+#if _FFR_ERRCODE
+# if _FFR_PROXY
+ if ((e->e_rcode == 0 || REPLYTYPE(e->e_rcode) < 5)
+ && REPLYTYPE(r) > 3 && firstline)
+# endif
+# if _FFR_LOGREPLY
+ if (REPLYTYPE(r) > 3 && firstline)
+# endif
+ {
+ int o = -1;
+# if PIPELINING
+ /*
+ ** ignore error iff: DATA, 5xy error, but we had
+ ** "retryable" recipients. XREF: smtpdata()
+ */
+
+ if (!(rtype == XS_DATA && REPLYTYPE(r) == 5 &&
+ mci->mci_okrcpts <= 0 && mci->mci_retryrcpt))
+# endif /* PIPELINING */
+ {
+ o = extenhsc(bufp + 4, ' ', enhstatcode);
+ if (o > 0)
+ {
+ sm_strlcpy(e->e_renhsc, enhstatcode,
+ sizeof(e->e_renhsc));
+
+ /* skip SMTP reply code, delimiters */
+ o += 5;
+ }
+ else
+ o = 4;
+ e->e_rcode = r;
+ e->e_text = sm_rpool_strdup_x(e->e_rpool,
+ bufp + o);
+ }
+ if (tTd(87, 2))
+ {
+ sm_dprintf("user: offset=%d, bufp=%s, rcode=%d, enhstat=%s, text=%s\n",
+ o, bufp, r, e->e_renhsc, e->e_text);
+ }
+ }
+#endif /* _FFR_ERRCODE */
firstline = false;
diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c
index 02e8ec2..9775915 100644
--- a/contrib/sendmail/src/util.c
+++ b/contrib/sendmail/src/util.c
@@ -1833,7 +1833,7 @@ dumpfd(fd, printclosed, logit)
}
(void) sm_snprintf(p, SPACELEFT(buf, p), "mode=%o: ",
- (int) st.st_mode);
+ (unsigned int) st.st_mode);
p += strlen(p);
switch (st.st_mode & S_IFMT)
{
@@ -1936,11 +1936,11 @@ dumpfd(fd, printclosed, logit)
default:
defprint:
(void) sm_snprintf(p, SPACELEFT(buf, p),
- "dev=%d/%d, ino=%llu, nlink=%d, u/gid=%d/%d, ",
- major(st.st_dev), minor(st.st_dev),
+ "dev=%ld/%ld, ino=%llu, nlink=%d, u/gid=%ld/%ld, ",
+ (long) major(st.st_dev), (long) minor(st.st_dev),
(ULONGLONG_T) st.st_ino,
- (int) st.st_nlink, (int) st.st_uid,
- (int) st.st_gid);
+ (int) st.st_nlink, (long) st.st_uid,
+ (long) st.st_gid);
p += strlen(p);
(void) sm_snprintf(p, SPACELEFT(buf, p), "size=%llu",
(ULONGLONG_T) st.st_size);
@@ -2866,3 +2866,139 @@ count_open_connections(hostaddr)
return n;
}
+#if _FFR_XCNCT
+/*
+** XCONNECT -- get X-CONNECT info
+**
+** Parameters:
+** inchannel -- FILE to check
+**
+** Returns:
+** -1 on error
+** 0 if X-CONNECT was not given
+** >0 if X-CONNECT was used successfully (D_XCNCT*)
+*/
+
+int
+xconnect(inchannel)
+ SM_FILE_T *inchannel;
+{
+ int r, i;
+ char *p, *b, delim, inp[MAXINPLINE];
+ SOCKADDR addr;
+ char **pvp;
+ char pvpbuf[PSBUFSIZE];
+ char *peerhostname; /* name of SMTP peer or "localhost" */
+ extern ENVELOPE BlankEnvelope;
+
+#define XCONNECT "X-CONNECT "
+#define XCNNCTLEN (sizeof(XCONNECT) - 1)
+
+ /* Ask the ruleset whether to use x-connect */
+ pvp = NULL;
+ peerhostname = RealHostName;
+ if (peerhostname == NULL)
+ peerhostname = "localhost";
+ r = rscap("x_connect", peerhostname,
+ anynet_ntoa(&RealHostAddr), &BlankEnvelope,
+ &pvp, pvpbuf, sizeof(pvpbuf));
+ if (tTd(75, 8))
+ sm_syslog(LOG_INFO, NOQID, "x-connect: rscap=%d", r);
+ if (r == EX_UNAVAILABLE)
+ return 0;
+ if (r != EX_OK)
+ {
+ /* ruleset error */
+ sm_syslog(LOG_INFO, NOQID, "x-connect: rscap=%d", r);
+ return 0;
+ }
+ if (pvp != NULL && pvp[0] != NULL && (pvp[0][0] & 0377) == CANONNET)
+ {
+ /* $#: no x-connect */
+ if (tTd(75, 7))
+ sm_syslog(LOG_INFO, NOQID, "x-connect: nope");
+ return 0;
+ }
+
+ p = sfgets(inp, sizeof(inp), InChannel, TimeOuts.to_nextcommand, "pre");
+ if (tTd(75, 6))
+ sm_syslog(LOG_INFO, NOQID, "x-connect: input=%s", p);
+ if (p == NULL || strncasecmp(p, XCONNECT, XCNNCTLEN) != 0)
+ return -1;
+ p += XCNNCTLEN;
+ while (isascii(*p) && isspace(*p))
+ p++;
+
+ /* parameters: IPAddress [Hostname[ M]] */
+ b = p;
+ while (*p != '\0' && isascii(*p) &&
+ (isalnum(*p) || *p == '.' || *p== ':'))
+ p++;
+ delim = *p;
+ *p = '\0';
+
+ memset(&addr, '\0', sizeof(addr));
+ addr.sin.sin_addr.s_addr = inet_addr(b);
+ if (addr.sin.sin_addr.s_addr != INADDR_NONE)
+ {
+ addr.sa.sa_family = AF_INET;
+ memcpy(&RealHostAddr, &addr, sizeof(addr));
+ if (tTd(75, 2))
+ sm_syslog(LOG_INFO, NOQID, "x-connect: addr=%s",
+ anynet_ntoa(&RealHostAddr));
+ }
+# if NETINET6
+ else if ((r = inet_pton(AF_INET6, b, &addr.sin6.sin6_addr)) == 1)
+ {
+ addr.sa.sa_family = AF_INET6;
+ memcpy(&RealHostAddr, &addr, sizeof(addr));
+ }
+# endif /* NETINET6 */
+ else
+ return -1;
+
+ /* more parameters? */
+ if (delim != ' ')
+ return D_XCNCT;
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ p++;
+
+ for (b = ++p, i = 0;
+ *p != '\0' && isascii(*p) && (isalnum(*p) || *p == '.' || *p == '-');
+ p++, i++)
+ ;
+ if (i == 0)
+ return D_XCNCT;
+ delim = *p;
+ if (i > MAXNAME)
+ b[MAXNAME] = '\0';
+ else
+ b[i] = '\0';
+ SM_FREE_CLR(RealHostName);
+ RealHostName = newstr(b);
+ if (tTd(75, 2))
+ sm_syslog(LOG_INFO, NOQID, "x-connect: host=%s", b);
+ *p = delim;
+
+ b = p;
+ if (*p != ' ')
+ return D_XCNCT;
+
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ p++;
+
+ if (tTd(75, 4))
+ {
+ char *e;
+
+ e = strpbrk(p, "\r\n");
+ if (e != NULL)
+ *e = '\0';
+ sm_syslog(LOG_INFO, NOQID, "x-connect: rest=%s", p);
+ }
+ if (*p == 'M')
+ return D_XCNCT_M;
+
+ return D_XCNCT;
+}
+#endif /* _FFR_XCNCT */
diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c
index 1476778..7145ce2 100644
--- a/contrib/sendmail/src/version.c
+++ b/contrib/sendmail/src/version.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2014 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 1998-2015 Proofpoint, 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.249 2013-11-27 00:38:50 ca Exp $")
+SM_RCSID("@(#)$Id: version.c,v 8.250 2014-01-27 12:55:16 ca Exp $")
-char Version[] = "8.14.9";
+char Version[] = "8.15.2";
OpenPOWER on IntegriCloud