mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MINOR: server: Make 'default-server' support 'sni' keyword.
This patch makes 'default-server' directives support 'sni' settings. A field 'sni_expr' has been added to 'struct server' to temporary stores SNI expressions as strings during both 'default-server' and 'server' lines parsing. So, to duplicate SNI expressions from 'default-server' 'sni' setting for new 'server' instances we only have to "strdup" these strings as this is often done for most of the 'server' settings. Then, sample expressions are computed calling sample_parse_expr() (only for 'server' instances). A new function has been added to produce the same error output as before in case of any error during 'sni' settings parsing (display_parser_err()). Should not break anything.
This commit is contained in:
parent
dba9707713
commit
9a146de934
@ -254,6 +254,7 @@ struct server {
|
|||||||
|
|
||||||
int use_ssl; /* ssl enabled */
|
int use_ssl; /* ssl enabled */
|
||||||
#ifdef USE_OPENSSL
|
#ifdef USE_OPENSSL
|
||||||
|
char *sni_expr; /* Temporary variable to store a sample expression for SNI */
|
||||||
struct {
|
struct {
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
SSL_SESSION *reused_sess;
|
SSL_SESSION *reused_sess;
|
||||||
|
75
src/server.c
75
src/server.c
@ -36,6 +36,7 @@
|
|||||||
#include <proto/port_range.h>
|
#include <proto/port_range.h>
|
||||||
#include <proto/protocol.h>
|
#include <proto/protocol.h>
|
||||||
#include <proto/queue.h>
|
#include <proto/queue.h>
|
||||||
|
#include <proto/sample.h>
|
||||||
#include <proto/server.h>
|
#include <proto/server.h>
|
||||||
#include <proto/stream.h>
|
#include <proto/stream.h>
|
||||||
#include <proto/stream_interface.h>
|
#include <proto/stream_interface.h>
|
||||||
@ -1438,6 +1439,53 @@ const char *server_parse_maxconn_change_request(struct server *sv,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
|
static int server_parse_sni_expr(struct server *newsrv, struct proxy *px, char **err)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
struct sample_expr *expr;
|
||||||
|
const char *args[] = {
|
||||||
|
newsrv->sni_expr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
proxy->conf.args.ctx = ARGC_SRV;
|
||||||
|
|
||||||
|
expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line,
|
||||||
|
err, &proxy->conf.args);
|
||||||
|
if (!expr) {
|
||||||
|
memprintf(err, "error detected while parsing sni expression : %s", *err);
|
||||||
|
return ERR_ALERT | ERR_FATAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
|
||||||
|
memprintf(err, "error detected while parsing sni expression : "
|
||||||
|
" fetch method '%s' extracts information from '%s', "
|
||||||
|
"none of which is available here.\n",
|
||||||
|
args[0], sample_src_names(expr->fetch->use));
|
||||||
|
return ERR_ALERT | ERR_FATAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
|
||||||
|
release_sample_expr(newsrv->ssl_ctx.sni);
|
||||||
|
newsrv->ssl_ctx.sni = expr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void display_parser_err(const char *file, int linenum, char **args, int cur_arg, char **err)
|
||||||
|
{
|
||||||
|
if (err && *err) {
|
||||||
|
indent_msg(err, 2);
|
||||||
|
Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], *err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
|
||||||
|
file, linenum, args[0], args[1], args[cur_arg]);
|
||||||
|
}
|
||||||
|
|
||||||
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy)
|
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy)
|
||||||
{
|
{
|
||||||
struct server *newsrv = NULL;
|
struct server *newsrv = NULL;
|
||||||
@ -1688,6 +1736,8 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
|
|||||||
newsrv->ssl_ctx.verify_host = strdup(curproxy->defsrv.ssl_ctx.verify_host);
|
newsrv->ssl_ctx.verify_host = strdup(curproxy->defsrv.ssl_ctx.verify_host);
|
||||||
if (curproxy->defsrv.ssl_ctx.ciphers != NULL)
|
if (curproxy->defsrv.ssl_ctx.ciphers != NULL)
|
||||||
newsrv->ssl_ctx.ciphers = strdup(curproxy->defsrv.ssl_ctx.ciphers);
|
newsrv->ssl_ctx.ciphers = strdup(curproxy->defsrv.ssl_ctx.ciphers);
|
||||||
|
if (curproxy->defsrv.sni_expr != NULL)
|
||||||
|
newsrv->sni_expr = strdup(curproxy->defsrv.sni_expr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TCP_USER_TIMEOUT
|
#ifdef TCP_USER_TIMEOUT
|
||||||
@ -2135,13 +2185,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
|
|||||||
err_code |= code;
|
err_code |= code;
|
||||||
|
|
||||||
if (code) {
|
if (code) {
|
||||||
if (err && *err) {
|
display_parser_err(file, linenum, args, cur_arg, &err);
|
||||||
indent_msg(&err, 2);
|
|
||||||
Alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], err);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Alert("parsing [%s:%d] : '%s %s' : error encountered while processing '%s'.\n",
|
|
||||||
file, linenum, args[0], args[1], args[cur_arg]);
|
|
||||||
if (code & ERR_FATAL) {
|
if (code & ERR_FATAL) {
|
||||||
free(err);
|
free(err);
|
||||||
cur_arg += 1 + kw->skip;
|
cur_arg += 1 + kw->skip;
|
||||||
@ -2270,6 +2314,23 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
|
|||||||
|
|
||||||
srv_lb_commit_status(newsrv);
|
srv_lb_commit_status(newsrv);
|
||||||
}
|
}
|
||||||
|
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||||
|
if (!defsrv && newsrv->sni_expr) {
|
||||||
|
int code;
|
||||||
|
char *err;
|
||||||
|
|
||||||
|
err = NULL;
|
||||||
|
|
||||||
|
code = server_parse_sni_expr(newsrv, curproxy, &err);
|
||||||
|
err_code |= code;
|
||||||
|
if (code) {
|
||||||
|
display_parser_err(file, linenum, args, cur_arg, &err);
|
||||||
|
free(err);
|
||||||
|
if (code & ERR_FATAL)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
free(fqdn);
|
free(fqdn);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -6679,32 +6679,17 @@ static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct ser
|
|||||||
memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
|
memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
|
||||||
return ERR_ALERT | ERR_FATAL;
|
return ERR_ALERT | ERR_FATAL;
|
||||||
#else
|
#else
|
||||||
int idx;
|
char *arg;
|
||||||
struct sample_expr *expr;
|
|
||||||
|
|
||||||
if (!*args[*cur_arg + 1]) {
|
arg = args[*cur_arg + 1];
|
||||||
|
if (!*arg) {
|
||||||
memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
|
memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
|
||||||
return ERR_ALERT | ERR_FATAL;
|
return ERR_ALERT | ERR_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = (*cur_arg) + 1;
|
free(newsrv->sni_expr);
|
||||||
proxy->conf.args.ctx = ARGC_SRV;
|
newsrv->sni_expr = strdup(arg);
|
||||||
|
|
||||||
expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
|
|
||||||
if (!expr) {
|
|
||||||
memprintf(err, "error detected while parsing sni expression : %s", *err);
|
|
||||||
return ERR_ALERT | ERR_FATAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
|
|
||||||
memprintf(err, "error detected while parsing sni expression : "
|
|
||||||
" fetch method '%s' extracts information from '%s', none of which is available here.\n",
|
|
||||||
args[idx-1], sample_src_names(expr->fetch->use));
|
|
||||||
return ERR_ALERT | ERR_FATAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
|
|
||||||
newsrv->ssl_ctx.sni = expr;
|
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -7510,7 +7495,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
|
|||||||
{ "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 */
|
||||||
{ "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
|
{ "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
|
||||||
{ "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
|
{ "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
|
||||||
{ "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
|
{ "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
|
||||||
{ "sslv3", srv_parse_sslv3, 0, 1 }, /* enable SSLv3 */
|
{ "sslv3", srv_parse_sslv3, 0, 1 }, /* enable SSLv3 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user