File 0002-New-option-ssl_disabled_protocols.patch of Package openwsman.10653

From e70dd2e4433bad3ae113641b0ebc3d4c365a90ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Klaus=20K=C3=A4mpf?= <kkaempf@suse.de>
Date: Mon, 20 Oct 2014 09:58:55 +0200
Subject: [PATCH 2/6] New option: ssl_disabled_protocols

make SSL_CTX_ctrl available
Honor ssl_disable_protocols config option

This patch adds a new option "ssl_disabled_protocols =" to the
openwsman.conf file to selectively disable SSL protocols.

This matches the openssl semantics and was choosen for simplicity.
---
 etc/openwsman.conf         |  4 ++++
 src/server/shttpd/config.c | 34 ++++++++++++++++++++++++++++++++++
 src/server/shttpd/io_ssl.c |  1 +
 src/server/shttpd/ssl.h    |  2 ++
 src/server/wsmand-daemon.c |  7 +++++++
 src/server/wsmand-daemon.h |  1 +
 6 files changed, 49 insertions(+)

diff --git a/etc/openwsman.conf b/etc/openwsman.conf
index 8aa9084e835f..27adb6b0f756 100644
--- a/etc/openwsman.conf
+++ b/etc/openwsman.conf
@@ -35,6 +35,10 @@ ssl_cert_file = /etc/openwsman/servercert.pem
 # the openwsman server private key, in .pem format
 ssl_key_file = /etc/openwsman/serverkey.pem
 
+# space-separated list of SSL protocols to *dis*able
+# possible values: SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv1_2
+ssl_disabled_protocols = SSLv2 SSLv3
+
 # set these to enable digest authentication against a local datbase
 #digest_password_file = /etc/openwsman/digest_auth.passwd
 
diff --git a/src/server/shttpd/config.c b/src/server/shttpd/config.c
index 340dc63ac2ee..67b904d0521a 100644
--- a/src/server/shttpd/config.c
+++ b/src/server/shttpd/config.c
@@ -87,6 +87,7 @@ set_ssl(struct shttpd_ctx *ctx, void *arg, const char *pem)
 	SSL_CTX		*CTX;
 	void		*lib;
 	struct ssl_func	*fp;
+        char *ssl_disabled_protocols = wsmand_options_get_ssl_disabled_protocols();
 
 	arg = NULL;	/* Unused */
 
@@ -125,6 +126,39 @@ set_ssl(struct shttpd_ctx *ctx, void *arg, const char *pem)
                 SSL_CTX_free(CTX);
                 CTX = NULL;
         }
+	while (ssl_disabled_protocols) {
+          struct ctx_opts_t {
+            char *name;
+            long opt;
+          } protocols[] = {
+            { "SSLv2", SSL_OP_NO_SSLv2 },
+            { "SSLv3", SSL_OP_NO_SSLv3 },
+            { "TLSv1", SSL_OP_NO_TLSv1 },
+# if OPENSSL_VERSION_NUMBER >= 0x10001000L
+            { "TLSv1_1", SSL_OP_NO_TLSv1_1 },
+            { "TLSv1_2", SSL_OP_NO_TLSv1_2 },
+# endif
+            { NULL, 0 }
+          };
+          char *blank_ptr;
+          int idx;
+          if (*ssl_disabled_protocols == 0)
+            break;
+          blank_ptr = strchr(ssl_disabled_protocols, ' ');
+          if (blank_ptr == NULL)
+            blank_ptr = ssl_disabled_protocols + strlen(ssl_disabled_protocols);
+          for (idx = 0; protocols[idx].name ; ++idx) {
+            if (strncasecmp(protocols[idx].name, ssl_disabled_protocols, blank_ptr-ssl_disabled_protocols) == 0) {
+              debug("SSL: disable %s protocol", protocols[idx].name);
+              SSL_CTX_ctrl(CTX, SSL_CTRL_OPTIONS, protocols[idx].opt, NULL);                      
+              break;
+            }
+          }
+          if (*blank_ptr == 0)
+            break;
+          ssl_disabled_protocols = blank_ptr + 1;          
+        }
+
 	ctx->ssl_ctx = CTX;
 }
 #endif /* NO_SSL */
