diff --git a/src/base.h b/src/base.h index 134fc41..f2d849e 100644 --- a/src/base.h +++ b/src/base.h @@ -289,6 +289,9 @@ typedef struct { unsigned short ssl_empty_fragments; /* whether to not set SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */ unsigned short ssl_use_sslv2; unsigned short ssl_use_sslv3; + unsigned short ssl_use_tlsv1; + unsigned short ssl_use_tlsv1_1; + unsigned short ssl_use_tlsv1_2; unsigned short ssl_verifyclient; unsigned short ssl_verifyclient_enforce; unsigned short ssl_verifyclient_depth; diff --git a/src/configfile.c b/src/configfile.c index bba6925..bbedd77 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -146,6 +146,10 @@ static int config_insert(server *srv) { { "server.max-request-field-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_SERVER }, /* 78 */ { "ssl.read-ahead", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 79 */ + { "ssl.use-tlsv1", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 80 */ + { "ssl.use-tlsv1_1", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 81 */ + { "ssl.use-tlsv1_2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 82 */ + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; @@ -226,6 +230,9 @@ static int config_insert(server *srv) { s->ssl_empty_fragments = 0; s->ssl_use_sslv2 = 0; s->ssl_use_sslv3 = 0; + s->ssl_use_tlsv1 = 0; + s->ssl_use_tlsv1_1 = 0; + s->ssl_use_tlsv1_2 = 1; s->use_ipv6 = (i == 0) ? 0 : srv->config_storage[0]->use_ipv6; s->set_v6only = (i == 0) ? 1 : srv->config_storage[0]->set_v6only; s->defer_accept = (i == 0) ? 0 : srv->config_storage[0]->defer_accept; @@ -318,6 +325,9 @@ static int config_insert(server *srv) { cv[76].destination = &(s->stream_request_body); cv[77].destination = &(s->stream_response_body); cv[79].destination = &(s->ssl_read_ahead); + cv[80].destination = &(s->ssl_use_tlsv1); + cv[81].destination = &(s->ssl_use_tlsv1_1); + cv[82].destination = &(s->ssl_use_tlsv1_2); srv->config_storage[i] = s; @@ -536,6 +546,9 @@ int config_setup_connection(server *srv, connection *con) { PATCH(ssl_empty_fragments); PATCH(ssl_use_sslv2); PATCH(ssl_use_sslv3); + PATCH(ssl_use_tlsv1); + PATCH(ssl_use_tlsv1_1); + PATCH(ssl_use_tlsv1_2); PATCH(etag_use_inode); PATCH(etag_use_mtime); PATCH(etag_use_size); @@ -615,6 +628,12 @@ int config_patch_connection(server *srv, connection *con) { PATCH(ssl_use_sslv2); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-sslv3"))) { PATCH(ssl_use_sslv3); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-tlsv1"))) { + PATCH(ssl_use_tlsv1); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-tlsv1_1"))) { + PATCH(ssl_use_tlsv1_1); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-tlsv1_2"))) { + PATCH(ssl_use_tlsv1_2); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.cipher-list"))) { PATCH(ssl_cipher_list); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.engine"))) { diff --git a/src/network.c b/src/network.c index 4295fe9..a3f9ec3 100644 --- a/src/network.c +++ b/src/network.c @@ -859,6 +859,33 @@ int network_init(server *srv) { } } + if (!s->ssl_use_tlsv1) { + /* disable TLSv1 */ + if (!(SSL_OP_NO_TLSv1 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_TLSv1))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + } + + if (!s->ssl_use_tlsv1_1) { + /* disable TLSv1.1 */ + if (!(SSL_OP_NO_TLSv1_1 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_TLSv1_1))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + } + + if (!s->ssl_use_tlsv1_2) { + /* disable TLSv1.2 */ + if (!(SSL_OP_NO_TLSv1_2 & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_TLSv1_2))) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + } + if (!buffer_string_is_empty(s->ssl_cipher_list)) { /* Disable support for low encryption ciphers */ if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {