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.

+This is only possible with SSLv3 (or higher), 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" output

List 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" output

The 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" output

The 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