diff --git a/src/server/shttpd/io_ssl.c b/src/server/shttpd/io_ssl.c
index 39359d68c8ab..293d0b5cb113 100644
--- a/src/server/shttpd/io_ssl.c
+++ b/src/server/shttpd/io_ssl.c
@@ -28,6 +28,7 @@ struct ssl_func	ssl_sw[] = {
 	{"SSL_CTX_free", {0}},
 	{"SSL_pending", {0}},
 	{"SSL_CTX_use_certificate_chain_file",{0}},
+	{"SSL_CTX_ctrl", {0}},
 	{NULL,				{0}}
 };
 
diff --git a/src/server/shttpd/ssl.h b/src/server/shttpd/ssl.h
index 0a167b518380..d045b6e75bb6 100644
--- a/src/server/shttpd/ssl.h
+++ b/src/server/shttpd/ssl.h
@@ -63,3 +63,5 @@ extern struct ssl_func	ssl_sw[];
 		const char *)) FUNC(15))((x), (y))
 #define	SSL_CTX_free(x)	(*(void (*)(SSL_CTX *)) FUNC(13))(x)
 #define	SSL_pending(x) (*(int (*)(SSL *)) FUNC(14))(x)
+#define SSL_CTX_ctrl(w,x,y,z) (*(long (*)(SSL_CTX *,int,long,void *)) FUNC(16))((w),(x),(y),(z))
+                                    
diff --git a/src/server/wsmand-daemon.c b/src/server/wsmand-daemon.c
index b02f11ad76ed..a17c83a6fea3 100644
--- a/src/server/wsmand-daemon.c
+++ b/src/server/wsmand-daemon.c
@@ -78,6 +78,7 @@ static int use_digest = 0;
 static char *ssl_key_file = NULL;
 static char *service_path = DEFAULT_SERVICE_PATH;
 static char *ssl_cert_file = NULL;
+static char *ssl_disabled_protocols = NULL;
 static char *pid_file = DEFAULT_PID_PATH;
 static char *uri_subscription_repository = DEFAULT_SUBSCRIPTION_REPOSITORY;
 static int daemon_flag = 0;
@@ -177,6 +178,7 @@ int wsmand_read_config(dictionary * ini)
 	    iniparser_getstring(ini, "server:service_path", "/wsman");
 	ssl_key_file = iniparser_getstr(ini, "server:ssl_key_file");
 	ssl_cert_file = iniparser_getstr(ini, "server:ssl_cert_file");
+        ssl_disabled_protocols = iniparser_getstr(ini, "server:ssl_disabled_protocols");
 	use_ipv4 = iniparser_getboolean(ini, "server:ipv4", 1);
 #ifdef ENABLE_IPV6
         use_ipv6 = iniparser_getboolean(ini, "server:ipv6", 1);
@@ -343,6 +345,11 @@ char *wsmand_options_get_ssl_cert_file(void)
 	return ssl_cert_file;
 }
 
+char *wsmand_options_get_ssl_disabled_protocols(void)
+{
+	return ssl_disabled_protocols;
+}
+
 int wsmand_options_get_digest(void)
 {
 	return use_digest;
diff --git a/src/server/wsmand-daemon.h b/src/server/wsmand-daemon.h
index e2d9ea6bb191..3bd6a9da34d3 100644
--- a/src/server/wsmand-daemon.h
+++ b/src/server/wsmand-daemon.h
@@ -76,6 +76,7 @@ int wsmand_options_get_server_port(void);
 int wsmand_options_get_server_ssl_port(void);
 char *wsmand_options_get_ssl_key_file(void);
 char *wsmand_options_get_ssl_cert_file(void);
+char *wsmand_options_get_ssl_disabled_protocols(void);
 int wsmand_options_get_digest(void);
 char *wsmand_options_get_digest_password_file(void);
 char *wsmand_options_get_basic_password_file(void);
-- 
2.1.4