diff options
| -rw-r--r-- | Makefile | 18 | ||||
| -rw-r--r-- | README.starttls | 8 | ||||
| -rw-r--r-- | TARGETS | 1 | ||||
| -rw-r--r-- | hier.c | 3 | ||||
| -rw-r--r-- | qmail-control.9 | 3 | ||||
| -rw-r--r-- | qmail-smtpd.8 | 17 | ||||
| -rw-r--r-- | qmail-smtpd.c | 92 | ||||
| -rw-r--r-- | update_tmprsadh.sh | 25 |
8 files changed, 66 insertions, 101 deletions
| @@ -812,7 +812,7 @@ dnsptr dnsip dnsmxip dnsfq hostname ipmeprint qreceipt qsmhook qbiff \ | |||
| 812 | forward preline condredirect bouncesaying except maildirmake \ | 812 | forward preline condredirect bouncesaying except maildirmake \ |
| 813 | maildir2mbox maildirwatch qail elq pinq idedit install-big install \ | 813 | maildir2mbox maildirwatch qail elq pinq idedit install-big install \ |
| 814 | instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \ | 814 | instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \ |
| 815 | binm3 binm3+df update_tmprsadh | 815 | binm3 binm3+df |
| 816 | 816 | ||
| 817 | load: \ | 817 | load: \ |
| 818 | make-load warn-auto.sh systype | 818 | make-load warn-auto.sh systype |
| @@ -1915,8 +1915,7 @@ date822fmt.h date822fmt.c dns.h dns.c trylsock.c tryrsolv.c ip.h ip.c \ | |||
| 1915 | ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \ | 1915 | ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \ |
| 1916 | ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \ | 1916 | ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \ |
| 1917 | prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \ | 1917 | prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \ |
| 1918 | maildir.5 maildir.h maildir.c constmap.h constmap.c \ | 1918 | maildir.5 maildir.h maildir.c constmap.h constmap.c |
| 1919 | update_tmprsadh | ||
| 1920 | shar -m `cat FILES` > shar | 1919 | shar -m `cat FILES` > shar |
| 1921 | chmod 400 shar | 1920 | chmod 400 shar |
| 1922 | 1921 | ||
| @@ -2247,16 +2246,3 @@ conf-qmail conf-users conf-groups Makefile-cert.mk | |||
| 2247 | @cat Makefile-cert.mk \ | 2246 | @cat Makefile-cert.mk \ |
| 2248 | | sed s}QMAIL}"`head -n 1 conf-qmail`"}g \ | 2247 | | sed s}QMAIL}"`head -n 1 conf-qmail`"}g \ |
| 2249 | > $@ | 2248 | > $@ |
| 2250 | |||
| 2251 | update_tmprsadh: \ | ||
| 2252 | conf-qmail conf-users conf-groups update_tmprsadh.sh | ||
| 2253 | @cat update_tmprsadh.sh\ | ||
| 2254 | | sed s}UGQMAILD}"`head -n 2 conf-users|tail -n 1`:`head -n 1 conf-groups`"}g \ | ||
| 2255 | | sed s}QMAIL}"`head -n 1 conf-qmail`"}g \ | ||
| 2256 | > $@ | ||
| 2257 | chmod 755 update_tmprsadh | ||
| 2258 | |||
| 2259 | tmprsadh: \ | ||
| 2260 | update_tmprsadh | ||
| 2261 | echo "Creating new temporary RSA and DH parameters" | ||
| 2262 | ./update_tmprsadh | ||
diff --git a/README.starttls b/README.starttls index 0286632..07ee275 100644 --- a/README.starttls +++ b/README.starttls | |||
| @@ -30,12 +30,6 @@ Optional: - when DEBUG is defined, some extra TLS info will be logged | |||
| 30 | /var/qmail/control/clientcert.pem. By preference this is | 30 | /var/qmail/control/clientcert.pem. By preference this is |
| 31 | the same as servercert.pem, where nsCertType should be | 31 | the same as servercert.pem, where nsCertType should be |
| 32 | == server,client or be a generic certificate (no usage specified). | 32 | == server,client or be a generic certificate (no usage specified). |
| 33 | - when a 512 bit RSA key is provided in /var/qmail/control/rsa512.pem, | ||
| 34 | this key will be used instead of (slow) on-the-fly generation by | ||
| 35 | qmail-smtpd. Idem for 512 and 1024 DH params in control/dh512.pem | ||
| 36 | and control/dh1024.pem. `make tmprsadh` does this. | ||
| 37 | Periodical replacement can be done by crontab: | ||
| 38 | 01 01 * * * /var/qmail/bin/update_tmprsadh > /dev/null 2>&1 | ||
| 39 | - server authentication: | 33 | - server authentication: |
| 40 | qmail-remote requires authentication from servers for which | 34 | qmail-remote requires authentication from servers for which |
| 41 | /var/qmail/control/tlshosts/host.dom.ain.pem exists. | 35 | /var/qmail/control/tlshosts/host.dom.ain.pem exists. |
| @@ -86,8 +80,6 @@ Caveats: - do a `make clean` after patching | |||
| 86 | will fail. This error can be ignored. Packagers should | 80 | will fail. This error can be ignored. Packagers should |
| 87 | cut the first 12 lines of this patch to make a happy | 81 | cut the first 12 lines of this patch to make a happy |
| 88 | patch | 82 | patch |
| 89 | - `make tmprsadh` is recommended (or should I say required), | ||
| 90 | otherwise DH generation can be unpredictably slow | ||
| 91 | - some need "-I/usr/kerberos/include" to be added in conf-cc | 83 | - some need "-I/usr/kerberos/include" to be added in conf-cc |
| 92 | 84 | ||
| 93 | Copyright: GPL | 85 | Copyright: GPL |
| @@ -403,4 +403,3 @@ forgeries.0 | |||
| 403 | man | 403 | man |
| 404 | setup | 404 | setup |
| 405 | check | 405 | check |
| 406 | update_tmprsadh | ||
| @@ -149,9 +149,6 @@ void hier() | |||
| 149 | c(auto_qmail,"bin","qail",auto_uido,auto_gidq,0755); | 149 | c(auto_qmail,"bin","qail",auto_uido,auto_gidq,0755); |
| 150 | c(auto_qmail,"bin","elq",auto_uido,auto_gidq,0755); | 150 | c(auto_qmail,"bin","elq",auto_uido,auto_gidq,0755); |
| 151 | c(auto_qmail,"bin","pinq",auto_uido,auto_gidq,0755); | 151 | c(auto_qmail,"bin","pinq",auto_uido,auto_gidq,0755); |
| 152 | #ifdef TLS | ||
| 153 | c(auto_qmail,"bin","update_tmprsadh",auto_uido,auto_gidq,0755); | ||
| 154 | #endif | ||
| 155 | 152 | ||
| 156 | c(auto_qmail,"man/man5","addresses.5",auto_uido,auto_gidq,0644); | 153 | c(auto_qmail,"man/man5","addresses.5",auto_uido,auto_gidq,0644); |
| 157 | c(auto_qmail,"man/cat5","addresses.0",auto_uido,auto_gidq,0644); | 154 | c(auto_qmail,"man/cat5","addresses.0",auto_uido,auto_gidq,0644); |
diff --git a/qmail-control.9 b/qmail-control.9 index 28c4ecf..9c6edd8 100644 --- a/qmail-control.9 +++ b/qmail-control.9 | |||
| @@ -58,8 +58,6 @@ control default used by | |||
| 58 | .I defaultdomain \fIme \fRqmail-inject | 58 | .I defaultdomain \fIme \fRqmail-inject |
| 59 | .I defaulthost \fIme \fRqmail-inject | 59 | .I defaulthost \fIme \fRqmail-inject |
| 60 | .I databytes \fR0 \fRqmail-smtpd | 60 | .I databytes \fR0 \fRqmail-smtpd |
| 61 | .I dh1024.pem \fR(none) \fRqmail-smtpd | ||
| 62 | .I dh512.pem \fR(none) \fRqmail-smtpd | ||
| 63 | .I doublebouncehost \fIme \fRqmail-send | 61 | .I doublebouncehost \fIme \fRqmail-send |
| 64 | .I doublebounceto \fRpostmaster \fRqmail-send | 62 | .I doublebounceto \fRpostmaster \fRqmail-send |
| 65 | .I envnoathost \fIme \fRqmail-send | 63 | .I envnoathost \fIme \fRqmail-send |
| @@ -74,7 +72,6 @@ control default used by | |||
| 74 | .I qmqpservers \fR(none) \fRqmail-qmqpc | 72 | .I qmqpservers \fR(none) \fRqmail-qmqpc |
| 75 | .I queuelifetime \fR604800 \fRqmail-send | 73 | .I queuelifetime \fR604800 \fRqmail-send |
| 76 | .I rcpthosts \fR(none) \fRqmail-smtpd | 74 | .I rcpthosts \fR(none) \fRqmail-smtpd |
| 77 | .I rsa512.pem \fR(none) \fRqmail-smtpd | ||
| 78 | .I servercert.pem \fR(none) \fRqmail-smtpd | 75 | .I servercert.pem \fR(none) \fRqmail-smtpd |
| 79 | .I smtpgreeting \fIme \fRqmail-smtpd | 76 | .I smtpgreeting \fIme \fRqmail-smtpd |
| 80 | .I smtproutes \fR(none) \fRqmail-remote | 77 | .I smtproutes \fR(none) \fRqmail-remote |
diff --git a/qmail-smtpd.8 b/qmail-smtpd.8 index d1c9820..05d1239 100644 --- a/qmail-smtpd.8 +++ b/qmail-smtpd.8 | |||
| @@ -171,17 +171,6 @@ is set, it overrides | |||
| 171 | .IR databytes . | 171 | .IR databytes . |
| 172 | 172 | ||
| 173 | .TP 5 | 173 | .TP 5 |
| 174 | .I dh1024.pem | ||
| 175 | If these 1024 bit DH parameters are provided, | ||
| 176 | .B qmail-smtpd | ||
| 177 | will use them for TLS sessions instead of generating one on-the-fly | ||
| 178 | (which is very timeconsuming). | ||
| 179 | .TP 5 | ||
| 180 | .I dh512.pem | ||
| 181 | 512 bit counterpart for | ||
| 182 | .B dh1024.pem. | ||
| 183 | |||
| 184 | .TP 5 | ||
| 185 | .I localiphost | 174 | .I localiphost |
| 186 | Replacement host name for local IP addresses. | 175 | Replacement host name for local IP addresses. |
| 187 | Default: | 176 | Default: |
| @@ -281,12 +270,6 @@ Envelope recipient addresses without @ signs are | |||
| 281 | always allowed through. | 270 | always allowed through. |
| 282 | 271 | ||
| 283 | .TP 5 | 272 | .TP 5 |
| 284 | .I rsa512.pem | ||
| 285 | If this 512 bit RSA key is provided, | ||
| 286 | .B qmail-smtpd | ||
| 287 | will use it for TLS sessions instead of generating one on-the-fly. | ||
| 288 | |||
| 289 | .TP 5 | ||
| 290 | .I servercert.pem | 273 | .I servercert.pem |
| 291 | SSL certificate to be presented to clients in TLS-encrypted sessions. | 274 | SSL certificate to be presented to clients in TLS-encrypted sessions. |
| 292 | Should contain both the certificate and the private key. Certifying Authority | 275 | Should contain both the certificate and the private key. Certifying Authority |
diff --git a/qmail-smtpd.c b/qmail-smtpd.c index 3360cfe..817524d 100644 --- a/qmail-smtpd.c +++ b/qmail-smtpd.c | |||
| @@ -1141,41 +1141,78 @@ void smtp_tls(char *arg) | |||
| 1141 | else tls_init(); | 1141 | else tls_init(); |
| 1142 | } | 1142 | } |
| 1143 | 1143 | ||
| 1144 | RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen) | 1144 | /* |
| 1145 | * Grab well-defined DH parameters from OpenSSL, see the get_rfc* | ||
| 1146 | * functions in <openssl/bn.h> for all available primes. | ||
| 1147 | */ | ||
| 1148 | static DH *make_dh_params(BIGNUM *(*prime)(BIGNUM *), const char *gen) | ||
| 1145 | { | 1149 | { |
| 1146 | if (!export) keylen = 512; | 1150 | DH *dh = DH_new(); |
| 1147 | if (keylen == 512) { | 1151 | |
| 1148 | FILE *in = fopen("control/rsa512.pem", "r"); | 1152 | if (!dh) { |
| 1149 | if (in) { | 1153 | return NULL; |
| 1150 | RSA *rsa = PEM_read_RSAPrivateKey(in, NULL, NULL, NULL); | ||
| 1151 | fclose(in); | ||
| 1152 | if (rsa) return rsa; | ||
| 1153 | } | 1154 | } |
| 1154 | } | 1155 | dh->p = prime(NULL); |
| 1155 | return RSA_generate_key(keylen, RSA_F4, NULL, NULL); | 1156 | BN_dec2bn(&dh->g, gen); |
| 1157 | if (!dh->p || !dh->g) { | ||
| 1158 | DH_free(dh); | ||
| 1159 | return NULL; | ||
| 1160 | } | ||
| 1161 | return dh; | ||
| 1156 | } | 1162 | } |
| 1157 | 1163 | ||
| 1164 | /* Storage and initialization for DH parameters. */ | ||
| 1165 | static struct dhparam { | ||
| 1166 | BIGNUM *(*const prime)(BIGNUM *); /* function to generate... */ | ||
| 1167 | DH *dh; /* ...this, used for keys.... */ | ||
| 1168 | const unsigned int min; /* ...of length >= this. */ | ||
| 1169 | } dhparams[] = { | ||
| 1170 | { get_rfc3526_prime_8192, NULL, 6145 }, | ||
| 1171 | { get_rfc3526_prime_6144, NULL, 4097 }, | ||
| 1172 | { get_rfc3526_prime_4096, NULL, 3073 }, | ||
| 1173 | { get_rfc3526_prime_3072, NULL, 2049 }, | ||
| 1174 | { get_rfc3526_prime_2048, NULL, 1025 }, | ||
| 1175 | { get_rfc2409_prime_1024, NULL, 0 } | ||
| 1176 | }; | ||
| 1177 | |||
| 1178 | /* Hand out the same DH structure though once generated as we leak | ||
| 1179 | * memory otherwise and freeing the structure up after use would be | ||
| 1180 | * hard to track and in fact is not needed at all as it is safe to | ||
| 1181 | * use the same parameters over and over again security wise (in | ||
| 1182 | * contrast to the keys itself) and code safe as the returned structure | ||
| 1183 | * is duplicated by OpenSSL anyway. Hence no modification happens | ||
| 1184 | * to our copy. */ | ||
| 1158 | DH *tmp_dh_cb(SSL *ssl, int export, int keylen) | 1185 | DH *tmp_dh_cb(SSL *ssl, int export, int keylen) |
| 1159 | { | 1186 | { |
| 1160 | if (!export) keylen = 1024; | 1187 | EVP_PKEY *pkey = SSL_get_privatekey(ssl); |
| 1161 | if (keylen == 512) { | 1188 | int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE; |
| 1162 | FILE *in = fopen("control/dh512.pem", "r"); | 1189 | unsigned n; |
| 1163 | if (in) { | 1190 | |
| 1164 | DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL); | 1191 | /* |
| 1165 | fclose(in); | 1192 | * OpenSSL will call us with either keylen == 512 or keylen == 1024 |
| 1166 | if (dh) return dh; | 1193 | * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h). |
| 1194 | * Adjust the DH parameter length according to the size of the | ||
| 1195 | * RSA/DSA private key used for the current connection, and always | ||
| 1196 | * use at least 1024-bit parameters. | ||
| 1197 | * Note: This may cause interoperability issues with implementations | ||
| 1198 | * which limit their DH support to 1024 bit - e.g. Java 7 and earlier. | ||
| 1199 | * In this case, SSLCertificateFile can be used to specify fixed | ||
| 1200 | * 1024-bit DH parameters (with the effect that OpenSSL skips this | ||
| 1201 | * callback). | ||
| 1202 | */ | ||
| 1203 | if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) | ||
| 1204 | keylen = EVP_PKEY_bits(pkey); | ||
| 1205 | |||
| 1206 | for (n = 0; n < sizeof(dhparams)/sizeof(dhparams[0]); n++) { | ||
| 1207 | if (keylen >= dhparams[n].min) { | ||
| 1208 | if (dhparams[n].dh == NULL) | ||
| 1209 | dhparams[n].dh = make_dh_params(dhparams[n].prime, "2"); | ||
| 1210 | return dhparams[n].dh; | ||
| 1167 | } | 1211 | } |
| 1168 | } | 1212 | } |
| 1169 | if (keylen == 1024) { | 1213 | |
| 1170 | FILE *in = fopen("control/dh1024.pem", "r"); | 1214 | return NULL; /* impossible to reach. */ |
| 1171 | if (in) { | 1215 | } |
| 1172 | DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL); | ||
| 1173 | fclose(in); | ||
| 1174 | if (dh) return dh; | ||
| 1175 | } | ||
| 1176 | } | ||
| 1177 | return DH_generate_parameters(keylen, DH_GENERATOR_2, NULL, NULL); | ||
| 1178 | } | ||
| 1179 | 1216 | ||
| 1180 | /* don't want to fail handshake if cert isn't verifiable */ | 1217 | /* don't want to fail handshake if cert isn't verifiable */ |
| 1181 | int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } | 1218 | int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } |
| @@ -1338,7 +1375,6 @@ void tls_init() | |||
| 1338 | SSL_set_cipher_list(myssl, ciphers); | 1375 | SSL_set_cipher_list(myssl, ciphers); |
| 1339 | alloc_free(saciphers.s); | 1376 | alloc_free(saciphers.s); |
| 1340 | 1377 | ||
| 1341 | SSL_set_tmp_rsa_callback(myssl, tmp_rsa_cb); | ||
| 1342 | SSL_set_tmp_dh_callback(myssl, tmp_dh_cb); | 1378 | SSL_set_tmp_dh_callback(myssl, tmp_dh_cb); |
| 1343 | SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin)); | 1379 | SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin)); |
| 1344 | SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout)); | 1380 | SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout)); |
diff --git a/update_tmprsadh.sh b/update_tmprsadh.sh deleted file mode 100644 index 563fcfb..0000000 --- a/update_tmprsadh.sh +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | # Update temporary RSA and DH keys | ||
| 4 | # Frederik Vermeulen 2004-05-31 GPL | ||
| 5 | |||
| 6 | umask 0077 || exit 0 | ||
| 7 | |||
| 8 | export PATH="$PATH:/usr/local/bin/ssl:/usr/sbin" | ||
| 9 | |||
| 10 | openssl genrsa -out QMAIL/control/rsa512.new 512 && | ||
| 11 | chmod 600 QMAIL/control/rsa512.new && | ||
| 12 | chown UGQMAILD QMAIL/control/rsa512.new && | ||
| 13 | mv -f QMAIL/control/rsa512.new QMAIL/control/rsa512.pem | ||
| 14 | echo | ||
| 15 | |||
| 16 | openssl dhparam -2 -out QMAIL/control/dh512.new 512 && | ||
| 17 | chmod 600 QMAIL/control/dh512.new && | ||
| 18 | chown UGQMAILD QMAIL/control/dh512.new && | ||
| 19 | mv -f QMAIL/control/dh512.new QMAIL/control/dh512.pem | ||
| 20 | echo | ||
| 21 | |||
| 22 | openssl dhparam -2 -out QMAIL/control/dh1024.new 1024 && | ||
| 23 | chmod 600 QMAIL/control/dh1024.new && | ||
| 24 | chown UGQMAILD QMAIL/control/dh1024.new && | ||
| 25 | mv -f QMAIL/control/dh1024.new QMAIL/control/dh1024.pem | ||
