Skip to content

Commit

Permalink
Backport of ssl_protocol_version
Browse files Browse the repository at this point in the history
This is part of civetweb@0ef099d ( civetweb#227 )
  • Loading branch information
xtne6f committed Apr 16, 2016
1 parent 888adc5 commit e1536a7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
11 changes: 11 additions & 0 deletions docs/UserManual.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,17 @@ See the [Wikipedia page on HTTP status codes](http://en.wikipedia.org/wiki/HTTP_
URL encoded request strings are decoded in the server, unless it is disabled
by setting this option to `no`.

### ssl_protocol_version `0`
Sets the minimal accepted version of SSL/TLS protocol according to the table:

Protocols | Value
------------ | -------------
SSL2+SSL3+TLS1.0+TLS1.1+TLS1.2 | 0
SSL3+TLS1.0+TLS1.1+TLS1.2 | 1
TLS1.0+TLS1.1+TLS1.2 | 2
TLS1.1+TLS1.2 | 3
TLS1.2 | 4

# Lua Scripts and Lua Server Pages
Pre-built Windows and Mac civetweb binaries have built-in Lua scripting
support as well as support for Lua Server Pages.
Expand Down
41 changes: 41 additions & 0 deletions src/civetweb.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,16 @@ typedef struct ssl_st SSL;
typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_ctx_st SSL_CTX;

#define SSL_CTRL_OPTIONS (32)
#define SSL_CTRL_CLEAR_OPTIONS (77)

#define SSL_OP_ALL (0x80000BFFL)
#define SSL_OP_NO_SSLv2 (0x01000000L)
#define SSL_OP_NO_SSLv3 (0x02000000L)
#define SSL_OP_NO_TLSv1 (0x04000000L)
#define SSL_OP_NO_TLSv1_2 (0x08000000L)
#define SSL_OP_NO_TLSv1_1 (0x10000000L)

struct ssl_func {
const char *name; /* SSL function name */
void (*ptr)(void); /* Function pointer */
Expand Down Expand Up @@ -795,6 +805,12 @@ struct ssl_func {
#define SSL_pending (*(int (*)(SSL *))ssl_sw[18].ptr)
#define SSL_CTX_set_verify (*(void (*)(SSL_CTX *, int, int))ssl_sw[19].ptr)
#define SSL_shutdown (*(int (*)(SSL *))ssl_sw[20].ptr)
#define SSL_CTX_ctrl \
(*(long (*)(SSL_CTX *, int, long, void *))ssl_sw[21].ptr)
#define SSL_CTX_set_options(ctx,op) \
SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
#define SSL_CTX_clear_options(ctx,op) \
SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)

#define CRYPTO_num_locks (*(int (*)(void))crypto_sw[0].ptr)
#define CRYPTO_set_locking_callback \
Expand Down Expand Up @@ -829,6 +845,7 @@ static struct ssl_func ssl_sw[] = {{"SSL_free", NULL},
{"SSL_pending", NULL},
{"SSL_CTX_set_verify", NULL},
{"SSL_shutdown", NULL},
{"SSL_CTX_ctrl", NULL},
{NULL, NULL}};

/* Similar array as ssl_sw. These functions could be located in different
Expand Down Expand Up @@ -923,6 +940,7 @@ enum {
REWRITE,
HIDE_FILES,
REQUEST_TIMEOUT,
SSL_PROTOCOL_VERSION,
#if defined(USE_WEBSOCKET)
WEBSOCKET_TIMEOUT,
#endif
Expand Down Expand Up @@ -978,6 +996,7 @@ static struct mg_option config_options[] = {
{"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL},
{"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL},
{"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
{"ssl_protocol_version", CONFIG_TYPE_NUMBER, "0"},
#if defined(USE_WEBSOCKET)
{"websocket_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
#endif
Expand Down Expand Up @@ -8985,11 +9004,27 @@ static int initialize_ssl(struct mg_context *ctx)
return 1;
}

static long
ssl_get_protocol(int version_id)
{
long ret = SSL_OP_ALL;
if (version_id > 0)
ret |= SSL_OP_NO_SSLv2;
if (version_id > 1)
ret |= SSL_OP_NO_SSLv3;
if (version_id > 2)
ret |= SSL_OP_NO_TLSv1;
if(version_id > 3)
ret |= SSL_OP_NO_TLSv1_1;
return ret;
}

/* Dynamically load SSL library. Set up ctx->ssl_ctx pointer. */
static int set_ssl_option(struct mg_context *ctx)
{
const char *pem;
int callback_ret;
int protocol_ver;

/* If PEM file is not specified and the init_ssl callback
* is not specified, skip SSL initialization. */
Expand Down Expand Up @@ -9023,6 +9058,12 @@ static int set_ssl_option(struct mg_context *ctx)
return 0;
}

SSL_CTX_clear_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 |
SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 |
SSL_OP_NO_TLSv1_1);
protocol_ver = atoi(ctx->config[SSL_PROTOCOL_VERSION]);
SSL_CTX_set_options(ctx->ssl_ctx, ssl_get_protocol(protocol_ver));

/* If a callback has been specified, call it. */
callback_ret =
(ctx->callbacks.init_ssl == NULL)
Expand Down

0 comments on commit e1536a7

Please sign in to comment.