MEDIUM: ssl: ssl_methods implementation is reworked and factored for min/max tlsxx

Plan is to add min-tlsxx max-tlsxx configuration, more consistent than no-tlsxx.
This patch introduce internal min/max and replace force-tlsxx implementation.
SSL method configuration is store in 'struct tls_version_filter'.
SSL method configuration to openssl setting is abstract in 'methodVersions' table.
With openssl < 1.1.0, SSL_CTX_set_ssl_version is used for force (min == max).
With openssl >= 1.1.0, SSL_CTX_set_min/max_proto_version is used.
This commit is contained in:
Emmanuel Hocdet 2017-03-30 19:19:37 +02:00 committed by Willy Tarreau
parent 6cb2d1e963
commit 5db33cbdc4
4 changed files with 240 additions and 362 deletions

View File

@ -27,6 +27,7 @@
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <types/ssl_sock.h>
#endif #endif
#include <common/config.h> #include <common/config.h>
@ -101,18 +102,7 @@ enum li_state {
*/ */
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
/* bind_conf ssl options */
#define BC_SSL_O_NONE 0x0000 #define BC_SSL_O_NONE 0x0000
#define BC_SSL_O_NO_SSLV3 0x0001 /* disable SSLv3 */
#define BC_SSL_O_NO_TLSV10 0x0002 /* disable TLSv10 */
#define BC_SSL_O_NO_TLSV11 0x0004 /* disable TLSv11 */
#define BC_SSL_O_NO_TLSV12 0x0008 /* disable TLSv12 */
/* 0x000F reserved for 'no' protocol version options */
#define BC_SSL_O_USE_SSLV3 0x0010 /* force SSLv3 */
#define BC_SSL_O_USE_TLSV10 0x0020 /* force TLSv10 */
#define BC_SSL_O_USE_TLSV11 0x0040 /* force TLSv11 */
#define BC_SSL_O_USE_TLSV12 0x0080 /* force TLSv12 */
/* 0x00F0 reserved for 'force' protocol version options */
#define BC_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets */ #define BC_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets */
#define BC_SSL_O_PREF_CLIE_CIPH 0x0200 /* prefer client ciphers */ #define BC_SSL_O_PREF_CLIE_CIPH 0x0200 /* prefer client ciphers */
#endif #endif
@ -148,6 +138,7 @@ struct bind_conf {
struct ssl_bind_conf *default_ssl_conf; /* custom SSL conf of default_ctx */ struct ssl_bind_conf *default_ssl_conf; /* custom SSL conf of default_ctx */
int strict_sni; /* refuse negotiation if sni doesn't match a certificate */ int strict_sni; /* refuse negotiation if sni doesn't match a certificate */
int ssl_options; /* ssl options */ int ssl_options; /* ssl options */
struct tls_version_filter ssl_methods; /* ssl methods */
struct eb_root sni_ctx; /* sni_ctx tree of all known certs full-names sorted by name */ struct eb_root sni_ctx; /* sni_ctx tree of all known certs full-names sorted by name */
struct eb_root sni_w_ctx; /* sni_ctx tree of all known certs wildcards sorted by name */ struct eb_root sni_w_ctx; /* sni_ctx tree of all known certs wildcards sorted by name */
struct tls_keys_ref *keys_ref; /* TLS ticket keys reference */ struct tls_keys_ref *keys_ref; /* TLS ticket keys reference */

View File

@ -27,6 +27,7 @@
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <types/ssl_sock.h>
#endif #endif
#include <common/config.h> #include <common/config.h>
@ -161,18 +162,6 @@ enum srv_initaddr {
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
/* server ssl options */ /* server ssl options */
#define SRV_SSL_O_NONE 0x0000 #define SRV_SSL_O_NONE 0x0000
#define SRV_SSL_O_NO_VMASK 0x000F /* force version mask */
#define SRV_SSL_O_NO_SSLV3 0x0001 /* disable SSLv3 */
#define SRV_SSL_O_NO_TLSV10 0x0002 /* disable TLSv1.0 */
#define SRV_SSL_O_NO_TLSV11 0x0004 /* disable TLSv1.1 */
#define SRV_SSL_O_NO_TLSV12 0x0008 /* disable TLSv1.2 */
/* 0x000F reserved for 'no' protocol version options */
#define SRV_SSL_O_USE_VMASK 0x00F0 /* force version mask */
#define SRV_SSL_O_USE_SSLV3 0x0010 /* force SSLv3 */
#define SRV_SSL_O_USE_TLSV10 0x0020 /* force TLSv1.0 */
#define SRV_SSL_O_USE_TLSV11 0x0040 /* force TLSv1.1 */
#define SRV_SSL_O_USE_TLSV12 0x0080 /* force TLSv1.2 */
/* 0x00F0 reserved for 'force' protocol version options */
#define SRV_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets */ #define SRV_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets */
#define SRV_SSL_O_NO_REUSE 0x200 /* disable session reuse */ #define SRV_SSL_O_NO_REUSE 0x200 /* disable session reuse */
#endif #endif
@ -281,6 +270,7 @@ struct server {
SSL_SESSION *reused_sess; SSL_SESSION *reused_sess;
char *ciphers; /* cipher suite to use if non-null */ char *ciphers; /* cipher suite to use if non-null */
int options; /* ssl options */ int options; /* ssl options */
struct tls_version_filter methods; /* ssl methods */
int verify; /* verify method (set of SSL_VERIFY_* flags) */ int verify; /* verify method (set of SSL_VERIFY_* flags) */
char *verify_host; /* hostname of certificate must match this host */ char *verify_host; /* hostname of certificate must match this host */
char *ca_file; /* CAfile to use on verify */ char *ca_file; /* CAfile to use on verify */

View File

@ -22,7 +22,6 @@
#ifndef _TYPES_SSL_SOCK_H #ifndef _TYPES_SSL_SOCK_H
#define _TYPES_SSL_SOCK_H #define _TYPES_SSL_SOCK_H
#include <types/listener.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <ebmbtree.h> #include <ebmbtree.h>
@ -35,6 +34,12 @@ struct sni_ctx {
struct ebmb_node name; /* node holding the servername value */ struct ebmb_node name; /* node holding the servername value */
}; };
struct tls_version_filter {
uint16_t flags; /* ssl options */
uint8_t min; /* min TLS version */
uint8_t max; /* max TLS version */
};
extern struct list tlskeys_reference; extern struct list tlskeys_reference;
struct tls_sess_key { struct tls_sess_key {

View File

@ -120,6 +120,24 @@
#define HASH_FUNCT EVP_sha256 #define HASH_FUNCT EVP_sha256
#endif /* OPENSSL_NO_SHA256 */ #endif /* OPENSSL_NO_SHA256 */
/* ssl_methods flags for ssl options */
#define MC_SSL_O_ALL 0x0000
#define MC_SSL_O_NO_SSLV3 0x0001 /* disable SSLv3 */
#define MC_SSL_O_NO_TLSV10 0x0002 /* disable TLSv10 */
#define MC_SSL_O_NO_TLSV11 0x0004 /* disable TLSv11 */
#define MC_SSL_O_NO_TLSV12 0x0008 /* disable TLSv12 */
/* ssl_methods versions */
enum {
CONF_TLSV_NONE = 0,
CONF_TLSV_MIN = 1,
CONF_SSLV3 = 1,
CONF_TLSV10 = 2,
CONF_TLSV11 = 3,
CONF_TLSV12 = 4,
CONF_TLSV_MAX = 4,
};
/* server and bind verify method, it uses a global value as default */ /* server and bind verify method, it uses a global value as default */
enum { enum {
SSL_SOCK_VERIFY_DEFAULT = 0, SSL_SOCK_VERIFY_DEFAULT = 0,
@ -140,6 +158,8 @@ static struct {
char *connect_default_ciphers; char *connect_default_ciphers;
int listen_default_ssloptions; int listen_default_ssloptions;
int connect_default_ssloptions; int connect_default_ssloptions;
struct tls_version_filter listen_default_sslmethods;
struct tls_version_filter connect_default_sslmethods;
int private_cache; /* Force to use a private session cache even if nbproc > 1 */ int private_cache; /* Force to use a private session cache even if nbproc > 1 */
unsigned int life_time; /* SSL session lifetime in seconds */ unsigned int life_time; /* SSL session lifetime in seconds */
@ -157,6 +177,13 @@ static struct {
.listen_default_ssloptions = BC_SSL_O_NONE, .listen_default_ssloptions = BC_SSL_O_NONE,
.connect_default_ssloptions = SRV_SSL_O_NONE, .connect_default_ssloptions = SRV_SSL_O_NONE,
.listen_default_sslmethods.flags = MC_SSL_O_ALL,
.listen_default_sslmethods.min = CONF_TLSV_NONE,
.listen_default_sslmethods.max = CONF_TLSV_NONE,
.connect_default_sslmethods.flags = MC_SSL_O_ALL,
.connect_default_sslmethods.min = CONF_TLSV_NONE,
.connect_default_sslmethods.max = CONF_TLSV_NONE,
#ifdef DEFAULT_SSL_MAX_RECORD #ifdef DEFAULT_SSL_MAX_RECORD
.max_record = DEFAULT_SSL_MAX_RECORD, .max_record = DEFAULT_SSL_MAX_RECORD,
#endif #endif
@ -3167,13 +3194,70 @@ int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct
#define SSL_MODE_SMALL_BUFFERS 0 #define SSL_MODE_SMALL_BUFFERS 0
#endif #endif
#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
static void ssl_set_SSLv3_func(SSL_CTX *ctx, int is_server)
{
#if SSL_OP_NO_SSLv3
is_server ? SSL_CTX_set_ssl_version(ctx, SSLv3_server_method())
: SSL_CTX_set_ssl_version(ctx, SSLv3_client_method());
#endif
}
static void ssl_set_TLSv10_func(SSL_CTX *ctx, int is_server) {
is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_server_method())
: SSL_CTX_set_ssl_version(ctx, TLSv1_client_method());
}
static void ssl_set_TLSv11_func(SSL_CTX *ctx, int is_server) {
#if SSL_OP_NO_TLSv1_1
is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method())
: SSL_CTX_set_ssl_version(ctx, TLSv1_1_client_method());
#endif
}
static void ssl_set_TLSv12_func(SSL_CTX *ctx, int is_server) {
#if SSL_OP_NO_TLSv1_2
is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method())
: SSL_CTX_set_ssl_version(ctx, TLSv1_2_client_method());
#endif
}
#else /* openssl >= 1.1.0 */
static void ssl_set_SSLv3_func(SSL_CTX *ctx, int is_max) {
is_max ? SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION)
: SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
}
static void ssl_set_TLSv10_func(SSL_CTX *ctx, int is_max) {
is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION)
: SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
}
static void ssl_set_TLSv11_func(SSL_CTX *ctx, int is_max) {
is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION)
: SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
}
static void ssl_set_TLSv12_func(SSL_CTX *ctx, int is_max) {
is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)
: SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
}
#endif
static void ssl_set_None_func(SSL_CTX *ctx, int i) {
}
static struct {
int option;
uint16_t flag;
void (*set_version)(SSL_CTX *, int);
const char *name;
} methodVersions[] = {
{0, 0, ssl_set_None_func, "NONE"}, /* CONF_TLSV_NONE */
{SSL_OP_NO_SSLv3, MC_SSL_O_NO_SSLV3, ssl_set_SSLv3_func, "SSLv3"}, /* CONF_SSLV3 */
{SSL_OP_NO_TLSv1, MC_SSL_O_NO_TLSV10, ssl_set_TLSv10_func, "TLSv1.0"}, /* CONF_TLSV10 */
{SSL_OP_NO_TLSv1_1, MC_SSL_O_NO_TLSV11, ssl_set_TLSv11_func, "TLSv1.1"}, /* CONF_TLSV11 */
{SSL_OP_NO_TLSv1_2, MC_SSL_O_NO_TLSV12, ssl_set_TLSv12_func, "TLSv1.2"}, /* CONF_TLSV12 */
};
/* Create an initial CTX used to start the SSL connection before switchctx */ /* Create an initial CTX used to start the SSL connection before switchctx */
static SSL_CTX * static SSL_CTX *
ssl_sock_initial_ctx(struct bind_conf *bind_conf) ssl_sock_initial_ctx(struct bind_conf *bind_conf)
{ {
SSL_CTX *ctx = NULL; SSL_CTX *ctx = NULL;
long ssloptions = long options =
SSL_OP_ALL | /* all known workarounds for bugs */ SSL_OP_ALL | /* all known workarounds for bugs */
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv2 |
SSL_OP_NO_COMPRESSION | SSL_OP_NO_COMPRESSION |
@ -3181,67 +3265,43 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
SSL_OP_SINGLE_ECDH_USE | SSL_OP_SINGLE_ECDH_USE |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_OP_CIPHER_SERVER_PREFERENCE;
long sslmode = long mode =
SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ENABLE_PARTIAL_WRITE |
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
SSL_MODE_RELEASE_BUFFERS | SSL_MODE_RELEASE_BUFFERS |
SSL_MODE_SMALL_BUFFERS; SSL_MODE_SMALL_BUFFERS;
int conf_ssl_options = bind_conf->ssl_options; struct tls_version_filter *conf_ssl_methods = &bind_conf->ssl_methods;
int i, min, max;
#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL || defined OPENSSL_IS_BORINGSSL) ctx = SSL_CTX_new(SSLv23_server_method());
if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV12) {
ctx = SSL_CTX_new(TLS_server_method()); /* set options per default */
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); /* XXX need check hole */
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
} if (conf_ssl_methods->flags & methodVersions[i].flag)
if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV11) { options |= methodVersions[i].option;
ctx = SSL_CTX_new(TLS_server_method());
SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION); /* XXX min and max can be CONF_TLSV_NONE or unavailable in openssl.
SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION); Real min and max should be determinate with conf + openssl's capabilities
} */
if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV10) { min = conf_ssl_methods->min;
ctx = SSL_CTX_new(TLS_server_method()); max = conf_ssl_methods->max;
SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); #if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION); /* Keep force-xxx implementation as it is in older haproxy. It's a
} precautionary measure to avoid any suprise with older openssl version. */
if (!ctx && conf_ssl_options & BC_SSL_O_USE_SSLV3) { if (min == max)
ctx = SSL_CTX_new(TLS_server_method()); methodVersions[min].set_version(ctx, 1 /* server */);
SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION); #else /* openssl >= 1.1.0 */
SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION); methodVersions[min].set_version(ctx, 0);
} methodVersions[max].set_version(ctx, 1);
#else
#if SSL_OP_NO_TLSv1_2
if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV12)
ctx = SSL_CTX_new(TLSv1_2_server_method());
#endif #endif
#if SSL_OP_NO_TLSv1_1
if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV11) if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
ctx = SSL_CTX_new(TLSv1_1_server_method()); options |= SSL_OP_NO_TICKET;
#endif if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV10) options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
ctx = SSL_CTX_new(TLSv1_server_method()); SSL_CTX_set_options(ctx, options);
#ifndef OPENSSL_NO_SSL3 SSL_CTX_set_mode(ctx, mode);
if (!ctx && conf_ssl_options & BC_SSL_O_USE_SSLV3)
ctx = SSL_CTX_new(SSLv3_server_method());
#endif
#endif
if (!ctx) {
ctx = SSL_CTX_new(SSLv23_server_method());
if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
ssloptions |= SSL_OP_NO_SSLv3;
if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
ssloptions |= SSL_OP_NO_TLSv1;
if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
ssloptions |= SSL_OP_NO_TLSv1_1;
if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
ssloptions |= SSL_OP_NO_TLSv1_2;
}
if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
ssloptions |= SSL_OP_NO_TICKET;
if (conf_ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
ssloptions &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
SSL_CTX_set_options(ctx, ssloptions);
SSL_CTX_set_mode(ctx, sslmode);
if (global_ssl.life_time) if (global_ssl.life_time)
SSL_CTX_set_timeout(ctx, global_ssl.life_time); SSL_CTX_set_timeout(ctx, global_ssl.life_time);
@ -3596,6 +3656,8 @@ int ssl_sock_prepare_srv_ctx(struct server *srv)
SSL_MODE_SMALL_BUFFERS; SSL_MODE_SMALL_BUFFERS;
int verify = SSL_VERIFY_NONE; int verify = SSL_VERIFY_NONE;
SSL_CTX *ctx = NULL; SSL_CTX *ctx = NULL;
struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
int i, min, max;
/* Make sure openssl opens /dev/urandom before the chroot */ /* Make sure openssl opens /dev/urandom before the chroot */
if (!ssl_initialize_random()) { if (!ssl_initialize_random()) {
@ -3613,56 +3675,7 @@ int ssl_sock_prepare_srv_ctx(struct server *srv)
if (srv->check.use_ssl) if (srv->check.use_ssl)
srv->check.xprt = &ssl_sock; srv->check.xprt = &ssl_sock;
#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL || defined OPENSSL_IS_BORINGSSL) ctx = SSL_CTX_new(SSLv23_client_method());
if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12) {
ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
}
if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11) {
ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION);
}
if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10) {
ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION);
}
if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION);
}
#else
#if SSL_OP_NO_TLSv1_2
if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
ctx = SSL_CTX_new(TLSv1_2_client_method());
#endif
#if SSL_OP_NO_TLSv1_1
if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
ctx = SSL_CTX_new(TLSv1_1_client_method());
#endif
if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
ctx = SSL_CTX_new(TLSv1_client_method());
#ifndef OPENSSL_NO_SSL3
if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
ctx = SSL_CTX_new(SSLv3_client_method());
#endif
#endif
if (!ctx) {
ctx = SSL_CTX_new(SSLv23_client_method());
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_NO_TLS_TICKETS)
options |= SSL_OP_NO_TICKET;
if (!ctx) { if (!ctx) {
Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n", Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
proxy_type_str(curproxy), curproxy->id, proxy_type_str(curproxy), curproxy->id,
@ -3670,6 +3683,30 @@ int ssl_sock_prepare_srv_ctx(struct server *srv)
cfgerr++; cfgerr++;
return cfgerr; return cfgerr;
} }
/* set options per default */
/* XXX need check hole */
for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
if (conf_ssl_methods->flags & methodVersions[i].flag)
options |= methodVersions[i].option;
/* XXX min and max can be CONF_TLSV_NONE or unavailable in openssl.
Real min and max should be determinate with conf + openssl's capabilities
*/
min = conf_ssl_methods->min;
max = conf_ssl_methods->max;
#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
/* Keep force-xxx implementation as it is in older haproxy. It's a
precautionary measure to avoid any suprise with older openssl version. */
if (min == max)
methodVersions[min].set_version(ctx, 0 /* client */);
#else /* openssl >= 1.1.0 */
methodVersions[min].set_version(ctx, 0);
methodVersions[max].set_version(ctx, 1);
#endif
if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
options |= SSL_OP_NO_TICKET;
SSL_CTX_set_options(ctx, options); SSL_CTX_set_options(ctx, options);
SSL_CTX_set_mode(ctx, mode); SSL_CTX_set_mode(ctx, mode);
srv->ssl_ctx.ctx = ctx; srv->ssl_ctx.ctx = ctx;
@ -6123,50 +6160,52 @@ static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, str
return 0; return 0;
} }
/* parse the "force-sslv3" bind keyword */ /* parse tls_method_options */
static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) static int parse_tls_method_options(char *arg, struct tls_version_filter *methods)
{ {
#ifndef OPENSSL_NO_SSL3 char *p;
conf->ssl_options |= BC_SSL_O_USE_SSLV3; int v;
return 0; p = strchr(arg, '-');
#else if (!p)
if (err) return 1;
memprintf(err, "'%s' : library does not support protocol SSLv3", args[cur_arg]); p++;
return ERR_ALERT | ERR_FATAL; if (!strcmp(p, "sslv3"))
#endif v = CONF_SSLV3;
} else if (!strcmp(p, "tlsv10"))
v = CONF_TLSV10;
/* parse the "force-tlsv10" bind keyword */ else if (!strcmp(p, "tlsv11"))
static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) v = CONF_TLSV11;
{ else if (!strcmp(p, "tlsv12"))
conf->ssl_options |= BC_SSL_O_USE_TLSV10; v = CONF_TLSV12;
else
return 1;
if (!strncmp(arg, "no-", 3))
methods->flags |= methodVersions[v].flag;
else if (!strncmp(arg, "force-", 6))
methods->min = methods->max = v;
else
return 1;
return 0; return 0;
} }
/* parse the "force-tlsv11" bind keyword */ static int bind_parse_tls_method_options(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{ {
#if SSL_OP_NO_TLSv1_1 if (parse_tls_method_options(args[cur_arg], &conf->ssl_methods)) {
conf->ssl_options |= BC_SSL_O_USE_TLSV11; if (err)
memprintf(err, "'%s' : option not implemented", args[cur_arg]);
return ERR_ALERT | ERR_FATAL;
}
return 0; return 0;
#else
if (err)
memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
return ERR_ALERT | ERR_FATAL;
#endif
} }
/* parse the "force-tlsv12" bind keyword */ static int srv_parse_tls_method_options(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{ {
#if SSL_OP_NO_TLSv1_2 if (parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods)) {
conf->ssl_options |= BC_SSL_O_USE_TLSV12; if (err)
memprintf(err, "'%s' : option not implemented", args[*cur_arg]);
return ERR_ALERT | ERR_FATAL;
}
return 0; return 0;
#else
if (err)
memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
return ERR_ALERT | ERR_FATAL;
#endif
} }
/* parse the "no-tls-tickets" bind keyword */ /* parse the "no-tls-tickets" bind keyword */
@ -6176,34 +6215,6 @@ static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px,
return 0; return 0;
} }
/* parse the "no-sslv3" bind keyword */
static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
conf->ssl_options |= BC_SSL_O_NO_SSLV3;
return 0;
}
/* parse the "no-tlsv10" bind keyword */
static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
conf->ssl_options |= BC_SSL_O_NO_TLSV10;
return 0;
}
/* parse the "no-tlsv11" bind keyword */
static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
conf->ssl_options |= BC_SSL_O_NO_TLSV11;
return 0;
}
/* parse the "no-tlsv12" bind keyword */
static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
conf->ssl_options |= BC_SSL_O_NO_TLSV12;
return 0;
}
/* parse the "npn" bind keyword */ /* parse the "npn" bind keyword */
static int ssl_bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err) static int ssl_bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
{ {
@ -6325,6 +6336,11 @@ static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bin
if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers) if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers); conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
conf->ssl_options |= global_ssl.listen_default_ssloptions; conf->ssl_options |= global_ssl.listen_default_ssloptions;
conf->ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
if (!conf->ssl_methods.min)
conf->ssl_methods.min = global_ssl.listen_default_sslmethods.min;
if (!conf->ssl_methods.max)
conf->ssl_methods.max = global_ssl.listen_default_sslmethods.max;
return 0; return 0;
} }
@ -6485,6 +6501,12 @@ static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, stru
if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers) if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers); newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions; newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
if (!newsrv->ssl_ctx.methods.min)
newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
if (!newsrv->ssl_ctx.methods.max)
newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
return 0; return 0;
} }
@ -6541,52 +6563,6 @@ static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct ser
return 0; return 0;
} }
/* parse the "force-sslv3" server keyword */
static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
#ifndef OPENSSL_NO_SSL3
newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
return 0;
#else
if (err)
memprintf(err, "'%s' : library does not support protocol SSLv3", args[*cur_arg]);
return ERR_ALERT | ERR_FATAL;
#endif
}
/* parse the "force-tlsv10" server keyword */
static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
return 0;
}
/* parse the "force-tlsv11" server keyword */
static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
#if SSL_OP_NO_TLSv1_1
newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
return 0;
#else
if (err)
memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
return ERR_ALERT | ERR_FATAL;
#endif
}
/* parse the "force-tlsv12" server keyword */
static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
#if SSL_OP_NO_TLSv1_2
newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
return 0;
#else
if (err)
memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
return ERR_ALERT | ERR_FATAL;
#endif
}
/* parse the "no-check-ssl" server keyword */ /* parse the "no-check-ssl" server keyword */
static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err) static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{ {
@ -6630,34 +6606,6 @@ static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, s
return 0; return 0;
} }
/* parse the "no-sslv3" server keyword */
static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
return 0;
}
/* parse the "no-tlsv10" server keyword */
static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
return 0;
}
/* parse the "no-tlsv11" server keyword */
static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
return 0;
}
/* parse the "no-tlsv12" server keyword */
static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
return 0;
}
/* parse the "no-tls-tickets" server keyword */ /* parse the "no-tls-tickets" server keyword */
static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err) static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{ {
@ -6775,39 +6723,11 @@ static int ssl_parse_default_bind_options(char **args, int section_type, struct
return -1; return -1;
} }
while (*(args[i])) { while (*(args[i])) {
if (!strcmp(args[i], "no-sslv3")) if (!strcmp(args[i], "no-tls-tickets"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
else if (!strcmp(args[i], "no-tlsv10"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
else if (!strcmp(args[i], "no-tlsv11"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
else if (!strcmp(args[i], "no-tlsv12"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
else if (!strcmp(args[i], "force-sslv3"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
else if (!strcmp(args[i], "force-tlsv10"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
else if (!strcmp(args[i], "force-tlsv11")) {
#if SSL_OP_NO_TLSv1_1
global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
#else
memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
return -1;
#endif
}
else if (!strcmp(args[i], "force-tlsv12")) {
#if SSL_OP_NO_TLSv1_2
global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
#else
memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
return -1;
#endif
}
else if (!strcmp(args[i], "no-tls-tickets"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS; global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
else if (!strcmp(args[i], "prefer-client-ciphers")) else if (!strcmp(args[i], "prefer-client-ciphers"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH; global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
else { else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods)) {
memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]); memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
return -1; return -1;
} }
@ -6827,37 +6747,9 @@ static int ssl_parse_default_server_options(char **args, int section_type, struc
return -1; return -1;
} }
while (*(args[i])) { while (*(args[i])) {
if (!strcmp(args[i], "no-sslv3")) if (!strcmp(args[i], "no-tls-tickets"))
global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
else if (!strcmp(args[i], "no-tlsv10"))
global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
else if (!strcmp(args[i], "no-tlsv11"))
global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
else if (!strcmp(args[i], "no-tlsv12"))
global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
else if (!strcmp(args[i], "force-sslv3"))
global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
else if (!strcmp(args[i], "force-tlsv10"))
global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
else if (!strcmp(args[i], "force-tlsv11")) {
#if SSL_OP_NO_TLSv1_1
global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
#else
memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
return -1;
#endif
}
else if (!strcmp(args[i], "force-tlsv12")) {
#if SSL_OP_NO_TLSv1_2
global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
#else
memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
return -1;
#endif
}
else if (!strcmp(args[i], "no-tls-tickets"))
global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS; global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
else { else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods)) {
memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]); memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
return -1; return -1;
} }
@ -7415,34 +7307,34 @@ static struct ssl_bind_kw ssl_bind_kws[] = {
}; };
static struct bind_kw_list bind_kws = { "SSL", { }, { static struct bind_kw_list bind_kws = { "SSL", { }, {
{ "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */ { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
{ "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */ { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
{ "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */ { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
{ "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */ { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
{ "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */ { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
{ "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */ { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
{ "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */ { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
{ "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */ { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
{ "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */ { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
{ "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */ { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
{ "curves", bind_parse_curves, 1 }, /* set SSL curve suite */ { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
{ "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */ { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
{ "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */ { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
{ "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */ { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
{ "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */ { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
{ "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */ { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
{ "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */ { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
{ "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */ { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
{ "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */ { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
{ "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */ { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
{ "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */ { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
{ "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */ { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
{ "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */ { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
{ "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */ { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
{ "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */ { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
{ "verify", bind_parse_verify, 1 }, /* set SSL verify method */ { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
{ "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */ { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
{ "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */ { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
{ NULL, NULL, 0 }, { NULL, NULL, 0 },
}}; }};
@ -7459,19 +7351,19 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
{ "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */ { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
{ "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */ { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
{ "crt", srv_parse_crt, 1, 1 }, /* set client certificate */ { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
{ "force-sslv3", srv_parse_force_sslv3, 0, 1 }, /* force SSLv3 */ { "force-sslv3", srv_parse_tls_method_options,0, 1 }, /* force SSLv3 */
{ "force-tlsv10", srv_parse_force_tlsv10, 0, 1 }, /* force TLSv10 */ { "force-tlsv10", srv_parse_tls_method_options,0, 1 }, /* force TLSv10 */
{ "force-tlsv11", srv_parse_force_tlsv11, 0, 1 }, /* force TLSv11 */ { "force-tlsv11", srv_parse_tls_method_options,0, 1 }, /* force TLSv11 */
{ "force-tlsv12", srv_parse_force_tlsv12, 0, 1 }, /* force TLSv12 */ { "force-tlsv12", srv_parse_tls_method_options,0, 1 }, /* force TLSv12 */
{ "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */ { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
{ "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */ { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
{ "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */ { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
{ "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */ { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
{ "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */ { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
{ "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */ { "no-sslv3", srv_parse_tls_method_options,0, 0 }, /* disable SSLv3 */
{ "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */ { "no-tlsv10", srv_parse_tls_method_options,0, 0 }, /* disable TLSv10 */
{ "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */ { "no-tlsv11", srv_parse_tls_method_options,0, 0 }, /* disable TLSv11 */
{ "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */ { "no-tlsv12", srv_parse_tls_method_options,0, 0 }, /* disable TLSv12 */
{ "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */ { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */ { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
{ "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */ { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */