From 05f5b6fa420f9cbef73bd6aac491bb5ea2a04193 Mon Sep 17 00:00:00 2001
From: Emmanuel Hocdet <manu@gandi.net>
Date: Mon, 12 Jun 2017 16:02:44 +0200
Subject: [PATCH] MEDIUM: ssl: allow haproxy to start without default
 certificate

Use case is to start haproxy with ssl before provisioning with customer
certificates. Typically with 'crt' on a empty directory and 'strict-sni'
parameters.
---
 src/ssl_sock.c | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index af09cfb..9034db0 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1993,7 +1993,7 @@ static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
 		}
 	} else {
 		/* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
-		if (!s->strict_sni) {
+		if (!s->strict_sni && s->default_ctx) {
 			ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
 			return 1;
 		}
@@ -2127,7 +2127,7 @@ static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
 			methodVersions[max].ssl_set_version(ctx->ssl, SET_MAX);
 		return 1;
 	}
-	if (!s->strict_sni) {
+	if (!s->strict_sni && s->default_ctx) {
 		/* no certificate match, is the default_ctx */
 		ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
 		return 1;
@@ -2173,7 +2173,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
 			}
 		}
 #endif
-		if (s->strict_sni)
+		if (s->strict_sni || !s->default_ctx)
 			return SSL_TLSEXT_ERR_ALERT_FATAL;
 		ssl_sock_switchctx_set(ssl, s->default_ctx);
 		return SSL_TLSEXT_ERR_NOACK;
@@ -2211,7 +2211,7 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
 			return SSL_TLSEXT_ERR_OK;
 		}
 #endif
-		if (s->strict_sni)
+		if (s->strict_sni || !s->default_ctx)
 			return SSL_TLSEXT_ERR_ALERT_FATAL;
 		ssl_sock_switchctx_set(ssl, s->default_ctx);
 		return SSL_TLSEXT_ERR_OK;
@@ -4218,15 +4218,12 @@ int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
 		   to initial_ctx in ssl_sock_initial_ctx. */
 		err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
 	}
-	if (bind_conf->default_ctx)
-		err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
 
 	node = ebmb_first(&bind_conf->sni_ctx);
 	while (node) {
 		sni = ebmb_entry(node, struct sni_ctx, name);
-		if (!sni->order && sni->ctx != bind_conf->default_ctx)
-			/* only initialize the CTX on its first occurrence and
-			   if it is not the default_ctx */
+		if (!sni->order)
+			/* only initialize the CTX on its first occurrence */
 			err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
 		node = ebmb_next(node);
 	}
@@ -4234,9 +4231,8 @@ int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
 	node = ebmb_first(&bind_conf->sni_w_ctx);
 	while (node) {
 		sni = ebmb_entry(node, struct sni_ctx, name);
-		if (!sni->order && sni->ctx != bind_conf->default_ctx)
-			/* only initialize the CTX on its first occurrence and
-			   if it is not the default_ctx */
+		if (!sni->order)
+			/* only initialize the CTX on its first occurrence */
 			err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
 		node = ebmb_next(node);
 	}
@@ -4261,9 +4257,8 @@ int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
 		return 0;
 	}
 	if (!bind_conf->default_ctx) {
-		Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
+		Warning("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
 		      px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
-		return -1;
 	}
 
 	alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
-- 
2.1.4

