MEDIUM: ssl_sock: implement ssl_sock_prepare_bind_conf()
Instead of hard-coding all SSL preparation in cfgparse.c, we now register
this new function as the transport layer's prepare_bind_conf() and call it
only when definied. This removes some non-obvious SSL-specific code from
cfgparse.c as well as a #ifdef.
diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h
index 119368a..eea5344 100644
--- a/include/proto/ssl_sock.h
+++ b/include/proto/ssl_sock.h
@@ -45,6 +45,7 @@
int ssl_sock_handshake(struct connection *conn, unsigned int flag);
int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx);
int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf);
+int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf);
int ssl_sock_prepare_srv_ctx(struct server *srv);
void ssl_sock_free_srv_ctx(struct server *srv);
void ssl_sock_free_all_ctx(struct bind_conf *bind_conf);
diff --git a/src/cfgparse.c b/src/cfgparse.c
index c4c392f..f1f0f9b 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -8717,45 +8717,15 @@
struct listener *listener;
unsigned int next_id;
-#ifdef USE_OPENSSL
/* Configure SSL for each bind line.
* Note: if configuration fails at some point, the ->ctx member
* remains NULL so that listeners can later detach.
*/
list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
- int alloc_ctx;
-
- if (!bind_conf->is_ssl) {
- if (bind_conf->default_ctx) {
- Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
- curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
- }
- continue;
- }
- if (!bind_conf->default_ctx) {
- Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
- curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
+ if (bind_conf->xprt->prepare_bind_conf &&
+ bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
cfgerr++;
- continue;
- }
-
- alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global.tune.sslprivatecache && (global.nbproc > 1)) ? 1 : 0);
- if (alloc_ctx < 0) {
- if (alloc_ctx == SHCTX_E_INIT_LOCK)
- Alert("Unable to initialize the lock for the shared SSL session cache. You can retry using the global statement 'tune.ssl.force-private-cache' but it could increase CPU usage due to renegotiations if nbproc > 1.\n");
- else
- Alert("Unable to allocate SSL session cache.\n");
- cfgerr++;
- continue;
- }
-
- /* initialize all certificate contexts */
- cfgerr += ssl_sock_prepare_all_ctx(bind_conf);
-
- /* initialize CA variables if the certificates generation is enabled */
- cfgerr += ssl_sock_load_ca(bind_conf);
}
-#endif /* USE_OPENSSL */
/* adjust this proxy's listeners */
next_id = 1;
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 6cb8d63..490003f 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -3223,6 +3223,47 @@
return err;
}
+/* Prepares all the contexts for a bind_conf and allocates the shared SSL
+ * context if needed. Returns < 0 on error, 0 on success. The warnings and
+ * alerts are directly emitted since the rest of the stack does it below.
+ */
+int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
+{
+ struct proxy *px = bind_conf->frontend;
+ int alloc_ctx;
+ int err;
+
+ if (!bind_conf->is_ssl) {
+ if (bind_conf->default_ctx) {
+ Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
+ px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
+ }
+ return 0;
+ }
+ if (!bind_conf->default_ctx) {
+ Alert("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.tune.sslprivatecache && (global.nbproc > 1)) ? 1 : 0);
+ if (alloc_ctx < 0) {
+ if (alloc_ctx == SHCTX_E_INIT_LOCK)
+ Alert("Unable to initialize the lock for the shared SSL session cache. You can retry using the global statement 'tune.ssl.force-private-cache' but it could increase CPU usage due to renegotiations if nbproc > 1.\n");
+ else
+ Alert("Unable to allocate SSL session cache.\n");
+ return -1;
+ }
+
+ err = 0;
+ /* initialize all certificate contexts */
+ err += ssl_sock_prepare_all_ctx(bind_conf);
+
+ /* initialize CA variables if the certificates generation is enabled */
+ err += ssl_sock_load_ca(bind_conf);
+
+ return -err;
+}
/* release ssl context allocated for servers. */
void ssl_sock_free_srv_ctx(struct server *srv)
@@ -6590,6 +6631,7 @@
.shutw = ssl_sock_shutw,
.close = ssl_sock_close,
.init = ssl_sock_init,
+ .prepare_bind_conf = ssl_sock_prepare_bind_conf,
.name = "SSL",
};