diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h index e50485306..8246b3563 100644 --- a/include/proto/ssl_sock.h +++ b/include/proto/ssl_sock.h @@ -33,6 +33,7 @@ int ssl_sock_handshake(struct connection *conn, unsigned int flag); int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *proxy); void ssl_sock_free_certs(struct bind_conf *bind_conf); int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px); +int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *px); void ssl_sock_free_all_ctx(struct bind_conf *bind_conf); #endif /* _PROTO_SSL_SOCK_H */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 6e96898fd..3c77eede9 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -6258,82 +6258,10 @@ out_uri_auth_compat: } #ifdef USE_OPENSSL -#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */ -#define SSL_OP_NO_COMPRESSION 0 -#endif -#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */ -#define SSL_MODE_RELEASE_BUFFERS 0 -#endif -#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */ -#define SSL_OP_NO_COMPRESSION 0 -#endif -#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */ -#define SSL_OP_NO_TLSv1_1 0 -#endif -#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */ -#define SSL_OP_NO_TLSv1_2 0 -#endif - if (newsrv->use_ssl || newsrv->check.use_ssl) { - int ssloptions = - SSL_OP_ALL | /* all known workarounds for bugs */ - SSL_OP_NO_SSLv2 | - SSL_OP_NO_COMPRESSION; - int sslmode = - SSL_MODE_ENABLE_PARTIAL_WRITE | - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | - SSL_MODE_RELEASE_BUFFERS; - - /* Initiate SSL context for current server */ - newsrv->ssl_ctx.reused_sess = NULL; - if (newsrv->use_ssl) - newsrv->xprt = &ssl_sock; - if (newsrv->check.use_ssl) - newsrv->check.xprt = &ssl_sock; - newsrv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method()); - if(!newsrv->ssl_ctx.ctx) { - - Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n", - proxy_type_str(curproxy), curproxy->id, - newsrv->id); - cfgerr++; - goto next_srv; - } - - if (newsrv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3) - ssloptions |= SSL_OP_NO_SSLv3; - if (newsrv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10) - ssloptions |= SSL_OP_NO_TLSv1; - if (newsrv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11) - ssloptions |= SSL_OP_NO_TLSv1_1; - if (newsrv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12) - ssloptions |= SSL_OP_NO_TLSv1_2; - if (newsrv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) - SSL_CTX_set_ssl_version(newsrv->ssl_ctx.ctx, SSLv3_client_method()); - if (newsrv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10) - SSL_CTX_set_ssl_version(newsrv->ssl_ctx.ctx, TLSv1_client_method()); -#if SSL_OP_NO_TLSv1_1 - if (newsrv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11) - SSL_CTX_set_ssl_version(newsrv->ssl_ctx.ctx, TLSv1_1_client_method()); -#endif -#if SSL_OP_NO_TLSv1_2 - if (newsrv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12) - SSL_CTX_set_ssl_version(newsrv->ssl_ctx.ctx, TLSv1_2_client_method()); -#endif - - SSL_CTX_set_options(newsrv->ssl_ctx.ctx, ssloptions); - SSL_CTX_set_mode(newsrv->ssl_ctx.ctx, sslmode); - SSL_CTX_set_verify(newsrv->ssl_ctx.ctx, SSL_VERIFY_NONE, NULL); - SSL_CTX_set_session_cache_mode(newsrv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF); - if (newsrv->ssl_ctx.ciphers && - !SSL_CTX_set_cipher_list(newsrv->ssl_ctx.ctx, newsrv->ssl_ctx.ciphers)) { - Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n", - curproxy->id, newsrv->id, - newsrv->conf.file, newsrv->conf.line, newsrv->ssl_ctx.ciphers); - cfgerr++; - goto next_srv; - } - } + if (newsrv->use_ssl || newsrv->check.use_ssl) + cfgerr += ssl_sock_prepare_srv_ctx(newsrv, curproxy); #endif /* USE_OPENSSL */ + if (newsrv->trackit) { struct proxy *px; struct server *srv; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 994b6f711..72eb88399 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -572,6 +573,72 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy return cfgerr; } +/* prepare ssl context from servers options. Returns an error count */ +int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy) +{ + int cfgerr = 0; + int options = + SSL_OP_ALL | /* all known workarounds for bugs */ + SSL_OP_NO_SSLv2 | + SSL_OP_NO_COMPRESSION; + int mode = + SSL_MODE_ENABLE_PARTIAL_WRITE | + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | + SSL_MODE_RELEASE_BUFFERS; + + /* Initiate SSL context for current server */ + srv->ssl_ctx.reused_sess = NULL; + if (srv->use_ssl) + srv->xprt = &ssl_sock; + if (srv->check.use_ssl) + srv->check.xprt = &ssl_sock; + + srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method()); + if (!srv->ssl_ctx.ctx) { + Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n", + proxy_type_str(curproxy), curproxy->id, + srv->id); + cfgerr++; + return cfgerr; + } + + + if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3) + options |= SSL_OP_NO_SSLv3; + if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10) + options |= SSL_OP_NO_TLSv1; + if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11) + options |= SSL_OP_NO_TLSv1_1; + if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12) + options |= SSL_OP_NO_TLSv1_2; + if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) + SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method()); + if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10) + SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method()); +#if SSL_OP_NO_TLSv1_1 + if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11) + SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method()); +#endif +#if SSL_OP_NO_TLSv1_2 + if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12) + SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method()); +#endif + + SSL_CTX_set_options(srv->ssl_ctx.ctx, options); + SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode); + SSL_CTX_set_verify(srv->ssl_ctx.ctx, SSL_VERIFY_NONE, NULL); + SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF); + if (srv->ssl_ctx.ciphers && + !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) { + Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n", + curproxy->id, srv->id, + srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers); + cfgerr++; + } + + return cfgerr; +} + /* Walks down the two trees in bind_conf and prepares all certs. The pointer may * be NULL, in which case nothing is done. Returns the number of errors * encountered.