MINOR: ssl/cli: support filters and options in add ssl crt-list
Add the support for filters and SSL options in the CLI command
"add ssl crt-list".
The feature was implemented by applying the same parser as the crt-list
file to the payload.
The new options are passed to the command as a payload with the same
format that is suppported by the crt-list file itself, so you can easily
copy a line from a file and push it via the CLI.
Example:
printf "add ssl crt-list localhost.crt-list <<\necdsa.pem [verify none allow-0rtt] localhost !www.test1.com\n\n" | socat /tmp/sock1 -
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 198d0dd..17d7939 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -11362,26 +11362,28 @@
/*
* Parse a "add ssl crt-list <crt-list> <certfile>" line.
- * Does not support options or filters yet.
+ * Filters and option must be passed through payload:
*/
static int cli_parse_add_crtlist(char **args, char *payload, struct appctx *appctx, void *private)
{
+ int cfgerr = 0;
struct ckch_store *store;
char *err = NULL;
- char *crtlist_path, *cert_path;
+ char path[MAXPATHLEN+1];
+ char *crtlist_path;
+ char *cert_path = NULL;
struct ebmb_node *eb;
struct ebpt_node *inserted;
struct crtlist *crtlist;
- struct crtlist_entry *entry;
+ struct crtlist_entry *entry = NULL;
if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
return 1;
- if (!*args[3] || !*args[4])
+ if (!*args[3] || (!payload && !*args[4]))
return cli_err(appctx, "'add ssl crtlist' expects a filename and a certificate name\n");
crtlist_path = args[3];
- cert_path = args[4];
if (HA_SPIN_TRYLOCK(CKCH_LOCK, &ckch_lock))
return cli_err(appctx, "Operations on certificates are currently locked!\n");
@@ -11393,6 +11395,46 @@
}
crtlist = ebmb_entry(eb, struct crtlist, node);
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL) {
+ memprintf(&err, "Not enough memory!");
+ goto error;
+ }
+ entry->filters = NULL;
+ entry->ssl_conf = NULL;
+
+ if (payload) {
+ char *lf;
+
+ lf = strrchr(payload, '\n');
+ if (lf) {
+ memprintf(&err, "only one line of payload is supported!");
+ goto error;
+ }
+ /* cert_path is filled here */
+ cfgerr |= crtlist_parse_line(payload, &cert_path, entry, "CLI", 1, &err);
+ if (cfgerr & ERR_CODE)
+ goto error;
+ } else {
+ cert_path = args[4];
+ }
+
+ if (!cert_path) {
+ memprintf(&err, "'add ssl crtlist' should contain the certificate name in the payload");
+ cfgerr |= ERR_ALERT | ERR_FATAL;
+ goto error;
+ }
+
+ if (*cert_path != '/' && global_ssl.crt_base) {
+ if ((strlen(global_ssl.crt_base) + 1 + strlen(cert_path)) > MAXPATHLEN) {
+ memprintf(&err, "'%s' : path too long", cert_path);
+ cfgerr |= ERR_ALERT | ERR_FATAL;
+ goto error;
+ }
+ snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, cert_path);
+ cert_path = path;
+ }
+
store = ckchs_lookup(cert_path);
if (store == NULL) {
memprintf(&err, "certificate '%s' does not exist!", cert_path);
@@ -11403,28 +11445,16 @@
goto error;
}
- entry = malloc(sizeof(*entry));
- if (entry == NULL) {
- memprintf(&err, "Not enough memory!");
- goto error;
- }
-
/* check if it's possible to insert this new crtlist_entry */
entry->node.key = store;
inserted = ebpt_insert(&crtlist->entries, &entry->node);
if (inserted != &entry->node) {
memprintf(&err, "file already exists in this directory!");
- free(entry);
goto error;
}
LIST_ADDQ(&crtlist->ord_entries, &entry->by_crtlist);
LIST_INIT(&entry->ckch_inst);
- /* TODO: SSL conf support */
- entry->ssl_conf = NULL;
- /* TODO: filters support */
- entry->fcount = 0;
- entry->filters = NULL;
entry->crtlist = crtlist;
LIST_ADDQ(&store->crtlist_entry, &entry->by_ckch_store);
@@ -11436,6 +11466,12 @@
return 0;
error:
+ if (entry) {
+ crtlist_free_filters(entry->filters);
+ ssl_sock_free_ssl_conf(entry->ssl_conf);
+ free(entry->ssl_conf);
+ free(entry);
+ }
HA_SPIN_UNLOCK(CKCH_LOCK, &ckch_lock);
err = memprintf(&err, "Can't edit the crt-list: %s\n", err ? err : "");
return cli_dynerr(appctx, err);