Index: proto/TLS_README.html --- proto/TLS_README.html 6 Feb 2012 20:11:09 -0000 1.1.1.5 +++ proto/TLS_README.html 22 Apr 2012 18:46:29 -0000 @@ -703,12 +703,18 @@ Postfix < 2.6, the minimum opportunistic TLS cipher grade is always "export".
-With mandatory TLS encryption, the Postfix SMTP server will by -default only use SSLv3 or TLSv1. SSLv2 is only used when TLS encryption -is optional. The mandatory TLS protocol list is specified via the -smtpd_tls_mandatory_protocols configuration parameter. The -corresponding smtpd_tls_protocols parameter (Postfix ≥ 2.6) -controls the SSL/TLS protocols used with opportunistic TLS.
+With mandatory TLS encryption, the Postfix SMTP server will by default +disable SSLv2. SSLv2 is only enabled when TLS encryption is optional. The +mandatory TLS protocol list is specified via the smtpd_tls_mandatory_protocols +configuration parameter. The corresponding smtpd_tls_protocols parameter +(Postfix ≥ 2.6) controls the SSL/TLS protocols used with opportunistic +TLS.
+ +Note that the underlying OpenSSL library only supports protocol +exclusion (not inclusion). It is only possible to exclude protocols that +are known at the time at which the the Postfix software is written. Therefore, +if new protocols are added to the OpenSSL library they cannot be excluded +without corresponding changes to the Postfix source code.
For a server that is not a public Internet MX host, Postfix
supports configurations with no server
@@ -728,7 +734,7 @@
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5
smtpd_tls_security_level = encrypt
smtpd_tls_mandatory_protocols = TLSv1
- # Also available with Postfix ≥ 2.5:
+ # Preferred interface with Postfix ≥ 2.5:
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
@@ -773,11 +779,11 @@
Postfix 2.8 and later, in combination with OpenSSL 0.9.7 and later
allows TLS servers to preempt the TLS client's cipher preference list.
-This is only possible with SSLv3, as in SSLv2 the client chooses the
-cipher from a list supplied by the server.
By default, the OpenSSL server selects the client's most preferred -cipher that the server supports. With SSLv3 and later, the server +cipher that the server supports. With SSLv3 or higher, the server may choose its own most preferred cipher that is supported (offered) by the client. Setting "tls_preempt_cipherlist = yes" enables server cipher preferences. The default OpenSSL behaviour applies with @@ -1010,8 +1016,8 @@
Examples:
In the example below, traffic to example.com and its sub-domains -via the corresponding MX hosts always uses TLS. The protocol version will be -"SSLv3" or "TLSv1" (the default setting of smtp_tls_mandatory_protocols +via the corresponding MX hosts always uses TLS. The SSLv2 protocol version will +be disabled (the default setting of smtp_tls_mandatory_protocols excludes "SSLv2"). Only high or medium strength (i.e. 128 bit or better) ciphers will be used by default for all "encrypt" security level sessions.
@@ -1883,7 +1889,7 @@ "export".With mandatory TLS encryption, the Postfix SMTP client will by -default only use SSLv3 or TLSv1. SSLv2 is only used when TLS encryption +default disable SSLv2. SSLv2 is only used when TLS encryption is optional. The mandatory TLS protocol list is specified via the smtp_tls_mandatory_protocols configuration parameter. The corresponding smtp_tls_protocols parameter (Postfix ≥ 2.6) controls Index: proto/postconf.proto --- proto/postconf.proto 6 Feb 2012 20:21:06 -0000 1.1.1.25 +++ proto/postconf.proto 22 Apr 2012 18:41:26 -0000 @@ -10457,7 +10457,7 @@
This feature is available in Postfix 2.3 and later.
-%PARAM smtp_tls_mandatory_protocols SSLv3, TLSv1 +%PARAM smtp_tls_mandatory_protocols see "postconf -d" outputList of SSL/TLS protocols that the Postfix SMTP client will use with mandatory TLS encryption. In main.cf the values are separated by @@ -10466,12 +10466,18 @@ empty value means allow all protocols. The valid protocol names, (see SSL_get_version(3)), are "SSLv2", "SSLv3" and "TLSv1".
+Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1_1" and +"TLSv1_2", these can only be disabled by Postfix 2.10 or later. If an +earlier version of Postfix is linked against OpenSSL 1.0.1 or later, +these, or any other new protocol versions, are unconditionally enabled.
+With Postfix ≥ 2.5 the parameter syntax is expanded to support protocol exclusions. One can now explicitly exclude SSLv2 by setting "smtp_tls_mandatory_protocols = !SSLv2". To exclude both SSLv2 and SSLv3 set "smtp_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing the protocols to include, rather than protocols to exclude, is still -supported; use the form you find more intuitive.
+supported, but not recommended. The exclusion form more closely matches +the actual behaviour when OpenSSL is newer than Postfix.Since SSL version 2 has known protocol weaknesses and is now deprecated, the default setting excludes "SSLv2". This means that by @@ -10616,7 +10622,7 @@
This feature is available in Postfix 2.3 and later.
-%PARAM lmtp_tls_mandatory_protocols SSLv3, TLSv1 +%PARAM lmtp_tls_mandatory_protocols see "postconf -d" outputThe LMTP-specific version of the smtp_tls_mandatory_protocols configuration parameter. See there for details.
@@ -10637,7 +10643,7 @@This feature is available in Postfix 2.3 and later.
-%PARAM smtpd_tls_mandatory_protocols SSLv3, TLSv1 +%PARAM smtpd_tls_mandatory_protocols see "postconf -d" outputThe SSL/TLS protocols accepted by the Postfix SMTP server with mandatory TLS encryption. If the list is empty, the server supports all @@ -10646,12 +10652,18 @@ names separated by whitespace, commas or colons. The supported protocol names are "SSLv2", "SSLv3" and "TLSv1", and are not case sensitive.
+Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1_1" and +"TLSv1_2", these can only be disabled by Postfix 2.10 or later. If an +earlier version of Postfix is linked against OpenSSL 1.0.1 or later, +these, or any other new protocol versions, are unconditionally enabled.
+With Postfix ≥ 2.5 the parameter syntax is expanded to support protocol exclusions. One can now explicitly exclude SSLv2 by setting "smtpd_tls_mandatory_protocols = !SSLv2". To exclude both SSLv2 and SSLv3 set "smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing the protocols to include, rather than protocols to exclude, is still -supported, use the form you find more intuitive.
+supported, but not recommended. The exclusion form more closely matches +the actual behaviour when OpenSSL is newer than Postfix.Since SSL version 2 has known protocol weaknesses and is now deprecated, the default setting excludes "SSLv2". This means that @@ -11687,9 +11699,14 @@ against an OpenSSL library that supports additional protocol versions, they cannot be excluded using either syntax.
+Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1_1" and +"TLSv1_2", these can only be disabled by Postfix 2.10 or later. If an +earlier version of Postfix is linked against OpenSSL 1.0.1 or later, +these, or any other new protocol versions, are unconditionally enabled.
+Example:
-# TLSv1 only! +# TLSv1 or higher! smtp_tls_protocols = !SSLv2, !SSLv3@@ -11717,6 +11734,11 @@ against an OpenSSL library that supports additional protocol versions, they cannot be excluded using either syntax. +
Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1_1" and +"TLSv1_2", these can only be disabled by Postfix 2.10 or later. If an +earlier version of Postfix is linked against OpenSSL 1.0.1 or later, +these, or any other new protocol versions, are unconditionally enabled.
+Example:
smtpd_tls_protocols = !SSLv2 Index: src/global/mail_params.h --- src/global/mail_params.h 6 Feb 2012 20:21:09 -0000 1.1.1.13 +++ src/global/mail_params.h 22 Apr 2012 18:42:53 -0000 @@ -1257,7 +1257,7 @@ extern char *var_smtpd_tls_proto; #define VAR_SMTPD_TLS_MAND_PROTO "smtpd_tls_mandatory_protocols" -#define DEF_SMTPD_TLS_MAND_PROTO "SSLv3, TLSv1" +#define DEF_SMTPD_TLS_MAND_PROTO "!SSLv2" extern char *var_smtpd_tls_mand_proto; #define VAR_SMTPD_TLS_CIPH "smtpd_tls_ciphers" @@ -1470,9 +1470,9 @@ extern char *var_smtp_tls_proto; #define VAR_SMTP_TLS_MAND_PROTO "smtp_tls_mandatory_protocols" -#define DEF_SMTP_TLS_MAND_PROTO "SSLv3, TLSv1" +#define DEF_SMTP_TLS_MAND_PROTO "!SSLv2" #define VAR_LMTP_TLS_MAND_PROTO "lmtp_tls_mandatory_protocols" -#define DEF_LMTP_TLS_MAND_PROTO "SSLv3, TLSv1" +#define DEF_LMTP_TLS_MAND_PROTO "!SSLv2" extern char *var_smtp_tls_mand_proto; #define VAR_SMTP_TLS_VFY_CMATCH "smtp_tls_verify_cert_match" Index: src/tls/tls.h --- src/tls/tls.h 6 Feb 2012 20:10:46 -0000 1.1.1.5 +++ src/tls/tls.h 22 Apr 2012 17:53:14 -0000 @@ -175,10 +175,22 @@ #define TLS_PROTOCOL_SSLv2 (1<<0) /* SSLv2 */ #define TLS_PROTOCOL_SSLv3 (1<<1) /* SSLv3 */ #define TLS_PROTOCOL_TLSv1 (1<<2) /* TLSv1 */ +#ifdef SSL_TXT_TLSV1_1 +#define TLS_PROTOCOL_TLSv1_1 (1<<3) /* TLSv1_1 */ +#else +#define TLS_PROTOCOL_TLSv1_1 0 /* Unknown */ +#endif +#ifdef SSL_TXT_TLSV1_2 +#define TLS_PROTOCOL_TLSv1_2 (1<<4) /* TLSv1_2 */ +#else +#define TLS_PROTOCOL_TLSv1_2 0 /* Unknown */ +#endif #define TLS_KNOWN_PROTOCOLS \ - ( TLS_PROTOCOL_SSLv2 | TLS_PROTOCOL_SSLv3 | TLS_PROTOCOL_TLSv1 ) + ( TLS_PROTOCOL_SSLv2 | TLS_PROTOCOL_SSLv3 | TLS_PROTOCOL_TLSv1 | \ + TLS_PROTOCOL_TLSv1_1 | TLS_PROTOCOL_TLSv1_2 ) extern int tls_protocol_mask(const char *); +extern unsigned long tls_protocol_ops(int); /* * Cipher grade selection. Index: src/tls/tls_client.c --- src/tls/tls_client.c 6 Feb 2012 20:10:46 -0000 1.1.1.7 +++ src/tls/tls_client.c 22 Apr 2012 17:51:42 -0000 @@ -857,10 +857,7 @@ * Apply session protocol restrictions. */ if (protomask != 0) - SSL_set_options(TLScontext->con, - ((protomask & TLS_PROTOCOL_TLSv1) ? SSL_OP_NO_TLSv1 : 0L) - | ((protomask & TLS_PROTOCOL_SSLv3) ? SSL_OP_NO_SSLv3 : 0L) - | ((protomask & TLS_PROTOCOL_SSLv2) ? SSL_OP_NO_SSLv2 : 0L)); + SSL_set_options(TLScontext->con, tls_protocol_ops(protomask)); /* * XXX To avoid memory leaks we must always call SSL_SESSION_free() after Index: src/tls/tls_misc.c --- src/tls/tls_misc.c 6 Feb 2012 20:10:46 -0000 1.1.1.5 +++ src/tls/tls_misc.c 22 Apr 2012 18:00:24 -0000 @@ -41,6 +41,9 @@ /* int tls_protocol_mask(plist) /* const char *plist; /* +/* unsigned long tls_protocol_ops(protomask) +/* int protomask; +/* /* int tls_cipher_grade(name) /* const char *name; /* @@ -103,6 +106,9 @@ /* If "plist" contains invalid protocol names, TLS_PROTOCOL_INVALID is /* returned and no warning is logged. /* +/* tls_protocol_ops() converts a bitmask of excluded TLS protocols to a +/* bitmask of corresponding SSL options. +/* /* tls_cipher_grade() converts a case-insensitive cipher grade /* name (high, medium, low, export, null) to the corresponding /* TLS_CIPHER_ constant. When the input specifies an unrecognized @@ -224,6 +230,12 @@ SSL_TXT_SSLV2, TLS_PROTOCOL_SSLv2, SSL_TXT_SSLV3, TLS_PROTOCOL_SSLv3, SSL_TXT_TLSV1, TLS_PROTOCOL_TLSv1, +#ifdef SSL_TXT_TLSV1_1 + SSL_TXT_TLSV1_1, TLS_PROTOCOL_TLSv1_1, +#endif +#ifdef SSL_TXT_TLSV1_2 + SSL_TXT_TLSV1_2, TLS_PROTOCOL_TLSv1_2, +#endif 0, TLS_PROTOCOL_INVALID, }; @@ -519,6 +531,25 @@ return (include ? (exclude | (TLS_KNOWN_PROTOCOLS & ~include)) : exclude); } +/* tls_protocol_ops - SSL options to select the desired protocols */ + +unsigned long tls_protocol_ops(int protomask) +{ + unsigned long ops = 0; + + if (protomask & TLS_PROTOCOL_SSLv2) ops |= SSL_OP_NO_SSLv2; + if (protomask & TLS_PROTOCOL_SSLv3) ops |= SSL_OP_NO_SSLv3; + if (protomask & TLS_PROTOCOL_TLSv1) ops |= SSL_OP_NO_TLSv1; +#ifdef SSL_TXT_TLSV1_1 + if (protomask & TLS_PROTOCOL_TLSv1_1) ops |= SSL_OP_NO_TLSv1_1; +#endif +#ifdef SSL_TXT_TLSV1_2 + if (protomask & TLS_PROTOCOL_TLSv1_2) ops |= SSL_OP_NO_TLSv1_2; +#endif + + return ops; +} + /* tls_param_init - Load TLS related config parameters */ void tls_param_init(void) Index: src/tls/tls_server.c --- src/tls/tls_server.c 6 Feb 2012 20:10:46 -0000 1.1.1.6 +++ src/tls/tls_server.c 22 Apr 2012 17:52:28 -0000 @@ -401,10 +401,7 @@ * Global protocol selection. */ if (protomask != 0) - SSL_CTX_set_options(server_ctx, - ((protomask & TLS_PROTOCOL_TLSv1) ? SSL_OP_NO_TLSv1 : 0L) - | ((protomask & TLS_PROTOCOL_SSLv3) ? SSL_OP_NO_SSLv3 : 0L) - | ((protomask & TLS_PROTOCOL_SSLv2) ? SSL_OP_NO_SSLv2 : 0L)); + SSL_CTX_set_options(server_ctx, tls_protocol_ops(protomask)); #if OPENSSL_VERSION_NUMBER >= 0x0090700fL