MEDIUM: ssl: move "server" keyword SSL options parsing to ssl_sock.c
All SSL-specific "server" keywords are now processed in ssl_sock.c. At
the moment, there is no more "not implemented" hint when SSL is disabled,
but keywords could be added in server.c if needed.
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 1f7c479..6e96898 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -4111,64 +4111,6 @@
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) {
@@ -4281,99 +4223,6 @@
newsrv->state &= ~SRV_RUNNING;
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"))
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 055bc6f..994b6f7 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -65,6 +65,7 @@
#include <proto/freq_ctr.h>
#include <proto/frontend.h>
#include <proto/listener.h>
+#include <proto/server.h>
#include <proto/log.h>
#include <proto/shctx.h>
#include <proto/ssl_sock.h>
@@ -1376,6 +1377,107 @@
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 <const> as its list will be overwritten.
* Please take care of keeping this list alphabetically sorted.
*/
@@ -1437,6 +1539,28 @@
{ NULL, NULL, 0 },
}};
+/* Note: must not be declared <const> 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 @@
};
__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 @@
sample_register_fetches(&sample_fetch_keywords);
acl_register_keywords(&acl_kws);
bind_register_keywords(&bind_kws);
+ srv_register_keywords(&srv_kws);
}
/*