BUG/MEDIUM: ssl: initialize correctly ssl w/ default-server
This bug was introduced by d817dc73 ("MEDIUM: ssl: Load client
certificates in a ckch for backend servers") in which the creation of
the SSL_CTX for a server was moved to the configuration parser when
using a "crt" keyword instead of being done in ssl_sock_prepare_srv_ctx().
The patch 0498fa40 ("BUG/MINOR: ssl: Default-server configuration ignored by
server") made it worse by setting the same SSL_CTX for every servers
using a default-server. Resulting in any SSL option on a server applied
to every server in its backend.
This patch fixes the issue by reintroducing a string which store the
path of certificate inside the server structure, and loading the
certificate in ssl_sock_prepare_srv_ctx() again.
This is a quick fix to backport, a cleaner way can be achieve by always
creating the SSL_CTX in ssl_sock_prepare_srv_ctx() and splitting
properly the ssl_sock_load_srv_cert() function.
This patch fixes issue #1488.
Must be backported as far as 2.4.
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 1fa7374..a14dea3 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -4837,8 +4837,7 @@
int ssl_sock_prepare_srv_ctx(struct server *srv)
{
int cfgerr = 0;
- SSL_CTX *ctx = srv->ssl_ctx.ctx;
-
+ SSL_CTX *ctx;
/* Automatic memory computations need to know we use SSL there */
global.ssl_used_backend = 1;
@@ -4853,6 +4852,27 @@
if (srv->use_ssl == 1)
srv->xprt = &ssl_sock;
+ if (srv->ssl_ctx.client_crt) {
+ const int create_if_none = srv->flags & SRV_F_DYNAMIC ? 0 : 1;
+ char *err = NULL;
+ int err_code = 0;
+
+ /* If there is a crt keyword there, the SSL_CTX will be created here. */
+ err_code = ssl_sock_load_srv_cert(srv->ssl_ctx.client_crt, srv, create_if_none, &err);
+ if (err_code != ERR_NONE) {
+ if ((err_code & ERR_WARN) && !(err_code & ERR_ALERT))
+ ha_warning("%s", err);
+ else
+ ha_alert("%s", err);
+
+ if (err_code & (ERR_FATAL|ERR_ABORT))
+ cfgerr++;
+ }
+ ha_free(&err);
+ }
+
+ ctx = srv->ssl_ctx.ctx;
+
/* The context will be uninitialized if there wasn't any "cert" option
* in the server line. */
if (!ctx) {