MINOR: ssl: add 'force-sslv3' and 'force-tlsvXX' statements on server

These options force the SSL lib to use the specified protocol when
connecting to a server. They are complentary to no-tlsv*/no-sslv3.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index ea89e99..50c6bb1 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -7140,6 +7140,31 @@
 
   Supported in default-server: Yes
 
+force-sslv3
+  This option enforces use of SSLv3 only when SSL is used to communicate with
+  the server. SSLv3 is generally less expensive than the TLS counterparts for
+  high connection rates. See also "no-tlsv*", "no-sslv3".
+
+  Supported in default-server: No
+
+force-tlsv10
+  This option enforces use of TLSv1.0 only when SSL is used to communicate with
+  the server. See also "no-tlsv*", "no-sslv3".
+
+  Supported in default-server: No
+
+force-tlsv11
+  This option enforces use of TLSv1.1 only when SSL is used to communicate with
+  the server. See also "no-tlsv*", "no-sslv3".
+
+  Supported in default-server: No
+
+force-tlsv12
+  This option enforces use of TLSv1.2 only when SSL is used to communicate with
+  the server. See also "no-tlsv*", "no-sslv3".
+
+  Supported in default-server: No
+
 id <value>
   Set a persistent ID for the server. This ID must be positive and unique for
   the proxy. An unused ID will automatically be assigned if unset. The first
@@ -7216,31 +7241,34 @@
 no-sslv3
   This option disables support for SSLv3 when SSL is used to communicate with
   the server. Note that SSLv2 is disabled in the code and cannot be enabled
-  using any configuration option.
+  using any configuration option. See also "force-sslv3", "force-tlsv*".
 
   Supported in default-server: No
 
 no-tlsv10
-  This option disables support for TLSv10 when SSL is used to communicate with
+  This option disables support for TLSv1.0 when SSL is used to communicate with
   the server. Note that SSLv2 is disabled in the code and cannot be enabled
   using any configuration option. TLSv1 is more expensive than SSLv3 so it
-  often makes sense to disable it when communicating with local servers.
+  often makes sense to disable it when communicating with local servers. See
+  also "force-sslv3", "force-tlsv*".
 
   Supported in default-server: No
 
 no-tlsv11
-  This option disables support for TLSv11 when SSL is used to communicate with
+  This option disables support for TLSv1.1 when SSL is used to communicate with
   the server. Note that SSLv2 is disabled in the code and cannot be enabled
   using any configuration option. TLSv1 is more expensive than SSLv3 so it
-  often makes sense to disable it when communicating with local servers.
+  often makes sense to disable it when communicating with local servers. See
+  also "force-sslv3", "force-tlsv*".
 
   Supported in default-server: No
 
 no-tlsv12
-  This option disables support for TLSv12 when SSL is used to communicate with
+  This option disables support for TLSv1.2 when SSL is used to communicate with
   the server. Note that SSLv2 is disabled in the code and cannot be enabled
   using any configuration option. TLSv1 is more expensive than SSLv3 so it
-  often makes sense to disable it when communicating with local servers.
+  often makes sense to disable it when communicating with local servers. See
+  also "force-sslv3", "force-tlsv*".
 
   Supported in default-server: No
 
diff --git a/include/types/server.h b/include/types/server.h
index 5453b08..2a22e72 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -87,6 +87,11 @@
 #define SRV_SSL_O_NO_TLSV11    0x0004 /* disable TLSv1.1 */
 #define SRV_SSL_O_NO_TLSV12    0x0008 /* disable TLSv1.2 */
 /* 0x000F reserved for 'no' protocol version options */
