BUG/MEDIUM: ssl/crt-list: fix error when no file found
authorWilliam Lallemand <wlallemand@haproxy.com>
Fri, 20 Nov 2020 17:26:09 +0000 (18:26 +0100)
committerWilliam Lallemand <wlallemand@haproxy.org>
Fri, 20 Nov 2020 17:38:56 +0000 (18:38 +0100)
When a file from a crt-list was not found, this one was ignored silently
letting HAProxy starts without it.

This bug was introduced by 47da821 ("MEDIUM: ssl: emulates the
multi-cert bundles in the crtlist").

This commit adds a found variable which is checked once we tried every
bundle combination so we can exits with an error if none were found.

Must be backported in 2.3.

src/ssl_crtlist.c

index 8e9e5a1..f72f60e 100644 (file)
@@ -471,6 +471,7 @@ int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *cu
                char *crt_path;
                char path[MAXPATHLEN+1];
                struct ckch_store *ckchs;
+               int found = 0;
 
                if (missing_lf != -1) {
                        memprintf(err, "parsing [%s:%d]: Stray NUL character at position %d.\n",
@@ -537,6 +538,7 @@ int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *cu
                ckchs = ckchs_lookup(crt_path);
                if (ckchs == NULL) {
                        if (stat(crt_path, &buf) == 0) {
+                               found++;
 
                                ckchs = ckchs_load_cert_file(crt_path, err);
                                if (ckchs == NULL) {
@@ -569,41 +571,51 @@ int crtlist_parse_file(char *file, struct bind_conf *bind_conf, struct proxy *cu
                                                continue;
 
                                        ckchs = ckchs_lookup(fp);
-                                       if (!ckchs && stat(fp, &buf) == 0) {
-
-                                               ckchs = ckchs_load_cert_file(fp, err);
-                                               if (ckchs == NULL) {
-                                                       cfgerr |= ERR_ALERT | ERR_FATAL;
-                                                       goto error;
-                                               }
-
-                                               linenum++; /* we duplicate the line for this entry in the bundle */
-                                               if (!entry_dup) { /* if the entry was used, duplicate one */
-                                                       linenum++;
-                                                       entry_dup = crtlist_entry_dup(entry);
-                                                       if (!entry_dup) {
+                                       if (!ckchs) {
+                                               if (stat(fp, &buf) == 0) {
+                                                       ckchs = ckchs_load_cert_file(fp, err);
+                                                       if (!ckchs) {
                                                                cfgerr |= ERR_ALERT | ERR_FATAL;
                                                                goto error;
                                                        }
-                                                       entry_dup->linenum = linenum;
+                                               } else {
+                                                       continue; /* didn't find this extension, skip */
                                                }
+                                       }
+                                       found++;
+                                       linenum++; /* we duplicate the line for this entry in the bundle */
+                                       if (!entry_dup) { /* if the entry was used, duplicate one */
+                                               linenum++;
+                                               entry_dup = crtlist_entry_dup(entry);
+                                               if (!entry_dup) {
+                                                       cfgerr |= ERR_ALERT | ERR_FATAL;
+                                                       goto error;
+                                               }
+                                               entry_dup->linenum = linenum;
+                                       }
 
-                                               entry_dup->node.key = ckchs;
-                                               entry_dup->crtlist = newlist;
-                                               ebpt_insert(&newlist->entries, &entry_dup->node);
-                                               LIST_ADDQ(&newlist->ord_entries, &entry_dup->by_crtlist);
-                                               LIST_ADDQ(&ckchs->crtlist_entry, &entry_dup->by_ckch_store);
+                                       entry_dup->node.key = ckchs;
+                                       entry_dup->crtlist = newlist;
+                                       ebpt_insert(&newlist->entries, &entry_dup->node);
+                                       LIST_ADDQ(&newlist->ord_entries, &entry_dup->by_crtlist);
+                                       LIST_ADDQ(&ckchs->crtlist_entry, &entry_dup->by_ckch_store);
 
-                                               entry_dup = NULL; /* the entry was used, we need a new one next round */
-                                       }
+                                       entry_dup = NULL; /* the entry was used, we need a new one next round */
                                }
                        }
+                       if (!found) {
+                               memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
+                                         err && *err ? *err : "", crt_path, strerror(errno));
+                               cfgerr |= ERR_ALERT | ERR_FATAL;
+                       }
+
                } else {
                        entry->node.key = ckchs;
                        entry->crtlist = newlist;
                        ebpt_insert(&newlist->entries, &entry->node);
                        LIST_ADDQ(&newlist->ord_entries, &entry->by_crtlist);
                        LIST_ADDQ(&ckchs->crtlist_entry, &entry->by_ckch_store);
+                       found++;
                }
                entry = NULL;
        }