diff --git a/src/Cedar/Cedar.c b/src/Cedar/Cedar.c index 790e8018..9abcea50 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 23a94ffd..0f927dbb 100644 --- a/src/Cedar/Cedar.h +++ b/src/Cedar/Cedar.h @@ -404,7 +404,22 @@ #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_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 ////////////////////////////////////////////////////////////////////// // @@ -1053,6 +1068,7 @@ typedef struct CEDAR LOCK *FifoBudgetLock; // Fifo budget lock UINT FifoBudget; // Fifo budget bool AcceptOnlyTls; // Accept only TLS (Disable SSL) + UINT DisableSslVersions; // 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 517096e4..f4b08972 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 561697b2..c0d5af72 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -6170,6 +6170,41 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f) { c->AcceptOnlyTls = true; } + + 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++) + { + char *sslVersion=sslVersions->Token[i]; + if (StrCmp(sslVersion, NAME_SSL_VERSION_SSL_V2)==0) { + c->DisableSslVersions |= SSL_VERSION_SSL_V2; + continue; + } + if (StrCmp(sslVersion, NAME_SSL_VERSION_SSL_V3)==0) { + c->DisableSslVersions |= SSL_VERSION_SSL_V3; + continue; + } + if (StrCmp(sslVersion, NAME_SSL_VERSION_TLS_V1_0)==0) { + c->DisableSslVersions |= SSL_VERSION_TLS_V1_0; + continue; + } + if (StrCmp(sslVersion, NAME_SSL_VERSION_TLS_V1_1)==0) { + c->DisableSslVersions |= SSL_VERSION_TLS_V1_1; + continue; + } + if (StrCmp(sslVersion, NAME_SSL_VERSION_TLS_V1_2)==0) { + c->DisableSslVersions |= SSL_VERSION_TLS_V1_2; + continue; + } + } + FreeToken(sslVersions); + } } Unlock(c->lock); @@ -6480,6 +6515,41 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s) CfgAddBool(f, "AcceptOnlyTls", c->AcceptOnlyTls); + { + 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)); } diff --git a/src/Mayaqua/Network.c b/src/Mayaqua/Network.c index 0a7a321a..2fa4ba41 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; @@ -12966,15 +12967,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 bb4c69b7..ed69edf2 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