From 8b1b67faedaac1c84c54874aa50a1e89952915af Mon Sep 17 00:00:00 2001 From: Raymond Tau Date: Tue, 10 Nov 2015 00:55:24 +0800 Subject: [PATCH 1/3] Introduce DisableSslVersions. The SSL Versions specified will be disabled on server context. --- src/Cedar/Cedar.h | 13 +++++++++++++ src/Cedar/Connection.c | 6 ++---- src/Cedar/Server.c | 35 +++++++++++++++++++++++++++++++++++ src/Mayaqua/Network.c | 23 ++++++++++++++++------- src/Mayaqua/Network.h | 1 + 5 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/Cedar/Cedar.h b/src/Cedar/Cedar.h index e7ae9dc0..4618c9c5 100644 --- a/src/Cedar/Cedar.h +++ b/src/Cedar/Cedar.h @@ -404,7 +404,19 @@ #define KEEP_ALIVE_MAGIC 0xffffffff #define MAX_KEEPALIVE_SIZE 512 +// SSL/TLS Versions +#define SSL_VERSION_SSL_V2 0x01 // SSLv2 +#define SSL_VERSION_SSL_V3 0x02 // SSLv3 +#define SSL_VERSION_TLS_V1_0 0x04 // TLS v1.0 +#define SSL_VERSION_TLS_V1_1 0x08 // TLS v1.1 +#define SSL_VERSION_TLS_V1_2 0x10 // TLS v1.2 +// SSL/TLS Version Names +#define NAME_SSL_VERSION_SSL_V2 "SSL_V2" // SSLv2 +#define NAME_SSL_VERSION_SSL_V3 "SSL_V3" // SSLv3 +#define NAME_SSL_VERSION_TLS_V1_0 "TLS_V1_0" // TLS v1.0 +#define NAME_SSL_VERSION_TLS_V1_0 "TLS_V1_1" // TLS v1.1 +#define NAME_SSL_VERSION_TLS_V1_0 "TLS_V1_2" // TLS v1.2 ////////////////////////////////////////////////////////////////////// // @@ -1053,6 +1065,7 @@ typedef struct CEDAR LOCK *FifoBudgetLock; // Fifo budget lock UINT FifoBudget; // Fifo budget bool AcceptOnlyTls; // Accept only TLS (Disable SSL) + UINT DisableSslVersions = 0x0; // Bitmap of SSL Version to disable char OpenVPNDefaultClientOption[MAX_SIZE]; // OpenVPN Default Client Option String } CEDAR; diff --git a/src/Cedar/Connection.c b/src/Cedar/Connection.c index 224afb37..6ec6cee6 100644 --- a/src/Cedar/Connection.c +++ b/src/Cedar/Connection.c @@ -3137,10 +3137,8 @@ void ConnectionAccept(CONNECTION *c) // Start the SSL communication Debug("StartSSL()\n"); - if (c->Cedar->AcceptOnlyTls) - { - s->AcceptOnlyTls = true; - } + s->DisableSslVersions = c->Cedar->DisableSslVersions; + if (StartSSL(s, x, k) == false) { // Failed diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index e5e2aff5..bfd14338 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -6157,6 +6157,39 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f) // AcceptOnlyTls c->AcceptOnlyTls = CfgGetBool(f, "AcceptOnlyTls"); + if (c->AcceptOnlyTls) { + c->DisableSslVersions |= SSL_VERSION_SSL_V2; + c->DisableSslVersions |= SSL_VERSION_SSL_V3; + } + + if (CfgGetStr(f, "DisableSslVersions", tmp, sizeof(tmp))) { + TOKEN_LIST *sslVersions= ParseToken(tmp, ", "); + UINT i; + for (i = 0;i < sslVersions->NumTokens;i++) + { + if (strcmp(tmp, NAME_SSL_VERSION_SSL_V2)) + c->DisableSslVersions |= SSL_VERSION_SSL_V2; + continue; + } + if (strcmp(tmp, NAME_SSL_VERSION_SSL_V3)) + c->DisableSslVersions |= SSL_VERSION_SSL_V3; + continue; + } + if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_0)) + c->DisableSslVersions |= SSL_VERSION_TLS_V1_0; + continue; + } + if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_1)) + c->DisableSslVersions |= SSL_VERSION_TLS_V1_1; + continue; + } + if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_2)) + c->DisableSslVersions |= SSL_VERSION_TLS_V1_2; + continue; + } + } + FreeToken(sslVersions); + } } Unlock(c->lock); @@ -6467,6 +6500,8 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s) CfgAddBool(f, "AcceptOnlyTls", c->AcceptOnlyTls); + CfgAddStr(f, "DisableSslVersions", c->DisableSslVersions); + // Disable session reconnect CfgAddBool(f, "DisableSessionReconnect", GetGlobalServerFlag(GSF_DISABLE_SESSION_RECONNECT)); } diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index def2f45e..e0395aa4 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -12966,15 +12966,24 @@ bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls, UINT ssl_timeout, ch { if (sock->ServerMode) { - if (sock->AcceptOnlyTls == false) - { - SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method()); + SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method()); + long ssl_opt_flags=0x0L; + if (sock->DisableSslVersions & SSL_VERSION_SSL_V2) { + ssl_opt_flags |= SSL_OP_NO_SSLv2; } - else - { - SSL_CTX_set_ssl_version(ssl_ctx, TLSv1_method()); + if (sock->DisableSslVersions & SSL_VERSION_SSL_V3) { + ssl_opt_flags |= SSL_OP_NO_SSLv3; } - + if (sock->DisableSslVersions & SSL_VERSION_TLS_V1_0) { + ssl_opt_flags |= SSL_OP_NO_TLSv1; + } + if (sock->DisableSslVersions & SSL_VERSION_TLS_V1_1) { + ssl_opt_flags |= SSL_OP_NO_TLSv1_1; + } + if (sock->DisableSslVersions & SSL_VERSION_TLS_V1_2) { + ssl_opt_flags |= SSL_OP_NO_TLSv1_2; + } + SSL_CTX_set_options(ssl_ctx, ssl_opt_flags); Unlock(openssl_lock); AddChainSslCertOnDirectory(ssl_ctx); Lock(openssl_lock); diff --git a/src/Mayaqua/Network.h b/src/Mayaqua/Network.h index 6f51bedf..18024c4b 100644 --- a/src/Mayaqua/Network.h +++ b/src/Mayaqua/Network.h @@ -313,6 +313,7 @@ struct SOCK UINT Reverse_MyServerPort; // Self port number when using the reverse socket UCHAR Ssl_Init_Async_SendAlert[2]; // Initial state of SSL send_alert bool AcceptOnlyTls; // Accept only TLS (disable SSLv3) + UINT DisableSslVersions; // Bitmap of SSL Version to disable bool RawIP_HeaderIncludeFlag; #ifdef ENABLE_SSL_LOGGING From 04b72873c79375fc9845e03f1d575d4891ea723f Mon Sep 17 00:00:00 2001 From: Raymond Tau Date: Mon, 23 Nov 2015 16:15:10 +0800 Subject: [PATCH 2/3] Fix the problem of the DisableSslVersions patch. --- src/Cedar/Cedar.c | 2 ++ src/Cedar/Cedar.h | 9 ++++++--- src/Cedar/Server.c | 10 +++++----- src/Mayaqua/Network.c | 1 + 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Cedar/Cedar.c b/src/Cedar/Cedar.c index 49841778..9242ff5b 100644 --- a/src/Cedar/Cedar.c +++ b/src/Cedar/Cedar.c @@ -1803,6 +1803,8 @@ CEDAR *NewCedar(X *server_x, K *server_k) c->BuildInfo = CopyStr(tmp); + c->DisableSslVersions = SSL_OPT_DEFAULT; + return c; } diff --git a/src/Cedar/Cedar.h b/src/Cedar/Cedar.h index 4618c9c5..6bbfd1cc 100644 --- a/src/Cedar/Cedar.h +++ b/src/Cedar/Cedar.h @@ -415,8 +415,11 @@ #define NAME_SSL_VERSION_SSL_V2 "SSL_V2" // SSLv2 #define NAME_SSL_VERSION_SSL_V3 "SSL_V3" // SSLv3 #define NAME_SSL_VERSION_TLS_V1_0 "TLS_V1_0" // TLS v1.0 -#define NAME_SSL_VERSION_TLS_V1_0 "TLS_V1_1" // TLS v1.1 -#define NAME_SSL_VERSION_TLS_V1_0 "TLS_V1_2" // TLS v1.2 +#define NAME_SSL_VERSION_TLS_V1_1 "TLS_V1_1" // TLS v1.1 +#define NAME_SSL_VERSION_TLS_V1_2 "TLS_V1_2" // TLS v1.2 + +// OpenSSL SSL Context Option Flags default +#define SSL_OPT_DEFAULT 0x0 ////////////////////////////////////////////////////////////////////// // @@ -1065,7 +1068,7 @@ typedef struct CEDAR LOCK *FifoBudgetLock; // Fifo budget lock UINT FifoBudget; // Fifo budget bool AcceptOnlyTls; // Accept only TLS (Disable SSL) - UINT DisableSslVersions = 0x0; // Bitmap of SSL Version to disable + UINT DisableSslVersions; // Bitmap of SSL Version to disable char OpenVPNDefaultClientOption[MAX_SIZE]; // OpenVPN Default Client Option String } CEDAR; diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index bfd14338..23c08593 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -6167,23 +6167,23 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f) UINT i; for (i = 0;i < sslVersions->NumTokens;i++) { - if (strcmp(tmp, NAME_SSL_VERSION_SSL_V2)) + if (strcmp(tmp, NAME_SSL_VERSION_SSL_V2)) { c->DisableSslVersions |= SSL_VERSION_SSL_V2; continue; } - if (strcmp(tmp, NAME_SSL_VERSION_SSL_V3)) + if (strcmp(tmp, NAME_SSL_VERSION_SSL_V3)) { c->DisableSslVersions |= SSL_VERSION_SSL_V3; continue; } - if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_0)) + if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_0)) { c->DisableSslVersions |= SSL_VERSION_TLS_V1_0; continue; } - if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_1)) + if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_1)) { c->DisableSslVersions |= SSL_VERSION_TLS_V1_1; continue; } - if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_2)) + if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_2)) { c->DisableSslVersions |= SSL_VERSION_TLS_V1_2; continue; } diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index e0395aa4..69278c80 100644 --- a/src/Mayaqua/Network.c +++ b/src/Mayaqua/Network.c @@ -155,6 +155,7 @@ #ifdef UNIX_MACOS #include #endif // UNIX_MACOS +#include #ifdef OS_WIN32 NETWORK_WIN32_FUNCTIONS *w32net; From 311ab9efaba485225c05b65437d0d1f5d685ef5f Mon Sep 17 00:00:00 2001 From: Raymond Tau Date: Wed, 9 Dec 2015 14:06:13 +0800 Subject: [PATCH 3/3] Correctly save and apply the DisableSslVersions config --- src/Cedar/Server.c | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index 23c08593..8081d2bc 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -6167,23 +6167,24 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f) UINT i; for (i = 0;i < sslVersions->NumTokens;i++) { - if (strcmp(tmp, NAME_SSL_VERSION_SSL_V2)) { + char *sslVersion=sslVersions->Token[i]; + if (StrCmp(sslVersion, NAME_SSL_VERSION_SSL_V2)==0) { c->DisableSslVersions |= SSL_VERSION_SSL_V2; continue; } - if (strcmp(tmp, NAME_SSL_VERSION_SSL_V3)) { + if (StrCmp(sslVersion, NAME_SSL_VERSION_SSL_V3)==0) { c->DisableSslVersions |= SSL_VERSION_SSL_V3; continue; } - if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_0)) { + if (StrCmp(sslVersion, NAME_SSL_VERSION_TLS_V1_0)==0) { c->DisableSslVersions |= SSL_VERSION_TLS_V1_0; continue; } - if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_1)) { + if (StrCmp(sslVersion, NAME_SSL_VERSION_TLS_V1_1)==0) { c->DisableSslVersions |= SSL_VERSION_TLS_V1_1; continue; } - if (strcmp(tmp, NAME_SSL_VERSION_TLS_V1_2)) { + if (StrCmp(sslVersion, NAME_SSL_VERSION_TLS_V1_2)==0) { c->DisableSslVersions |= SSL_VERSION_TLS_V1_2; continue; } @@ -6500,7 +6501,40 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s) CfgAddBool(f, "AcceptOnlyTls", c->AcceptOnlyTls); - CfgAddStr(f, "DisableSslVersions", c->DisableSslVersions); + { + char tmp[MAX_SIZE]; + tmp[0] = 0; + if (c->DisableSslVersions & SSL_VERSION_SSL_V2) { + StrCat(tmp, sizeof(tmp), NAME_SSL_VERSION_SSL_V2); + StrCat(tmp, sizeof(tmp), ","); + } + if (c->DisableSslVersions & SSL_VERSION_SSL_V3) { + StrCat(tmp, sizeof(tmp), NAME_SSL_VERSION_SSL_V3); + StrCat(tmp, sizeof(tmp), ","); + } + if (c->DisableSslVersions & SSL_VERSION_TLS_V1_0) { + StrCat(tmp, sizeof(tmp), NAME_SSL_VERSION_TLS_V1_0); + StrCat(tmp, sizeof(tmp), ","); + } + if (c->DisableSslVersions & SSL_VERSION_TLS_V1_1) { + StrCat(tmp, sizeof(tmp), NAME_SSL_VERSION_TLS_V1_1); + StrCat(tmp, sizeof(tmp), ","); + } + if (c->DisableSslVersions & SSL_VERSION_TLS_V1_2) { + StrCat(tmp, sizeof(tmp), NAME_SSL_VERSION_TLS_V1_2); + StrCat(tmp, sizeof(tmp), ","); + } + if (StrLen(tmp) >= 1) + { + if (tmp[StrLen(tmp) - 1] == ',') + { + tmp[StrLen(tmp) - 1] = 0; + } + } + CfgAddStr(f, "DisableSslVersions", tmp); + } + + // Disable session reconnect CfgAddBool(f, "DisableSessionReconnect", GetGlobalServerFlag(GSF_DISABLE_SESSION_RECONNECT));