FreeBSD Bugzilla – Attachment 84025 Details for
Bug 119954
mail/qmail-tls is broken. qmail-smtpd does not accept ssl connections if /var/qmail/control/tlsserverchiphers does not exist.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 60.87 KB, created by
Luiz Otavio O Souza
on 2008-01-24 23:00:03 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
Luiz Otavio O Souza
Created:
2008-01-24 23:00:03 UTC
Size:
60.87 KB
patch
obsolete
>--- qmail-tls-orig/Makefile 2007-12-26 14:43:55.000000000 -0200 >+++ qmail-tls/Makefile 2008-01-24 20:18:43.000000000 -0200 >@@ -7,7 +7,7 @@ > > PORTNAME= qmail > PORTVERSION= ${QMAIL_VERSION}.${TLS_PATCH_DATE} >-PORTREVISION= 2 >+PORTREVISION= > CATEGORIES= mail > PKGNAMESUFFIX= -tls > >@@ -17,7 +17,7 @@ > > SLAVE_TLS= yes > >-TLS_PATCH_DATE= 20021228 >+TLS_PATCH_DATE= 20070408 > > USE_OPENSSL= yes > >--- qmail-tls-orig/pkg-descr 2005-06-01 19:22:46.000000000 -0300 >+++ qmail-tls/pkg-descr 2008-01-24 20:18:43.000000000 -0200 >@@ -1,6 +1,6 @@ > What is is: [excerpt taken from tls patch] > >-Frederik Vermeulen <qmail-tls at inoa.net> 20021228 >+Frederik Vermeulen <qmail-tls at inoa.net> 20070408 > http://inoa.net/qmail/qmail-1.03-tls.patch > > This patch implements RFC2487 in qmail. This means you can >--- qmail-orig/distinfo 2007-09-05 17:47:45.000000000 -0300 >+++ qmail/distinfo 2008-01-24 20:18:43.000000000 -0200 >@@ -1,9 +1,27 @@ > MD5 (qmail/qmail-1.03.tar.gz) = 622f65f982e380dbe86e6574f3abcb7c > SHA256 (qmail/qmail-1.03.tar.gz) = 21ed6c562cbb55092a66197c35c8222b84115d1acab0854fdb1ad1f301626f88 > SIZE (qmail/qmail-1.03.tar.gz) = 220668 >+MD5 (qmail/qmail-smtpd-auth-0.31.tar.gz) = 6b202f71a99fb41e9e32906017270ba0 >+SHA256 (qmail/qmail-smtpd-auth-0.31.tar.gz) = 1b439fa7e128de13fa80b86883f61a39d17b87b7e8916b6a0eab065bbe49b938 >+SIZE (qmail/qmail-smtpd-auth-0.31.tar.gz) = 8798 >+MD5 (qmail/qmail-smtpd-auth-close3.patch) = 0ba66d73dcba1c68ed714b07e47abd3e >+SHA256 (qmail/qmail-smtpd-auth-close3.patch) = d933e871261d6740cebe5c21cad81146525cfe06a464e277979f61c1242b5ad4 >+SIZE (qmail/qmail-smtpd-auth-close3.patch) = 520 >+MD5 (qmail/auth.patch.diff-tls) = c152ec1a6cf9c78d0aede6c212736f2f >+SHA256 (qmail/auth.patch.diff-tls) = ba875152d7b2e01d5e8a9b5d02719bc1a77c8f862cc3383cea778823d506f6d4 >+SIZE (qmail/auth.patch.diff-tls) = 3389 > MD5 (qmail/qmail-103.patch) = 9140ad2b03017145cd7963c84bb24f16 > SHA256 (qmail/qmail-103.patch) = 4cad53c7a6628a600c74c36bfee327db5052ca24c222d4013e4dfcd7f427653d > SIZE (qmail/qmail-103.patch) = 2104 >+MD5 (qmail/sendmail-flagf.patch) = 4e1f2d8315e7e2a5482798c9d19fac4d >+SHA256 (qmail/sendmail-flagf.patch) = 9b3951c22b98c0e5a6ebfa793f052d91dfe01d68a0ad8dc83b8e0bd60c01802e >+SIZE (qmail/sendmail-flagf.patch) = 863 >+MD5 (qmail/qmail-1.03-tls-20070408-renato.patch) = 77a74dc9c771e25e026b8dd8c42e0063 >+SHA256 (qmail/qmail-1.03-tls-20070408-renato.patch) = 7a6289f4748d31a58bfdaf37018117fbbb6731652e59387c13facc9752801b2b >+SIZE (qmail/qmail-1.03-tls-20070408-renato.patch) = 46613 >+MD5 (qmail/qmail-discard-double-bounces.patch) = 55d45bb8d2c3822a0e3544058aa5a3a3 >+SHA256 (qmail/qmail-discard-double-bounces.patch) = 14489eefd9908f60af13fadd574d0e9bb936e5d1b706690ce52efef68529a8d8 >+SIZE (qmail/qmail-discard-double-bounces.patch) = 1305 > MD5 (qmail/qmailqueue-patch) = 5a8d7a5863b0c56236af945dedd45754 > SHA256 (qmail/qmailqueue-patch) = 52e82aaa34e9f1308b063cc986a701f67e161662e9f789bb12af03a381530f94 > SIZE (qmail/qmailqueue-patch) = 2510 >@@ -13,94 +31,3 @@ > MD5 (qmail/big-concurrency.patch) = 2ff58c3570870a8ff9a1d9eb9aec05a6 > SHA256 (qmail/big-concurrency.patch) = 0322991955878e86af495f7317c3a4bd2e60640f9a6dd70ad501fff27242ac2f > SIZE (qmail/big-concurrency.patch) = 9331 >-MD5 (qmail/sendmail-flagf.patch) = 4e1f2d8315e7e2a5482798c9d19fac4d >-SHA256 (qmail/sendmail-flagf.patch) = 9b3951c22b98c0e5a6ebfa793f052d91dfe01d68a0ad8dc83b8e0bd60c01802e >-SIZE (qmail/sendmail-flagf.patch) = 863 >-MD5 (qmail/patch-qmail-1.03-rfc2821.diff) = 1b85f233ab5b9d7ec1a8da1188bf10ef >-SHA256 (qmail/patch-qmail-1.03-rfc2821.diff) = c34b331e27882f0596529df14f0e9f24c4dff9f941d04e5df17cc158dddac426 >-SIZE (qmail/patch-qmail-1.03-rfc2821.diff) = 2564 >-MD5 (qmail/qmail-date-localtime.patch) = d566e8bd99b33efee0194e855b8d6995 >-SHA256 (qmail/qmail-date-localtime.patch) = 852aee7577edf8814c2429f82740da2a7e0b0b23516e10c4f3f7e845a47be2d5 >-SIZE (qmail/qmail-date-localtime.patch) = 2603 >-MD5 (qmail/qmail-1.03-qmtpc.patch) = 122664c38338e5ec35fcac43f33d6927 >-SHA256 (qmail/qmail-1.03-qmtpc.patch) = f704b6c0ca3515a4bb488d14f7c94910aba4daa87420db6cd5b7ea19f17f7449 >-SIZE (qmail/qmail-1.03-qmtpc.patch) = 6197 >-MD5 (qmail/outgoingip.patch) = 3c9277dcf5f9b4b6d3a270fb3abf7994 >-SHA256 (qmail/outgoingip.patch) = c117f5c41033f062cdc782a16403fc19725e98d92e73ab193dfd24f48c0ca5ac >-SIZE (qmail/outgoingip.patch) = 6839 >-MD5 (qmail/outgoingip.patch-spamcontrol) = ed3ca1e309116647e9adb0a49194e2e5 >-SHA256 (qmail/outgoingip.patch-spamcontrol) = 721f5a1199867a26e69773608b07ec54fce1444cfa0679906592b60b7dd68abe >-SIZE (qmail/outgoingip.patch-spamcontrol) = 6769 >-MD5 (qmail/qmail-1.03-qmtpc_outgoingip.patch) = 4b2623cbd9e9a4f137f7b16f78a43975 >-SHA256 (qmail/qmail-1.03-qmtpc_outgoingip.patch) = d8dc66a5057b5ffbab4a9e0a27a6392b1f29d3c6aadea1f13f2290918846e89c >-SIZE (qmail/qmail-1.03-qmtpc_outgoingip.patch) = 10357 >-MD5 (qmail/qmail-maildir++.patch) = fd92b624ac1129a656eb1e567d1f0409 >-SHA256 (qmail/qmail-maildir++.patch) = 79e3f1f8f95b58b6d17e5469f125d873fe212d0a5a6d19b538ad57176fbafb52 >-SIZE (qmail/qmail-maildir++.patch) = 38088 >-MD5 (qmail/qmail-block-executables.patch) = e425b420e5251b4882fc699f7822f7a0 >-SHA256 (qmail/qmail-block-executables.patch) = 97512624eb02db51e10ab6d0dd834a8797a238d0e006bd1c6c94a183d291b456 >-SIZE (qmail/qmail-block-executables.patch) = 5070 >-MD5 (qmail/qmail-discard-double-bounces.patch) = 55d45bb8d2c3822a0e3544058aa5a3a3 >-SHA256 (qmail/qmail-discard-double-bounces.patch) = 14489eefd9908f60af13fadd574d0e9bb936e5d1b706690ce52efef68529a8d8 >-SIZE (qmail/qmail-discard-double-bounces.patch) = 1305 >-MD5 (qmail/qmail-spf-rc5.patch) = 434bd84b87e2027cfa643673c498bd6f >-SHA256 (qmail/qmail-spf-rc5.patch) = 8ad251d779125e11422ae9bcbf619b0ba002c0893dd8c8fe55a34a8b5fc42640 >-SIZE (qmail/qmail-spf-rc5.patch) = 63582 >-MD5 (qmail/qmail-spf-rc5.patch-tls) = db126b4ac29ad83c1c219e5323cef452 >-SHA256 (qmail/qmail-spf-rc5.patch-tls) = c884665ff0bc5a5272efe3e09aed71e648a79d0279bc708d5a9df25c5758804f >-SIZE (qmail/qmail-spf-rc5.patch-tls) = 63617 >-MD5 (qmail/qmail-spf-rc5.patch-auth-tls) = 262e381adc967df0a8ab4f15f2f6fe8f >-SHA256 (qmail/qmail-spf-rc5.patch-auth-tls) = 16fe99894938c30ed1928a61dabf0a598ef7e08a766a76cf084fe658d6d50092 >-SIZE (qmail/qmail-spf-rc5.patch-auth-tls) = 63752 >-MD5 (qmail/qmail-ldap-1.03-20060201.patch.gz) = 55fa135415ee011f3f4234d7d52a3565 >-SHA256 (qmail/qmail-ldap-1.03-20060201.patch.gz) = 92ba895df1957109ad856cc1d1554ece4d25d59017e77127dd52d76afd05525a >-SIZE (qmail/qmail-ldap-1.03-20060201.patch.gz) = 270788 >-MD5 (qmail/qmail-mysql-1.1.15.patch) = c0298550475f928e82881e574e905313 >-SHA256 (qmail/qmail-mysql-1.1.15.patch) = 3d2b6a08fb149d6c9fe6c8250e87edd6c4d4b2b0417f03adf5cf4202bbadc53f >-SIZE (qmail/qmail-mysql-1.1.15.patch) = 67602 >-MD5 (qmail/spamcontrol-2418_tgz.bin) = a5502cd69e573a2753e532bce8fb6c3a >-SHA256 (qmail/spamcontrol-2418_tgz.bin) = e9874f9961707cd15e135269796fbec7a2d417b18124d802a352d65b76e22d85 >-SIZE (qmail/spamcontrol-2418_tgz.bin) = 124059 >-MD5 (qmail/qmail-spf-rc5.patch-spamcontrol) = c7da17aa55896eae8c525d05c65387fd >-MD5 (qmail/qmail-1.03-tls-20021228-renato.patch) = be15cd5eaff7aa3cd88aee962febadc6 >-SHA256 (qmail/qmail-1.03-tls-20021228-renato.patch) = ab0de8f744241dcb7f5ee207fc7eab4f067bf42812deb85f9eb0050ac49e6e23 >-SIZE (qmail/qmail-1.03-tls-20021228-renato.patch) = 42095 >-MD5 (qmail/qmail-smtpd-auth-0.31.tar.gz) = 6b202f71a99fb41e9e32906017270ba0 >-SHA256 (qmail/qmail-smtpd-auth-0.31.tar.gz) = 1b439fa7e128de13fa80b86883f61a39d17b87b7e8916b6a0eab065bbe49b938 >-SIZE (qmail/qmail-smtpd-auth-0.31.tar.gz) = 8798 >-MD5 (qmail/qmail-smtpd-auth-close3.patch) = 0ba66d73dcba1c68ed714b07e47abd3e >-SHA256 (qmail/qmail-smtpd-auth-close3.patch) = d933e871261d6740cebe5c21cad81146525cfe06a464e277979f61c1242b5ad4 >-SIZE (qmail/qmail-smtpd-auth-close3.patch) = 520 >-MD5 (qmail/tarpit.patch) = 49a2c0a445981deb09f3af73041d75f5 >-SHA256 (qmail/tarpit.patch) = de94abbb71ef5d25e168725e435edd96ce3b14b7347440e0805dcb919b9d9604 >-SIZE (qmail/tarpit.patch) = 3089 >-MD5 (qmail/ext_todo-20030105.patch) = 99070bb55cac5ad61f8fb203422e651e >-SHA256 (qmail/ext_todo-20030105.patch) = d46d0225360c0477f93e2990637ebf912b2a86e494f424ef2952ee11ab533ac7 >-SIZE (qmail/ext_todo-20030105.patch) = 33763 >-MD5 (qmail/ext_todo-20030105_spf.patch) = 4d760732c92c01bd14d9957257ca4c1a >-SHA256 (qmail/ext_todo-20030105_spf.patch) = 544629c0003d01d27a5a45508e84332f247ed54ece57ff22c0c7c3a56ba086d6 >-SIZE (qmail/ext_todo-20030105_spf.patch) = 33781 >-MD5 (qmail/ext_todo-20030105_mysql.patch) = ecddff9ba6d725ec3be61843bc8007a7 >-SHA256 (qmail/ext_todo-20030105_mysql.patch) = 3fc65b91faaaae147dbf6264f9381664819ef2f236532764309d174f29919ff1 >-SIZE (qmail/ext_todo-20030105_mysql.patch) = 33797 >-MD5 (qmail/qmail-spf-rc5.patch-spamcontrol) = c7da17aa55896eae8c525d05c65387fd >-SHA256 (qmail/qmail-spf-rc5.patch-spamcontrol) = 52a3e4a6c8ae0124be280b6c0d183d81f4a6bd10c23fc735d99f4f731d4f5c6d >-SIZE (qmail/qmail-spf-rc5.patch-spamcontrol) = 64214 >-MD5 (qmail/auth.patch.diff) = 23e0509061cd5dda4a1abf9a7cb7596d >-SHA256 (qmail/auth.patch.diff) = 1d0f8e0ce139cd00b86f056bc31c1422d30b88cb8b125023d534cc3664f827b8 >-SIZE (qmail/auth.patch.diff) = 4412 >-MD5 (qmail/auth.patch.diff-tls) = 7e706dd124deb9a25cecd91fe652a90b >-SHA256 (qmail/auth.patch.diff-tls) = 467c5f68d5d332d2400f937c76311e5358b613923d64e68ae98d51d178c7de5e >-SIZE (qmail/auth.patch.diff-tls) = 2993 >-MD5 (qmail/ext_todo-20030105+big-todo.103.patch) = 5878870ef85d6a83ba9465ce94d9cd42 >-SHA256 (qmail/ext_todo-20030105+big-todo.103.patch) = 4e44ad403b21f5910b6af11295b82296bc8c0f18bc40dcfecfb95c11e5a296f7 >-SIZE (qmail/ext_todo-20030105+big-todo.103.patch) = 2523 >-MD5 (qmail/smtpextfork-ldap-20060201.patch) = a359bf9aa2a2799e4ab0fb9cc2dd6593 >-SHA256 (qmail/smtpextfork-ldap-20060201.patch) = 554eb7879d26bb5a3f3dd671e91abc803a53d5ba2fee397ab248b52917ff2ffc >-SIZE (qmail/smtpextfork-ldap-20060201.patch) = 6715 >-MD5 (qmail/smtpextfork-spamcontrol-2418_1.patch) = af5b96daaa2021e03712ada45e3b523c >-SHA256 (qmail/smtpextfork-spamcontrol-2418_1.patch) = 59c03c8ec28aa32c7869b3b63d9d760712f983fc5b8d9723fddbdb9e95c9f650 >-SIZE (qmail/smtpextfork-spamcontrol-2418_1.patch) = 7609 >-MD5 (qmail/README.smtpextfork) = e783965f5a7510c38b30f0ba3cda1e11 >-SHA256 (qmail/README.smtpextfork) = c43122d27d4e20dd955c30ca402903d2e9a6a1820c3cf11902e2477316abdcbb >-SIZE (qmail/README.smtpextfork) = 7618 >--- /usr/ports/distfiles/qmail/qmail-1.03-tls-20070408-renato.patch.orig 2008-01-24 20:35:28.000000000 -0200 >+++ /usr/ports/distfiles/qmail/qmail-1.03-tls-20070408-renato.patch 2008-01-24 18:19:51.000000000 -0200 >@@ -0,0 +1,1525 @@ >+Frederik Vermeulen <qmail-tls akrul inoa.net> 20070408 >+http://inoa.net/qmail-tls/ >+ >+This patch implements RFC 3207 (was RFC 2487) in qmail. >+This means you can get SSL or TLS encrypted and >+authenticated SMTP between the MTAs and from MUA to MTA. >+The code is considered experimental (but has worked for >+many since its first release on 1999-03-21). >+ >+Usage: - install OpenSSL-0.9.8 http://www.openssl.org/ >+ (any 0.9.6 to 0.9.8 version is presumed to work) >+ - apply patch to netqmail-1.05 http://qmail.org/netqmail >+ (should work on qmail-1.03 too). The patches to >+ qmail-remote.c and qmail-smtpd.c can be applied separately. >+ - provide a server certificate in /var/qmail/control/servercert.pem. >+ "make cert" makes a self-signed certificate. >+ "make cert-req" makes a certificate request. >+ Note: you can add the CA certificate and intermediate >+ certs to the end of servercert.pem. >+ - replace qmail-smtpd and/or qmail-remote binary >+ - verify operation (header information should show >+ something like >+ "Received [..] with (DHE-RSA-AES256-SHA encrypted) SMTP;") >+ If you don't have a server to test with, you can test >+ by sending mail to tag-ping@tbs-internet.com, >+ which will bounce your mail. >+ >+Optional: - when DEBUG is defined, some extra TLS info will be logged >+ - qmail-remote will authenticate with the certificate in >+ /var/qmail/control/clientcert.pem. By preference this is >+ the same as servercert.pem, where nsCertType should be >+ == server,client or be a generic certificate (no usage specified). >+ - when a 512 bit RSA key is provided in /var/qmail/control/rsa512.pem, >+ this key will be used instead of (slow) on-the-fly generation by >+ qmail-smtpd. Idem for 512 and 1024 DH params in control/dh512.pem >+ and control/dh1024.pem. `make tmprsadh` does this. >+ Periodical replacement can be done by crontab: >+ 01 01 * * * /var/qmail/bin/update_tmprsadh > /dev/null 2>&1 >+ - server authentication: >+ qmail-remote requires authentication from servers for which >+ /var/qmail/control/tlshosts/host.dom.ain.pem exists. >+ The .pem file contains the validating CA certificates. >+ One of the dNSName or the CommonName attributes have to match. >+ WARNING: this option may cause mail to be delayed, bounced, >+ doublebounced, and lost. >+ If /var/qmail/control/tlshosts/exhaustivelist is present, >+ the lists of hosts in /var/qmail/control/tlshosts is >+ an exhaustive list of hosts TLS is tried on. >+ If /var/qmail/control/notlshosts/host.dom.ain is present, >+ no TLS is tried on this host. >+ - client authentication: >+ when relay rules would reject an incoming mail, >+ qmail-smtpd can allow the mail based on a presented cert. >+ Certs are verified against a CA list in >+ /var/qmail/control/clientca.pem (eg. http://www.modssl.org/ >+ source/cvs/exp/mod_ssl/pkg.mod_ssl/pkg.sslcfg/ca-bundle.crt) >+ and the cert email-address has to match a line in >+ /var/qmail/control/tlsclients. This email-address is logged >+ in the headers. CRLs can be provided through >+ /var/qmail/control/clientcrl.pem. >+ - cipher selection: >+ qmail-remote: >+ openssl cipher string (`man ciphers`) read from >+ /var/qmail/control/tlsclientciphers >+ qmail-smtpd: >+ openssl cipher string read from TLSCIPHERS environment variable >+ (can vary based on client IP address e.g.) >+ or if that is not available /var/qmail/control/tlsserverciphers >+ - smtps (deprecated SMTP over TLS via port 465): >+ qmail-remote: when connecting to port 465 >+ qmail-smtpd: when SMTPS environment variable is not empty >+ >+Caveats: - do a `make clean` after patching >+ - binaries dynamically linked with current openssl versions need >+ recompilation when the shared openssl libs are upgraded. >+ - this patch could conflict with other patches (notably those >+ replacing \n with \r\n, which is a bad idea on encrypted links). >+ - some broken servers have a problem with TLSv1 compatibility. >+ Uncomment the line where we set the SSL_OP_NO_TLSv1 option. >+ - needs working /dev/urandom (or EGD for openssl versions >0.9.7) >+ for seeding random number generator. >+ - packagers should make sure that installing without a valid >+ servercert is impossible >+ - when applied in combination with AUTH patch, AUTH patch >+ should be applied first and first part of this patch >+ will fail. This error can be ignored. Packagers should >+ cut the first 12 lines of this patch to make a happy >+ patch >+ - `make tmprsadh` is recommended (or should I say required), >+ otherwise DH generation can be unpredictably slow >+ - some need "-I/usr/kerberos/include" to be added in conf-cc >+ >+Copyright: GPL >+ Links with OpenSSL >+ Inspiration and code from examples in SSLeay (E. Young >+ <eay@cryptsoft.com> and T. Hudson <tjh@cryptsoft.com>), >+ stunnel (M. Trojnara <mtrojnar@ddc.daewoo.com.pl>), >+ Postfix/TLS (L. Jaenicke <Lutz.Jaenicke@aet.tu-cottbus.de>), >+ modssl (R. Engelschall <rse@engelschall.com>), >+ openssl examples of E. Rescorla <ekr@rtfm.com>. >+ >+Bug reports: mailto:<qmail-tls akrul inoa.net> >+ >+ >+--- qmail-1.03-orig/Makefile-cert.mk 1969-12-31 21:00:00.000000000 -0300 >++++ qmail-1.03/Makefile-cert.mk 2008-01-24 14:34:28.000000000 -0200 >+@@ -0,0 +1,21 @@ >++cert-req: req.pem >++cert cert-req: QMAIL/control/clientcert.pem >++ @: >++ >++QMAIL/control/clientcert.pem: QMAIL/control/servercert.pem >++ ln -s $< $@ >++ >++QMAIL/control/servercert.pem: >++ PATH=$$PATH:/usr/local/ssl/bin \ >++ openssl req -new -x509 -nodes -days 366 -out $@ -keyout $@ >++ chmod 640 $@ >++ chown `head -2 conf-users | tail -1`:`head -1 conf-groups` $@ >++ >++req.pem: >++ PATH=$$PATH:/usr/local/ssl/bin openssl req \ >++ -new -nodes -out $@ -keyout QMAIL/control/servercert.pem >++ chmod 640 QMAIL/control/servercert.pem >++ chown `head -2 conf-users | tail -1`:`head -1 conf-groups` QMAIL/control/servercert.pem >++ @echo >++ @echo "Send req.pem to your CA to obtain signed_req.pem, and do:" >++ @echo "cat signed_req.pem >> QMAIL/control/servercert.pem" >+--- qmail-1.03-orig/TARGETS 2008-01-24 15:54:07.000000000 -0200 >++++ qmail-1.03/TARGETS 2008-01-24 14:36:13.000000000 -0200 >+@@ -168,6 +168,8 @@ >+ constmap.o >+ timeoutread.o >+ timeoutwrite.o >++tls.o >++ssl_timeoutio.o >+ timeoutconn.o >+ tcpto.o >+ dns.o >+@@ -321,6 +323,7 @@ >+ binm2+df >+ binm3 >+ binm3+df >++Makefile-cert >+ it >+ qmail-local.0 >+ qmail-lspawn.0 >+@@ -386,3 +389,4 @@ >+ man >+ setup >+ check >++update_tmprsadh >+--- qmail-1.03-orig/conf-cc 2008-01-24 15:54:08.000000000 -0200 >++++ qmail-1.03/conf-cc 2008-01-24 14:27:50.000000000 -0200 >+@@ -1 +1 @@ >+-cc -O2 >++cc -O2 -pipe -DTLS=20070408 -I/usr/local/ssl/include >+--- qmail-1.03-orig/dns.c 2008-01-24 15:54:11.000000000 -0200 >++++ qmail-1.03/dns.c 2008-01-24 14:27:50.000000000 -0200 >+@@ -286,12 +286,11 @@ >+ int pref; >+ { >+ int r; >+- struct ip_mx ix; >++ struct ip_mx ix = {0}; >+ >+ if (!stralloc_copy(&glue,sa)) return DNS_MEM; >+ if (!stralloc_0(&glue)) return DNS_MEM; >+ if (glue.s[0]) { >+- ix.pref = 0; >+ if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)]) >+ { >+ if (!ipalloc_append(ia,&ix)) return DNS_MEM; >+@@ -310,9 +309,16 @@ >+ ix.ip = ip; >+ ix.pref = pref; >+ if (r == DNS_SOFT) return DNS_SOFT; >+- if (r == 1) >++ if (r == 1) { >++#ifdef IX_FQDN >++ ix.fqdn = glue.s; >++#endif >+ if (!ipalloc_append(ia,&ix)) return DNS_MEM; >+ } >++ } >++#ifdef IX_FQDN >++ glue.s = 0; >++#endif >+ return 0; >+ } >+ >+@@ -332,7 +338,7 @@ >+ { >+ int r; >+ struct mx { stralloc sa; unsigned short p; } *mx; >+- struct ip_mx ix; >++ struct ip_mx ix = {0}; >+ int nummx; >+ int i; >+ int j; >+@@ -344,7 +350,6 @@ >+ if (!stralloc_copy(&glue,sa)) return DNS_MEM; >+ if (!stralloc_0(&glue)) return DNS_MEM; >+ if (glue.s[0]) { >+- ix.pref = 0; >+ if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)]) >+ { >+ if (!ipalloc_append(ia,&ix)) return DNS_MEM; >+--- qmail-1.03-orig/hier.c 2008-01-24 15:54:09.000000000 -0200 >++++ qmail-1.03/hier.c 2008-01-24 14:37:02.000000000 -0200 >+@@ -102,6 +102,9 @@ >+ c(auto_qmail,"bin","qail",auto_uido,auto_gidq,0755); >+ c(auto_qmail,"bin","elq",auto_uido,auto_gidq,0755); >+ c(auto_qmail,"bin","pinq",auto_uido,auto_gidq,0755); >++#ifdef TLS >++ c(auto_qmail,"bin","update_tmprsadh",auto_uido,auto_gidq,0755); >++#endif >+ >+ >+ >+--- qmail-1.03-orig/ipalloc.h 2008-01-24 15:54:11.000000000 -0200 >++++ qmail-1.03/ipalloc.h 2008-01-24 14:27:50.000000000 -0200 >+@@ -3,7 +3,15 @@ >+ >+ #include "ip.h" >+ >++#ifdef TLS >++# define IX_FQDN 1 >++#endif >++ >++#ifdef IX_FQDN >++struct ip_mx { struct ip_address ip; int pref; char *fqdn; } ; >++#else >+ struct ip_mx { struct ip_address ip; int pref; } ; >++#endif >+ >+ #include "gen_alloc.h" >+ >+--- qmail-1.03-orig/qmail-control.9 2008-01-24 15:54:07.000000000 -0200 >++++ qmail-1.03/qmail-control.9 2008-01-24 14:38:13.000000000 -0200 >+@@ -43,11 +43,15 @@ >+ .I badmailfrom \fR(none) \fRqmail-smtpd >+ .I bouncefrom \fRMAILER-DAEMON \fRqmail-send >+ .I bouncehost \fIme \fRqmail-send >++.I clientca.pem \fR(none) \fRqmail-smtpd >++.I clientcert.pem \fR(none) \fRqmail-remote >+ .I concurrencylocal \fR10 \fRqmail-send >+ .I concurrencyremote \fR20 \fRqmail-send >+ .I defaultdomain \fIme \fRqmail-inject >+ .I defaulthost \fIme \fRqmail-inject >+ .I databytes \fR0 \fRqmail-smtpd >++.I dh1024.pem \fR(none) \fRqmail-smtpd >++.I dh512.pem \fR(none) \fRqmail-smtpd >+ .I doublebouncehost \fIme \fRqmail-send >+ .I doublebounceto \fRpostmaster \fRqmail-send >+ .I envnoathost \fIme \fRqmail-send >+@@ -61,11 +65,17 @@ >+ .I qmqpservers \fR(none) \fRqmail-qmqpc >+ .I queuelifetime \fR604800 \fRqmail-send >+ .I rcpthosts \fR(none) \fRqmail-smtpd >++.I rsa512.pem \fR(none) \fRqmail-smtpd >++.I servercert.pem \fR(none) \fRqmail-smtpd >+ .I smtpgreeting \fIme \fRqmail-smtpd >+ .I smtproutes \fR(none) \fRqmail-remote >+ .I timeoutconnect \fR60 \fRqmail-remote >+ .I timeoutremote \fR1200 \fRqmail-remote >+ .I timeoutsmtpd \fR1200 \fRqmail-smtpd >++.I tlsclients \fR(none) \fRqmail-smtpd >++.I tlsclientciphers \fR(none) \fRqmail-remote >++.I tlshosts/FQDN.pem \fR(none) \fRqmail-remote >++.I tlsserverciphers \fR(none) \fRqmail-smtpd >+ .I virtualdomains \fR(none) \fRqmail-send >+ .fi >+ .RE >+--- qmail-1.03-orig/qmail-remote.8 2008-01-24 15:54:07.000000000 -0200 >++++ qmail-1.03/qmail-remote.8 2008-01-24 15:02:04.000000000 -0200 >+@@ -114,6 +114,10 @@ >+ always exits zero. >+ .SH "CONTROL FILES" >+ .TP 5 >++.I clientcert.pem >++SSL certificate that is used to authenticate with the remote server >++during a TLS session. >++.TP 5 >+ .I helohost >+ Current host name, >+ for use solely in saying hello to the remote SMTP server. >+@@ -123,6 +127,16 @@ >+ otherwise >+ .B qmail-remote >+ refuses to run. >++ >++.TP 5 >++.I notlshosts/<FQDN> >++.B qmail-remote >++will not try TLS on servers for which this file exists >++.RB ( <FQDN> >++is the fully-qualified domain name of the server). >++.IR (tlshosts/<FQDN>.pem >++takes precedence over this file however). >++ >+ .TP 5 >+ .I smtproutes >+ Artificial SMTP routes. >+@@ -156,6 +170,8 @@ >+ this tells >+ .B qmail-remote >+ to look up MX records as usual. >++.I port >++value of 465 (deprecated smtps port) causes TLS session to be started. >+ .I smtproutes >+ may include wildcards: >+ >+@@ -195,6 +211,33 @@ >+ .B qmail-remote >+ will wait for each response from the remote SMTP server. >+ Default: 1200. >++ >++.TP 5 >++.I tlsclientciphers >++A set of OpenSSL client cipher strings. Multiple ciphers >++contained in a string should be separated by a colon. >++ >++.TP 5 >++.I tlshosts/<FQDN>.pem >++.B qmail-remote >++requires TLS authentication from servers for which this file exists >++.RB ( <FQDN> >++is the fully-qualified domain name of the server). One of the >++.I dNSName >++or the >++.I CommonName >++attributes have to match. The file contains the trusted CA certificates. >++ >++.B WARNING: >++this option may cause mail to be delayed, bounced, doublebounced, or lost. >++ >++.TP 5 >++.I tlshosts/exhaustivelist >++if this file exists >++no TLS will be tried on hosts other than those for which a file >++.B tlshosts/<FQDN>.pem >++exists. >++ >+ .SH "SEE ALSO" >+ addresses(5), >+ envelopes(5), >+--- qmail-1.03-orig/qmail-smtpd.8 2008-01-24 15:54:07.000000000 -0200 >++++ qmail-1.03/qmail-smtpd.8 2008-01-24 15:14:50.000000000 -0200 >+@@ -19,6 +19,15 @@ >+ see >+ .BR tcp-environ(5) . >+ >++If the environment variable >++.B SMTPS >++is non-empty, >++.B qmail-smtpd >++starts a TLS session (to support the deprecated SMTPS protocol, >++normally on port 465). Otherwise, >++.B qmail-smtpd >++offers the STARTTLS extension to ESMTP. >++ >+ .B qmail-smtpd >+ is responsible for counting hops. >+ It rejects any message with 100 or more >+@@ -76,6 +85,19 @@ >+ .BR @\fIhost , >+ meaning every address at >+ .IR host . >++ >++.TP 5 >++.I clientca.pem >++A list of Certifying Authority (CA) certificates that are used to verify >++the client-presented certificates during a TLS-encrypted session. >++ >++ .TP 5 >++.I clientcrl.pem >++A list of Certificate Revocation Lists (CRLs). If present it >++should contain the CRLs of the CAs in >++.I clientca.pem >++and client certs will be checked for revocation. >++ >+ .TP 5 >+ .I databytes >+ Maximum number of bytes allowed in a message, >+@@ -103,6 +125,18 @@ >+ .B DATABYTES >+ is set, it overrides >+ .IR databytes . >++ >++.TP 5 >++.I dh1024.pem >++If these 1024 bit DH parameters are provided, >++.B qmail-smtpd >++will use them for TLS sessions instead of generating one on-the-fly >++(which is very timeconsuming). >++.TP 5 >++.I dh512.pem >++512 bit counterpart for >++.B dh1024.pem. >++ >+ .TP 5 >+ .I localiphost >+ Replacement host name for local IP addresses. >+@@ -178,6 +212,19 @@ >+ >+ Envelope recipient addresses without @ signs are >+ always allowed through. >++ >++.TP 5 >++.I rsa512.pem >++If this 512 bit RSA key is provided, >++.B qmail-smtpd >++will use it for TLS sessions instead of generaring one on-the-fly. >++ >++.TP 5 >++.I servercert.pem >++SSL certificate to be presented to clients in TLS-encrypted sessions. >++Should contain both the certificate and the private key. Certifying Authority >++(CA) and intermediate certificates can be added at the end of the file. >++ >+ .TP 5 >+ .I smtpgreeting >+ SMTP greeting message. >+@@ -196,6 +243,24 @@ >+ .B qmail-smtpd >+ will wait for each new buffer of data from the remote SMTP client. >+ Default: 1200. >++ >++.TP 5 >++.I tlsclients >++A list of email addresses. When relay rules would reject an incoming message, >++.B qmail-smtpd >++can allow it if the client presents a certificate that can be verified against >++the CA list in >++.I clientca.pem >++and the certificate email address is in >++.IR tlsclients . >++ >++.TP 5 >++.I tlsserverciphers >++A set of OpenSSL cipher strings. Multiple ciphers contained in a >++string should be separated by a colon. If the environment variable >++.B TLSCIPHERS >++is set to such a string, it takes precedence. >++ >+ .SH "SEE ALSO" >+ tcp-env(1), >+ tcp-environ(5), >+--- qmail-1.03-orig/ssl_timeoutio.c 1969-12-31 21:00:00.000000000 -0300 >++++ qmail-1.03/ssl_timeoutio.c 2008-01-24 14:56:54.000000000 -0200 >+@@ -0,0 +1,95 @@ >++#include "select.h" >++#include "error.h" >++#include "ndelay.h" >++#include "now.h" >++#include "ssl_timeoutio.h" >++ >++int ssl_timeoutio(int (*fun)(), >++ int t, int rfd, int wfd, SSL *ssl, char *buf, int len) >++{ >++ int n; >++ const datetime_sec end = (datetime_sec)t + now(); >++ >++ do { >++ fd_set fds; >++ struct timeval tv; >++ >++ const int r = buf ? fun(ssl, buf, len) : fun(ssl); >++ if (r > 0) return r; >++ >++ t = end - now(); >++ if (t < 0) break; >++ tv.tv_sec = (time_t)t; tv.tv_usec = 0; >++ >++ FD_ZERO(&fds); >++ switch (SSL_get_error(ssl, r)) >++ { >++ default: return r; /* some other error */ >++ case SSL_ERROR_WANT_READ: >++ FD_SET(rfd, &fds); n = select(rfd + 1, &fds, NULL, NULL, &tv); >++ break; >++ case SSL_ERROR_WANT_WRITE: >++ FD_SET(wfd, &fds); n = select(wfd + 1, NULL, &fds, NULL, &tv); >++ break; >++ } >++ >++ /* n is the number of descriptors that changed status */ >++ } while (n > 0); >++ >++ if (n != -1) errno = error_timeout; >++ return -1; >++} >++ >++int ssl_timeoutaccept(int t, int rfd, int wfd, SSL *ssl) >++{ >++ int r; >++ >++ /* if connection is established, keep NDELAY */ >++ if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1) return -1; >++ r = ssl_timeoutio(SSL_accept, t, rfd, wfd, ssl, NULL, 0); >++ >++ if (r <= 0) { ndelay_off(rfd); ndelay_off(wfd); } >++ else SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); >++ >++ return r; >++} >++ >++int ssl_timeoutconn(int t, int rfd, int wfd, SSL *ssl) >++{ >++ int r; >++ >++ /* if connection is established, keep NDELAY */ >++ if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1) return -1; >++ r = ssl_timeoutio(SSL_connect, t, rfd, wfd, ssl, NULL, 0); >++ >++ if (r <= 0) { ndelay_off(rfd); ndelay_off(wfd); } >++ else SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); >++ >++ return r; >++} >++ >++int ssl_timeoutrehandshake(int t, int rfd, int wfd, SSL *ssl) >++{ >++ int r; >++ >++ SSL_renegotiate(ssl); >++ r = ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0); >++ if (r <= 0 || ssl->type == SSL_ST_CONNECT) return r; >++ >++ /* this is for the server only */ >++ ssl->state = SSL_ST_ACCEPT; >++ return ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0); >++} >++ >++int ssl_timeoutread(int t, int rfd, int wfd, SSL *ssl, char *buf, int len) >++{ >++ if (!buf) return 0; >++ if (SSL_pending(ssl)) return SSL_read(ssl, buf, len); >++ return ssl_timeoutio(SSL_read, t, rfd, wfd, ssl, buf, len); >++} >++ >++int ssl_timeoutwrite(int t, int rfd, int wfd, SSL *ssl, char *buf, int len) >++{ >++ if (!buf) return 0; >++ return ssl_timeoutio(SSL_write, t, rfd, wfd, ssl, buf, len); >++} >+diff -urN qmail-1.03-orig/ssl_timeoutio.h qmail-1.03/ssl_timeoutio.h >+--- qmail-1.03-orig/ssl_timeoutio.h 1969-12-31 21:00:00.000000000 -0300 >++++ qmail-1.03/ssl_timeoutio.h 2008-01-24 14:57:40.000000000 -0200 >+@@ -0,0 +1,21 @@ >++#ifndef SSL_TIMEOUTIO_H >++#define SSL_TIMEOUTIO_H >++ >++#include <openssl/ssl.h> >++ >++/* the version is like this: 0xMNNFFPPS: major minor fix patch status */ >++#if OPENSSL_VERSION_NUMBER < 0x00906000L >++# error "Need OpenSSL version at least 0.9.6" >++#endif >++ >++int ssl_timeoutconn(int t, int rfd, int wfd, SSL *ssl); >++int ssl_timeoutaccept(int t, int rfd, int wfd, SSL *ssl); >++int ssl_timeoutrehandshake(int t, int rfd, int wfd, SSL *ssl); >++ >++int ssl_timeoutread(int t, int rfd, int wfd, SSL *ssl, char *buf, int len); >++int ssl_timeoutwrite(int t, int rfd, int wfd, SSL *ssl, char *buf, int len); >++ >++int ssl_timeoutio( >++ int (*fun)(), int t, int rfd, int wfd, SSL *ssl, char *buf, int len); >++ >++#endif >+--- qmail-1.03-orig/tls.c 1969-12-31 21:00:00.000000000 -0300 >++++ qmail-1.03/tls.c 2008-01-24 15:01:09.000000000 -0200 >+@@ -0,0 +1,25 @@ >++#include "exit.h" >++#include "error.h" >++#include <openssl/ssl.h> >++#include <openssl/err.h> >++ >++int smtps = 0; >++SSL *ssl = NULL; >++ >++void ssl_free(SSL *myssl) { SSL_shutdown(myssl); SSL_free(myssl); } >++void ssl_exit(int status) { if (ssl) ssl_free(ssl); _exit(status); } >++ >++const char *ssl_error() >++{ >++ int r = ERR_get_error(); >++ if (!r) return NULL; >++ SSL_load_error_strings(); >++ return ERR_error_string(r, NULL); >++} >++const char *ssl_error_str() >++{ >++ const char *err = ssl_error(); >++ if (err) return err; >++ if (!errno) return 0; >++ return (errno == error_timeout) ? "timed out" : error_str(errno); >++} >+--- qmail-1.03-orig/tls.h 1969-12-31 21:00:00.000000000 -0300 >++++ qmail-1.03/tls.h 2008-01-24 14:58:30.000000000 -0200 >+@@ -0,0 +1,16 @@ >++#ifndef TLS_H >++#define TLS_H >++ >++#include <openssl/ssl.h> >++ >++extern int smtps; >++extern SSL *ssl; >++ >++void ssl_free(SSL *myssl); >++void ssl_exit(int status); >++# define _exit ssl_exit >++ >++const char *ssl_error(); >++const char *ssl_error_str(); >++ >++#endif >+--- qmail-1.03-orig/update_tmprsadh.sh 1969-12-31 21:00:00.000000000 -0300 >++++ qmail-1.03/update_tmprsadh.sh 2008-01-24 14:58:42.000000000 -0200 >+@@ -0,0 +1,25 @@ >++#!/bin/sh >++ >++# Update temporary RSA and DH keys >++# Frederik Vermeulen 2004-05-31 GPL >++ >++umask 0077 || exit 0 >++ >++export PATH="$PATH:/usr/local/bin/ssl:/usr/sbin" >++ >++openssl genrsa -out QMAIL/control/rsa512.new 512 && >++chmod 600 QMAIL/control/rsa512.new && >++chown UGQMAILD QMAIL/control/rsa512.new && >++mv -f QMAIL/control/rsa512.new QMAIL/control/rsa512.pem >++echo >++ >++openssl dhparam -2 -out QMAIL/control/dh512.new 512 && >++chmod 600 QMAIL/control/dh512.new && >++chown UGQMAILD QMAIL/control/dh512.new && >++mv -f QMAIL/control/dh512.new QMAIL/control/dh512.pem >++echo >++ >++openssl dhparam -2 -out QMAIL/control/dh1024.new 1024 && >++chmod 600 QMAIL/control/dh1024.new && >++chown UGQMAILD QMAIL/control/dh1024.new && >++mv -f QMAIL/control/dh1024.new QMAIL/control/dh1024.pem >+--- qmail-1.03-orig/Makefile 2008-01-24 17:10:07.000000000 -0200 >++++ qmail-1.03/Makefile 2008-01-24 17:11:30.000000000 -0200 >+@@ -808,7 +808,7 @@ >+ forward preline condredirect bouncesaying except maildirmake \ >+ maildir2mbox maildirwatch qail elq pinq idedit install-big install \ >+ instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \ >+-binm3 binm3+df >++binm3 binm3+df update_tmprsadh >+ >+ load: \ >+ make-load warn-auto.sh systype >+@@ -1444,6 +1444,7 @@ >+ substdio.a error.a str.a fs.a auto_qmail.o dns.lib socket.lib >+ ./load qmail-remote control.o constmap.o timeoutread.o \ >+ timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \ >++ tls.o ssl_timeoutio.o -L/usr/lib -lssl -lcrypto \ >+ ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \ >+ lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \ >+ str.a fs.a auto_qmail.o `cat dns.lib` `cat socket.lib` >+@@ -1539,6 +1540,7 @@ >+ fs.a auto_qmail.o socket.lib >+ ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \ >+ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \ >++ tls.o ssl_timeoutio.o ndelay.a -L/usr/lib -lssl -lcrypto \ >+ received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \ >+ datetime.a getln.a open.a sig.a case.a env.a stralloc.a \ >+ alloc.a substdio.a error.a str.a fs.a auto_qmail.o `cat \ >+@@ -1827,7 +1829,8 @@ >+ ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \ >+ ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \ >+ prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \ >+-maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c >++maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c \ >++update_tmprsadh >+ shar -m `cat FILES` > shar >+ chmod 400 shar >+ >+@@ -2108,6 +2111,19 @@ >+ compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h >+ ./compile timeoutwrite.c >+ >++qmail-smtpd: tls.o ssl_timeoutio.o ndelay.a >++qmail-remote: tls.o ssl_timeoutio.o >++qmail-smtpd.o: tls.h ssl_timeoutio.h >++qmail-remote.o: tls.h ssl_timeoutio.h >++ >++tls.o: \ >++compile tls.c exit.h error.h >++ ./compile tls.c >++ >++ssl_timeoutio.o: \ >++compile ssl_timeoutio.c ssl_timeoutio.h select.h error.h ndelay.h >++ ./compile ssl_timeoutio.c >++ >+ token822.o: \ >+ compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \ >+ gen_alloc.h gen_allocdefs.h >+@@ -2139,3 +2155,26 @@ >+ wait_pid.o: \ >+ compile wait_pid.c error.h haswaitp.h >+ ./compile wait_pid.c >++ >++cert cert-req: \ >++Makefile-cert >++ @$(MAKE) -sf $< $@ >++ >++Makefile-cert: \ >++conf-qmail conf-users conf-groups Makefile-cert.mk >++ @cat Makefile-cert.mk \ >++ | sed s}QMAIL}"`head -1 conf-qmail`"}g \ >++ > $@ >++ >++update_tmprsadh: \ >++conf-qmail conf-users conf-groups update_tmprsadh.sh >++ @cat update_tmprsadh.sh\ >++ | sed s}UGQMAILD}"`head -2 conf-users|tail -1`:`head -1 conf-groups`"}g \ >++ | sed s}QMAIL}"`head -1 conf-qmail`"}g \ >++ > $@ >++ chmod 755 update_tmprsadh >++ >++tmprsadh: \ >++update_tmprsadh >++ echo "Creating new temporary RSA and DH parameters" >++ ./update_tmprsadh >+--- qmail-1.03-orig/qmail-remote.c 2008-01-24 17:36:23.000000000 -0200 >++++ qmail-1.03/qmail-remote.c 2008-01-24 17:45:57.000000000 -0200 >+@@ -48,6 +48,17 @@ >+ >+ struct ip_address partner; >+ >++#ifdef TLS >++# include <sys/stat.h> >++# include "tls.h" >++# include "ssl_timeoutio.h" >++# include <openssl/x509v3.h> >++# define EHLO 1 >++ >++int tls_init(); >++const char *ssl_err_str = 0; >++#endif >++ >+ void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); } >+ void zero() { if (substdio_put(subfdoutsmall,"\0",1) == -1) _exit(0); } >+ void zerodie() { zero(); substdio_flush(subfdoutsmall); _exit(0); } >+@@ -99,6 +110,9 @@ >+ outhost(); >+ out(" but connection died. "); >+ if (flagcritical) out("Possible duplicate! "); >++#ifdef TLS >++ if (ssl_err_str) { out(ssl_err_str); out(" "); } >++#endif >+ out("(#4.4.2)\n"); >+ zerodie(); >+ } >+@@ -110,6 +124,12 @@ >+ int saferead(fd,buf,len) int fd; char *buf; int len; >+ { >+ int r; >++#ifdef TLS >++ if (ssl) { >++ r = ssl_timeoutread(timeout, smtpfd, smtpfd, ssl, buf, len); >++ if (r < 0) ssl_err_str = ssl_error_str(); >++ } else >++#endif >+ r = timeoutread(timeout,smtpfd,buf,len); >+ if (r <= 0) dropped(); >+ return r; >+@@ -117,6 +137,12 @@ >+ int safewrite(fd,buf,len) int fd; char *buf; int len; >+ { >+ int r; >++#ifdef TLS >++ if (ssl) { >++ r = ssl_timeoutwrite(timeout, smtpfd, smtpfd, ssl, buf, len); >++ if (r < 0) ssl_err_str = ssl_error_str(); >++ } else >++#endif >+ r = timeoutwrite(timeout,smtpfd,buf,len); >+ if (r <= 0) dropped(); >+ return r; >+@@ -163,6 +189,65 @@ >+ return code; >+ } >+ >++#ifdef EHLO >++saa ehlokw = {0}; /* list of EHLO keywords and parameters */ >++int maxehlokwlen = 0; >++ >++unsigned long ehlo() >++{ >++ stralloc *sa; >++ char *s, *e, *p; >++ unsigned long code; >++ >++ if (ehlokw.len > maxehlokwlen) maxehlokwlen = ehlokw.len; >++ ehlokw.len = 0; >++ >++# ifdef MXPS >++ if (type == 's') return 0; >++# endif >++ >++ substdio_puts(&smtpto, "EHLO "); >++ substdio_put(&smtpto, helohost.s, helohost.len); >++ substdio_puts(&smtpto, "\r\n"); >++ substdio_flush(&smtpto); >++ >++ code = smtpcode(); >++ if (code != 250) return code; >++ >++ s = smtptext.s; >++ while (*s++ != '\n') ; /* skip the first line: contains the domain */ >++ >++ e = smtptext.s + smtptext.len - 6; /* 250-?\n */ >++ while (s <= e) >++ { >++ int wasspace = 0; >++ >++ if (!saa_readyplus(&ehlokw, 1)) temp_nomem(); >++ sa = ehlokw.sa + ehlokw.len++; >++ if (ehlokw.len > maxehlokwlen) *sa = sauninit; else sa->len = 0; >++ >++ /* smtptext is known to end in a '\n' */ >++ for (p = (s += 4); ; ++p) >++ if (*p == '\n' || *p == ' ' || *p == '\t') { >++ if (!wasspace) >++ if (!stralloc_catb(sa, s, p - s) || !stralloc_0(sa)) temp_nomem(); >++ if (*p == '\n') break; >++ wasspace = 1; >++ } else if (wasspace == 1) { >++ wasspace = 0; >++ s = p; >++ } >++ s = ++p; >++ >++ /* keyword should consist of alpha-num and '-' >++ * broken AUTH might use '=' instead of space */ >++ for (p = sa->s; *p; ++p) if (*p == '=') { *p = 0; break; } >++ } >++ >++ return 250; >++} >++#endif >++ >+ void outsmtptext() >+ { >+ int i; >+@@ -179,6 +264,11 @@ >+ char *prepend; >+ char *append; >+ { >++#ifdef TLS >++ /* shouldn't talk to the client unless in an appropriate state */ >++ int state = ssl ? ssl->state : SSL_ST_BEFORE; >++ if (state & SSL_ST_OK || (!smtps && state & SSL_ST_BEFORE)) >++#endif >+ substdio_putsflush(&smtpto,"QUIT\r\n"); >+ /* waiting for remote side is just too ridiculous */ >+ out(prepend); >+@@ -186,6 +276,30 @@ >+ out(append); >+ out(".\n"); >+ outsmtptext(); >++ >++#if defined(TLS) && defined(DEBUG) >++ if (ssl) { >++ X509 *peercert; >++ >++ out("STARTTLS proto="); out(SSL_get_version(ssl)); >++ out("; cipher="); out(SSL_get_cipher(ssl)); >++ >++ /* we want certificate details */ >++ if (peercert = SSL_get_peer_certificate(ssl)) { >++ char *str; >++ >++ str = X509_NAME_oneline(X509_get_subject_name(peercert), NULL, 0); >++ out("; subject="); out(str); OPENSSL_free(str); >++ >++ str = X509_NAME_oneline(X509_get_issuer_name(peercert), NULL, 0); >++ out("; issuer="); out(str); OPENSSL_free(str); >++ >++ X509_free(peercert); >++ } >++ out(";\n"); >++ } >++#endif >++ >+ zerodie(); >+ } >+ >+@@ -214,6 +328,194 @@ >+ substdio_flush(&smtpto); >+ } >+ >++#ifdef TLS >++char *partner_fqdn = 0; >++ >++# define TLS_QUIT quit(ssl ? "; connected to " : "; connecting to ", "") >++void tls_quit(const char *s1, const char *s2) >++{ >++ out(s1); if (s2) { out(": "); out(s2); } TLS_QUIT; >++} >++# define tls_quit_error(s) tls_quit(s, ssl_error()) >++ >++int match_partner(const char *s, int len) >++{ >++ if (!case_diffb(partner_fqdn, len, s) && !partner_fqdn[len]) return 1; >++ /* we also match if the name is *.domainname */ >++ if (*s == '*') { >++ const char *domain = partner_fqdn + str_chr(partner_fqdn, '.'); >++ if (!case_diffb(domain, --len, ++s) && !domain[len]) return 1; >++ } >++ return 0; >++} >++ >++/* don't want to fail handshake if certificate can't be verified */ >++int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } >++ >++int tls_init() >++{ >++ int i; >++ SSL *myssl; >++ SSL_CTX *ctx; >++ stralloc saciphers = {0}; >++ const char *ciphers, *servercert = 0; >++ >++ if (partner_fqdn) { >++ struct stat st; >++ stralloc tmp = {0}; >++ if (!stralloc_copys(&tmp, "control/tlshosts/") >++ || !stralloc_catb(&tmp, partner_fqdn, str_len(partner_fqdn)) >++ || !stralloc_catb(&tmp, ".pem", 5)) temp_nomem(); >++ if (stat(tmp.s, &st) == 0) >++ servercert = tmp.s; >++ else { >++ if (!stralloc_copys(&tmp, "control/notlshosts/") >++ || !stralloc_catb(&tmp, partner_fqdn, str_len(partner_fqdn)+1)) >++ temp_nomem(); >++ if ((stat("control/tlshosts/exhaustivelist", &st) == 0) || >++ (stat(tmp.s, &st) == 0)) { >++ alloc_free(tmp.s); >++ return 0; >++ } >++ alloc_free(tmp.s); >++ } >++ } >++ >++ if (!smtps) { >++ stralloc *sa = ehlokw.sa; >++ unsigned int len = ehlokw.len; >++ /* look for STARTTLS among EHLO keywords */ >++ for ( ; len && case_diffs(sa->s, "STARTTLS"); ++sa, --len) ; >++ if (!len) { >++ if (!servercert) return 0; >++ out("ZNo TLS achieved while "); out(servercert); >++ out(" exists"); smtptext.len = 0; TLS_QUIT; >++ } >++ } >++ >++ SSL_library_init(); >++ ctx = SSL_CTX_new(SSLv23_client_method()); >++ if (!ctx) { >++ if (!smtps && !servercert) return 0; >++ smtptext.len = 0; >++ tls_quit_error("ZTLS error initializing ctx"); >++ } >++ >++ if (servercert) { >++ if (!SSL_CTX_load_verify_locations(ctx, servercert, NULL)) { >++ SSL_CTX_free(ctx); >++ smtptext.len = 0; >++ out("ZTLS unable to load "); tls_quit_error(servercert); >++ } >++ /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ >++ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb); >++ } >++ >++ /* let the other side complain if it needs a cert and we don't have one */ >++# define CLIENTCERT "control/clientcert.pem" >++ if (SSL_CTX_use_certificate_chain_file(ctx, CLIENTCERT)) >++ SSL_CTX_use_RSAPrivateKey_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM); >++# undef CLIENTCERT >++ >++ myssl = SSL_new(ctx); >++ SSL_CTX_free(ctx); >++ if (!myssl) { >++ if (!smtps && !servercert) return 0; >++ smtptext.len = 0; >++ tls_quit_error("ZTLS error initializing ssl"); >++ } >++ >++ if (!smtps) substdio_putsflush(&smtpto, "STARTTLS\r\n"); >++ >++ /* while the server is preparing a responce, do something else */ >++ if (control_readfile(&saciphers, "control/tlsclientciphers", 0) == -1) >++ { SSL_free(myssl); temp_control(); } >++ if (saciphers.len) { >++ for (i = 0; i < saciphers.len - 1; ++i) >++ if (!saciphers.s[i]) saciphers.s[i] = ':'; >++ ciphers = saciphers.s; >++ } >++ else ciphers = "DEFAULT"; >++ SSL_set_cipher_list(myssl, ciphers); >++ alloc_free(saciphers.s); >++ >++ /* SSL_set_options(myssl, SSL_OP_NO_TLSv1); */ >++ SSL_set_fd(myssl, smtpfd); >++ >++ /* read the responce to STARTTLS */ >++ if (!smtps) { >++ if (smtpcode() != 220) { >++ SSL_free(myssl); >++ if (!servercert) return 0; >++ out("ZSTARTTLS rejected while "); >++ out(servercert); out(" exists"); TLS_QUIT; >++ } >++ smtptext.len = 0; >++ } >++ >++ ssl = myssl; >++ if (ssl_timeoutconn(timeout, smtpfd, smtpfd, ssl) <= 0) >++ tls_quit("ZTLS connect failed", ssl_error_str()); >++ >++ if (servercert) { >++ X509 *peercert; >++ STACK_OF(GENERAL_NAME) *gens; >++ >++ int r = SSL_get_verify_result(ssl); >++ if (r != X509_V_OK) { >++ out("ZTLS unable to verify server with "); >++ tls_quit(servercert, X509_verify_cert_error_string(r)); >++ } >++ alloc_free(servercert); >++ >++ peercert = SSL_get_peer_certificate(ssl); >++ if (!peercert) { >++ out("ZTLS unable to verify server "); >++ tls_quit(partner_fqdn, "no certificate provided"); >++ } >++ >++ /* RFC 2595 section 2.4: find a matching name >++ * first find a match among alternative names */ >++ gens = X509_get_ext_d2i(peercert, NID_subject_alt_name, 0, 0); >++ if (gens) { >++ for (i = 0, r = sk_GENERAL_NAME_num(gens); i < r; ++i) >++ { >++ const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i); >++ if (gn->type == GEN_DNS) >++ if (match_partner(gn->d.ia5->data, gn->d.ia5->length)) break; >++ } >++ sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); >++ } >++ >++ /* no alternative name matched, look up commonName */ >++ if (!gens || i >= r) { >++ stralloc peer = {0}; >++ X509_NAME *subj = X509_get_subject_name(peercert); >++ i = X509_NAME_get_index_by_NID(subj, NID_commonName, -1); >++ if (i >= 0) { >++ const ASN1_STRING *s = X509_NAME_get_entry(subj, i)->value; >++ if (s) { peer.len = s->length; peer.s = s->data; } >++ } >++ if (peer.len <= 0) { >++ out("ZTLS unable to verify server "); >++ tls_quit(partner_fqdn, "certificate contains no valid commonName"); >++ } >++ if (!match_partner(peer.s, peer.len)) { >++ out("ZTLS unable to verify server "); out(partner_fqdn); >++ out(": received certificate for "); outsafe(&peer); TLS_QUIT; >++ } >++ } >++ >++ X509_free(peercert); >++ } >++ >++ if (smtps) if (smtpcode() != 220) >++ quit("ZTLS Connected to "," but greeting failed"); >++ >++ return 1; >++} >++#endif >++ >+ stralloc recip = {0}; >+ >+ void smtp() >+@@ -221,15 +523,57 @@ >+ unsigned long code; >+ int flagbother; >+ int i; >+- >+- if (smtpcode() != 220) quit("ZConnected to "," but greeting failed"); >+- >++ >++#ifndef PORT_SMTP >++ /* the qmtpc patch uses smtp_port and undefines PORT_SMTP */ >++# define port smtp_port >++#endif >++ >++#ifdef TLS >++# ifdef MXPS >++ if (type == 'S') smtps = 1; >++ else if (type != 's') >++# endif >++ if (port == 465) smtps = 1; >++ if (!smtps) >++#endif >++ >++ code = smtpcode(); >++ if (code >= 500 && code < 600) quit("DConnected to "," but greeting failed"); >++ if (code >= 400 && code < 500) return; /* try next MX, see RFC-2821 */ >++ if (code != 220) quit("ZConnected to "," but greeting failed"); >++ >++#ifdef EHLO >++# ifdef TLS >++ if (!smtps) >++# endif >++ code = ehlo(); >++ >++# ifdef TLS >++ if (tls_init()) >++ /* RFC2487 says we should issue EHLO (even if we might not need >++ * extensions); at the same time, it does not prohibit a server >++ * to reject the EHLO and make us fallback to HELO */ >++ code = ehlo(); >++# endif >++ >++ if (code == 250) { >++ /* add EHLO response checks here */ >++ >++ /* and if EHLO failed, use HELO */ >++ } else { >++#endif >++ >+ substdio_puts(&smtpto,"HELO "); >+ substdio_put(&smtpto,helohost.s,helohost.len); >+ substdio_puts(&smtpto,"\r\n"); >+ substdio_flush(&smtpto); >+ if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected"); >+ >++#ifdef EHLO >++ } >++#endif >++ >+ substdio_puts(&smtpto,"MAIL FROM:<"); >+ substdio_put(&smtpto,sender.s,sender.len); >+ substdio_puts(&smtpto,">\r\n"); >+@@ -417,7 +761,10 @@ >+ if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) { >+ tcpto_err(&ip.ix[i].ip,0); >+ partner = ip.ix[i].ip; >+- smtp(); /* does not return */ >++#ifdef TLS >++ partner_fqdn = ip.ix[i].fqdn; >++#endif >++ smtp(); /* only returns when the next MX is to be tried */ >+ } >+ tcpto_err(&ip.ix[i].ip,errno == error_timeout); >+ close(smtpfd); >+--- qmail-1.03-orig/qmail-smtpd.c 2008-01-24 18:15:42.000000000 -0200 >++++ qmail-1.03/qmail-smtpd.c 2008-01-24 18:16:54.000000000 -0200 >+@@ -28,9 +28,27 @@ >+ unsigned int databytes = 0; >+ int timeout = 1200; >+ >++const char *protocol = "SMTP"; >++ >++#ifdef TLS >++# include <sys/stat.h> >++# include "tls.h" >++# include "ssl_timeoutio.h" >++ >++void tls_init(); >++int tls_verify(); >++void tls_nogateway(); >++int ssl_rfd = -1, ssl_wfd = -1; /* SSL_get_Xfd() are broken */ >++#endif >++ >+ int safewrite(fd,buf,len) int fd; char *buf; int len; >+ { >+ int r; >++#ifdef TLS >++ if (ssl && fd == ssl_wfd) >++ r = ssl_timeoutwrite(timeout, ssl_rfd, ssl_wfd, ssl, buf, len); >++ else >++#endif >+ r = timeoutwrite(timeout,fd,buf,len); >+ if (r <= 0) _exit(1); >+ return r; >+@@ -50,7 +68,16 @@ >+ void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); } >+ >+ void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); } >++#ifndef TLS >+ void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } >++#else >++void err_nogateway() >++{ >++ out("553 sorry, that domain isn't in my list of allowed rcpthosts"); >++ tls_nogateway(); >++ out(" (#5.7.1)\r\n"); >++} >++#endif >+ void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); } >+ void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } >+ void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } >+@@ -131,6 +158,11 @@ >+ if (!remotehost) remotehost = "unknown"; >+ remoteinfo = env_get("TCPREMOTEINFO"); >+ relayclient = env_get("RELAYCLIENT"); >++ >++#ifdef TLS >++ if (env_get("SMTPS")) { smtps = 1; tls_init(); } >++ else >++#endif >+ dohelo(remotehost); >+ } >+ >+@@ -213,6 +245,9 @@ >+ int r; >+ r = rcpthosts(addr.s,str_len(addr.s)); >+ if (r == -1) die_control(); >++#ifdef TLS >++ if (r == 0) if (tls_verify()) r = -2; >++#endif >+ return r; >+ } >+ >+@@ -227,9 +262,18 @@ >+ smtp_greet("250 "); out("\r\n"); >+ seenmail = 0; dohelo(arg); >+ } >++/* ESMTP extensions are published here */ >+ void smtp_ehlo(arg) char *arg; >+ { >+- smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); >++#ifdef TLS >++ struct stat st; >++#endif >++ smtp_greet("250-"); >++#ifdef TLS >++ if (!ssl && (stat("control/servercert.pem",&st) == 0)) >++ out("\r\n250-STARTTLS"); >++#endif >++ out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); >+ seenmail = 0; dohelo(arg); >+ } >+ void smtp_rset() >+@@ -269,6 +313,11 @@ >+ { >+ int r; >+ flush(); >++#ifdef TLS >++ if (ssl && fd == ssl_rfd) >++ r = ssl_timeoutread(timeout, ssl_rfd, ssl_wfd, ssl, buf, len); >++ else >++#endif >+ r = timeoutread(timeout,fd,buf,len); >+ if (r == -1) if (errno == error_timeout) die_alarm(); >+ if (r <= 0) die_read(); >+@@ -378,7 +427,7 @@ >+ qp = qmail_qp(&qqt); >+ out("354 go ahead\r\n"); >+ >+- received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo); >++ received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo); >+ blast(&hops); >+ hops = (hops >= MAXHOPS); >+ if (hops) qmail_fail(&qqt); >+@@ -394,6 +443,240 @@ >+ out("\r\n"); >+ } >+ >++#ifdef TLS >++stralloc proto = {0}; >++int ssl_verified = 0; >++const char *ssl_verify_err = 0; >++ >++void smtp_tls(char *arg) >++{ >++ if (ssl) err_unimpl(); >++ else if (*arg) out("501 Syntax error (no parameters allowed) (#5.5.4)\r\n"); >++ else tls_init(); >++} >++ >++RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen) >++{ >++ if (!export) keylen = 512; >++ if (keylen == 512) { >++ FILE *in = fopen("control/rsa512.pem", "r"); >++ if (in) { >++ RSA *rsa = PEM_read_RSAPrivateKey(in, NULL, NULL, NULL); >++ fclose(in); >++ if (rsa) return rsa; >++ } >++ } >++ return RSA_generate_key(keylen, RSA_F4, NULL, NULL); >++} >++ >++DH *tmp_dh_cb(SSL *ssl, int export, int keylen) >++{ >++ if (!export) keylen = 1024; >++ if (keylen == 512) { >++ FILE *in = fopen("control/dh512.pem", "r"); >++ if (in) { >++ DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL); >++ fclose(in); >++ if (dh) return dh; >++ } >++ } >++ if (keylen == 1024) { >++ FILE *in = fopen("control/dh1024.pem", "r"); >++ if (in) { >++ DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL); >++ fclose(in); >++ if (dh) return dh; >++ } >++ } >++ return DH_generate_parameters(keylen, DH_GENERATOR_2, NULL, NULL); >++} >++ >++/* don't want to fail handshake if cert isn't verifiable */ >++int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } >++ >++void tls_nogateway() >++{ >++ /* there may be cases when relayclient is set */ >++ if (!ssl || relayclient) return; >++ out("; no valid cert for gatewaying"); >++ if (ssl_verify_err) { out(": "); out(ssl_verify_err); } >++} >++void tls_out(const char *s1, const char *s2) >++{ >++ out("454 TLS "); out(s1); >++ if (s2) { out(": "); out(s2); } >++ out(" (#4.3.0)\r\n"); flush(); >++} >++void tls_err(const char *s) { tls_out(s, ssl_error()); if (smtps) die_read(); } >++ >++# define CLIENTCA "control/clientca.pem" >++# define CLIENTCRL "control/clientcrl.pem" >++# define SERVERCERT "control/servercert.pem" >++ >++int tls_verify() >++{ >++ stralloc clients = {0}; >++ struct constmap mapclients; >++ >++ if (!ssl || relayclient || ssl_verified) return 0; >++ ssl_verified = 1; /* don't do this twice */ >++ >++ /* request client cert to see if it can be verified by one of our CAs >++ * and the associated email address matches an entry in tlsclients */ >++ switch (control_readfile(&clients, "control/tlsclients", 0)) >++ { >++ case 1: >++ if (constmap_init(&mapclients, clients.s, clients.len, 0)) { >++ /* if CLIENTCA contains all the standard root certificates, a >++ * 0.9.6b client might fail with SSL_R_EXCESSIVE_MESSAGE_SIZE; >++ * it is probably due to 0.9.6b supporting only 8k key exchange >++ * data while the 0.9.6c release increases that limit to 100k */ >++ STACK_OF(X509_NAME) *sk = SSL_load_client_CA_file(CLIENTCA); >++ if (sk) { >++ SSL_set_client_CA_list(ssl, sk); >++ SSL_set_verify(ssl, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); >++ break; >++ } >++ constmap_free(&mapclients); >++ } >++ case 0: alloc_free(clients.s); return 0; >++ case -1: die_control(); >++ } >++ >++ if (ssl_timeoutrehandshake(timeout, ssl_rfd, ssl_wfd, ssl) <= 0) { >++ const char *err = ssl_error_str(); >++ tls_out("rehandshake failed", err); die_read(); >++ } >++ >++ do { /* one iteration */ >++ X509 *peercert; >++ X509_NAME *subj; >++ stralloc email = {0}; >++ >++ int n = SSL_get_verify_result(ssl); >++ if (n != X509_V_OK) >++ { ssl_verify_err = X509_verify_cert_error_string(n); break; } >++ peercert = SSL_get_peer_certificate(ssl); >++ if (!peercert) break; >++ >++ subj = X509_get_subject_name(peercert); >++ n = X509_NAME_get_index_by_NID(subj, NID_pkcs9_emailAddress, -1); >++ if (n >= 0) { >++ const ASN1_STRING *s = X509_NAME_get_entry(subj, n)->value; >++ if (s) { email.len = s->length; email.s = s->data; } >++ } >++ >++ if (email.len <= 0) >++ ssl_verify_err = "contains no email address"; >++ else if (!constmap(&mapclients, email.s, email.len)) >++ ssl_verify_err = "email address not in my list of tlsclients"; >++ else { >++ /* add the cert email to the proto if it helped allow relaying */ >++ --proto.len; >++ if (!stralloc_cats(&proto, "\n (cert ") /* continuation line */ >++ || !stralloc_catb(&proto, email.s, email.len) >++ || !stralloc_cats(&proto, ")") >++ || !stralloc_0(&proto)) die_nomem(); >++ relayclient = ""; >++ protocol = proto.s; >++ } >++ >++ X509_free(peercert); >++ } while (0); >++ constmap_free(&mapclients); alloc_free(clients.s); >++ >++ /* we are not going to need this anymore: free the memory */ >++ SSL_set_client_CA_list(ssl, NULL); >++ SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); >++ >++ return relayclient ? 1 : 0; >++} >++ >++void tls_init() >++{ >++ SSL *myssl; >++ SSL_CTX *ctx; >++ const char *ciphers; >++ stralloc saciphers = {0}; >++ X509_STORE *store; >++ X509_LOOKUP *lookup; >++ >++ SSL_library_init(); >++ >++ /* a new SSL context with the bare minimum of options */ >++ ctx = SSL_CTX_new(SSLv23_server_method()); >++ if (!ctx) { tls_err("unable to initialize ctx"); return; } >++ >++ if (!SSL_CTX_use_certificate_chain_file(ctx, SERVERCERT)) >++ { SSL_CTX_free(ctx); tls_err("missing certificate"); return; } >++ SSL_CTX_load_verify_locations(ctx, CLIENTCA, NULL); >++ >++#if OPENSSL_VERSION_NUMBER >= 0x00907000L >++ /* crl checking */ >++ store = SSL_CTX_get_cert_store(ctx); >++ if ((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) && >++ (X509_load_crl_file(lookup, CLIENTCRL, X509_FILETYPE_PEM) == 1)) >++ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | >++ X509_V_FLAG_CRL_CHECK_ALL); >++#endif >++ >++ /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ >++ SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb); >++ >++ /* a new SSL object, with the rest added to it directly to avoid copying */ >++ myssl = SSL_new(ctx); >++ SSL_CTX_free(ctx); >++ if (!myssl) { tls_err("unable to initialize ssl"); return; } >++ >++ /* this will also check whether public and private keys match */ >++ if (!SSL_use_RSAPrivateKey_file(myssl, SERVERCERT, SSL_FILETYPE_PEM)) >++ { SSL_free(myssl); tls_err("no valid RSA private key"); return; } >++ >++ ciphers = env_get("TLSCIPHERS"); >++ if (!ciphers) { >++ if (control_readfile(&saciphers, "control/tlsserverciphers", 0) == -1) >++ { SSL_free(myssl); die_control(); } >++ if (saciphers.len) { /* convert all '\0's except the last one to ':' */ >++ int i; >++ for (i = 0; i < saciphers.len - 1; ++i) >++ if (!saciphers.s[i]) saciphers.s[i] = ':'; >++ ciphers = saciphers.s; >++ } >++ } >++ if (!ciphers || !*ciphers) ciphers = "DEFAULT"; >++ SSL_set_cipher_list(myssl, ciphers); >++ alloc_free(saciphers.s); >++ >++ SSL_set_tmp_rsa_callback(myssl, tmp_rsa_cb); >++ SSL_set_tmp_dh_callback(myssl, tmp_dh_cb); >++ SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin)); >++ SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout)); >++ >++ if (!smtps) { out("220 ready for tls\r\n"); flush(); } >++ >++ if (ssl_timeoutaccept(timeout, ssl_rfd, ssl_wfd, myssl) <= 0) { >++ /* neither cleartext nor any other response here is part of a standard */ >++ const char *err = ssl_error_str(); >++ ssl_free(myssl); tls_out("connection failed", err); die_read(); >++ } >++ ssl = myssl; >++ >++ /* populate the protocol string, used in Received */ >++ if (!stralloc_copys(&proto, SSL_get_cipher(ssl)) >++ || !stralloc_cats(&proto, " encrypted SMTP")) die_nomem(); >++ if (smtps) if (!stralloc_append(&proto, "S")) die_nomem(); >++ if (!stralloc_0(&proto)) die_nomem(); >++ protocol = proto.s; >++ >++ /* have to discard the pre-STARTTLS HELO/EHLO argument, if any */ >++ dohelo(remotehost); >++} >++ >++# undef SERVERCERT >++# undef CLIENTCA >++ >++#endif >++ >+ struct commands smtpcommands[] = { >+ { "rcpt", smtp_rcpt, 0 } >+ , { "mail", smtp_mail, 0 } >+@@ -403,6 +686,9 @@ >+ , { "ehlo", smtp_ehlo, flush } >+ , { "rset", smtp_rset, 0 } >+ , { "help", smtp_help, flush } >++#ifdef TLS >++, { "starttls", smtp_tls, flush } >++#endif >+ , { "noop", err_noop, flush } >+ , { "vrfy", err_vrfy, flush } >+ , { 0, err_unimpl, flush } >--- /usr/ports/distfiles/qmail/auto.patch.diff-tls.orig 2008-01-24 20:35:28.000000000 -0200 >+++ /usr/ports/distfiles/qmail/auth.patch.diff-tls 2008-01-24 20:13:16.000000000 -0200 >@@ -0,0 +1,98 @@ >+--- auth.patch.orig 2002-05-10 02:41:20.000000000 -0300 >++++ auth.patch 2008-01-24 20:13:02.000000000 -0200 >+@@ -14,34 +14,36 @@ >+ binm1.sh conf-qmail >+ cat binm1.sh \ >+ *************** >+-*** 1536,1547 **** >++*** 1537,1549 **** >+ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \ >+ date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \ >+ open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \ >+ ! fs.a auto_qmail.o socket.lib >+ ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \ >+ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \ >++ tls.o ssl_timeoutio.o ndelay.a -L/usr/lib -lssl -lcrypto \ >+ received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \ >+ datetime.a getln.a open.a sig.a case.a env.a stralloc.a \ >+ ! alloc.a substdio.a error.a str.a fs.a auto_qmail.o `cat \ >+ socket.lib` >+ >+ qmail-smtpd.0: \ >+---- 1540,1551 ---- >++--- 1541,1553 ---- >+ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \ >+ date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \ >+ open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \ >+ ! fs.a auto_qmail.o base64.o socket.lib >+ ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \ >+ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \ >++ tls.o ssl_timeoutio.o ndelay.a -L/usr/lib -lssl -lcrypto \ >+ received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \ >+ datetime.a getln.a open.a sig.a case.a env.a stralloc.a \ >+-! alloc.a substdio.a error.a str.a fs.a auto_qmail.o base64.o `cat \ >++! alloc.a substdio.a error.a str.a fs.a auto_qmail.o base64.o `cat \ >+ socket.lib` >+ >+ qmail-smtpd.0: \ >+ *************** >+-*** 1553,1559 **** >++*** 1555,1561 **** >+ substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \ >+ error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \ >+ substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \ >+@@ -49,7 +51,7 @@ >+ ./compile qmail-smtpd.c >+ >+ qmail-start: \ >+---- 1557,1564 ---- >++--- 1559,1566 ---- >+ substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \ >+ error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \ >+ substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \ >+@@ -174,30 +176,21 @@ >+ stralloc greeting = {0}; >+ >+ *************** >+-*** 229,235 **** >+- } >+- void smtp_ehlo(arg) char *arg; >+- { >+-! smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); >+- seenmail = 0; dohelo(arg); >+- } >+- void smtp_rset() >+---- 241,255 ---- >+- } >+- void smtp_ehlo(arg) char *arg; >+- { >+-! smtp_greet("250-"); >+-! #ifdef AUTHCRAM >+-! out("\r\n250-AUTH LOGIN CRAM-MD5 PLAIN"); >+-! out("\r\n250-AUTH=LOGIN CRAM-MD5 PLAIN"); >+-! #else >+-! out("\r\n250-AUTH LOGIN PLAIN"); >+-! out("\r\n250-AUTH=LOGIN PLAIN"); >+-! #endif >+-! out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); >+- seenmail = 0; dohelo(arg); >+- } >+- void smtp_rset() >++*** 269,274 **** >++--- 281,293 ---- >++ struct stat st; >++ #endif >++ smtp_greet("250-"); >+++ #ifdef AUTHCRAM >+++ out("\r\n250-AUTH LOGIN CRAM-MD5 PLAIN"); >+++ out("\r\n250-AUTH=LOGIN CRAM-MD5 PLAIN"); >+++ #else >+++ out("\r\n250-AUTH LOGIN PLAIN"); >+++ out("\r\n250-AUTH=LOGIN PLAIN"); >+++ #endif >++ #ifdef TLS >++ if (!ssl && (stat("control/servercert.pem",&st) == 0)) >++ out("\r\n250-STARTTLS"); >+ *************** >+ *** 394,403 **** >+ --- 414,639 ----
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 119954
: 84025