diff --git a/src/cfgparse.c b/src/cfgparse.c index 1f7c479df..6e96898fd 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -4111,64 +4111,6 @@ stats_error_parsing: newsrv->fastinter = val; cur_arg += 2; } - else if (!strcmp(args[cur_arg], "force-sslv3")) { -#ifdef USE_OPENSSL - newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3; - cur_arg += 1; -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } - else if (!strcmp(args[cur_arg], "force-tlsv10")) { -#ifdef USE_OPENSSL - newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10; - cur_arg += 1; -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } - else if (!strcmp(args[cur_arg], "force-tlsv11")) { -#ifdef USE_OPENSSL -#if SSL_OP_NO_TLSv1_1 - newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11; - cur_arg += 1; -#else - Alert("parsing [%s:%d]: '%s' library does not support protocol TLSv1.1.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } - else if (!strcmp(args[cur_arg], "force-tlsv12")) { -#ifdef USE_OPENSSL -#if SSL_OP_NO_TLSv1_2 - newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12; - cur_arg += 1; -#else - Alert("parsing [%s:%d]: '%s' library does not support protocol TLSv1.2.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } else if (!strcmp(args[cur_arg], "downinter")) { const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_MS); if (err) { @@ -4282,99 +4224,6 @@ stats_error_parsing: newsrv->health = 0; cur_arg += 1; } - else if (!strcmp(args[cur_arg], "ssl")) { -#ifdef USE_OPENSSL - newsrv->use_ssl = 1; - cur_arg += 1; - - if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers) - newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers); -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } - else if (!strcmp(args[cur_arg], "check-ssl")) { -#ifdef USE_OPENSSL - newsrv->check.use_ssl = 1; - cur_arg += 1; - - if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers) - newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers); -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } - else if (!strcmp(args[cur_arg], "ciphers")) { /* use this SSL cipher suite */ -#ifdef USE_OPENSSL - if (!*args[cur_arg + 1]) { - Alert("parsing [%s:%d] : '%s' : '%s' : missing cipher suite.\n", - file, linenum, args[0], args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - - free(newsrv->ssl_ctx.ciphers); - newsrv->ssl_ctx.ciphers = strdup(args[cur_arg + 1]); - - cur_arg += 2; - continue; -#else - Alert("parsing [%s:%d] : '%s' : '%s' option not implemented.\n", - file, linenum, args[0], args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif - } - else if (!strcmp(args[cur_arg], "no-sslv3")) { -#ifdef USE_OPENSSL - newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3; - cur_arg += 1; -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } - else if (!strcmp(args[cur_arg], "no-tlsv10")) { -#ifdef USE_OPENSSL - newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10; - cur_arg += 1; -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } - else if (!strcmp(args[cur_arg], "no-tlsv11")) { -#ifdef USE_OPENSSL - newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11; - cur_arg += 1; -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } - else if (!strcmp(args[cur_arg], "no-tlsv12")) { -#ifdef USE_OPENSSL - newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12; - cur_arg += 1; -#else /* USE_OPENSSL */ - Alert("parsing [%s:%d]: '%s' option not implemented.\n", - file, linenum, args[cur_arg]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; -#endif /* USE_OPENSSL */ - } else if (!defsrv && !strcmp(args[cur_arg], "observe")) { if (!strcmp(args[cur_arg + 1], "none")) newsrv->observe = HANA_OBS_NONE; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 055bc6fe5..994b6f711 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -1376,6 +1377,107 @@ static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct return 0; } +/************** "server" keywords ****************/ + +/* parse the "check-ssl" server keyword */ +static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err) +{ + newsrv->check.use_ssl = 1; + if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers) + newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers); + return 0; +} + +/* parse the "ciphers" server keyword */ +static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err) +{ + if (!*args[*cur_arg + 1]) { + memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]); + return ERR_ALERT | ERR_FATAL; + } + + free(newsrv->ssl_ctx.ciphers); + newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]); + 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) +{ + newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3; + return 0; +} + +/* 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-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 "ssl" server keyword */ +static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err) +{ + newsrv->use_ssl = 1; + if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers) + newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers); + return 0; +} + /* Note: must not be declared as its list will be overwritten. * Please take care of keeping this list alphabetically sorted. */ @@ -1437,6 +1539,28 @@ static struct bind_kw_list bind_kws = { "SSL", { }, { { NULL, NULL, 0 }, }}; +/* Note: must not be declared as its list will be overwritten. + * Please take care of keeping this list alphabetically sorted, doing so helps + * all code contributors. + * Optional keywords are also declared with a NULL ->parse() function so that + * the config parser can report an appropriate error when a known keyword was + * not enabled. + */ +static struct srv_kw_list srv_kws = { "SSL", { }, { + { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */ + { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */ + { "force-sslv3", srv_parse_force_sslv3, 0, 1 }, /* force SSLv3 */ + { "force-tlsv10", srv_parse_force_tlsv10, 0, 1 }, /* force TLSv10 */ + { "force-tlsv11", srv_parse_force_tlsv11, 0, 1 }, /* force TLSv11 */ + { "force-tlsv12", srv_parse_force_tlsv12, 0, 1 }, /* force TLSv12 */ + { "no-sslv3", srv_parse_no_sslv3, 0, 1 }, /* disable SSLv3 */ + { "no-tlsv10", srv_parse_no_tlsv10, 0, 1 }, /* disable TLSv10 */ + { "no-tlsv11", srv_parse_no_tlsv11, 0, 1 }, /* disable TLSv11 */ + { "no-tlsv12", srv_parse_no_tlsv12, 0, 1 }, /* disable TLSv12 */ + { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */ + { NULL, NULL, 0, 0 }, +}}; + /* transport-layer operations for SSL sockets */ struct xprt_ops ssl_sock = { .snd_buf = ssl_sock_from_buf, @@ -1450,7 +1574,8 @@ struct xprt_ops ssl_sock = { }; __attribute__((constructor)) -static void __ssl_sock_init(void) { +static void __ssl_sock_init(void) +{ STACK_OF(SSL_COMP)* cm; SSL_library_init(); @@ -1459,6 +1584,7 @@ static void __ssl_sock_init(void) { sample_register_fetches(&sample_fetch_keywords); acl_register_keywords(&acl_kws); bind_register_keywords(&bind_kws); + srv_register_keywords(&srv_kws); } /*