+#define SRV_SSL_O_USE_SSLV3    0x0001 /* force SSLv3 */
+#define SRV_SSL_O_USE_TLSV10   0x0002 /* force TLSv1.0 */
+#define SRV_SSL_O_USE_TLSV11   0x0004 /* force TLSv1.1 */
+#define SRV_SSL_O_USE_TLSV12   0x0008 /* force TLSv1.2 */
+/* 0x00F0 reserved for 'force' protocol version options */
 #endif
 
 /* A tree occurrence is a descriptor of a place in a tree, with a pointer back
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 9b1ac46..88c6300 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4138,6 +4138,64 @@
 				newsrv->fastinter = val;
 				cur_arg += 2;
 			}
+			else if (!strcmp(args[cur_arg], "force-sslv3")) {
+#ifdef USE_OPENSSL
+				newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
+				cur_arg += 1;
+#else /* USE_OPENSSL */
+				Alert("parsing [%s:%d]: '%s' option not implemented.\n",
+				      file, linenum, args[cur_arg]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+#endif /* USE_OPENSSL */
+			}
+			else if (!strcmp(args[cur_arg], "force-tlsv10")) {
+#ifdef USE_OPENSSL
+				newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
+				cur_arg += 1;
+#else /* USE_OPENSSL */
+				Alert("parsing [%s:%d]: '%s' option not implemented.\n",
+				      file, linenum, args[cur_arg]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+#endif /* USE_OPENSSL */
+			}
+			else if (!strcmp(args[cur_arg], "force-tlsv11")) {
+#ifdef USE_OPENSSL
+#if SSL_OP_NO_TLSv1_1
+				newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
+				cur_arg += 1;
+#else
+				Alert("parsing [%s:%d]: '%s' library does not support protocol TLSv1.1.\n",
+                                      file, linenum, args[cur_arg]);
+                                err_code |= ERR_ALERT | ERR_FATAL;
+                                goto out;
+#endif
+#else /* USE_OPENSSL */
+				Alert("parsing [%s:%d]: '%s' option not implemented.\n",
+				      file, linenum, args[cur_arg]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+#endif /* USE_OPENSSL */
+			}
+			else if (!strcmp(args[cur_arg], "force-tlsv12")) {
+#ifdef USE_OPENSSL
+#if SSL_OP_NO_TLSv1_2
+				newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
+				cur_arg += 1;
+#else
+				Alert("parsing [%s:%d]: '%s' library does not support protocol TLSv1.2.\n",
+                                      file, linenum, args[cur_arg]);
+                                err_code |= ERR_ALERT | ERR_FATAL;
+                                goto out;
+#endif
+#else /* USE_OPENSSL */
+				Alert("parsing [%s:%d]: '%s' option not implemented.\n",
+				      file, linenum, args[cur_arg]);
+				err_code |= ERR_ALERT | ERR_FATAL;
+				goto out;
+#endif /* USE_OPENSSL */
+			}
 			else if (!strcmp(args[cur_arg], "downinter")) {
 				const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_MS);
 				if (err) {
@@ -6368,6 +6426,19 @@
 					ssloptions |= SSL_OP_NO_TLSv1_1;
 				if (newsrv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
 					ssloptions |= SSL_OP_NO_TLSv1_2;
+				if (newsrv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
+					SSL_CTX_set_ssl_version(newsrv->ssl_ctx.ctx, SSLv3_client_method());
+				if (newsrv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
+					SSL_CTX_set_ssl_version(newsrv->ssl_ctx.ctx, TLSv1_client_method());
+#if SSL_OP_NO_TLSv1_1
+				if (newsrv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
+					SSL_CTX_set_ssl_version(newsrv->ssl_ctx.ctx, TLSv1_1_client_method());
+#endif
+#if SSL_OP_NO_TLSv1_2
+				if (newsrv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
+					SSL_CTX_set_ssl_version(newsrv->ssl_ctx.ctx, TLSv1_2_client_method());
+#endif
+
 				SSL_CTX_set_options(newsrv->ssl_ctx.ctx, ssloptions);
 				SSL_CTX_set_mode(newsrv->ssl_ctx.ctx, sslmode);
 				SSL_CTX_set_verify(newsrv->ssl_ctx.ctx, SSL_VERIFY_NONE, NULL);