Updated patch. It now:

- Allows using a custom CA
- Reconfigure DoT resolvers' config when just the CA changed (previous
  version only impacted CA changes when there were also resolvers
  changes)

Have been running it without problems so far, and it seemed to work in
the early boot process too. If anyone has a better way to test that
other than "ntpd works", am all ears.

I'd really like to see this merged. Comments?

-Lucas

P.S.: I found a remnant of a previous imsg in the form of IMSG_ADD_DNS,
which should be IMSG_REPLACE_DNS. I included it in the patch.


Index: frontend.c
===================================================================
RCS file: /home/cvs/src/sbin/unwind/frontend.c,v
retrieving revision 1.68
diff -u -p -r1.68 frontend.c
--- frontend.c  6 Feb 2021 18:01:02 -0000       1.68
+++ frontend.c  20 Jul 2021 18:21:30 -0000
@@ -365,6 +365,7 @@ frontend_dispatch_main(int fd, short eve
                case IMSG_RECONF_FORWARDER:
                case IMSG_RECONF_DOT_FORWARDER:
                case IMSG_RECONF_FORCE:
+               case IMSG_RECONF_CA_FILE:
                        imsg_receive_config(&imsg, &nconf);
                        break;
                case IMSG_RECONF_END:
Index: parse.y
===================================================================
RCS file: /home/cvs/src/sbin/unwind/parse.y,v
retrieving revision 1.25
diff -u -p -r1.25 parse.y
--- parse.y     27 Feb 2021 10:32:28 -0000      1.25
+++ parse.y     20 Jul 2021 20:40:34 -0000
@@ -103,6 +103,7 @@ typedef struct {
 %token FORWARDER DOT PORT ODOT_FORWARDER ODOT_DHCP
 %token AUTHENTICATION NAME PREFERENCE RECURSOR DHCP STUB
 %token BLOCK LIST LOG FORCE ACCEPT BOGUS
+%token CA FILE
 
 %token <v.string>      STRING
 %token <v.number>      NUMBER
@@ -120,6 +121,7 @@ grammar             : /* empty */
                | grammar uw_forwarder '\n'
                | grammar block_list '\n'
                | grammar force '\n'
+               | grammar cafile '\n'
                | grammar error '\n'            { file->errors++; }
                ;
 
@@ -343,7 +345,7 @@ acceptbogus:        ACCEPT BOGUS    { $$ = 1; }
 
 force_list:    force_list optnl STRING {
                        struct force_tree_entry *e;
-                       size_t                           len;
+                       size_t                   len;
 
                        len = strlen($3);
                        e = malloc(sizeof(*e));
@@ -374,6 +376,20 @@ force_list:        force_list optnl STRING {
                }
        ;
 
+cafile :       CA FILE STRING {
+                       if (conf->ca_file != NULL) {
+                               yyerror("CA file already configured");
+                               free($3);
+                               YYERROR;
+                       } else {
+                               conf->ca_file = strdup($3);
+                               if (conf->ca_file == NULL)
+                                       err(1, "strdup");
+                               free($3);
+                       }
+               }
+       ;
+
 %%
 
 struct keywords {
@@ -413,8 +429,10 @@ lookup(char *s)
                {"authentication",      AUTHENTICATION},
                {"block",               BLOCK},
                {"bogus",               BOGUS},
+               {"ca",                  CA},
                {"dhcp",                DHCP},
                {"dot",                 DOT},
+               {"file",                FILE},
                {"force",               FORCE},
                {"forwarder",           FORWARDER},
                {"include",             INCLUDE},
Index: printconf.c
===================================================================
RCS file: /home/cvs/src/sbin/unwind/printconf.c,v
retrieving revision 1.16
diff -u -p -r1.16 printconf.c
--- printconf.c 1 Dec 2019 14:37:34 -0000       1.16
+++ printconf.c 20 Jul 2021 20:41:25 -0000
@@ -33,6 +33,9 @@ print_config(struct uw_conf *conf)
        int                      i;
        enum uw_resolver_type    j;
 
+       if (conf->ca_file != NULL)
+               printf("ca file %s\n", conf->ca_file);
+
        if (conf->res_pref.len > 0) {
                printf("preference {");
                for (i = 0; i < conf->res_pref.len; i++) {
Index: resolver.c
===================================================================
RCS file: /home/cvs/src/sbin/unwind/resolver.c,v
retrieving revision 1.144
diff -u -p -r1.144 resolver.c
--- resolver.c  12 Jul 2021 15:09:19 -0000      1.144
+++ resolver.c  22 Jul 2021 12:43:12 -0000
@@ -127,6 +127,7 @@ struct running_query {
 };
 
 TAILQ_HEAD(, running_query)     running_queries;
+static const char              *ca_file;
 
 typedef void (*resolve_cb_t)(struct uw_resolver *, void *, int, void *, int,
     int, char *);
@@ -376,9 +377,6 @@ resolver(int debug, int verbose)
            setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
                fatal("can't drop privileges");
 
-       if (unveil(TLS_DEFAULT_CA_CERT_FILE, "r") == -1)
-               fatal("unveil %s", TLS_DEFAULT_CA_CERT_FILE);
-
        if (pledge("stdio inet dns rpath recvfd", NULL) == -1)
                fatal("pledge");
 
@@ -563,7 +561,7 @@ resolver_dispatch_frontend(int fd, short
                case IMSG_REPLACE_DNS:
                        if (IMSG_DATA_SIZE(imsg) !=
                            sizeof(struct imsg_rdns_proposal))
-                               fatalx("%s: IMSG_ADD_DNS wrong length: %lu",
+                               fatalx("%s: IMSG_REPLACE_DNS wrong length: %lu",
                                    __func__, IMSG_DATA_SIZE(imsg));
                        replace_autoconf_forwarders((struct
                            imsg_rdns_proposal *)imsg.data);
@@ -664,6 +662,7 @@ resolver_dispatch_main(int fd, short eve
                case IMSG_RECONF_FORWARDER:
                case IMSG_RECONF_DOT_FORWARDER:
                case IMSG_RECONF_FORCE:
+               case IMSG_RECONF_CA_FILE:
                        imsg_receive_config(&imsg, &nconf);
                        break;
                case IMSG_RECONF_END:
@@ -672,6 +671,8 @@ resolver_dispatch_main(int fd, short eve
                                    "IMSG_RECONF_CONF", __func__);
                        restart = resolvers_to_restart(resolver_conf, nconf);
                        merge_config(resolver_conf, nconf);
+                       ca_file = resolver_conf->ca_file == NULL ?
+                           TLS_DEFAULT_CA_CERT_FILE : resolver_conf->ca_file;
                        memset(enabled_resolvers, 0, sizeof(enabled_resolvers));
                        for (i = 0; i < resolver_conf->res_pref.len; i++)
                                enabled_resolvers[
@@ -1320,8 +1321,7 @@ create_resolver(enum uw_resolver_type ty
                break;
        case UW_RES_ODOT_DHCP:
                set_forwarders(res, &autoconf_forwarder_list, 853);
-               ub_ctx_set_option(res->ctx, "tls-cert-bundle:",
-                   TLS_DEFAULT_CA_CERT_FILE);
+               ub_ctx_set_option(res->ctx, "tls-cert-bundle:", ca_file);
                ub_ctx_set_tls(res->ctx, 1);
                break;
        case UW_RES_FORWARDER:
@@ -1329,14 +1329,12 @@ create_resolver(enum uw_resolver_type ty
                break;
        case UW_RES_ODOT_FORWARDER:
                set_forwarders(res, &resolver_conf->uw_forwarder_list, 853);
-               ub_ctx_set_option(res->ctx, "tls-cert-bundle:",
-                   TLS_DEFAULT_CA_CERT_FILE);
+               ub_ctx_set_option(res->ctx, "tls-cert-bundle:", ca_file);
                ub_ctx_set_tls(res->ctx, 1);
                break;
        case UW_RES_DOT:
                set_forwarders(res, &resolver_conf->uw_dot_forwarder_list, 0);
-               ub_ctx_set_option(res->ctx, "tls-cert-bundle:",
-                   TLS_DEFAULT_CA_CERT_FILE);
+               ub_ctx_set_option(res->ctx, "tls-cert-bundle:", ca_file);
                ub_ctx_set_tls(res->ctx, 1);
                break;
        default:
@@ -2162,6 +2160,7 @@ int *
 resolvers_to_restart(struct uw_conf *oconf, struct uw_conf *nconf)
 {
        static int       restart[UW_RES_NONE];
+       const char      *o_ca_file, *n_ca_file;
        int              o_enabled[UW_RES_NONE];
        int              n_enabled[UW_RES_NONE];
        int              i;
@@ -2172,7 +2171,12 @@ resolvers_to_restart(struct uw_conf *oco
                restart[UW_RES_FORWARDER] = 1;
                restart[UW_RES_ODOT_FORWARDER] = 1;
        }
-       if (check_forwarders_changed(&oconf->uw_dot_forwarder_list,
+       o_ca_file = oconf->ca_file == NULL ? TLS_DEFAULT_CA_CERT_FILE :
+           oconf->ca_file;
+       n_ca_file = nconf->ca_file == NULL ? TLS_DEFAULT_CA_CERT_FILE :
+           nconf->ca_file;
+       if (strcmp(o_ca_file, n_ca_file) != 0 ||
+           check_forwarders_changed(&oconf->uw_dot_forwarder_list,
            &nconf->uw_dot_forwarder_list)) {
                restart[UW_RES_DOT] = 1;
        }
Index: unwind.c
===================================================================
RCS file: /home/cvs/src/sbin/unwind/unwind.c,v
retrieving revision 1.61
diff -u -p -r1.61 unwind.c
--- unwind.c    27 Feb 2021 10:32:28 -0000      1.61
+++ unwind.c    20 Jul 2021 20:59:20 -0000
@@ -586,7 +586,7 @@ main_reload(void)
 int
 main_imsg_send_config(struct uw_conf *xconf)
 {
-       struct uw_forwarder             *uw_forwarder;
+       struct uw_forwarder     *uw_forwarder;
        struct force_tree_entry *force_entry;
 
        /* Send fixed part of config to children. */
@@ -599,6 +599,11 @@ main_imsg_send_config(struct uw_conf *xc
                    == -1)
                        return (-1);
        }
+       if (xconf->ca_file != NULL) {
+               if (main_sendall(IMSG_RECONF_CA_FILE, xconf->ca_file,
+                   strlen(xconf->ca_file) + 1) == -1)
+                       return (-1);
+       }
 
        /* send static forwarders to children */
        TAILQ_FOREACH(uw_forwarder, &xconf->uw_forwarder_list, entry) {
@@ -679,6 +684,9 @@ merge_config(struct uw_conf *conf, struc
                RB_INSERT(force_tree, &conf->force, n);
        }
 
+       free(conf->ca_file);
+       conf->ca_file = xconf->ca_file;
+
        free(xconf);
 }
 
@@ -952,6 +960,13 @@ imsg_receive_config(struct imsg *imsg, s
                        fatalx("%s: IMSG_RECONF_FORCE duplicate entry",
                            __func__);
                }
+               break;
+       case IMSG_RECONF_CA_FILE:
+               /* make sure this is a string */
+               ((char *)imsg->data)[IMSG_DATA_SIZE(*imsg) - 1] = '\0';
+               if ((nconf->ca_file = strdup(imsg->data)) ==
+                   NULL)
+                       fatal("%s: strdup", __func__);
                break;
        default:
                log_debug("%s: error handling imsg %d", __func__,
Index: unwind.h
===================================================================
RCS file: /home/cvs/src/sbin/unwind/unwind.h,v
retrieving revision 1.54
diff -u -p -r1.54 unwind.h
--- unwind.h    27 Feb 2021 10:32:28 -0000      1.54
+++ unwind.h    20 Jul 2021 21:57:24 -0000
@@ -94,6 +94,7 @@ enum imsg_type {
        IMSG_RECONF_FORWARDER,
        IMSG_RECONF_DOT_FORWARDER,
        IMSG_RECONF_FORCE,
+       IMSG_RECONF_CA_FILE,
        IMSG_RECONF_END,
        IMSG_UDP4SOCK,
        IMSG_UDP6SOCK,
@@ -156,6 +157,7 @@ struct uw_conf {
        struct resolver_preference       res_pref;
        char                            *blocklist_file;
        int                              blocklist_log;
+       char                            *ca_file;
 };
 
 struct query_imsg {

Reply via email to