From 9b62f85118139f435ba3729e634d3f57c1246ad8 Mon Sep 17 00:00:00 2001 From: gshapiro Date: Sat, 11 Jul 2015 03:46:36 +0000 Subject: [PATCH] MFC: Merge sendmail 8.15.2 git-svn-id: svn://svn.freebsd.org/base/stable/8@285374 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- contrib/sendmail/CACerts | 96 ++ contrib/sendmail/FAQ | 6 +- contrib/sendmail/INSTALL | 5 +- contrib/sendmail/KNOWNBUGS | 13 +- contrib/sendmail/PGPKEYS | 180 +++- contrib/sendmail/README | 22 +- contrib/sendmail/RELEASE_NOTES | 165 +++- contrib/sendmail/cf/README | 152 ++- contrib/sendmail/cf/cf/Makefile | 5 + contrib/sendmail/cf/cf/submit.cf | 37 +- contrib/sendmail/cf/cf/submit.mc | 4 +- contrib/sendmail/cf/feature/bcc.m4 | 90 ++ contrib/sendmail/cf/feature/block_bad_helo.m4 | 2 + contrib/sendmail/cf/feature/ldap_routing.m4 | 2 + contrib/sendmail/cf/feature/nopercenthack.m4 | 27 + contrib/sendmail/cf/feature/prefixmod.m4 | 24 + .../cf/feature/tls_session_features.m4 | 16 + contrib/sendmail/cf/hack/xconnect.m4 | 37 + contrib/sendmail/cf/m4/cfhead.m4 | 2 +- contrib/sendmail/cf/m4/proto.m4 | 70 +- contrib/sendmail/cf/m4/version.m4 | 6 +- contrib/sendmail/contrib/AuthRealm.p0 | 44 + contrib/sendmail/doc/op/op.me | 263 +++++- contrib/sendmail/editmap/editmap.c | 7 +- contrib/sendmail/include/sendmail/sendmail.h | 4 +- contrib/sendmail/include/sm/bdb.h | 8 +- contrib/sendmail/include/sm/cdefs.h | 6 +- contrib/sendmail/include/sm/conf.h | 14 + contrib/sendmail/include/sm/errstring.h | 12 +- contrib/sendmail/include/sm/fdset.h | 8 +- .../libmilter/docs/smfi_setsymlist.html | 5 +- contrib/sendmail/libmilter/engine.c | 52 +- contrib/sendmail/libmilter/handler.c | 2 +- contrib/sendmail/libmilter/listener.c | 15 + contrib/sendmail/libmilter/signal.c | 6 +- contrib/sendmail/libmilter/smfi.c | 2 +- contrib/sendmail/libmilter/worker.c | 2 +- contrib/sendmail/libsm/Makefile.m4 | 2 +- contrib/sendmail/libsm/errstring.c | 6 +- contrib/sendmail/libsm/local.h | 3 +- contrib/sendmail/libsm/mbdb.c | 4 +- contrib/sendmail/libsm/path.c | 15 - contrib/sendmail/libsm/refill.c | 3 +- contrib/sendmail/libsm/stdio.c | 2 +- contrib/sendmail/libsm/vfprintf.c | 2 +- contrib/sendmail/libsmdb/smdb.c | 6 +- contrib/sendmail/makemap/makemap.c | 100 +- contrib/sendmail/src/README | 10 +- contrib/sendmail/src/TRACEFLAGS | 6 + contrib/sendmail/src/TUNING | 13 +- contrib/sendmail/src/bf.c | 3 +- contrib/sendmail/src/collect.c | 14 +- contrib/sendmail/src/conf.c | 529 ++++++----- contrib/sendmail/src/daemon.c | 98 +- contrib/sendmail/src/deliver.c | 135 ++- contrib/sendmail/src/envelope.c | 20 +- contrib/sendmail/src/err.c | 122 ++- contrib/sendmail/src/headers.c | 32 +- contrib/sendmail/src/main.c | 67 +- contrib/sendmail/src/map.c | 40 +- contrib/sendmail/src/mci.c | 1 + contrib/sendmail/src/milter.c | 39 +- contrib/sendmail/src/parseaddr.c | 36 +- contrib/sendmail/src/queue.c | 139 +-- contrib/sendmail/src/readcf.c | 868 ++++++++++++++---- contrib/sendmail/src/recipient.c | 70 +- contrib/sendmail/src/savemail.c | 15 +- contrib/sendmail/src/sendmail.8 | 3 + contrib/sendmail/src/sendmail.h | 138 ++- contrib/sendmail/src/sfsasl.c | 22 +- contrib/sendmail/src/sm_resolve.c | 2 +- contrib/sendmail/src/srvrsmtp.c | 430 ++++++++- contrib/sendmail/src/tls.c | 407 ++++++-- contrib/sendmail/src/usersmtp.c | 65 +- contrib/sendmail/src/util.c | 146 ++- contrib/sendmail/src/version.c | 6 +- 76 files changed, 3923 insertions(+), 1107 deletions(-) create mode 100644 contrib/sendmail/cf/feature/bcc.m4 create mode 100644 contrib/sendmail/cf/feature/nopercenthack.m4 create mode 100644 contrib/sendmail/cf/feature/prefixmod.m4 create mode 100644 contrib/sendmail/cf/feature/tls_session_features.m4 create mode 100644 contrib/sendmail/cf/hack/xconnect.m4 create mode 100644 contrib/sendmail/contrib/AuthRealm.p0 delete mode 100644 contrib/sendmail/libsm/path.c diff --git a/contrib/sendmail/CACerts b/contrib/sendmail/CACerts index 618c3dcfe..b5deb36b1 100644 --- a/contrib/sendmail/CACerts +++ b/contrib/sendmail/CACerts @@ -6,6 +6,102 @@ # a certificate signed by one of these CA certificates. # +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 92:91:67:de:e0:ef:2c:e4 + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2015/emailAddress=ca+ca-rsa2015@esmtp.org + Validity + Not Before: Mar 2 19:15:29 2015 GMT + Not After : Mar 1 19:15:29 2018 GMT + Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2015/emailAddress=ca+ca-rsa2015@esmtp.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b9:1a:a1:56:ce:cb:16:af:4f:96:ba:2a:70:31: + 70:d3:86:6c:7a:46:26:47:42:3f:de:49:57:3e:08: + 1e:10:25:bf:06:8f:ca:fd:f4:5e:6a:01:7d:31:4d: + 50:88:18:43:71:66:65:42:9c:90:97:0d:95:f2:14: + ef:d7:5e:77:ef:7d:b5:49:3f:02:bb:83:20:f7:e6: + fc:9a:cd:13:df:60:41:28:8e:39:07:a6:a4:40:98: + 15:1e:46:b6:04:2e:f9:ab:32:d1:8b:fe:52:81:f1: + d2:e1:c3:cf:bf:ab:40:a7:f0:e4:e5:a2:82:37:30: + 8c:10:7d:aa:a8:7c:7e:76:cc:5f:1a:24:d0:8c:94: + f6:f2:7f:4a:be:2f:38:67:c0:06:e6:9e:51:ad:55: + d0:cb:26:71:cf:f4:af:7d:5a:41:81:16:fb:26:ec: + f0:35:01:6e:db:f9:e9:00:d7:d0:89:7b:cf:88:16: + 8b:1c:8f:77:1f:5d:ef:70:04:28:76:c5:1b:c6:23: + 8d:49:6b:f0:b8:21:56:d6:7d:68:6c:be:21:e3:e6: + e3:1d:6f:a5:ea:dc:83:e4:27:b3:6f:5f:1b:3d:33: + a1:d5:d3:f0:73:1a:12:eb:d9:95:00:71:59:16:b4: + e4:60:38:b2:2e:7f:b7:d4:c5:e9:3f:74:e4:48:38: + 29:89 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + B1:69:DB:5E:9B:CE:1A:B4:1D:B2:6A:FC:5A:22:97:B6:24:14:6F:32 + X509v3 Authority Key Identifier: + keyid:B1:69:DB:5E:9B:CE:1A:B4:1D:B2:6A:FC:5A:22:97:B6:24:14:6F:32 + DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=Claus Assmann CA RSA 2015/emailAddress=ca+ca-rsa2015@esmtp.org + serial:92:91:67:DE:E0:EF:2C:E4 + + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Alternative Name: + email:ca+ca-rsa2015@esmtp.org + X509v3 Issuer Alternative Name: + email:ca+ca-rsa2015@esmtp.org + Signature Algorithm: sha1WithRSAEncryption + 0a:ce:07:39:77:08:c5:3a:00:04:e8:a0:3b:f7:d2:4c:79:02: + 23:0b:da:c0:55:39:82:71:0a:0c:83:e2:de:f2:3b:fe:23:bc: + 9b:13:34:d1:29:0a:16:3f:01:7d:9f:fb:4b:aa:12:dc:3b:7e: + b9:27:7b:ec:0c:3f:c0:d9:f5:d8:a8:a1:9c:1c:3a:2f:40:df: + 27:1a:1a:a0:74:00:19:b7:82:0e:f9:45:86:bf:32:da:0e:72: + 0a:4c:2c:39:21:63:c3:1f:61:6e:e2:4d:ba:7a:26:1a:15:ce: + b1:f6:1a:59:04:70:ed:e8:72:05:4c:fc:84:c6:a5:f4:e2:4a: + 40:e4:42:70:87:9a:a7:02:26:3a:47:34:09:e0:7b:88:ca:fb: + 99:d9:9b:bb:0c:52:8a:93:d5:59:30:0b:55:42:b4:bb:d2:b1: + 49:55:81:a4:70:a0:49:19:f2:4f:61:94:af:e9:d7:62:68:65: + 97:67:00:26:b8:9b:b2:2c:d0:2c:83:7d:3e:b3:31:73:b9:55: + 49:53:fa:a3:ad:1b:02:67:08:9e:ce:9e:eb:9f:47:0d:6c:95: + e9:6c:30:92:c1:94:67:ad:d9:e3:b9:61:ea:a9:72:98:81:3a: + 62:80:70:20:9a:3e:c4:1f:6f:bd:b4:00:ec:b1:fe:71:da:91: + 15:89:f7:8f +-----BEGIN CERTIFICATE----- +MIIFJzCCBA+gAwIBAgIJAJKRZ97g7yzkMA0GCSqGSIb3DQEBBQUAMIGlMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkx +FDASBgNVBAoMC0VuZG1haWwgT3JnMQwwCgYDVQQLDANNVEExIjAgBgNVBAMMGUNs +YXVzIEFzc21hbm4gQ0EgUlNBIDIwMTUxJjAkBgkqhkiG9w0BCQEWF2NhK2NhLXJz +YTIwMTVAZXNtdHAub3JnMB4XDTE1MDMwMjE5MTUyOVoXDTE4MDMwMTE5MTUyOVow +gaUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhC +ZXJrZWxleTEUMBIGA1UECgwLRW5kbWFpbCBPcmcxDDAKBgNVBAsMA01UQTEiMCAG +A1UEAwwZQ2xhdXMgQXNzbWFubiBDQSBSU0EgMjAxNTEmMCQGCSqGSIb3DQEJARYX +Y2ErY2EtcnNhMjAxNUBlc210cC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC5GqFWzssWr0+WuipwMXDThmx6RiZHQj/eSVc+CB4QJb8Gj8r99F5q +AX0xTVCIGENxZmVCnJCXDZXyFO/XXnfvfbVJPwK7gyD35vyazRPfYEEojjkHpqRA +mBUeRrYELvmrMtGL/lKB8dLhw8+/q0Cn8OTlooI3MIwQfaqofH52zF8aJNCMlPby +f0q+LzhnwAbmnlGtVdDLJnHP9K99WkGBFvsm7PA1AW7b+ekA19CJe8+IFoscj3cf +Xe9wBCh2xRvGI41Ja/C4IVbWfWhsviHj5uMdb6Xq3IPkJ7NvXxs9M6HV0/BzGhLr +2ZUAcVkWtORgOLIuf7fUxek/dORIOCmJAgMBAAGjggFWMIIBUjAdBgNVHQ4EFgQU +sWnbXpvOGrQdsmr8WiKXtiQUbzIwgdoGA1UdIwSB0jCBz4AUsWnbXpvOGrQdsmr8 +WiKXtiQUbzKhgaukgagwgaUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9y +bmlhMREwDwYDVQQHDAhCZXJrZWxleTEUMBIGA1UECgwLRW5kbWFpbCBPcmcxDDAK +BgNVBAsMA01UQTEiMCAGA1UEAwwZQ2xhdXMgQXNzbWFubiBDQSBSU0EgMjAxNTEm +MCQGCSqGSIb3DQEJARYXY2ErY2EtcnNhMjAxNUBlc210cC5vcmeCCQCSkWfe4O8s +5DAMBgNVHRMEBTADAQH/MCIGA1UdEQQbMBmBF2NhK2NhLXJzYTIwMTVAZXNtdHAu +b3JnMCIGA1UdEgQbMBmBF2NhK2NhLXJzYTIwMTVAZXNtdHAub3JnMA0GCSqGSIb3 +DQEBBQUAA4IBAQAKzgc5dwjFOgAE6KA799JMeQIjC9rAVTmCcQoMg+Le8jv+I7yb +EzTRKQoWPwF9n/tLqhLcO365J3vsDD/A2fXYqKGcHDovQN8nGhqgdAAZt4IO+UWG +vzLaDnIKTCw5IWPDH2Fu4k26eiYaFc6x9hpZBHDt6HIFTPyExqX04kpA5EJwh5qn +AiY6RzQJ4HuIyvuZ2Zu7DFKKk9VZMAtVQrS70rFJVYGkcKBJGfJPYZSv6ddiaGWX +ZwAmuJuyLNAsg30+szFzuVVJU/qjrRsCZwiezp7rn0cNbJXpbDCSwZRnrdnjuWHq +qXKYgTpigHAgmj7EH2+9tADssf5x2pEVifeP +-----END CERTIFICATE----- + + Certificate: Data: Version: 3 (0x2) diff --git a/contrib/sendmail/FAQ b/contrib/sendmail/FAQ index 4bab6b4c8..dd7ac046d 100644 --- a/contrib/sendmail/FAQ +++ b/contrib/sendmail/FAQ @@ -1,8 +1,4 @@ The FAQ is no longer maintained with the sendmail release. It is available at http://www.sendmail.org/faq/ . -A plain-text version of the questions only, with URLs referring to -the answers, is posted to comp.mail.sendmail on the 10th and 25th -of each month. - -$Revision: 8.24 $, Last updated $Date: 1999-02-07 03:21:03 $ +$Revision: 8.25 $, Last updated $Date: 2014-01-27 12:49:52 $ diff --git a/contrib/sendmail/INSTALL b/contrib/sendmail/INSTALL index 1f76d77e6..565cc42e0 100644 --- a/contrib/sendmail/INSTALL +++ b/contrib/sendmail/INSTALL @@ -28,8 +28,9 @@ sendmail/SECURITY for more installation information. /etc/mail/submit.cf. This can be done in the cf/cf by using "sh ./Build install-cf". - Please read sendmail/SECURITY before continuing; you have to create a - new user smmsp and a new group smmsp for the default installation. + Please read sendmail/SECURITY before continuing; you may have to create + a new user smmsp and a new group smmsp for the default installation + if you are updating from a really old version. Then install the sendmail binary built in step 3 by cd-ing back to sendmail/ and running "sh ./Build install". diff --git a/contrib/sendmail/KNOWNBUGS b/contrib/sendmail/KNOWNBUGS index fb5e44e2d..de8bd0e15 100644 --- a/contrib/sendmail/KNOWNBUGS +++ b/contrib/sendmail/KNOWNBUGS @@ -62,9 +62,9 @@ This list is not guaranteed to be complete. libmilter and hence the communication fails. This can be avoided by increasing the constant MILTER_CHUNK_SIZE in include/libmilter/mfdef.h and recompiling sendmail, libmilter, and - all (statically linked) milters (or by using an undocumented compile - time option: _FFR_MAXDATASIZE; you have to read the source code in - order to use this properly). + all (statically linked) milters (or by using undocumented compile + time options: _FFR_MAXDATASIZE/_FFR_MDS_NEGOTIATE; you have to + read the source code in order to use these properly). * Sender addresses whose domain part cause a temporary A record lookup failure but have a valid MX record will be temporarily rejected in @@ -102,6 +102,11 @@ Kresolve sequence dnsmx canon Header addresses that have the \231 character (and possibly others in the range \201 - \237) behave in odd and usually unexpected ways. +* AuthRealm for Cyrus SASL may not work as expected. The man page + and the actual usage for sasl_server_new() seem to differ. + Feedback for the "correct" usage is welcome, a patch to match + the description of the man page is in contrib/AuthRealm.p0. + * accept() problem on SVR4. Apparently, the sendmail daemon loop (doing accept()s on the network) @@ -252,7 +257,7 @@ Kresolve sequence dnsmx canon * Race condition for delivery to set-user-ID files - Sendmail will deliver to a fail if the file is owned by the DefaultUser + Sendmail will deliver to a file if the file is owned by the DefaultUser or has the set-user-ID bit set. Unfortunately, some systems clear that bit when a file is modified. Sendmail compensates by resetting the file mode back to it's original settings. Unfortunately, there's still a diff --git a/contrib/sendmail/PGPKEYS b/contrib/sendmail/PGPKEYS index eb77d9cfa..361d3e7b8 100644 --- a/contrib/sendmail/PGPKEYS +++ b/contrib/sendmail/PGPKEYS @@ -141,6 +141,185 @@ gpExpdV7qPrw9k01j5rod5PjZlG8zV0= =SR28 -----END PGP PUBLIC KEY BLOCK----- + +pub 2048R/0xAAF5B5DE05BDCC53 2015-01-02 +fingerprint: 30BC A747 05FA 4154 5573 1D7B AAF5 B5DE 05BD CC53 +uid Sendmail Signing Key/2015 + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQENBFSl4rQBCADRCzgFSJkzyoOHw9/9L/+G3mzA1fWR7TgCE0WxGX7PDzyLDaUS +a4XpCDtadjXyr7c5YPo1T7ybxUH39yvUgEHBiPQDssik+bbpOiHL7V0sUDAYfKSq +YC8/MG42Oj/zd+0WUhnI+RckFYPBNDQ+sZC6ErLDxCYDZMYhG4vhJOGqAKpglNTb +w4Fdx4LNmL3e4t3z4IEtnzAqeGVxIZm8MGGFhKkb8ufpgh8Jiz4Q6cOis0ZD9K6f +LvMPRJXSBy9jBtmS2oI2e9Q5LLhmzd1PVyA8jwAlK0QfJLmlRrgRUfHFKhkf+EuW +tTi592OYCZ9bw7QVSiGVQUK+7VACfM+FQR81ABEBAAG0MVNlbmRtYWlsIFNpZ25p +bmcgS2V5LzIwMTUgPHNlbmRtYWlsQFNlbmRtYWlsLk9SRz6JATgEEwECACIFAlSl +4rQCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEKr1td4FvcxTTPMH/29J +kNmt6EGNo/eLQySB8HTenfJjZaQxwPRhq22kWgr/7WP1BR2411bopyNk4IZ0rcDr +tnyeJj4UWKJljVuXyTDQPtU8uUlgiOT8QiHEbge7MOzxrn0cy6KIOgKq+vtuxa28 +McaxjENR7XVIDFkesQ7P/yLkcCjlE6jaD4r9OIKpqEVMPs1WUFff+rsgTo7mdcgR +QowQOgYqNil5awQ5Y2Gol71hZ6oRcpqMwSd6w4dEEx2U8rF8oqJuoxeUTgNCSv0n +iFtewLznocmxlrxe1mQAeLfRmUAG4LSL6p5wx1lRjJA3gtyWRjY0404jGxkATLG4 +AtK2OkHj8MbrWLP7PKyJARwEEAECAAYFAlSl5AQACgkQYd4R7OJ2OnPHXAf/Y6Rk +rROF45+SgbsEIiDXQBcBOoO1GKe0nFTc1jfAKUHAQ94fqcDxNeFRA9fNIA2d7XNI +0Lw6W7X3RcEkF58xytIe/Y+EXDmOt/BUbpch9KIz6J9pqBhPdyHvG+ZeyA3A+TGT +ZGnnnAxNFtCjt2IID9lzZSLuWhH8+DNC2Vp15NngDTa1VIk17n5iIvi7r3V5cdIE +MblKLGm+ZaiTeccVLjwMKIUSgrLP87+yF/aaZH2kotuI7f3tD1ycN0sVZJxcFS+c +GFw7uvOarDBSm0Q/FgfhDUOJLy4w5SqVmgPEIAeogz94q0JXxSSr1XWQBD8X9XwF +f3+dPXmgMHXLGRWclYkBHAQQAQIABgUCVKXkPAAKCRA9aLJdUgfK08cnB/96BV+v +xyBx35TPg8eI/WIskdQAIpCQsm6FoO1ejbMzfWn9bImCewOp1UMlowdfQC52Hdp8 +EXnuwCpJ3rtnZctRld5dNM/clbZ+r3lr78wX7hqPUajlvxe+TMpyZbJirLn1f5Ba +yoysE4oICfzJivPfixZd7oFVr9EkftbatYenl0rgf/0lJTKRDIqNGezeeyfxaKdX +qd545wqis7PrrXDOrEq815aosG09KQBhIoPgti2us1R95nSm9z6dVCY/nSDOxL+a +Vyq/XD5KSUqbZVocY+fbR3dNX5haTvawuG0GPvl+YvYb2lW4hhi7Q4aUL7Dd4c9c +vk5+WAvfJwHtbxrgiQEcBBABAgAGBQJUpeREAAoJEI5a6fvO7vQ7OWUH/2NNxhlI +JEtvD+Nj2oPGgVQJrlFI1pbzyMCtD+6iy8Lfnp2DK+qKPMjBw96LUqcXC32VFPQr +17iyZDv26MSb/acmdIfTPpPTwJ6zEmMI8mXradeuoiWxeVHSg7n+D3u0xtikmb9Y +uRKv0yx43fcL70bqV5DzyXQte0chfRnOiwMrImWdgDekkmxE9udbtgK24rifNVGa +TBB6eHJAsFVu5Y38hsZLe10bCKyUCqT6Qywfy3RCMpXYeo6fXOk0fKatG2oi3CZp +LI+AnjmAJ0t2oMkrwUxogkK3LkShJT/aJYIR24eZm0GdzwRHZxXKClGFvdJslIea +TKHSXNK41eEIfreJARwEEAECAAYFAlSl5EgACgkQOaTHfal4hLAXfwf+M0YmlHd4 +1sfvckYhOYf99n1BGnfQx5RJn+X+EBjGyOfPKMBPQuZIlwAI20T+cFnR3WmgrmlO +IBG8qVcSDoValzNPcr0V3WGDrT75fYhf5iYj2ZsZDBUqE1VF3dAVUw40x2c1n+98 +7lbq3NtolSPYk07h5rhEhmkjdNcixv/exVCTGVwaT4X9ZHY8heETmF5tsCtPavpr +i/DjcDQQQ0sQ8um1eX41j2bhrN4MERUC5oadvSULaA2QUoWgCrzVG8zx715Au77N +jLtfA31hJI0GP/dpSREaYlqA0nwVDR5tz1TyTNwPN1ylxjQmjKXtJwx3jUtlT9Zh +qxRf+ngYHpWArokBHAQQAQIABgUCVKXkTAAKCRBgTfvyhUEKvl11B/9aYJBEEQZp +JWAT6HPmQK//i2x4y1euQfaHsjqJALvvPrgiTp/ZE3o6dKHhs+SbawsB57RtootN +maQr7x2drvBojWhJJdaouAh345qOfZYb0bD9klkr6W+Mjl5T0xWIKFEyIZn0Tcbr +8ekHgSIx2trL8LduSJou2bdPMh46PORzEpuQQ4IAyV0uRyBdNFOPwTy2OdXs51fr +M7lp1hJp84+y2a6z3vz3VCs2A9LzlnXKZ6bXljpd5dQfrmrSNXltPKA3jVLkWi8+ +rh9f1rAGsj1e6N1aVF2uJ1Y3u+U0XQ/dwa1vDF3y4KVObxYM9eNGbF4J8lGkUy2a +gZ1s1X8QzEDUiJwEEAECAAYFAlSl5FAACgkQEolum6d/JCmUSQP+KEz6xSvPSbFP +Hip4JiX1Wbvd+t3TyL0u9Fv/POwUrFIHVpTkCwOz6jsBH3TdGGiYOP5F8k/US2jU +3WB0J1mK5Rn3GwLhUGNTEeuaJZCuKE+j3qwMFmDqC/2IxEvlWtrIbTqkgf7cRv/O +O7VNv+EL0axtsrOcwZlUWe6Lc4571oaInAQQAQIABgUCVKXkUwAKCRDYqvDK9rMH +KX7xBACUFTBRCmboY/GRTHMZW1DGfcO2vMxwnYKqWomuzi/YonDCWtoTpeMDaAhY +NnIchC1mlYteIE94/+ZsoYsZeaR3fe7CN6h/deBu4tW/dQ+TW1ZPF6EuVhoviKgz +rd3rb+gcS0f0PgSPyg5LGtoMGMD9/gx1NJOTFec83jmBI95Gb4icBBABAgAGBQJU +peRXAAoJEJdDARhwk7hBAUED/0oyeD2Z4wMQ6IQEprOAWbR+vIRzaThemmCGobRw +UlM44nUXqKSM1+naLEVz/JzBuKWG00zTz6Su3NesWoFzDDUGYcIJggbOm39Pc+V8 +eXV86An64/v3P6gypJc+q9P+FFGGO884wFmYN634Mi4SDBVFUzffcghueAFcxtzt +0mH5iJwEEAECAAYFAlSl5FoACgkQHnuzyK+VliVGdwP/fmdK9MdWIzPD/6eYm6JZ +zbksaGWiqpwgp9IEr/OhSmGkXuwUsP35PFJ8FsJbEV5x/y6pP3UNp6EFRN/116ue +jp5vVM7nnj2K3V8f85J4dXCRbv+kek+Ufo1Qzm5kgvRuBxX1sXpxFX6yBM0Y6WuV +gszdbTVNlS04q6bnPFE9L4uInAQQAQIABgUCVKXkXgAKCRBwoCRNHvmSUZ/7A/9W +yQJrrdrs2SuYtoxov/pL/TVMejbnxsF8Y0dRtM/KiquP57PMQSmLqy4fTRzAMHBv +XK1aKfewTVfGKLcHIzfMfv2XcPpWfwcyMeZKtcSr25lWl9GJZP221rCok76XYwqk +BPPp0pjSwdy0Qq4sd3N3ESZmqAMWJ7ouMmlQ7VWReYicBBABAgAGBQJUpeRhAAoJ +EMjV7SmV9hdxLv0EALX3yjI2KDNG1mo5ctCSYlIlhXHQ6csHuUK9lzj9R1gVEzDU +0dEZH0+a5UXh5xf8nyTDLytUe8PxTtPit3AOP6TvTJlANULh/3MKS6317RwUe2e0 +OitWbhQAOYfpYAkSdXZACzPacxrefkxmSM3Pq+SYoumZTI2N6AvVu8MeCS0GiJwE +EAECAAYFAlSl5GQACgkQIYPhsTlvB4mWJgP/XAlvlBityADJkdN+3mp/OtdYzw04 ++dBdNtmLqWUiMZg6rPPHUQi7dfBKi95FFe2U8hxSRk8oLzSzmh/M/CP72mxKh4pi +PbmEkmKHYlNdyfCCNqXdjkBXFAKXAes/4DaBlZwvLjPtrupEaW2eYdU8cSrdeGuv +1PMLRPxRr3nPCb+InAQQAQIABgUCVKXkaAAKCRCJaWK4Z4wKA3ZVA/4iYD+xrYv0 +8I+0GZJRdEL5f7T97a7Vtf5xSxUhHDww4xC9gs8LzEGWZXoNaZEVl4j+63EnCIbY +o4g+c4m81D5NWFqeJWhWpcyvejo9hfGM3ZK/XbiF+ZTzznU5YJclGaZ7t8TY8gcx +GSWxUzxBJQcSEzAKKi286ielMAXocNx10oicBBABAgAGBQJUpeRrAAoJEDgi20fM +N08tDkwD/2F5j5irsDw+MQyLKpfPv3GRJ5J3ebOPpLQkQ5T34+qeIw4LkcXW9OJA +ohW47JLb7R8zwAlUoqmmNXtxTM0r0FlTYGPOVEnSEkMqqa3KR68B3jWAGXXdqig9 +yBxYRleawQ4ltnegBn8q7gC4MwnIAZxzK+Y8cM0Rk/FjC9+NhwrviJwEEAECAAYF +AlSl5G8ACgkQnBy94uNcVjUfvgQAlQijnoE3de1CanB0JqIN+h+XOLOpalFti+B7 +Swc2ZlnlQ9mofYPK5UHlbsiC7/TilD6xm4YEFKim9sOIMi8FNka8+EH+/d1DmS4M +qVPDssxTG6VOzn7tYOuC9qIw15IpfbHW2bk/YIImwP9nViKCMLIGw+ZgK+uiRQx9 +fT8O1NqInAQQAQIABgUCVKXkcgAKCRBvUpPYo5umVYKeA/9n63K1nF3DNY3Hckvz +tN8OrPmyCIOh+7t4sc5NHhTK0+BQTv+cgG6ig7K2cdI6VBAovs/c/u7+RrcMhp7l +45AVnycfKcNaMHKFyMHDk9FZgpRG/bv1zwDxdh+scUc3IekqkSiQ2wTjDQ5Q/BMK +L5zfOSnTOoltWjpVgsjdM75Ol4icBBABAgAGBQJUpeR2AAoJEO9YlmTUMuGd8R0D +/3mhriMu/cp3DXHnlDykqLJI1q5K4xCHOWwFYZ8DxW116AVjluJYYW1HmWcJrjK3 +cwuN3FUcsIjafanIJWCsdeZaPAyFEfUBEW0YXIIpBXRw2N7jNtrd5X6Zjptd+zW+ +4dUzvT1pqVtdPHjova3fcGLSmcdZYbddotaGi7xi7kXviJwEEAECAAYFAlSl5HoA +CgkQwZwdJRLTRh0iwwP/Y/pwp9ttAMuQUz6oH71BTkUrzu9LiI7vhrYxEquFdzCO +dE4jBNB3LGfwzjhJRtjmQ/gVhjXWWrDYnOXt3gNxb9KzmTHmSDu65cBxX54Un0pZ ++MXjjWOT2l8+GA1lXeICIoZjJL88/zEZAiaH67ch2LEix1fOaJmXJzUSmP1pR3KI +nAQQAQIABgUCVKXkfgAKCRDAKcpAFvTM6XVwA/9Eb+Dwn2lmEFFo64gj8ocpWzP8 +/sD86PP5KkZ+b/HQnGB3lsQTwsGytDvJfutLDa05sS/HWZ9wXPltX/G3omp/A1G5 +qEKzVSe0vEWedpf9wn82Ll6hzaiS5qX7r0+FpyUjY8arNrze5S4Q6Q2kjl8YduXl +wG877igRHkGpAtApxYhGBBARAgAGBQJUpeSHAAoJEBj1A4AkwngCRCMAnjHfd5db +KK6DJxrWVnEbyXs/QJGKAJsErKkiUX55B8k/P3cyzyXIaOujBYicBBABAgAGBQJU +peSOAAoJEHxLZ22gDhVjCDQD/j7DE5wyhpjHrtf0hsQcaQoVHWZb2JTLZUMRAQyj +zKMTSs0GslamlxLZmyV1HqkB+41zuJeBQtRV4gjqa5DQmWDRC2mHl7o9A40v4SDa +O1jmfU5hfJSMecucPyEcfaAG4BIMvBo6TL484uHBi45SN4Ik3f2wc6D1XOluD1vB +gIwpiJwEEAECAAYFAlSl5JMACgkQ1uCh/k++Kt2s6gP/RNcMKtx4u61vz+Aji/Fa +H9q03JxQaRgmN1q2AvZQ/NTWTXU7Y5GnH4kW/8rOoUQiR+agJsvTt4ciM+y33pZ/ +ZZLkAuo0uKelEHhdQhtRbSktKBHSgDWbiqaJJIxazeLpxcSgaoM6RW/7aIFdMtEl +ALAzTACYlTN/nKWWICn8GnGIRgQQEQIABgUCVKXkmAAKCRAh+cW892qb9aWOAKCg +aznvUX8PIvKPzoHld39xWlJ+FgCg76wrEc1h9IiIgUoqH5NWVCxcHneInAQQAQIA +BgUCVKXkngAKCRC92o/WP+p9/ancA/0Z4JHZT7NRBMr47zQvSwE4eLpSE5QDGXi7 +RNmOUgZxrxsFWRZLJCVupXDBQVZEhOBRZYqXPw1eDglOU952oj5OjaHsYnSEu7jz +VUwlp2BxZQ3mnepdUcQz1A3k2cPZ0I6KFP9hP88GU+77nubB7IqRH/Q3QKMgO0eW +yd5kYugyYYkBHAQQAQIABgUCVKXkpwAKCRC9J20ub8+ohR46CADMEvAns+L+BkVN +d9INsiR1rONrNRPT6w4dnBeTLaykkuMjc6+7s+UuXm6AMAelI28pG+fJyt/lZAGx +QLS9zFgREge0lVbOZVeAYeC1YyFsrJE4Lr2quq3fajj23tnsHmCv16znMHrh/E1m +Udm4145NprijrZn+PsjuVWYV+pxiLpLM0YBdGNwCEMi/KCQ1fcaiAZZWSqLmHIe0 +ubWDdqq8/5JRQ22SEnqP2FT/lfOmKTxMNmE0uEr4+C4fG2nd38BvzpHu9eN/4Nwx +IwzK5DhbAj+I57+VDncgkNGe1q4QY/5LaZQh/nHIcmX1ln23f9Lxkr6EYYZ1ptq+ +A8buvD+XiQEcBBABAgAGBQJUp+zrAAoJEBCQryClqlvm6AgIAKAR8HY4G9AD2jDb +ouS4Al4QICagwQ0Y7Rc2/fHyPQEAP714EimakPFVFDbSD6SW569Qtdxr+ggH4wFI +bzd21pCgIUC6nVoDotIjplMdYkNfq8AODpxn3HTBnNQ7e609xnWxFo/+httKoWok +fEP9qZk4MJq7lE75iX+wohjLwoF6v0tCB8CrBFJcfKrDvXQSGvKiaEp4g0sEfyXv +gL6X0xKMflupofdnFLJliV0WqGhBOGUghPdLsA02E3e1utj6WABmudMytRxWB8is +SWGaywaEKLSdCgi+XlQVypKeWNMbZZZcftVZ91r4iNTAkw4cv5Wea+YnngfurGCq +J/jUq7aJAiIEEgEKAAwFAlSn7r4FgweGH4AACgkQZhs61tgqu9C9Aw/+JMTXzwni +NPwBxkbcNWbnWODVEElmDloHNpr3z+ryF1XNgbiOY8dn7uwRnPoeCDhIDwvNkK+x +h4xmjH0970v1ltbzcZv0wnK6UeHQssqN9NGsXM9rbodYRIam4yxbwd1ddOC9QZFM +ToRVWiqCzGOVYL50a24OYKClGjm4ncRznXJrNwYMEjxQ3j5FOkXIn0096z3szWCY +6yDpPzOsl2TPwdjMKZWoMEDh/SvY3AxAXo1XqDCj2/+C8dDwO7kn+QAl3fUGmkI6 +dUHCAJm/WtSyvINdphzhZ1ZdkPhqDUKcR0JTX03QJ6bnu5vmmOncWm2NA7rP74fq +KE9XzT808xP0GBwR1co7Eq+/751j2TA33JSlt/hIgi5aEWc4laCingJ02yaW8tUS +DCoVNITaXcF/B47hjBgovQk8TOTsQ0nkSYvOoh05OYBmzl17G57QuPx1stRJ29QA +VLGem1v1mXAuNdHH0kNE+/Rv0A2vGqauLx9ba84RfbXMM4SJw8CjhX6OxhAM8xoU +tO6T56XZS8qLtWLkNQNZNdNlAo6tYk/cTrjdX1M63nYjoVbuc0nic6Wp+dQk/DEb +wsiIpFoisvMK6EH49v70/c9Gtg6rk5z2yBHMZsjo2Y0TheTKwKIUEz0MuTncH8jD +yB/NtQkrbiBdEqRJUoKKUtS0B4cUYTUyd+SJAhwEEAEKAAYFAlSn8agACgkQ8Ar2 +6sJF0gs2yA//cgc+g1wPRFzJeQGv5UFR3TCAMtS+/bzY3UU/eG2Jmbv2qwPbn+kx +RH5dYlZ72VHXEggBaEweCBrBWsweX5dGEMNDLNlI9ArAjjhBAZFFUQKj55EzIZpp +YTbvgxOD2ENKU2HfeQYCGFYZr3L2DXQ1k0U7VnaElBQV3o88CMi7bIsQq2aWk+c6 +Cy15UVr0niVLm95EUZM4yYm2gOGJXUeaGIExSBtiwuzvAiDEGaqfPGAi1ePkNmLJ +3UzYfgiQumSh1kDVlQkCc8UQiF6ckEma618cmmaHs5vZvHsTX5O2/qPkLpXunA/7 +5yM/Jde8a5VbNGWyZ4rmstlWR5rPd7r3uP85miHn7Arait3aGo8RQeAHzOdTvMqS +n3oCotQlOvBhOo7qA8oYQVlU0+77gOfZZeEXDZG13lU95ptFhdsGstIQH67jPQ6z +TpVnd28ip92ysrwvxPhOzO74yKcYoKtzwLctcvptlKTkrFMHP3wJwqbaSfJGK4JE +rjT8WnnWyHY465nTDN9AKkoH4WQNozniWX8OkF3CpPj7ow8roFXlPOxXH4QsaQu3 +Kk31APn/A925d4xyYuWYHZ7A/FzsHafFHPMoG3iwZyuFhfl1UXVvEd8w9mEcxXoh +2iCy87TdpesG0GDzSmWwEYEPkg20BD2+vdc0EekALDjAGM+lfBxN67KIRgQQEQIA +BgUCVKgM0gAKCRAJp6JK0eWCB94UAJ98O6S6r1hFnCLrbU3GeqrA4DCtBQCfcza/ +WoVLc3/+bOf1jzjJ/eJ20IyJAiIEEwEKAAwFAlSoCRMFgweGH4AACgkQhS2G+DXA +JIrWURAAvgl1LkqB9pRPViK1U+xa3b5zt0O/fLbov59aLhA4uPJ10BgaKptflLim +aE2EsS4Mnk0DQgGEBjlywJ5Ft3aMk3vbRz7lDE3zQ3oWa7+N4fcG7WWsAxmh0NtX +Ak7orN6rQcyGgWgpF7wOau79i4VO7oLHKeS7QNs7X59CW+k64TAJabxi74PRoVMz +843qWPjsuFIYM7n/nF0vdECwhSE8zUgcYG2n5CdA0Lq7XRE+II11VOT2XEXFMyR/ +Qh2m7l+jy12MEzHQfGC1HYBo/Zi/MRIN53Rd2LLJWQdMxz/BDiuSxZhKVeCRe7gT +Mc2k3VrmfViBoaUE0zqMbx0j29XUbNQNU3afE8MOBkmyd6AQjoswBEsgU9uyCJYD +Jq3V1stwSVBm9G7X/l8GFlPawLg/uM9gTYb2JYUYPlphTAwVcL469rKQNMhPj2ww +zT7NzjwFb9XrmyiIrqH5z2ieG+LRjajOPVPwBsqZ3gOA+z9QkU1lRYEJOTlEYCkv +8oA6ZeFm31S4JoeogbCDaMiqDszkFtYGBUgGEbnHoCgXi7aINSb17VZ8LTzpD4V9 +vGdFVuE3vJf2POMERP+buLV8OiG38cBJXb+JVSC+pkpm+32nY0UR5ccDPwAC3cGq +SbI6ftKlQeaYp3UEncFUaB8NNZings3jzRexPjzUzo0vhRkkIs2InAQQAQIABgUC +VKg5iQAKCRBfHshviAyeVbEVBACL9Vve0dF0UqO+DN4PzrTOx2JzRw7ujhcrZ6I/ +TCXjANGLWUheylRWhvxMojvbhZEg2835+9l6tpD7BVnrfkBE+LYIKFTusye+WYre +dAaHFpuN6XfmsXmhXaSodhH9gKS+oftYX61qUmiE7L98nvINNBMnFVkptCQVDl8o +GWiMRYhGBBMRAgAGBQJUqBAmAAoJEMSxB5iFeWojCtoAoLa2/SUyfC5EiKdvEbap +49v6XPyxAJ9mPvhe75aTOU7uWoa+c0wn6fXIcrkBDQRUpeK0AQgA7ctg3cJD4eTw +j4sQ94AtSYjwT+Yp7r2s6h4cHUge6AMZy9ixtyg87JnviRFob2zeo2JFDAwtl7Zs +GHo+py/mJwfQKmUsXUmQqgHJFXDiiux+4+dYOXZyVYKP5bTV0JVlKjRjSWNnh7Bv +yZNUZlrLz5ZKF1NAYKJAw4fx3TFbC4K3hvDwHQW3croPQYq0wNq6as956LHYjUOB +Q5K0uy4TXY2EcIyAy253UX9MAFgacuP1jf3ITEVZpcebzl+gcaB54gXqOfmgQQP5 +PmQDyb96ZxFsKa5UfsS3Kh0PeERa5TDlgiw55O55pUSGKKfYfOXvqpJ/ZKYl+ado +wgsmbq09UwARAQABiQEfBBgBAgAJBQJUpeK0AhsMAAoJEKr1td4FvcxTNO0IAJ2b +V48mulcdCS8G3t8qRHlEXGbxgYBQRa500M9fdgRyIWBxubP7r6/nLFDGiIpdUVmT +g9F3r1JsyK6Q7+VUp9XLirj/gT1kwxXT/UHHIQO8ObtPbfFtqISaBjaklTOUPCud ++nOpzRIfct6CZM0xAVIoqm4kaRFaWefxRiyeosDQ7tCD4lDRwxNJE2deE1WmOeN1 +YCJHa8QaewJXtUvqMq6pRmTlzSn+5/w3gV3XVF+CHjGD/COeSm7CGazLmlypN4n8 +ib9eRg0K2rAqKfUbn+aFwmqSBhBcw/UhOoXnteNQvd9KNdKiHERJEI3qZ2rLAlYf +uYT6oSAR9rPSpsZpyTI= +=Jib4 +-----END PGP PUBLIC KEY BLOCK----- + + Type Bits KeyID Created Expires Algorithm Use pub 2048 E2763A73 2014-01-02 ------- RSA Sign & Encrypt fingerprint: 49F6 A8BE 8473 3949 5191 6F3B 61DE 11EC E276 3A73 @@ -2613,4 +2792,3 @@ DnF3FZZEzV7oqPwC2jzv/1dD6GFhtgy0cnyoPGUJCyc= =nES8 -----END PGP PUBLIC KEY BLOCK----- -$Revision: 8.46 $, Last updated $Date: 2014-01-18 00:20:24 $ diff --git a/contrib/sendmail/README b/contrib/sendmail/README index 56f4c59ec..a87989846 100644 --- a/contrib/sendmail/README +++ b/contrib/sendmail/README @@ -211,29 +211,11 @@ There are other files you should read. Rooted in this directory are: +--------------+ There are several related RFCs that you may wish to read -- they are -available via anonymous FTP to several sites. For a list of the -primary repositories see: - - http://www.isi.edu/in-notes/rfc-retrieval.txt - -They are also online at: +available from several sites, see + http://www.rfc-editor.org/ http://www.ietf.org/ -They can also be retrieved via electronic mail by sending -email to one of: - - mail-server@nisc.sri.com - Put "send rfcNNN" in message body - nis-info@nis.nsf.net - Put "send RFCnnn.TXT-1" in message body - sendrfc@jvnc.net - Put "RFCnnn" as Subject: line - -For further instructions see: - - http://www.isi.edu/in-notes/rfc-editor/rfc-info - Important RFCs for electronic mail are: RFC821 SMTP protocol diff --git a/contrib/sendmail/RELEASE_NOTES b/contrib/sendmail/RELEASE_NOTES index f58171263..18a7cae9f 100644 --- a/contrib/sendmail/RELEASE_NOTES +++ b/contrib/sendmail/RELEASE_NOTES @@ -5,6 +5,165 @@ This listing shows the version of the sendmail binary, the version of the sendmail configuration files, the date of release, and a summary of the changes in that release. +8.15.2/8.15.2 2015/07/03 + If FEATURE(`nopercenthack') is used then some bogus input triggered + a recursion which was caught and logged as + SYSERR: rewrite: excessive recursion (max 50) ... + Fix based on patch from Ondrej Holas. + DHParameters now by default uses an included 2048 bit prime. + The value 'none' previously caused a log entry claiming + there was an error "cannot read or set DH parameters". + Also note that this option applies to the server side only. + The U= mailer field didn't accept group names containing hyphens, + underbars, or periods. Based on patch from David Gwynne + of the University of Queensland. + CONFIG: Allow connections from IPv6:0:0:0:0:0:0:0:1 to relay again. + Patch from Lars-Johan Liman of Netnod Internet Exchange. + CONFIG: New option UseCompressedIPv6Addresses to select between + compressed and uncompressed IPv6 addresses. The default + value depends on the compile-time option IPV6_FULL: + For 1 the default is False, for 0 it is True, thus + preserving the current behaviour. Based on patch from + John Beck of Oracle. + CONFIG: Account for IPv6 localhost addresses in + FEATURE(`block_bad_helo'). Suggested by Andrey Chernov + from FreeBSD and Robert Scheck from the Fedora Project. + CONFIG: Account for IPv6 localhost addresses in check_mail ruleset. + LIBMILTER: Deal with more invalid protocol data to avoid potential + crashes. Problem noted by Dimitri Kirchner. + LIBMILTER: Allow a milter to specify an empty macro list ("", not + NULL) in smfi_setsymlist() so no macro is sent for the + selected stage. + MAKEMAP: A change to check TrustedUser in fewer cases which was + made in 2013 caused a potential regression when makemap + was run as root (which should not be done anyway). + Note: sendmail often contains options "For Future Releases" + (prefix _FFR_) which might be enabled in a subsequent + version or might simply be removed as they turned out not + to be really useful. These features are usually not + documented but if they are, then the required (FFR) + options are listed in + - doc/op/op.* for rulesets and macros, + - cf/README for mc/cf options. + +8.15.1/8.15.1 2014/12/06 + SECURITY: Properly set the close-on-exec flag for file descriptors + (except stdin, stdout, and stderr) before executing mailers. + If header rewriting fails due to a temporary map lookup failure, + queue the mail for later retry instead of sending it + without rewriting the header. Note: this is done + while the mail is being sent and hence the transaction + is aborted, which only works for SMTP/LMTP mailers + hence the handling of temporary map failures is + suppressed for other mailers. SMTP/LMTP servers may + complain about aborted transactions when this problem + occurs. + See also "DNS Lookups" in sendmail/TUNING. + Incompatible Change: Use uncompressed IPv6 addresses by default, + i.e., they will not contain "::". For example, + instead of ::1 it will be 0:0:0:0:0:0:0:1. This + permits a zero subnet to have a more specific match, + such as different map entries for IPv6:0:0 vs IPv6:0. + This change requires that configuration data + (including maps, files, classes, custom ruleset, + etc) must use the same format, so make certain such + configuration data is updated before using 8.15. + As a very simple check search for patterns like + 'IPv6:[0-9a-fA-F:]*::' and 'IPv6::'. If necessary, + the prior format can be retained by compiling with: + APPENDDEF(`conf_sendmail_ENVDEF', `-DIPV6_FULL=0') + in your devtools/Site/site.config.m4 file. + If debugging is turned on (-d0.14) also print the OpenSSL + versions, both build time and run time + (provided STARTTLS is compiled in). + If a connection to the MTA is dropped by the client before its + hostname can be validated, treat it as "may be forged", + so that the unvalidated hostname is not passed to a + milter in xxfi_connect(). + Add a timeout for communication with socket map servers + which can be specified using the -d option. + Add a compile time option HESIOD_ALLOW_NUMERIC_LOGIN to allow + numeric logins even if HESIOD is enabled. + The new option CertFingerprintAlgorithm specifies the finger- + print algorithm (digest) to use for the presented cert. + If the option is not set, md5 is used and the macro + {cert_md5} contains the cert fingerprint. + However, if the option is set, the specified algorithm + (e.g., sha1) is used and the macro {cert_fp} contains + the cert fingerprint. + That is, as long as the option is not set, the behaviour + does not change, but otherwise, {cert_md5} is superseded + by {cert_fp} even if you set CertFingerprintAlgorithm + to md5. + The options ServerSSLOptions and ClientSSLOptions can be used + to set SSL options for the server and client side + respectively. See SSL_CTX_set_options(3) for a list. + Note: this change turns on SSL_OP_NO_SSLv2 and + SSL_OP_NO_TICKET for the client. See doc/op/op.me + for details. + The option CipherList sets the list of ciphers for STARTTLS. + See ciphers(1) for possible values. + Do not log "STARTTLS: internal error: tls_verify_cb: ssl == NULL" + if a CRLFfile is in use (and LogLevel is 14 or higher.) + Store a more specific TLS protocol version in ${tls_version} + instead of a generic one, e.g., TLSv1 instead of + TLSv1/SSLv3. + Properly set {client_port} value on little endian machines. + Patch from Kelsey Cummings of Sonic.net. + Per RFC 3848, indicate in the Received: header whether SSL or + SMTP AUTH was negotiated by setting the protocol clause + to ESMTPS, ESMTPA, or ESMTPSA instead of ESMTP. + If the 'C' flag is listed as TLSSrvOptions the requirement for the + TLS server to have a cert is removed. This only works + under very specific circumstances and should only be used + if the consequences are understood, e.g., clients + may not work with a server using this. + The options ClientCertFile, ClientKeyFile, ServerCertFile, and + ServerKeyFile can take a second file name, which must be + separated from the first with a comma (note: do not use + any spaces) to set up a second cert/key pair. This can + be used to have certs of different types, e.g., RSA + and DSA. + A new map type "arpa" is available to reverse an IP (IPv4 or IPv6) + address. It returns the string for the PTR lookup, but + without trailing {ip6,in-addr}.arpa. + New operation mode 'C' just checks the configuration file, e.g., + sendmail -C new.cf -bC + will perform a basic syntax/consistency check of new.cf. + The mailer flag 'I' is deprecated and will be removed in a + future version. + Allow local (not just TCP) socket connections to the server, e.g., + O DaemonPortOptions=Family=local, Addr=/var/mta/server.sock + can be used. + If the new option MaxQueueAge is set to a value greater than zero, + entries in the queue will be retried during a queue run + only if the individual retry time has been reached which + is doubled for each attempt. The maximum retry time is + limited by the specified value. + New DontBlameSendmail option GroupReadableDefaultAuthInfoFile + to relax requirement for DefaultAuthInfo file. + Reset timeout after receiving a message to appropriate value if + STARTTLS is in use. Based on patch by Kelsey Cummings + of Sonic.net. + Report correct error messages from the LDAP library for a range of + small negative return values covering those used by OpenLDAP. + Fix compilation with Berkeley DB 5.0 and 6.0. Patch from + Allan E Johannesen of Worcester Polytechnic Institute. + CONFIG: FEATURE(`nopercenthack') takes one parameter: reject or + nospecial which describes whether to disallow "%" in the + local part of an address. + DEVTOOLS: Fix regression in auto-detection of libraries when only + shared libraries are available. Problem reported by + Bryan Costales. + LIBMILTER: Mark communication socket as close-on-exec in case + a user's filter starts other applications. + Based on patch from Paul Howarth. + Portability: + SunOS 5.12 has changed the API for sigwait(2) to conform + with XPG7. Based on patch from Roger Faulkner of Oracle. + Deleted Files: + libsm/path.c + 8.14.9/8.14.9 2014/05/21 SECURITY: Properly set the close-on-exec flag for file descriptors (except stdin, stdout, and stderr) before executing mailers. @@ -681,7 +840,7 @@ summary of the changes in that release. LIBMILTER: The "hostname" argument of the xxfi_connect() callback previously was the equivalent of {client_ptr}. However, this did not match the documentation of the function, hence - it has been changed to {client_name}. See doc/op/op.* + it has been changed to {client_name}. See doc/op/op.me about these macros. 8.13.7/8.13.7 2006/06/14 @@ -3509,11 +3668,11 @@ summary of the changes in that release. Add new STARTTLS related options CACERTPath, CACERTFile, ClientCertFile, ClientKeyFile, DHParameters, RandFile, ServerCertFile, and ServerKeyFile. These are documented in - cf/README and doc/op/op.*. + cf/README and doc/op/op.me. New STARTTLS related macros: ${cert_issuer}, ${cert_subject}, ${tls_version}, ${cipher}, ${cipher_bits}, ${verify}, ${server_name}, and ${server_addr}. These are documented - in cf/README and doc/op/op.*. + in cf/README and doc/op/op.me. Add support for the Entropy Gathering Daemon (EGD) for better random data. New DontBlameSendmail option InsufficientEntropy for systems which diff --git a/contrib/sendmail/cf/README b/contrib/sendmail/cf/README index b26c99c6a..91e69a918 100644 --- a/contrib/sendmail/cf/README +++ b/contrib/sendmail/cf/README @@ -158,6 +158,26 @@ FEATURE(`local_procmail'). ******************************************************************* +Note: +Some rulesets, features, and options are only useful if the sendmail +binary has been compiled with the appropriate options, e.g., the +ruleset tls_server is only invoked if sendmail has been compiled +with STARTTLS. This is usually obvious from the context and hence +not further specified here. +There are also so called "For Future Releases" (FFR) compile time +options which might be included in a subsequent version or might +simply be removed as they turned out not to be really useful. +These are generally not documented but if they are, then the required +compile time options are listed in doc/op/op.* for rulesets and +macros, and for mc/cf specific options they are usually listed here. +In addition to compile time options for the sendmail binary, there +can also be FFRs for mc/cf which in general can be enabled when the +configuration file is generated by defining them at the top of your +.mc file: + +define(`_FFR_NAME_HERE', 1) + + +----------------------------+ | A BRIEF INTRODUCTION TO M4 | +----------------------------+ @@ -397,6 +417,10 @@ SMTP_MAILER_CHARSET [undefined] If defined, messages containing 8-bit data that ARRIVE from an address that resolves to one of the SMTP mailers and which are converted to MIME will be labeled with this character set. +RELAY_MAILER_CHARSET [undefined] If defined, messages containing 8-bit data + that ARRIVE from an address that resolves to the + relay mailers and which are converted to MIME will + be labeled with this character set. SMTP_MAILER_LL [990] The maximum line length for SMTP mailers (except the relay mailer). RELAY_MAILER_LL [2040] The maximum line length for the relay mailer. @@ -743,6 +767,16 @@ nouucp Don't route UUCP addresses. This feature takes one 2. don't remove "!" from OperatorChars if `reject' is given as parameter. +nopercenthack Don't treat % as routing character. This feature takes one + parameter: + `reject': reject addresses which have % in the local + part unless it originates from a system + that is allowed to relay. + `nospecial': don't do anything special with %. + Warnings: 1. See the notice in the anti-spam section. + 2. Don't remove % from OperatorChars if `reject' is + given as parameter. + nocanonify Don't pass addresses to $[ ... $] for canonification by default, i.e., host/domain names are considered canonical, except for unqualified names, which must not be used in this @@ -1441,7 +1475,7 @@ msp Defines config file for Message Submission Program. by default. If you have a machine with IPv6 only, change it to - FEATURE(`msp', `[IPv6:::1]') + FEATURE(`msp', `[IPv6:0:0:0:0:0:0:0:1]') If you want to continue using '[localhost]', (the behavior up to 8.12.6), use @@ -1499,8 +1533,12 @@ block_bad_helo Reject messages from SMTP clients which provide a HELO/EHLO - connections from IP addresses in class $={R}. Currently access_db lookups can not be used to (selectively) disable this test, moreover, + FEATURE(`delay_checks') - is required. + + is required. Note, the block_bad_helo feature automatically + adds the IPv6 and IPv4 localhost IP addresses to $={w} (local + host names) and $={R} (relay permitted). require_rdns Reject mail from connecting SMTP clients without proper rDNS (reverse DNS), functional gethostbyaddr() resolution. @@ -2442,17 +2480,19 @@ should only be used for sites which have no control over the addresses that they provide a gateway for. Use this FEATURE with caution as it can allow spammers to relay through your server if not setup properly. -NOTICE: It is possible to relay mail through a system which the anti-relay -rules do not prevent: the case of a system that does use FEATURE(`nouucp', -`nospecial') (system A) and relays local messages to a mail hub (e.g., via -LOCAL_RELAY or LUSER_RELAY) (system B). If system B doesn't use -FEATURE(`nouucp') at all, addresses of the form - would be relayed to . -System A doesn't recognize `!' as an address separator and therefore -forwards it to the mail hub which in turns relays it because it came from -a trusted local host. So if a mailserver allows UUCP (bang-format) -addresses, all systems from which it allows relaying should do the same -or reject those addresses. +NOTICE: It is possible to relay mail through a system which the +anti-relay rules do not prevent: the case of a system that does use +FEATURE(`nouucp', `nospecial') / FEATURE(`nopercenthack', `nospecial') +(system A) and relays local messages to a mail hub (e.g., via +LOCAL_RELAY or LUSER_RELAY) (system B). If system B doesn't use the +same feature (nouucp / nopercenthack) at all, addresses of the form + / +would be relayed to . +System A doesn't recognize `!' / `%' as an address separator and +therefore forwards it to the mail hub which in turns relays it +because it came from a trusted local host. So if a mailserver +allows UUCP (bang-format) / %-hack addresses, all systems from which +it allows relaying should do the same or reject those addresses. As of 8.9, sendmail will refuse mail if the MAIL FROM: parameter has an unresolvable domain (i.e., one that DNS, your local name service, @@ -3160,17 +3200,49 @@ TLS_Clt:laptop.example.com PERM+VERIFY:112 TLS_Rcpt:darth@endmail.org ENCR:112+CN:smtp.endmail.org -Disabling STARTTLS And Setting SMTP Server Features ---------------------------------------------------- +TLS Options per Session +----------------------- By default STARTTLS is used whenever possible. However, there are -some broken MTAs that don't properly implement STARTTLS. To be able -to send to (or receive from) those MTAs, the ruleset try_tls -(srv_features) can be used that work together with the access map. -Entries for the access map must be tagged with Try_TLS (Srv_Features) -and refer to the hostname or IP address of the connecting system. -A default case can be specified by using just the tag. For example, -the following entries in the access map: +MTAs with STARTTLS interoperability issues. To be able to send to +(or receive from) those MTAs several features are available: + +1) Various TLS options be be set per IP/domain. +2) STARTTLS can be turned off for specific IP addresses/domains. + +About 1): the rulesets tls_srv_features and tls_clt_features can +be used to return a (semicolon separated) list of TLS related +options: + +- Options: compare {Server,Client}SSLOptions. +- CipherList: same as the global option. +- CertFile, KeyFile: {Server,Client}{Cert,Key}File + +If FEATURE(`tls_session_features') is used, then default rulesets +are activated which look up entries in the access map with the tags +TLS_Srv_features and TLS_Clt_features, respectively. +For example, these entries: + + TLS_Srv_features:10.0.2.4 CipherList=MEDIUM+aRSA; + TLS_Clt_features:10.1.0.1 Options=SSL_OP_NO_TLSv1_2; CipherList=ALL:-EXPORT + +specify a cipherlist with MEDIUM strength ciphers that use RSA +certificates only for the client with the IP address 10.0.2.4, +and turn off TLSv1.2 when connecting to the server with the IP +address 10.1.0.1 as well as setting a specific cipherlist. +If FEATURE(`tls_session_features') is not used the user can provide +their own rulesets which must return the appropriate data. +If the rulesets are not defined or do not return a value, the +default TLS options are not modified. +(These rulesets require the sendmail binary to be built with +_FFR_TLS_SE_OPTS enabled.) + +About 2): the ruleset try_tls (srv_features) can be used that work +together with the access map. Entries for the access map must be +tagged with Try_TLS (Srv_Features) and refer to the hostname or IP +address of the connecting system. A default case can be specified +by using just the tag. For example, the following entries in the +access map: Try_TLS:broken.server NO Srv_Features:my.domain v @@ -3756,6 +3828,12 @@ confSINGLE_THREAD_DELIVERY SingleThreadDelivery cached but otherwise idle connection to a host will prevent other sendmails from connecting to the other host. +confUSE_COMPRESSED_IPV6_ADDRESSES + UseCompressedIPv6Addresses + [undefined] If set, use the compressed + form of IPv6 addresses, such as + IPV6:::1, instead of the uncompressed + form, such as IPv6:0:0:0:0:0:0:0:1. confUSE_ERRORS_TO* UseErrorsTo [False] Use the Errors-To: header to deliver error messages. This should not be necessary because of general @@ -3990,6 +4068,13 @@ confWORK_TIME_FACTOR RetryFactor [90000] Cost of each delivery attempt. confQUEUE_SORT_ORDER QueueSortOrder [Priority] Queue sort algorithm: Priority, Host, Filename, Random, Modification, or Time. +confMAX_QUEUE_AGE MaxQueueAge [undefined] If set to a value greater + than zero, entries in the queue + will be retried during a queue run + only if the individual retry time + has been reached which is doubled + for each attempt. The maximum retry + time is limited by the specified value. confMIN_QUEUE_AGE MinQueueAge [0] The minimum amount of time a job must sit in the queue between queue runs. This allows you to set the @@ -4208,7 +4293,7 @@ confAUTH_MECHANISMS AuthMechanisms [GSSAPI KERBEROS_V4 DIGEST-MD5 confAUTH_REALM AuthRealm [undefined] The authentication realm that is passed to the Cyrus SASL library. If no realm is specified, - $j is used. + $j is used. See KNOWNBUGS. confDEF_AUTH_INFO DefaultAuthInfo [undefined] Name of file that contains authentication information for outgoing connections. This file must @@ -4241,6 +4326,14 @@ confTLS_SRV_OPTIONS TLSSrvOptions If this option is 'V' no client verification is performed, i.e., the server doesn't ask for a certificate. +confSERVER_SSL_OPTIONS ServerSSLOptions [undefined] SSL related + options for server side. See + SSL_CTX_set_options(3) for a list. +confCLIENT_SSL_OPTIONS ClientSSLOptions [undefined] SSL related + options for client side. See + SSL_CTX_set_options(3) for a list. +confCIPHER_LIST CipherList [undefined] Cipher list for TLS. + See ciphers(1) for possible values. confLDAP_DEFAULT_SPEC LDAPDefaultSpec [undefined] Default map specification for LDAP maps. The value should only contain LDAP @@ -4250,10 +4343,11 @@ confLDAP_DEFAULT_SPEC LDAPDefaultSpec [undefined] Default map maps unless they are specified in the individual map specification ('K' command). -confCACERT_PATH CACertPath [undefined] Path to directory - with certs of CAs. -confCACERT CACertFile [undefined] File containing one CA - cert. +confCACERT_PATH CACertPath [undefined] Path to directory with + certificates of CAs which must contain + their hashes as filenames or links. +confCACERT CACertFile [undefined] File containing at least + one CA certificate. confSERVER_CERT ServerCertFile [undefined] File containing the cert of the server, i.e., this cert is used when sendmail acts as @@ -4281,6 +4375,10 @@ confRAND_FILE RandFile [undefined] File containing random requires this option if the compile flag HASURANDOM is not set (see sendmail/README). +confCERT_FINGERPRINT_ALGORITHM CertFingerprintAlgorithm + [undefined] The fingerprint algorithm + (digest) to use for the presented + cert. confNICE_QUEUE_RUN NiceQueueRun [undefined] If set, the priority of queue runners is set the given value (nice(3)). diff --git a/contrib/sendmail/cf/cf/Makefile b/contrib/sendmail/cf/cf/Makefile index 00b75a8a0..efec478cb 100644 --- a/contrib/sendmail/cf/cf/Makefile +++ b/contrib/sendmail/cf/cf/Makefile @@ -100,6 +100,7 @@ M4FILES=\ ${CFDIR}/feature/access_db.m4 \ ${CFDIR}/feature/allmasquerade.m4 \ ${CFDIR}/feature/always_add_domain.m4 \ + ${CFDIR}/feature/bcc.m4 \ ${CFDIR}/feature/bestmx_is_local.m4 \ ${CFDIR}/feature/bitdomain.m4 \ ${CFDIR}/feature/blacklist_recipients.m4 \ @@ -118,9 +119,11 @@ M4FILES=\ ${CFDIR}/feature/masquerade_envelope.m4 \ ${CFDIR}/feature/no_default_msa.m4 \ ${CFDIR}/feature/nocanonify.m4 \ + ${CFDIR}/feature/nopercenthack.m4 \ ${CFDIR}/feature/notsticky.m4 \ ${CFDIR}/feature/nouucp.m4 \ ${CFDIR}/feature/nullclient.m4 \ + ${CFDIR}/feature/prefixmod.m4 \ ${CFDIR}/feature/promiscuous_relay.m4 \ ${CFDIR}/feature/redirect.m4 \ ${CFDIR}/feature/ratecontrol.m4 \ @@ -131,12 +134,14 @@ M4FILES=\ ${CFDIR}/feature/relay_mail_from.m4 \ ${CFDIR}/feature/smrsh.m4 \ ${CFDIR}/feature/stickyhost.m4 \ + ${CFDIR}/feature/tls_session_features.m4 \ ${CFDIR}/feature/use_ct_file.m4 \ ${CFDIR}/feature/use_cw_file.m4 \ ${CFDIR}/feature/uucpdomain.m4 \ ${CFDIR}/feature/virtuser_entire_domain.m4 \ ${CFDIR}/feature/virtusertable.m4 \ ${CFDIR}/hack/cssubdomain.m4 \ + ${CFDIR}/hack/xconnect.m4 \ ${CFDIR}/m4/cf.m4 \ ${CFDIR}/m4/cfhead.m4 \ ${CFDIR}/m4/proto.m4 \ diff --git a/contrib/sendmail/cf/cf/submit.cf b/contrib/sendmail/cf/cf/submit.cf index 498b8f9f6..6295d32db 100644 --- a/contrib/sendmail/cf/cf/submit.cf +++ b/contrib/sendmail/cf/cf/submit.cf @@ -16,8 +16,8 @@ ##### ##### SENDMAIL CONFIGURATION FILE ##### -##### built by ca@lab.smi.sendmail.com on Tue May 20 12:12:52 PDT 2014 -##### in /home/ca/sm8.git/sendmail/OpenSource/sendmail-8.14.9/cf/cf +##### built by ca@sandman.dev-lab.sendmail.com on Thu Jul 2 05:24:31 PDT 2015 +##### in /x/ca/smi.git/sendmail/OpenSource/sendmail-8.15.2/cf/cf ##### using ../ as configuration include directory ##### ###################################################################### @@ -114,7 +114,7 @@ D{MTAHost}[127.0.0.1] # Configuration version number -DZ8.14.9/Submit +DZ8.15.2/Submit ############### @@ -202,6 +202,9 @@ O ConnectionCacheTimeout=5m # use Errors-To: header? O UseErrorsTo=False +# use compressed IPv6 address format? +#O UseCompressedIPv6Addresses + # log level O LogLevel=9 @@ -251,6 +254,9 @@ O PrivacyOptions=goaway,noetrn,restrictqrun # minimum time in queue before retry #O MinQueueAge=30m +# maximum time in queue before retry (if > 0; only for exponential delay) +#O MaxQueueAge + # how many jobs can you process in the queue? #O MaxQueueRunSize=0 @@ -501,6 +507,12 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid # SMTP STARTTLS server options #O TLSSrvOptions +# SSL cipherlist +#O CipherList +# server side SSL options +#O ServerSSLOptions +# client side SSL options +#O ClientSSLOptions # Input mail filters #O InputMailFilters @@ -524,6 +536,8 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid #O DHParameters # Random data source (required for systems without /dev/urandom under OpenSSL) #O RandFile +# fingerprint algorithm (digest) to use for the presented cert +#O CertFingerprintAlgorithm # Maximum number of "useless" commands before slowing down #O MaxNOOPCommands=20 @@ -531,6 +545,8 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid # Name to use for EHLO (defaults to $j) #O HeloName + + ############################ # QUEUE GROUP DEFINITIONS # ############################ @@ -645,6 +661,7 @@ R$- . $- :: $+ $@ $>Canonify2 $3 < @ $1.$2 .DECNET > numeric DECnet addr # if we have % signs, take the rightmost one R$* % $* $1 @ $2 First make them all @s. R$* @ $* @ $* $1 % $2 @ $3 Undo all but the last. + R$* @ $* $@ $>Canonify2 $1 < @ $2 > Insert < > and finish # else we must be a local name @@ -781,6 +798,7 @@ R$* $=O $* < @ *LOCAL* > $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ... R$* < @ *LOCAL* > $: $1 + # # Parse1 -- the bottom half of ruleset 0. # @@ -818,6 +836,8 @@ R$* < @$* > $* $#esmtp $@ $2 $: $1 < @ $2 > $3 user@host.domain R$=L $#local $: @ $1 special local names R$+ $#local $: $1 regular local names + + ########################################################################### ### Ruleset 5 -- special rewriting after aliases have been expanded ### ########################################################################### @@ -1027,6 +1047,10 @@ R$* $| $* $: $2 R<@> < $* @ localhost > $: < ? $&{client_name} > < $1 @ localhost > R<@> < $* @ [127.0.0.1] > $: < ? $&{client_name} > < $1 @ [127.0.0.1] > +R<@> < $* @ [IPv6:0:0:0:0:0:0:0:1] > + $: < ? $&{client_name} > < $1 @ [IPv6:0:0:0:0:0:0:0:1] > +R<@> < $* @ [IPv6:::1] > + $: < ? $&{client_name} > < $1 @ [IPv6:::1] > R<@> < $* @ localhost.$m > $: < ? $&{client_name} > < $1 @ localhost.$m > R<@> < $* @ localhost.UUCP > @@ -1141,6 +1165,7 @@ R$* $: $&{client_addr} R$@ $@ RELAY originated locally R0 $@ RELAY originated locally R127.0.0.1 $@ RELAY originated locally +RIPv6:0:0:0:0:0:0:0:1 $@ RELAY originated locally RIPv6:::1 $@ RELAY originated locally R$=R $* $@ RELAY relayable IP address R$* $: [ $1 ] put brackets around it... @@ -1245,6 +1270,8 @@ STLS_connection RSOFTWARE $#error $@ 4.7.0 $: "403 TLS handshake." + + ###################################################################### ### RelayTLS: allow relaying based on TLS authentication ### @@ -1442,7 +1469,7 @@ Mrelay, P=[IPC], F=mDFMuXa8k, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L= ### submit.mc ### # divert(-1) # # -# # 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 @@ -1464,5 +1491,5 @@ Mrelay, P=[IPC], F=mDFMuXa8k, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L= # define(`confTIME_ZONE', `USE_TZ')dnl # define(`confDONT_INIT_GROUPS', `True')dnl # dnl -# dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:::1] +# dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:0:0:0:0:0:0:0:1] # FEATURE(`msp', `[127.0.0.1]')dnl diff --git a/contrib/sendmail/cf/cf/submit.mc b/contrib/sendmail/cf/cf/submit.mc index 580f4ff46..fc3cceec6 100644 --- a/contrib/sendmail/cf/cf/submit.mc +++ b/contrib/sendmail/cf/cf/submit.mc @@ -1,6 +1,6 @@ divert(-1) # -# 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 @@ -22,5 +22,5 @@ define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet define(`confTIME_ZONE', `USE_TZ')dnl define(`confDONT_INIT_GROUPS', `True')dnl dnl -dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:::1] +dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:0:0:0:0:0:0:0:1] FEATURE(`msp', `[127.0.0.1]')dnl diff --git a/contrib/sendmail/cf/feature/bcc.m4 b/contrib/sendmail/cf/feature/bcc.m4 new file mode 100644 index 000000000..9454143f2 --- /dev/null +++ b/contrib/sendmail/cf/feature/bcc.m4 @@ -0,0 +1,90 @@ +divert(-1) +# +# Copyright (c) 2014 Proofpoint, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(-1) +# Arguments: +# 1: Map to use +# - empty/none: default map bcctable +# - `access': to use access_db (with bcc: as tag) +# - map definition +# The map contains domain names and the RHS should be simply "ok". +# If the access map is used, then its lookup algorithm is used. +# Otherwise: +# domain ok +# matches anything@domain +# .domain ok +# matches any subdomain, e.g., l@sub.domain and l@sub.dom.domain +# On a match, the original address will be used as bcc address unless +# argument 3 is set. +# 2: Name of host ([mailer:]host) +# 3: Default bcc address: if set, this will be always used. +# Only one of 2/3 can be empty. +# Note: if Bcc address is used then only one copy will be sent! +# (due to duplicate elimination) +# 4: Map definition for canonicalRcpt map of address rewriting to +# apply to the added bcc envelope recipients. +# The option -T is required to handle temporary map failures. +# +# The ruleset must return either +# - an e-mail address (user@dom.ain) which is then added as "bcc" recipient. +# - an empty string: do not add a "bcc" recipient, or +# - $#error: fail the SMTP transaction (e.g., temporary lookup failure) +# +# This feature sets O AddBcc=true + +ifelse(lower(_ARG_),`access',`define(`_BCC_ACCESS_', `1')') +define(`_ADD_BCC_', `1') + +ifdef(`_BCC_ACCESS_', `dnl +ifdef(`_ACCESS_TABLE_', `', + `errprint(`*** ERROR: FEATURE(`bcc') requires FEATURE(`access_db') +')')') + +ifdef(`_BCC_ACCESS_', `', ` +LOCAL_CONFIG +Kbcctable ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`bcctable', `_ARG_')') + +LOCAL_CONFIG +O AddBcc=true +ifelse(len(X`'_ARG2_),`1', `', ` +DA`'_ARG2_') + +ifelse(len(X`'_ARG4_), `1', `', +`define(`_CANONIFY_BCC_', `1')dnl +define(`_NEED_SMTPOPMODES_', `1')dnl +# canonical address look up for AddBcc recipients +KcanonicalRcpt _ARG4_ +')dnl + +LOCAL_RULESETS +Sbcc +R< $+ > $1 +ifdef(`_BCC_ACCESS_', `dnl +R$+ @ $+ $: $1@$2 $| $>SearchList $| <>', +`R$+ @ $+ $: $1@$2 $| $>BCC $2') +R$* $| $@ +R$* $| $* $: ifelse(len(X`'_ARG3_),`1', `$1', `_ARG3_') + +ifdef(`_CANONIFY_BCC_', `dnl +R$+ @ $+ $: $1@$2 $| <$(canonicalRcpt $1 @ $2 $: $)> +R$* $| <> $@ +R$* $| <$* > $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later." +R$* $| <$+> $@ $2 map matched? +') + + +ifdef(`_BCC_ACCESS_', `', ` +SBCC +R$+ $: $1 < $(bcctable $1 $: ? $) > +R$- . $+ $: $2 < $(bcctable .$2 $: ? $) > +R$- . $+ $: $>BCC $2 +R$* <$*> $: <$2> +') diff --git a/contrib/sendmail/cf/feature/block_bad_helo.m4 b/contrib/sendmail/cf/feature/block_bad_helo.m4 index e720be129..c6cf54d05 100644 --- a/contrib/sendmail/cf/feature/block_bad_helo.m4 +++ b/contrib/sendmail/cf/feature/block_bad_helo.m4 @@ -15,4 +15,6 @@ divert(-1) define(`_BLOCK_BAD_HELO_', `')dnl RELAY_DOMAIN(`127.0.0.1')dnl +RELAY_DOMAIN(`IPv6:0:0:0:0:0:0:0:1 IPv6:::1')dnl LOCAL_DOMAIN(`[127.0.0.1]')dnl +LOCAL_DOMAIN(`[IPv6:0:0:0:0:0:0:0:1] [IPv6:::1]')dnl diff --git a/contrib/sendmail/cf/feature/ldap_routing.m4 b/contrib/sendmail/cf/feature/ldap_routing.m4 index 9310600f1..0d8ccb973 100644 --- a/contrib/sendmail/cf/feature/ldap_routing.m4 +++ b/contrib/sendmail/cf/feature/ldap_routing.m4 @@ -35,6 +35,8 @@ ifelse(len(X`'_ARG6_), `1', `define(`_LDAP_ROUTE_MAPTEMP_', `_QUEUE_')', _ARG6_, `tempfail', `define(`_LDAP_ROUTE_MAPTEMP_', `_TEMPFAIL_')', _ARG6_, `queue', `define(`_LDAP_ROUTE_MAPTEMP_', `_QUEUE_')') +define(`_NEED_SMTPOPMODES_', `1') + LOCAL_CONFIG # LDAP routing maps Kldapmh ifelse(len(X`'_ARG1_), `1', diff --git a/contrib/sendmail/cf/feature/nopercenthack.m4 b/contrib/sendmail/cf/feature/nopercenthack.m4 new file mode 100644 index 000000000..f6c9621c9 --- /dev/null +++ b/contrib/sendmail/cf/feature/nopercenthack.m4 @@ -0,0 +1,27 @@ +divert(-1) +# +# Copyright (c) 1998, 1999 Proofpoint, Inc. and its suppliers. +# All rights reserved. +# Copyright (c) 1983 Eric P. Allman. All rights reserved. +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +VERSIONID(`$Id: nopercenthack.m4,v 8.14 2013/01/31 15:07:00 ca Exp $') +divert(-1) + +ifelse(defn(`_ARG_'), `', + `errprint(`*** ERROR: missing argument for FEATURE(nopercenthack): + use `reject' or `nospecial'. See cf/README. +')define(`_NO_PERCENTHACK_', `e')', + substr(_ARG_,0,1), `r', `define(`_NO_PERCENTHACK_', `r')', + substr(_ARG_,0,1), `n', `define(`_NO_PERCENTHACK_', `n')', + `errprint(`*** ERROR: illegal argument _ARG_ for FEATURE(nopercenthack) +') + ') diff --git a/contrib/sendmail/cf/feature/prefixmod.m4 b/contrib/sendmail/cf/feature/prefixmod.m4 new file mode 100644 index 000000000..abafe18da --- /dev/null +++ b/contrib/sendmail/cf/feature/prefixmod.m4 @@ -0,0 +1,24 @@ +divert(-1) +# +# Copyright (c) 2014 Proofpoint, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(-1) +# Arguments: +# 1: prefix to match; must be one or more tokens +# (this is not a "substring" match) +# 2: flags to set +# NYI: 3: replacement for 1 (empty for now) + +ifelse(defn(`_ARG_'), `', `errprint(`Feature "prefixmod" requires argument')', + `define(`_PREFIX_MOD_', _ARG_)') +ifelse(len(X`'_ARG2_),`1', `errprint(`Feature "prefixmod" requires two arguments')', + `define(`_PREFIX_FLAGS_', _ARG2_)') + +define(`_NEED_MACRO_MAP_', `1') diff --git a/contrib/sendmail/cf/feature/tls_session_features.m4 b/contrib/sendmail/cf/feature/tls_session_features.m4 new file mode 100644 index 000000000..b45fb3613 --- /dev/null +++ b/contrib/sendmail/cf/feature/tls_session_features.m4 @@ -0,0 +1,16 @@ +divert(-1) +# +# Copyright (c) 2015 Proofpoint, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +VERSIONID(`$Id: tls_session_features.m4,v 8.1 2015-02-25 20:51:11 ca Exp $') +divert(-1) + +define(`_TLS_SESSION_FEATURES_', 1) diff --git a/contrib/sendmail/cf/hack/xconnect.m4 b/contrib/sendmail/cf/hack/xconnect.m4 new file mode 100644 index 000000000..72fba31d7 --- /dev/null +++ b/contrib/sendmail/cf/hack/xconnect.m4 @@ -0,0 +1,37 @@ +divert(-1) +# +# Copyright (c) 1998-2011 Proofpoint, Inc. and its suppliers. +# All rights reserved. +# Copyright (c) 1983 Eric P. Allman. All rights reserved. +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# + +divert(0) +VERSIONID(`$Id: xconnect.m4,v 1.3 2013-11-22 20:51:13 ca Exp $') +divert(-1) + +ifdef(`_ACCESS_TABLE_', `dnl +LOCAL_RULESETS +# +# x_connect ruleset for looking up XConnect: tag in access DB to enable +# XCONNECT support in MTA +# +Sx_connect +dnl workspace: {client_name} $| {client_addr} +R$+ $| $+ $: $>D < $1 > < $2 > +dnl workspace: <{client_addr}> +dnl OR $| $+ if client_name is empty +R $| $+ $: $>A < $1 > <> empty client_name +dnl workspace: <{client_addr}> +R <$+> $: $>A < $1 > <> no: another lookup +dnl workspace: (<>|<{client_addr}>) +R <$*> $# no found nothing +dnl workspace: (<>|<{client_addr}>) | OK +R<$+> <$*> $@ yes found in access DB', + `errprint(`*** ERROR: HACK(xconnect) requires FEATURE(access_db) +')') diff --git a/contrib/sendmail/cf/m4/cfhead.m4 b/contrib/sendmail/cf/m4/cfhead.m4 index a244b9ab3..0931d6e37 100644 --- a/contrib/sendmail/cf/m4/cfhead.m4 +++ b/contrib/sendmail/cf/m4/cfhead.m4 @@ -17,7 +17,7 @@ ##### ##### SENDMAIL CONFIGURATION FILE ##### -ifdef(`__win32__', `dnl', `dnl +ifdef(`_NO_MAKEINFO_', `dnl', `dnl ifdef(`TEMPFILE', `dnl', `define(`TEMPFILE', maketemp(/tmp/cfXXXXXX))dnl syscmd(sh _CF_DIR_`'sh/makeinfo.sh _CF_DIR_ > TEMPFILE)dnl include(TEMPFILE)dnl diff --git a/contrib/sendmail/cf/m4/proto.m4 b/contrib/sendmail/cf/m4/proto.m4 index 4089bf6a0..696bf36a5 100644 --- a/contrib/sendmail/cf/m4/proto.m4 +++ b/contrib/sendmail/cf/m4/proto.m4 @@ -149,7 +149,7 @@ DL`'LUSER_RELAY', `dnl') # operators that cannot be in local usernames (i.e., network indicators) -CO @ % ifdef(`_NO_UUCP_', `', `!') +CO @ ifdef(`_NO_PERCENTHACK_', `', `%') ifdef(`_NO_UUCP_', `', `!') # a class with just dot (for identifying canonical names) C.. @@ -326,6 +326,9 @@ _OPTION(SingleThreadDelivery, `confSINGLE_THREAD_DELIVERY', `False') # use Errors-To: header? _OPTION(UseErrorsTo, `confUSE_ERRORS_TO', `False') +# use compressed IPv6 address format? +_OPTION(UseCompressedIPv6Addresses, `confUSE_COMPRESSED_IPV6_ADDRESSES', `') + # log level _OPTION(LogLevel, `confLOG_LEVEL', `10') @@ -387,6 +390,9 @@ _OPTION(QueueSortOrder, `confQUEUE_SORT_ORDER', `priority') # minimum time in queue before retry _OPTION(MinQueueAge, `confMIN_QUEUE_AGE', `30m') +# maximum time in queue before retry (if > 0; only for exponential delay) +_OPTION(MaxQueueAge, `confMAX_QUEUE_AGE', `') + # how many jobs can you process in the queue? _OPTION(MaxQueueRunSize, `confMAX_QUEUE_RUN_SIZE', `0') @@ -641,6 +647,12 @@ _OPTION(AuthMaxBits, `confAUTH_MAX_BITS', `') # SMTP STARTTLS server options _OPTION(TLSSrvOptions, `confTLS_SRV_OPTIONS', `') +# SSL cipherlist +_OPTION(CipherList, `confCIPHER_LIST', `') +# server side SSL options +_OPTION(ServerSSLOptions, `confSERVER_SSL_OPTIONS', `') +# client side SSL options +_OPTION(ClientSSLOptions, `confCLIENT_SSL_OPTIONS', `') # Input mail filters _OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `') @@ -674,6 +686,8 @@ _OPTION(CRLFile, `confCRL', `') _OPTION(DHParameters, `confDH_PARAMETERS', `') # Random data source (required for systems without /dev/urandom under OpenSSL) _OPTION(RandFile, `confRAND_FILE', `') +# fingerprint algorithm (digest) to use for the presented cert +_OPTION(CertFingerprintAlgorithm, `confCERT_FINGERPRINT_ALGORITHM', `') # Maximum number of "useless" commands before slowing down _OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20') @@ -681,6 +695,10 @@ _OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20') # Name to use for EHLO (defaults to $j) _OPTION(HeloName, `confHELO_NAME') +ifdef(`_NEED_SMTPOPMODES_', `dnl +# SMTP operation modes +C{SMTPOpModes} s d D') + ############################ `# QUEUE GROUP DEFINITIONS #' ############################ @@ -808,9 +826,11 @@ R$- :: $+ $@ $>Canonify2 $2 < @ $1 .DECNET > resolve DECnet names R$- . $- :: $+ $@ $>Canonify2 $3 < @ $1.$2 .DECNET > numeric DECnet addr ', `dnl') -# if we have % signs, take the rightmost one +ifdef(`_NO_PERCENTHACK_', `dnl', +`# if we have % signs, take the rightmost one R$* % $* $1 @ $2 First make them all @s. R$* @ $* @ $* $1 % $2 @ $3 Undo all but the last. +') R$* @ $* $@ $>Canonify2 $1 < @ $2 > Insert < > and finish # else we must be a local name @@ -1036,6 +1056,13 @@ R$* $=O $* < @ *LOCAL* > $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ... R$* < @ *LOCAL* > $: $1 +ifdef(`_ADD_BCC_', `dnl +R$+ $: $>ParseBcc $1', `dnl') +ifdef(`_PREFIX_MOD_', `dnl +dnl do this only for addr_type=e r? +R _PREFIX_MOD_ $+ $: $1 $(macro {rcpt_flags} $@ _PREFIX_FLAGS_ $) +')dnl + # # Parse1 -- the bottom half of ruleset 0. # @@ -1198,6 +1225,13 @@ ifdef(`_MAILER_smtp_', R$=L $#_LOCAL_ $: @ $1 special local names R$+ $#_LOCAL_ $: $1 regular local names +ifdef(`_ADD_BCC_', `dnl +SParseBcc +R$+ $: $&{addr_type} $| $&A $| $1 +Re b $| $+ $| $+ $>MailerToTriple < $1 > $2 copy? +R$* $| $* $| $+ $@ $3 no copy +') + ########################################################################### ### Ruleset 5 -- special rewriting after aliases have been expanded ### ########################################################################### @@ -1457,9 +1491,6 @@ ifdef(`_LDAP_ROUTING_', `dnl ### Parsed address (user < @ domain . >) ###################################################################### -# SMTP operation modes -C{SMTPOpModes} s d D - SLDAPExpand # do the LDAP lookups R<$+><$+><$*> $: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3> @@ -1861,6 +1892,10 @@ R$* $| $* $: $2 R<@> < $* @ localhost > $: < ? $&{client_name} > < $1 @ localhost > R<@> < $* @ [127.0.0.1] > $: < ? $&{client_name} > < $1 @ [127.0.0.1] > +R<@> < $* @ [IPv6:0:0:0:0:0:0:0:1] > + $: < ? $&{client_name} > < $1 @ [IPv6:0:0:0:0:0:0:0:1] > +R<@> < $* @ [IPv6:::1] > + $: < ? $&{client_name} > < $1 @ [IPv6:::1] > R<@> < $* @ localhost.$m > $: < ? $&{client_name} > < $1 @ localhost.$m > ifdef(`_NO_UUCP_', `dnl', @@ -2137,6 +2172,9 @@ dnl workspace: localpart<@domain> | localpart ifelse(defn(`_NO_UUCP_'), `r', `R$* ! $* < @ $* > $: $2 < @ BANG_PATH > R$* ! $* $: $2 < @ BANG_PATH >', `dnl') +ifelse(defn(`_NO_PERCENTHACK_'), `r', +`R$* % $* < @ $* > $: $1 < @ PERCENT_HACK > +R$* % $* $: $1 < @ PERCENT_HACK >', `dnl') # anything terminating locally is ok ifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl R$+ < @ $* $=m > $@ RELAY', `dnl') @@ -2217,6 +2255,8 @@ R$* $: $&{client_addr} R$@ $@ RELAY originated locally R0 $@ RELAY originated locally R127.0.0.1 $@ RELAY originated locally +RIPv6:0:0:0:0:0:0:0:1 $@ RELAY originated locally +dnl if compiled with IPV6_FULL=0 RIPv6:::1 $@ RELAY originated locally R$=R $* $@ RELAY relayable IP address ifdef(`_ACCESS_TABLE_', `dnl @@ -2889,6 +2929,26 @@ R$-:$-:$- $: $2 dnl endif _ACCESS_TABLE_ divert(0) +ifdef(`_TLS_SESSION_FEATURES_', `dnl +Stls_srv_features +ifdef(`_ACCESS_TABLE_', `dnl +R$* $| $* $: $>D <$1> <$2> +R <$*> $: $>A <$1> <$1> +R <$*> $@ "" +R<$+> <$*> $@ $1 +', `dnl +R$* $@ ""') + +Stls_clt_features +ifdef(`_ACCESS_TABLE_', `dnl +R$* $| $* $: $>D <$1> <$2> +R <$*> $: $>A <$1> <$1> +R <$*> $@ "" +R<$+> <$*> $@ $1 +', `dnl +R$* $@ ""') +') + ###################################################################### ### RelayTLS: allow relaying based on TLS authentication ### diff --git a/contrib/sendmail/cf/m4/version.m4 b/contrib/sendmail/cf/m4/version.m4 index 31f6ffeac..8d2680534 100644 --- a/contrib/sendmail/cf/m4/version.m4 +++ b/contrib/sendmail/cf/m4/version.m4 @@ -1,6 +1,6 @@ divert(-1) # -# 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 @@ -11,8 +11,8 @@ divert(-1) # the sendmail distribution. # # -VERSIONID(`$Id: version.m4,v 8.236 2013-11-27 00:38:51 ca Exp $') +VERSIONID(`$Id: version.m4,v 8.237 2014-01-27 12:55:17 ca Exp $') # divert(0) # Configuration version number -DZ8.14.9`'ifdef(`confCF_VERSION', `/confCF_VERSION') +DZ8.15.2`'ifdef(`confCF_VERSION', `/confCF_VERSION') diff --git a/contrib/sendmail/contrib/AuthRealm.p0 b/contrib/sendmail/contrib/AuthRealm.p0 new file mode 100644 index 000000000..1ba8f5805 --- /dev/null +++ b/contrib/sendmail/contrib/AuthRealm.p0 @@ -0,0 +1,44 @@ +Patch from John Marshall (slightly modified). + +diff --git a/sendmail/srvrsmtp.c b/sendmail/srvrsmtp.c +index 7dba983..bf804ab 100644 +--- a/sendmail/srvrsmtp.c ++++ b/sendmail/srvrsmtp.c +@@ -84,7 +84,7 @@ static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname, + # define RESET_SASLCONN \ + do \ + { \ +- result = reset_saslconn(&conn, AuthRealm, remoteip, \ ++ result = reset_saslconn(&conn, hostname, remoteip, \ + localip, auth_id, &ext_ssf); \ + if (result != SASL_OK) \ + sasl_ok = false; \ +@@ -938,8 +938,6 @@ smtp(nullserver, d_flags, e) + e->e_features = features; + hostname = macvalue('j', e); + #if SASL +- if (AuthRealm == NULL) +- AuthRealm = hostname; + sasl_ok = bitset(SRV_OFFER_AUTH, features); + n_mechs = 0; + authenticating = SASL_NOT_AUTH; +@@ -948,8 +946,8 @@ smtp(nullserver, d_flags, e) + if (sasl_ok) + { + # if SASL >= 20000 +- result = sasl_server_new("smtp", AuthRealm, NULL, NULL, NULL, +- NULL, 0, &conn); ++ result = sasl_server_new("smtp", hostname, AuthRealm, NULL, ++ NULL, NULL, 0, &conn); + # elif SASL > 10505 + /* use empty realm: only works in SASL > 1.5.5 */ + result = sasl_server_new("smtp", AuthRealm, "", NULL, 0, &conn); +@@ -5392,7 +5390,7 @@ reset_saslconn(sasl_conn_t **conn, char *hostname, + + sasl_dispose(conn); + # if SASL >= 20000 +- result = sasl_server_new("smtp", hostname, NULL, NULL, NULL, ++ result = sasl_server_new("smtp", hostname, AuthRealm, NULL, NULL, + NULL, 0, conn); + # elif SASL > 10505 + /* use empty realm: only works in SASL > 1.5.5 */ diff --git a/contrib/sendmail/doc/op/op.me b/contrib/sendmail/doc/op/op.me index 7534667dd..57e25cd09 100644 --- a/contrib/sendmail/doc/op/op.me +++ b/contrib/sendmail/doc/op/op.me @@ -93,7 +93,7 @@ Version \\$2 .Ve $Revision: 8.759 $ .rm Ve .sp -For Sendmail Version 8.14 +For Sendmail Version 8.15 .)l .(f Sendmail is a trademark of Proofpoint, Inc. @@ -3262,6 +3262,8 @@ to program and files. Accept a group-readable key file for STARTTLS. .ip GroupReadableSASLDBFile Accept a group-readable Cyrus SASL password file. +.ip GroupReadableDefaultAuthInfoFile +Accept a group-readable DefaultAuthInfo file for SASL. .ip GroupWritableAliasFile Allow group-writable alias files. .ip GroupWritableDirPathSafe @@ -4481,8 +4483,76 @@ ruleset is called when sendmail connects to another MTA. If the ruleset does resolve to the .q error mailer, sendmail does not try STARTTLS even if it is offered. -This is useful to interact with MTAs that have broken -STARTTLS implementations by simply not using it. +This is useful to deal with STARTTLS interoperability issues +by simply not using it. +.sh 4 "tls_srv_features and tls_clt_features" +.pp +The +.i tls_clt_features +ruleset is called when sendmail connects to another MTA +and the +.i tls_srv_features +ruleset is called when a client connects to +.i sendmail . +The arguments for the rulesets are the host name and IP address +of the other side separated by +.b $| +(which is a metacharacter). +They should return a list of +.i key=value +pairs separated by semicolons; +the list can be empty if no options should be applied to the connection. +Available keys are and their allowed values are: +.nr ii 0.2i +.ip Options +A comma separated list of SSL related options. +See +.i ServerSSLOptions +and +.i ClientSSLOptions +for details, as well as +.i SSL_set_options (3) +and note this warning: +Options already set before are not cleared! +.ip CipherList +Specify cipher list for STARTTLS, +see +.i ciphers (1) +for possible values. +This overrides the global +.i CipherList +for the session. +.ip CertFile +File containing a certificate. +.ip KeyFile +File containing the private key for the certificate. +.lp +.lp +Example: +.(b +.ta 1.5i +Stls_srv_features +R$* $| 10.$+ $: cipherlist=HIGH +.)b +.lp +Notes: +.pp +Errors in these features (e.g., unknown keys or invalid values) +are logged +and the current session is aborted to avoid using STARTTLS +with features that should have been changed. +.pp +The keys are case-insensitive. +.pp +Both +.i CertFile +and +.i KeyFile +must be specified together; +specifying only one is an error. +.pp +These rulesets require the sendmail binary to be built with _FFR_TLS_SE_OPTS +enabled (see the "For Future Release" section). .sh 4 "authinfo" .pp The @@ -4870,12 +4940,28 @@ used for the security layer of a SASL mechanism. The message body type (7BIT or 8BITMIME), as determined from the envelope. +.ip ${cert_fp} +The fingerprint of the presented certificate (STARTTLS only). +Note: this macro is only defined if the option +.b CertFingerprintAlgorithm +is set, +in which case the specified fingerprint algorithm is used. +The valid algorithms depend on the OpenSSL version, +but usually md5, sha1, and sha256 are available. +See +.(b +openssl dgst -h +.)b +for a list. .ip ${cert_issuer} The DN (distinguished name) of the CA (certificate authority) that signed the presented certificate (the cert issuer) (STARTTLS only). .ip ${cert_md5} The MD5 hash of the presented certificate (STARTTLS only). +Note: this macro is only defined if the option +.b CertFingerprintAlgorithm +is not set. .ip ${cert_subject} The DN of the presented certificate (called the cert subject) (STARTTLS only). @@ -5756,6 +5842,8 @@ for this mailer. .ip i Do User Database rewriting on envelope sender address. .ip I +This flag is deprecated +and will be removed from a future version. This mailer will be speaking SMTP to another .i sendmail @@ -6534,6 +6622,7 @@ The authentication realm that is passed to the Cyrus SASL library. If no realm is specified, .b $j is used. +See also KNOWNBUGS. .ip BadRcptThrottle=\fIN\fP [no short name] If set and the specified number of recipients in a single SMTP @@ -6554,6 +6643,22 @@ as filenames (or as links to them). [no short name] File containing one or more CA certificates; see section about STARTTLS for more information. +.ip CertFingerprintAlgorithm +Specify the fingerprint algorithm (digest) to use for the presented cert. +If the option is not set, +md5 is used and the macro +.p ${cert_md5} +contains the cert fingerprint. +If the option is explicitly set, +the specified algorithm (e.g., sha1) is used +and the macro +.b ${cert_fp} +contains the cert fingerprint. +.ip CipherList +Specify cipher list for STARTTLS. +See +.i ciphers (1) +for possible values. .ip CheckAliases [n] Validate the RHS of aliases when rebuilding the alias database. @@ -6636,6 +6741,24 @@ in order to give settings for each protocol family (e.g., one for Family=inet and one for Family=inet6). A restriction placed on one family only affects outgoing connections on that particular family. +.ip ClientSSLOptions +A space or comma separated list of SSL related options for the client side. +See +.i SSL_CTX_set_options (3) +for a list; +the available values depend on the OpenSSL version against which +.i sendmail +is compiled. +By default, +.i SSL_OP_ALL +.i SSL_OP_NO_SSLv2 +.i SSL_OP_NO_TICKET +.i -SSL_OP_TLSEXT_PADDING +are used +(if those options are available). +Options can be cleared by preceeding them with a minus sign. +It is also possible to specify numerical values, e.g., +.b -0x0010 . .ip ColonOkInAddr [no short name] If set, colons are acceptable in e-mail addresses @@ -6732,26 +6855,35 @@ CRL checking requires at least OpenSSL version 0.9.7. Note: if a CRLFile is specified but the file is unusable, STARTTLS is disabled. .ip DHParameters +This option applies to the server side only. Possible values are: .(b -.ta 1i -5 use precomputed 512 bit prime +.ta 2i +5 use precomputed 512 bit prime. 1 generate 1024 bit prime -2 generate 2048 bit prime -none do not use Diffie-Hellman -NAME load prime from file +2 generate 2048 bit prime. +i use included precomputed 2048 bit prime (default). +none do not use Diffie-Hellman. +/path/to/file load prime from file. .)b This is only required if a ciphersuite containing DSA/DH is used. +The default is ``i'' which selects a precomputed, fixed 2048 bit prime. If ``5'' is selected, then precomputed, fixed primes are used. -This is the default for the client side. +Note: this option should not be used +(unless necessary for compatibility with old implementations). If ``1'' or ``2'' is selected, then prime values are computed during startup. -The server side default is ``1''. Note: this operation can take a significant amount of time on a slow machine (several seconds), but it is only done once at startup. If ``none'' is selected, then TLS ciphersuites containing DSA/DH cannot be used. If a file name is specified (which must be an absolute path), then the primes are read from it. +It is recommended to generate such a file using a command like this: +.(b + openssl dhparam -out /etc/mail/dhparams.pem 2048 +.)b +If the file is not readable or contains unusable data, +the default ``i'' is used instead. .ip DaemonPortOptions=\fIoptions\fP [O] Set server SMTP options. @@ -6784,8 +6916,10 @@ The key is used for error messages and logging. The .i Addr ess -mask may be a numeric address in IPv4 dot notation or IPv6 colon notation -or a network name. +mask may be +a numeric address in IPv4 dot notation or IPv6 colon notation, +or a network name, +or a path to a local socket. Note that if a network name is specified, only the first IP address returned for it will be used. This may cause indeterminate behavior for network names @@ -6798,6 +6932,10 @@ IPv6 users who wish to also accept IPv6 connections should add additional Family=inet6 .b DaemonPortOptions lines. +For a local socket, use +Family=local +or +Family=unix. The .i InputMailFilters key overrides the default list of input mail filters listed in the @@ -7543,6 +7681,13 @@ If there is insufficient space gives a 452 response to the MAIL command. This invites the sender to try again later. +.ip MaxQueueAge=\fIage\fP +[no short name] +If this is set to a value greater than zero, +entries in the queue will be retried during a queue run +only if the individual retry time has been reached +which is doubled for each attempt. +The maximum retry time is limited by the specified value. .ip MinQueueAge=\fIage\fP [no short name] Don't process any queued jobs @@ -8031,6 +8176,22 @@ is used when sendmail acts as server [no short name] File containing the private key belonging to the server certificate (used for STARTTLS). +.ip ServerSSLOptions +A space or comma separated list of SSL related options for the server side. +See +.i SSL_CTX_set_options (3) +for a list; +the available values depend on the OpenSSL version against which +.i sendmail +is compiled. +By default, +.i SSL_OP_ALL +.i -SSL_OP_TLSEXT_PADDING +are used +(if those options are available). +Options can be cleared by preceeding them with a minus sign. +It is also possible to specify numerical values, e.g., +.b -0x0010 . .ip ServiceSwitchFile=\fIfilename\fP [no short name] If your host operating system has a service switch abstraction @@ -8186,7 +8347,11 @@ consisting of single characters with intervening white space or commas. The flag ``V'' disables client verification, and hence it is not possible to use a client certificate for relaying. -Currently there are no other flags available. +The flag ``C'' removes the requirement for the TLS server +to have a cert. +This only works under very specific circumstances +and should only be used if the consequences are understood, +e.g., clients may not work with a server using this. .ip TempFileMode=\fImode\fP [F] The file mode for transcript files, files to which @@ -8272,6 +8437,12 @@ are always unsafe. Note: use .b DontBlameSendmail instead; this option is deprecated. +.ip UseCompressedIPv6Addresses +[no short name] +If set, the compressed format of IPv6 addresses, +such as IPV6:::1, will be used, +instead of the uncompressed format, +such as IPv6:0:0:0:0:0:0:0:1. .ip UseErrorsTo [l] If there is an @@ -8786,6 +8957,31 @@ A, AAAA, AFSDB, CNAME, MX, NS, PTR, SRV, and TXT. A map lookup will return only one record. Hence for some types, e.g., MX records, the return value might be a random element of the list due to randomizing in the DNS resolver. +.ip arpa +Returns the ``reverse'' for the given IP (IPv4 or IPv6) address, +i.e., the string for the PTR lookup, +but without trailing +.b ip6.arpa +or +.b in-addr.arpa . +For example, the following configuration lines: +.(b +Karpa arpa +SArpa +R$+ $: $(arpa $1 $) +.)b +work like this in test mode: +.(b +sendmail -bt +ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) +Enter
+> Arpa IPv6:1:2:dead:beef:9876:0:0:1 +Arpa input: IPv6 : 1 : 2 : dead : beef : 9876 : 0 : 0 : 1 +Arpa returns: 1 . 0 . 0 . 0 . 0 . 0 . 0 . 0 . 0 . 0 . 0 . 0 . 6 . 7 . 8 . 9 . f . e . e . b . d . a . e . d . 2 . 0 . 0 . 0 . 1 . 0 . 0 . 0 +> Arpa 1.2.3.4 +Arpa input: 1 . 2 . 3 . 4 +Arpa returns: 4 . 3 . 2 . 1 +.)b .ip sequence The arguments on the `K' line are a list of maps; the resulting map searches the argument maps in order @@ -9211,6 +9407,11 @@ The dns map has another flag: .ip "\-B" basedomain: specify a domain that is always appended to queries. .pp +Socket maps have an optional flag: +.ip "\-d" +timeout: specify the timeout (in seconds) for communication +with the socket map server. +.pp The following additional flags are present in the ldap map only: .ip "\-R" Do not auto chase referrals. sendmail must be compiled with @@ -9851,6 +10052,26 @@ and .q _SCO_unix_ . See the sendmail/README file for the latest scoop on these flags. +.sh 3 "For Future Releases" +.pp +.i sendmail +often contains compile time options +.i "For Future Releases" +(prefix _FFR_) +which might be enabled in a subsequent version +or might simply be removed as they turned out not to be really useful. +These features are usually not documented but if they are, +then the required (FFR) compile +time options are listed here for rulesets and macros, +and in +.i cf/README +for mc/cf options. +FFR compile times options must be enabled when the sendmail binary +is built from source. +Enabled FFRs in a binary can be listed with +.(b +sendmail -d0.13 < /dev/null | grep FFR +.)b .sh 2 "Parameters in sendmail/conf.h" .pp Parameters and compilation options @@ -10653,7 +10874,7 @@ one as certificate for the server (ServerCertFile and corresponding private ServerKeyFile) at least one root CA (CACertFile), i.e., a certificate that is used to sign other certificates, -and a path to a directory which contains other CAs (CACertPath). +and a path to a directory which contains (zero or more) other CAs (CACertPath). The file specified via CACertFile can contain several certificates of CAs. @@ -10699,6 +10920,19 @@ To allow for automatic startup of sendmail, private keys must be stored unencrypted. The keys are only protected by the permissions of the file system. Never make a private key available to a third party. +.pp +The options +.i ClientCertFile , +.i ClientKeyFile , +.i ServerCertFile , +and +.i ServerKeyFile +can take a second file name, +which must be separated from the first with a comma +(note: do not use any spaces) +to set up a second cert/key pair. +This can be used to have certs of different types, +e.g., RSA and DSA. .sh 3 "PRNG for STARTTLS" .pp STARTTLS requires a strong pseudo random number generator (PRNG) @@ -10883,6 +11117,7 @@ Operation modes are: m Deliver mail (default) s Speak SMTP on input side a\(dg ``Arpanet'' mode (get envelope sender information from header) +C Check the configuration file d Run as a daemon in background D Run as a daemon in foreground t Run in test mode diff --git a/contrib/sendmail/editmap/editmap.c b/contrib/sendmail/editmap/editmap.c index 3c1b8b9a8..66ee5793d 100644 --- a/contrib/sendmail/editmap/editmap.c +++ b/contrib/sendmail/editmap/editmap.c @@ -76,7 +76,6 @@ main(argc, argv) { char *progname; char *cfile; - bool verbose = false; bool query = false; bool update = false; bool remove = false; @@ -131,7 +130,7 @@ main(argc, argv) (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, SMDB_MAX_USER_NAME_LEN); -#define OPTIONS "C:fquxvN" +#define OPTIONS "C:fquxN" while ((opt = getopt(argc, argv, OPTIONS)) != -1) { switch (opt) @@ -159,10 +158,6 @@ main(argc, argv) nops++; break; - case 'v': - verbose = true; - break; - case 'N': inclnull = true; break; diff --git a/contrib/sendmail/include/sendmail/sendmail.h b/contrib/sendmail/include/sendmail/sendmail.h index fbd85d3b1..c79072299 100644 --- a/contrib/sendmail/include/sendmail/sendmail.h +++ b/contrib/sendmail/include/sendmail/sendmail.h @@ -117,9 +117,7 @@ extern bool filechanged __P((char *, int, struct stat *)); #define DBS_WORLDWRITABLEFORWARDFILE 39 #define DBS_WORLDWRITABLEINCLUDEFILE 40 #define DBS_GROUPREADABLEKEYFILE 41 -#if _FFR_GROUPREADABLEAUTHINFOFILE -# define DBS_GROUPREADABLEAUTHINFOFILE 42 -#endif /* _FFR_GROUPREADABLEAUTHINFOFILE */ +#define DBS_GROUPREADABLEAUTHINFOFILE 42 /* struct defining such things */ struct dbsval diff --git a/contrib/sendmail/include/sm/bdb.h b/contrib/sendmail/include/sm/bdb.h index a8a977a82..893d81522 100644 --- a/contrib/sendmail/include/sm/bdb.h +++ b/contrib/sendmail/include/sm/bdb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003 Proofpoint, Inc. and its suppliers. + * Copyright (c) 2002, 2003, 2014 Proofpoint, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -19,7 +19,7 @@ # define DB_VERSION_MAJOR 1 # endif /* ! DB_VERSION_MAJOR */ -# if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +# if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) || DB_VERSION_MAJOR >= 5 # define DBTXN NULL , @@ -32,7 +32,7 @@ # define SM_DB_FLAG_ADD(flag) (flag) |= DB_FCNTL_LOCKING -# else /* DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 */ +# else /* (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) || DB_VERSION_MAJOR >= 5 */ # define DBTXN # if !HASFLOCK && defined(DB_FCNTL_LOCKING) @@ -41,7 +41,7 @@ # define SM_DB_FLAG_ADD(flag) ((void) 0) # endif /* !HASFLOCK && defined(DB_FCNTL_LOCKING) */ -# endif /* DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 */ +# endif /* (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) || DB_VERSION_MAJOR >= 5 */ #endif /* NEWDB */ #endif /* ! SM_BDB_H */ diff --git a/contrib/sendmail/include/sm/cdefs.h b/contrib/sendmail/include/sm/cdefs.h index d288aa0f7..0802d5941 100644 --- a/contrib/sendmail/include/sm/cdefs.h +++ b/contrib/sendmail/include/sm/cdefs.h @@ -121,11 +121,11 @@ */ # ifndef SM_CONF_FORMAT_TEST -# if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 +# if (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || __GNUC__ > 2 # define SM_CONF_FORMAT_TEST 1 -# else /* __GNUC__ == 2 && __GNUC_MINOR__ >= 7 */ +# else # define SM_CONF_FORMAT_TEST 0 -# endif /* __GNUC__ == 2 && __GNUC_MINOR__ >= 7 */ +# endif # endif /* SM_CONF_FORMAT_TEST */ # ifndef PRINTFLIKE diff --git a/contrib/sendmail/include/sm/conf.h b/contrib/sendmail/include/sm/conf.h index bea380aad..459eda4cc 100644 --- a/contrib/sendmail/include/sm/conf.h +++ b/contrib/sendmail/include/sm/conf.h @@ -473,6 +473,9 @@ typedef int pid_t; # ifndef HASGETUSERSHELL # define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps pre-2.7 */ # endif /* ! HASGETUSERSHELL */ +# if SOLARIS < 21200 +# define SIGWAIT_TAKES_1_ARG 1 /* S12 moves to UNIX V7 semantic */ +# endif /* SOLARIS < 21200 */ # else /* SOLARIS */ /* SunOS 4.0.3 or 4.1.x */ @@ -1906,6 +1909,7 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t)); # define GIDSET_T gid_t # define SOCKADDR_LEN_T size_t # define SOCKOPT_LEN_T size_t +# define SIGWAIT_TAKES_1_ARG 1 # ifndef _PATH_UNIX # define _PATH_UNIX "/stand/unix" # endif /* ! _PATH_UNIX */ @@ -2920,6 +2924,10 @@ typedef void (*sigfunc_t) __P((int)); # define FD_SETSIZE 256 #endif /* ! FD_SETSIZE */ +#ifndef SIGWAIT_TAKES_1_ARG +# define SIGWAIT_TAKES_1_ARG 0 +#endif /* ! SIGWAIT_TAKES_1_ARG */ + /* ** Size of prescan buffer. ** Despite comments in the _sendmail_ book, this probably should @@ -2970,6 +2978,12 @@ typedef void (*sigfunc_t) __P((int)); # define SM_UINT16 uint16_t # endif /* ! SM_UINT16 */ +/* additional valid chars in user/group names in passwd */ +# ifndef SM_PWN_CHARS +# define SM_PWN_CHARS "-_." +# endif + + /* ** SVr4 and similar systems use different routines for setjmp/longjmp ** with signal support diff --git a/contrib/sendmail/include/sm/errstring.h b/contrib/sendmail/include/sm/errstring.h index 836fe14f7..14c100773 100644 --- a/contrib/sendmail/include/sm/errstring.h +++ b/contrib/sendmail/include/sm/errstring.h @@ -49,9 +49,17 @@ extern int errno; #define E_SM_WRFILE (E_PSEUDOBASE + 11) /* o readable file */ #define E_DNSBASE (E_PSEUDOBASE + 20) /* base for DNS h_errno */ #define E_SMDBBASE (E_PSEUDOBASE + 40) /* base for libsmdb errors */ -#define E_LDAPBASE (E_PSEUDOBASE + 70) /* base for LDAP errors */ -#define E_LDAPURLBASE (E_PSEUDOBASE + 200) /* base for LDAP URL errors */ +#define E_LDAPREALBASE (E_PSEUDOBASE + 70) /* start of range for LDAP */ +#define E_LDAPBASE (E_LDAPREALBASE + E_LDAP_SHIM) /* LDAP error zero */ +#define E_LDAPURLBASE (E_PSEUDOBASE + 230) /* base for LDAP URL errors */ +/* +** OpenLDAP uses small negative errors for internal (non-protocol) +** errors. We expect them to be between zero and -E_LDAP_SHIM +** (and then offset by E_LDAPBASE). +*/ + +#define E_LDAP_SHIM 30 /* libsmdb */ #define SMDBE_OK 0 diff --git a/contrib/sendmail/include/sm/fdset.h b/contrib/sendmail/include/sm/fdset.h index 8a5a1d4db..b4a1e7dec 100644 --- a/contrib/sendmail/include/sm/fdset.h +++ b/contrib/sendmail/include/sm/fdset.h @@ -17,9 +17,9 @@ ** before. */ -# define SM_FD_SET(fd, pfdset) FD_SET(fd, pfdset) -# define SM_FD_ISSET(fd, pfdset) FD_ISSET(fd, pfdset) -# define SM_FD_SETSIZE FD_SETSIZE -# define SM_FD_OK_SELECT(fd) (FD_SETSIZE <= 0 || (fd) < FD_SETSIZE) +#define SM_FD_SET(fd, pfdset) FD_SET(fd, pfdset) +#define SM_FD_ISSET(fd, pfdset) FD_ISSET(fd, pfdset) +#define SM_FD_SETSIZE FD_SETSIZE +#define SM_FD_OK_SELECT(fd) (SM_FD_SETSIZE <= 0 || (fd) < SM_FD_SETSIZE) #endif /* SM_FDSET_H */ diff --git a/contrib/sendmail/libmilter/docs/smfi_setsymlist.html b/contrib/sendmail/libmilter/docs/smfi_setsymlist.html index 1b879c447..c270d0b56 100644 --- a/contrib/sendmail/libmilter/docs/smfi_setsymlist.html +++ b/contrib/sendmail/libmilter/docs/smfi_setsymlist.html @@ -62,6 +62,9 @@ milter wants to receive from the MTA. macros list of macros (separated by space). Example: "{rcpt_mailer} {rcpt_host}" +
+ An empty string ("", not NULL) can be used to specify that no macros + should be sent. @@ -74,7 +77,7 @@ milter wants to receive from the MTA. MI_FAILURE is returned if
  • there is not enough free memory to make a copy of the macro list, -
  • macros is NULL or empty, +
  • macros is NULL,
  • stage is not a valid protocol stage,
  • the macro list for stage has been set before. diff --git a/contrib/sendmail/libmilter/engine.c b/contrib/sendmail/libmilter/engine.c index e557a59ea..808ffdbf6 100644 --- a/contrib/sendmail/libmilter/engine.c +++ b/contrib/sendmail/libmilter/engine.c @@ -42,13 +42,8 @@ struct cmdfct_t typedef struct cmdfct_t cmdfct; /* possible values for cm_argt */ -#define CM_ARG0 0 /* no args */ -#define CM_ARG1 1 /* one arg (string) */ -#define CM_ARG2 2 /* two args (strings) */ -#define CM_ARGA 4 /* one string and _SOCK_ADDR */ -#define CM_ARGO 5 /* two integers */ -#define CM_ARGV 8 /* \0 separated list of args, NULL-terminated */ -#define CM_ARGN 9 /* \0 separated list of args (strings) */ +#define CM_BUF 0 +#define CM_NULLOK 1 /* possible values for cm_todo */ #define CT_CONT 0x0000 /* continue reading commands */ @@ -200,21 +195,21 @@ static int next_states[] = /* commands received by milter */ static cmdfct cmds[] = { - {SMFIC_ABORT, CM_ARG0, ST_ABRT, CT_CONT, CI_NONE, st_abortfct } -, {SMFIC_MACRO, CM_ARGV, ST_NONE, CT_KEEP, CI_NONE, st_macros } -, {SMFIC_BODY, CM_ARG1, ST_BODY, CT_CONT, CI_NONE, st_bodychunk } -, {SMFIC_CONNECT, CM_ARG2, ST_CONN, CT_CONT, CI_CONN, st_connectinfo } -, {SMFIC_BODYEOB, CM_ARG1, ST_ENDM, CT_CONT, CI_EOM, st_bodyend } -, {SMFIC_HELO, CM_ARG1, ST_HELO, CT_CONT, CI_HELO, st_helo } -, {SMFIC_HEADER, CM_ARG2, ST_HDRS, CT_CONT, CI_NONE, st_header } -, {SMFIC_MAIL, CM_ARGV, ST_MAIL, CT_CONT, CI_MAIL, st_sender } -, {SMFIC_OPTNEG, CM_ARGO, ST_OPTS, CT_CONT, CI_NONE, st_optionneg } -, {SMFIC_EOH, CM_ARG0, ST_EOHS, CT_CONT, CI_EOH, st_eoh } -, {SMFIC_QUIT, CM_ARG0, ST_QUIT, CT_END, CI_NONE, st_quit } -, {SMFIC_DATA, CM_ARG0, ST_DATA, CT_CONT, CI_DATA, st_data } -, {SMFIC_RCPT, CM_ARGV, ST_RCPT, CT_IGNO, CI_RCPT, st_rcpt } -, {SMFIC_UNKNOWN, CM_ARG1, ST_UNKN, CT_IGNO, CI_NONE, st_unknown } -, {SMFIC_QUIT_NC, CM_ARG0, ST_Q_NC, CT_CONT, CI_NONE, st_quit } + {SMFIC_ABORT, CM_NULLOK, ST_ABRT, CT_CONT, CI_NONE, st_abortfct} +, {SMFIC_MACRO, CM_BUF, ST_NONE, CT_KEEP, CI_NONE, st_macros } +, {SMFIC_BODY, CM_BUF, ST_BODY, CT_CONT, CI_NONE, st_bodychunk} +, {SMFIC_CONNECT, CM_BUF, ST_CONN, CT_CONT, CI_CONN, st_connectinfo} +, {SMFIC_BODYEOB, CM_NULLOK, ST_ENDM, CT_CONT, CI_EOM, st_bodyend } +, {SMFIC_HELO, CM_BUF, ST_HELO, CT_CONT, CI_HELO, st_helo } +, {SMFIC_HEADER, CM_BUF, ST_HDRS, CT_CONT, CI_NONE, st_header } +, {SMFIC_MAIL, CM_BUF, ST_MAIL, CT_CONT, CI_MAIL, st_sender } +, {SMFIC_OPTNEG, CM_BUF, ST_OPTS, CT_CONT, CI_NONE, st_optionneg} +, {SMFIC_EOH, CM_NULLOK, ST_EOHS, CT_CONT, CI_EOH, st_eoh } +, {SMFIC_QUIT, CM_NULLOK, ST_QUIT, CT_END, CI_NONE, st_quit } +, {SMFIC_DATA, CM_NULLOK, ST_DATA, CT_CONT, CI_DATA, st_data } +, {SMFIC_RCPT, CM_BUF, ST_RCPT, CT_IGNO, CI_RCPT, st_rcpt } +, {SMFIC_UNKNOWN, CM_BUF, ST_UNKN, CT_IGNO, CI_NONE, st_unknown } +, {SMFIC_QUIT_NC, CM_NULLOK, ST_Q_NC, CT_CONT, CI_NONE, st_quit } }; /* @@ -390,6 +385,15 @@ mi_engine(ctx) continue; } } + if (cmds[i].cm_argt != CM_NULLOK && buf == NULL) + { + /* stop for now */ + if (ctx->ctx_dbg > 1) + sm_dprintf("[%lu] cmd='%c', buf=NULL\n", + (long) ctx->ctx_id, cmd); + ret = MI_FAILURE; + break; + } arg.a_len = len; arg.a_buf = buf; if (newstate != ST_NONE) @@ -726,7 +730,7 @@ sendreply(r, sd, timeout_ptr, ctx) } /* -** CLR_MACROS -- clear set of macros starting from a given index +** MI_CLR_MACROS -- clear set of macros starting from a given index ** ** Parameters: ** ctx -- context structure @@ -1816,7 +1820,7 @@ dec_arg2(buf, len, s1, s2) } /* -** SENDOK -- is it ok for the filter to send stuff to the MTA? +** MI_SENDOK -- is it ok for the filter to send stuff to the MTA? ** ** Parameters: ** ctx -- context structure diff --git a/contrib/sendmail/libmilter/handler.c b/contrib/sendmail/libmilter/handler.c index 5b4073b85..7622839d6 100644 --- a/contrib/sendmail/libmilter/handler.c +++ b/contrib/sendmail/libmilter/handler.c @@ -15,7 +15,7 @@ SM_RCSID("@(#)$Id: handler.c,v 8.40 2013-11-22 20:51:36 ca Exp $") #if !_FFR_WORKERS_POOL /* -** HANDLE_SESSION -- Handle a connected session in its own context +** MI_HANDLE_SESSION -- Handle a connected session in its own context ** ** Parameters: ** ctx -- context structure diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c index b0a1362d4..11d92bb09 100644 --- a/contrib/sendmail/libmilter/listener.c +++ b/contrib/sendmail/libmilter/listener.c @@ -728,6 +728,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) int acnt = 0; /* error count for accept() failures */ int scnt = 0; /* error count for select() failures */ int save_errno = 0; + int fdflags; #if !_FFR_WORKERS_POOL sthread_t thread_id; #endif /* !_FFR_WORKERS_POOL */ @@ -885,6 +886,20 @@ mi_listener(conn, dbg, smfi, timeout, backlog) } #endif /* _FFR_DUP_FD */ + /* + ** Need to set close-on-exec for connfd in case a user's + ** filter starts other applications. + ** Note: errors will not stop processing (for now). + */ + + if ((fdflags = fcntl(connfd, F_GETFD, 0)) == -1 || + fcntl(connfd, F_SETFD, fdflags | FD_CLOEXEC) == -1) + { + smi_log(SMI_LOG_ERR, + "%s: Unable to set close-on-exec: %s", + smfi->xxfi_name, sm_errstring(errno)); + } + if (setsockopt(connfd, SOL_SOCKET, SO_KEEPALIVE, (void *) &sockopt, sizeof sockopt) < 0) { diff --git a/contrib/sendmail/libmilter/signal.c b/contrib/sendmail/libmilter/signal.c index 4f8ec6e2d..8d4c8b2f4 100644 --- a/contrib/sendmail/libmilter/signal.c +++ b/contrib/sendmail/libmilter/signal.c @@ -104,11 +104,11 @@ mi_signal_thread(name) for (;;) { sigerr = sig = 0; -#if defined(SOLARIS) || defined(__svr5__) +#if SIGWAIT_TAKES_1_ARG if ((sig = sigwait(&set)) < 0) -#else /* defined(SOLARIS) || defined(__svr5__) */ +#else if ((sigerr = sigwait(&set, &sig)) != 0) -#endif /* defined(SOLARIS) || defined(__svr5__) */ +#endif { /* some OS return -1 and set errno: copy it */ if (sigerr <= 0) diff --git a/contrib/sendmail/libmilter/smfi.c b/contrib/sendmail/libmilter/smfi.c index 2148f3c18..d6c63a2ce 100644 --- a/contrib/sendmail/libmilter/smfi.c +++ b/contrib/sendmail/libmilter/smfi.c @@ -325,7 +325,7 @@ smfi_setsymlist(ctx, where, macros) { SM_ASSERT(ctx != NULL); - if (macros == NULL || *macros == '\0') + if (macros == NULL) return MI_FAILURE; if (where < SMFIM_FIRST || where > SMFIM_LAST) return MI_FAILURE; diff --git a/contrib/sendmail/libmilter/worker.c b/contrib/sendmail/libmilter/worker.c index 75a1f7caa..bf7086a95 100644 --- a/contrib/sendmail/libmilter/worker.c +++ b/contrib/sendmail/libmilter/worker.c @@ -254,7 +254,7 @@ nonblocking(int fd, const char *name) } /* -** MI_POOL_CONTROLER_INIT -- Launch the worker pool controller +** MI_POOL_CONTROLLER_INIT -- Launch the worker pool controller ** Must be called before starting sessions. ** ** Parameters: diff --git a/contrib/sendmail/libsm/Makefile.m4 b/contrib/sendmail/libsm/Makefile.m4 index 3901fe887..5882bb63f 100644 --- a/contrib/sendmail/libsm/Makefile.m4 +++ b/contrib/sendmail/libsm/Makefile.m4 @@ -6,7 +6,7 @@ define(`confREQUIRE_LIBSM', `true') define(`confREQUIRE_SM_OS_H', `true') PREPENDDEF(`confENVDEF', `confMAPDEF') bldPRODUCT_START(`library', `libsm') -define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c path.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c memstat.c util.c inet6_ntop.c ') +define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c memstat.c util.c inet6_ntop.c ') bldPRODUCT_END dnl msg.c dnl syslogio.c diff --git a/contrib/sendmail/libsm/errstring.c b/contrib/sendmail/libsm/errstring.c index 7233c5a9b..01d5a6419 100644 --- a/contrib/sendmail/libsm/errstring.c +++ b/contrib/sendmail/libsm/errstring.c @@ -264,10 +264,12 @@ sm_errstring(errnum) #if LDAPMAP /* - ** LDAP error messages. + ** LDAP error messages. Handle small negative errors from + ** libldap (in the range -E_LDAP_SHIM to zero, offset by E_LDAPBASE) + ** as well. */ - if (errnum >= E_LDAPBASE) + if (errnum >= E_LDAPBASE - E_LDAP_SHIM) return ldap_err2string(errnum - E_LDAPBASE); #endif /* LDAPMAP */ diff --git a/contrib/sendmail/libsm/local.h b/contrib/sendmail/libsm/local.h index 8532ad8db..304a52e29 100644 --- a/contrib/sendmail/libsm/local.h +++ b/contrib/sendmail/libsm/local.h @@ -20,6 +20,7 @@ */ #include +#include #if !SM_CONF_MEMCHR # include #endif /* !SM_CONF_MEMCHR */ @@ -244,7 +245,7 @@ int sm_flags __P((int)); sm_io_to.tv_sec = (to) / 1000; \ sm_io_to.tv_usec = ((to) - (sm_io_to.tv_sec * 1000)) * 1000; \ } \ - if (FD_SETSIZE > 0 && (fd) >= FD_SETSIZE) \ + if (!SM_FD_OK_SELECT(fd)) \ { \ errno = EINVAL; \ return SM_IO_EOF; \ diff --git a/contrib/sendmail/libsm/mbdb.c b/contrib/sendmail/libsm/mbdb.c index d68d3b124..3d7426cd5 100644 --- a/contrib/sendmail/libsm/mbdb.c +++ b/contrib/sendmail/libsm/mbdb.c @@ -315,7 +315,7 @@ mbdb_pw_lookup(name, user) { struct passwd *pw; -#ifdef HESIOD +#if HESIOD && !HESIOD_ALLOW_NUMERIC_LOGIN /* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */ { char *p; @@ -326,7 +326,7 @@ mbdb_pw_lookup(name, user) if (*p == '\0') return EX_NOUSER; } -#endif /* HESIOD */ +#endif /* HESIOD && !HESIOD_ALLOW_NUMERIC_LOGIN */ errno = 0; pw = getpwnam(name); diff --git a/contrib/sendmail/libsm/path.c b/contrib/sendmail/libsm/path.c deleted file mode 100644 index 0819c3e08..000000000 --- a/contrib/sendmail/libsm/path.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers. - * All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - */ - -#include -SM_RCSID("@(#)$Id: path.c,v 1.10 2013-11-22 20:51:43 ca Exp $") - -#include -#include - diff --git a/contrib/sendmail/libsm/refill.c b/contrib/sendmail/libsm/refill.c index 43eee9738..e13c831be 100644 --- a/contrib/sendmail/libsm/refill.c +++ b/contrib/sendmail/libsm/refill.c @@ -25,6 +25,7 @@ SM_RCSID("@(#)$Id: refill.c,v 1.54 2013-11-22 20:51:43 ca Exp $") #include #include #include +#include #include "local.h" static int sm_lflush __P((SM_FILE_T *, int *)); @@ -65,7 +66,7 @@ static int sm_lflush __P((SM_FILE_T *, int *)); errno = EAGAIN; \ return SM_IO_EOF; \ } \ - if (FD_SETSIZE > 0 && (fd) >= FD_SETSIZE) \ + if (!SM_FD_OK_SELECT(fd)) \ { \ errno = EINVAL; \ return SM_IO_EOF; \ diff --git a/contrib/sendmail/libsm/stdio.c b/contrib/sendmail/libsm/stdio.c index a13f2ffd6..16277c09a 100644 --- a/contrib/sendmail/libsm/stdio.c +++ b/contrib/sendmail/libsm/stdio.c @@ -317,7 +317,7 @@ sm_stdsetinfo(fp, what, valp) } /* -** SM_GETINFO -- get information about the open file +** SM_STDGETINFO -- get information about the open file ** ** Parameters: ** fp -- file to get info for diff --git a/contrib/sendmail/libsm/vfprintf.c b/contrib/sendmail/libsm/vfprintf.c index 860938d31..87c353c1b 100644 --- a/contrib/sendmail/libsm/vfprintf.c +++ b/contrib/sendmail/libsm/vfprintf.c @@ -156,7 +156,7 @@ sm_bprintf(fp, fmt, ap) #define FPT 0x100 /* Floating point number */ /* -** SM_IO_VPRINTF -- performs actual formating for o/p +** SM_IO_VFPRINTF -- performs actual formating for o/p ** ** Parameters: ** fp -- file pointer for o/p diff --git a/contrib/sendmail/libsmdb/smdb.c b/contrib/sendmail/libsmdb/smdb.c index 74d42e299..96473b89b 100644 --- a/contrib/sendmail/libsmdb/smdb.c +++ b/contrib/sendmail/libsmdb/smdb.c @@ -198,12 +198,16 @@ smdb_open_database(database, db_name, mode, mode_mask, sff, type, user_info, SMDB_USER_INFO *user_info; SMDB_DBPARAMS *params; { +#if defined(NEWDB) && defined(NDBM) bool type_was_default = false; +#endif if (type == SMDB_TYPE_DEFAULT) { - type_was_default = true; #ifdef NEWDB +# ifdef NDBM + type_was_default = true; +# endif type = SMDB_TYPE_HASH; #else /* NEWDB */ # ifdef NDBM diff --git a/contrib/sendmail/makemap/makemap.c b/contrib/sendmail/makemap/makemap.c index fa889447c..cf1f62c8e 100644 --- a/contrib/sendmail/makemap/makemap.c +++ b/contrib/sendmail/makemap/makemap.c @@ -234,71 +234,67 @@ main(argc, argv) } #if HASFCHOWN - if (!unmake && geteuid() == 0) + /* Find TrustedUser value in sendmail.cf */ + if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, + NULL)) == NULL) { - /* Find TrustedUser value in sendmail.cf */ - if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, - SM_IO_RDONLY, NULL)) == NULL) - { - sm_io_fprintf(smioerr, SM_TIME_DEFAULT, - "makemap: %s: %s\n", - cfile, sm_errstring(errno)); - exit(EX_NOINPUT); - } - while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0) - { - register char *b; + sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "makemap: %s: %s\n", + cfile, sm_errstring(errno)); + exit(EX_NOINPUT); + } + while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0) + { + register char *b; - if ((b = strchr(buf, '\n')) != NULL) - *b = '\0'; + if ((b = strchr(buf, '\n')) != NULL) + *b = '\0'; - b = buf; - switch (*b++) + b = buf; + switch (*b++) + { + case 'O': /* option */ + if (strncasecmp(b, " TrustedUser", 12) == 0 && + !(isascii(b[12]) && isalnum(b[12]))) { - case 'O': /* option */ - if (strncasecmp(b, " TrustedUser", 12) == 0 && - !(isascii(b[12]) && isalnum(b[12]))) + b = strchr(b, '='); + if (b == NULL) + continue; + while (isascii(*++b) && isspace(*b)) + continue; + if (isascii(*b) && isdigit(*b)) + TrustedUid = atoi(b); + else { - b = strchr(b, '='); - if (b == NULL) - continue; - while (isascii(*++b) && isspace(*b)) - continue; - if (isascii(*b) && isdigit(*b)) - TrustedUid = atoi(b); + TrustedUid = 0; + pw = getpwnam(b); + if (pw == NULL) + (void) sm_io_fprintf(smioerr, + SM_TIME_DEFAULT, + "TrustedUser: unknown user %s\n", b); else - { - TrustedUid = 0; - pw = getpwnam(b); - if (pw == NULL) - (void) sm_io_fprintf(smioerr, - SM_TIME_DEFAULT, - "TrustedUser: unknown user %s\n", b); - else - TrustedUid = pw->pw_uid; - } + TrustedUid = pw->pw_uid; + } # ifdef UID_MAX - if (TrustedUid > UID_MAX) - { - (void) sm_io_fprintf(smioerr, - SM_TIME_DEFAULT, - "TrustedUser: uid value (%ld) > UID_MAX (%ld)", - (long) TrustedUid, - (long) UID_MAX); - TrustedUid = 0; - } -# endif /* UID_MAX */ - break; + if (TrustedUid > UID_MAX) + { + (void) sm_io_fprintf(smioerr, + SM_TIME_DEFAULT, + "TrustedUser: uid value (%ld) > UID_MAX (%ld)", + (long) TrustedUid, + (long) UID_MAX); + TrustedUid = 0; } +# endif /* UID_MAX */ + break; + } - default: - continue; - } + default: + continue; } - (void) sm_io_close(cfp, SM_TIME_DEFAULT); } + (void) sm_io_close(cfp, SM_TIME_DEFAULT); #endif /* HASFCHOWN */ if (!params.smdbp_allow_dup && !allowreplace) diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README index c437b1e88..fddce9d36 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 e73ed10ed..06efaa91c 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 77c3f64f6..8df58030a 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 7d908560d..0f2c9c019 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 8d90acb82..5f090b23a 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 b64f3c7fa..c73334e27 100644 --- a/contrib/sendmail/src/conf.c +++ b/contrib/sendmail/src/conf.c @@ -13,7 +13,7 @@ #include -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 #include @@ -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 d6b3f497a..42883658d 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 +# include #endif /* STARTTLS */ #include @@ -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 e00414163..2a0d13706 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 +# include 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 */ @@ -2459,8 +2463,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); } } @@ -2486,8 +2490,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); } } @@ -2516,9 +2520,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); } @@ -2613,8 +2617,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); } @@ -2656,9 +2660,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) @@ -2958,8 +2962,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; @@ -3033,7 +3037,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) { @@ -3358,7 +3362,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); @@ -3584,7 +3588,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 @@ -4160,14 +4164,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", @@ -4209,6 +4212,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 @@ -4218,7 +4223,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; @@ -4226,6 +4231,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; @@ -4270,6 +4277,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)); @@ -4336,6 +4353,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))) { @@ -4362,6 +4416,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; } @@ -5321,8 +5376,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); } } @@ -5362,9 +5417,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); } } @@ -5405,8 +5460,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); } } @@ -5468,9 +5523,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 */ @@ -6157,11 +6212,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) @@ -6183,6 +6245,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, @@ -6200,7 +6263,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 df6c5c781..bae6b0010 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 835fa4b10..0594eb9ba 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 3c59a40d3..0af72436f 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 09e013845..39edd94fc 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 b79f59174..2cc283e5f 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 773eb16e5..c3f925f3c 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 cbc4d35bc..9b3667dc5 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 4c787204d..2adb39caf 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 db339f2e3..a323301fd 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 9189a9523..2b0fbf711 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,13 +162,18 @@ 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 */ + Srv_SSL_Options &= ~SSL_OP_TLSEXT_PADDING; + Clt_SSL_Options &= ~SSL_OP_TLSEXT_PADDING; +# endif /* SSL_OP_TLSEXT_PADDING */ #endif /* STARTTLS */ if (DontLockReadFiles) sff |= SFF_NOLOCK; @@ -725,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(); @@ -751,6 +805,7 @@ readcf(cfname, safe, e) } } } + setupdynmailers(); } /* @@ -1170,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. ** @@ -1203,6 +1377,7 @@ fileclass(class, filename, fmt, ismap, safe, optional) ** enters the mailer into the mailer table. */ + void makemailer(line) char *line; @@ -1233,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; @@ -1274,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); } } @@ -1411,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'; @@ -1455,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') @@ -1934,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 ** @@ -2175,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 @@ -2266,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 }, @@ -2292,125 +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 - { NULL, 0 } -}; -#endif /* STARTTLS && _FFR_TLS_1 */ - - # define CANONIFY(val) # define SET_OPT_DEFAULT(opt, val) opt = val @@ -2451,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 == ' ') @@ -2698,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); @@ -3151,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)); @@ -3370,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) @@ -3394,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 { @@ -3411,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)) @@ -3741,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); @@ -3831,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 @@ -3843,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 */ @@ -3876,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: @@ -4056,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 ff3a3b9d3..3fad95717 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 07c3c90ff..6de8f2f19 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 a6c47fecf..f525c3e29 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 bb0a46f84..1ab7b6953 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 +# include # if !TLS_NO_RSA # if _FFR_FIPSMODE # define RSA_KEYLENGTH 1024 @@ -194,10 +194,19 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1104 2013-11-22 20:5 # 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 @@ -278,11 +287,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 */ @@ -337,6 +358,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 *)); @@ -417,6 +441,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 */ @@ -444,6 +469,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 */ @@ -459,11 +485,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 */ @@ -493,7 +522,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. @@ -737,6 +770,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) @@ -940,10 +979,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)) @@ -1136,7 +1181,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)); @@ -1300,15 +1345,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 */ @@ -1628,6 +1664,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 */ @@ -1636,7 +1676,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) @@ -1731,6 +1775,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. @@ -1888,6 +1934,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 /* @@ -1921,6 +1971,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 | \ @@ -1930,8 +1981,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) @@ -1942,7 +1992,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)); @@ -1955,10 +2005,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 */ @@ -1968,7 +2017,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 */ /* @@ -2049,9 +2098,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 */ @@ -2059,6 +2106,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 *)); @@ -2260,7 +2310,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 @@ -2269,14 +2319,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 */ @@ -2332,6 +2384,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 */ @@ -2499,6 +2552,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 *, ...)); @@ -2514,7 +2571,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 *, ...)); @@ -2651,6 +2708,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)); @@ -2661,6 +2726,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 *)); @@ -2714,10 +2782,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 [])); @@ -2769,16 +2837,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 0593a2577..5209dfa1c 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 #include #include +#include #include /* allow to disable error handling code just in case... */ @@ -415,7 +416,7 @@ sfdcsasl(fin, fout, conn, tmo) #if STARTTLS # include "sfsasl.h" -# include +# include /* 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 662eaa5cb..8ec2cb68e 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 1a5356782..b05348d4b 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 +# include # include 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 ca93ee8b7..6b0ea25da 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 -# include -# include -# ifndef HASURANDOMDEV -# include -# endif /* ! HASURANDOMDEV */ +# include +# include +# include +# ifndef HASURANDOMDEV +# include +# 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 67e52d4f0..4011de68b 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 02e8ec204..9775915d6 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 14767780b..7145ce219 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_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"; -- 2.45.0