]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Can set tls authentication with forward-addr: IP#tls.auth.name
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 19 Apr 2018 12:10:05 +0000 (12:10 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 19 Apr 2018 12:10:05 +0000 (12:10 +0000)
  And put the public cert bundle in tls-cert-bundle: "ca-bundle.pem".

git-svn-id: file:///svn/unbound/trunk@4631 be551aaa-1e26-0410-a405-d3ace91eadb9

20 files changed:
daemon/remote.c
daemon/worker.c
doc/Changelog
iterator/iter_delegpt.c
iterator/iter_delegpt.h
iterator/iter_fwd.c
iterator/iter_hints.c
iterator/iterator.c
libunbound/libworker.c
libunbound/worker.h
pythonmod/interface.i
services/outside_network.c
services/outside_network.h
smallapp/worker_cb.c
testcode/fake_event.c
util/fptr_wlist.c
util/fptr_wlist.h
util/module.h
util/net_help.c
util/net_help.h

index 11c3cf34cc74f1c1233916f3e0e4b74e6e0f072c..c58e3618965642c1a2f31889b6a844a292d9f2da 100644 (file)
@@ -1941,6 +1941,7 @@ parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names)
        struct delegpt* dp = delegpt_create_mlc(nm);
        struct sockaddr_storage addr;
        socklen_t addrlen;
+       char* auth_name;
        if(!dp) {
                (void)ssl_printf(ssl, "error out of memory\n");
                return NULL;
@@ -1953,7 +1954,7 @@ parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names)
                        p = skipwhite(p); /* position at next spot */
                }
                /* parse address */
-               if(!extstrtoaddr(todo, &addr, &addrlen)) {
+               if(!authextstrtoaddr(todo, &addr, &addrlen, &auth_name)) {
                        if(allow_names) {
                                uint8_t* n = NULL;
                                size_t ln;
@@ -1981,7 +1982,8 @@ parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names)
                        }
                } else {
                        /* add address */
-                       if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
+                       if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
+                               auth_name)) {
                                (void)ssl_printf(ssl, "error out of memory\n");
                                delegpt_free_mlc(dp);
                                return NULL;
index 77ac9e8e81b4e29b17029efc20698b559629220a..91f7558d68dac0939e9a1ca490c0e1197260bbfe 100644 (file)
@@ -1875,7 +1875,7 @@ struct outbound_entry*
 worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
        int want_dnssec, int nocaps, struct sockaddr_storage* addr,
        socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream,
-       struct module_qstate* q)
+       char* tls_auth_name, struct module_qstate* q)
 {
        struct worker* worker = q->env->worker;
        struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
@@ -1885,7 +1885,7 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
        e->qstate = q;
        e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
                want_dnssec, nocaps, q->env->cfg->tcp_upstream,
-               ssl_upstream, addr, addrlen, zone, zonelen, q,
+               ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
                worker_handle_service_reply, e, worker->back->udp_buff, q->env);
        if(!e->qsent) {
                return NULL;
@@ -1932,7 +1932,8 @@ struct outbound_entry* libworker_send_query(
        int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
        struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
        uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
-       int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
+       int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
+       struct module_qstate* ATTR_UNUSED(q))
 {
        log_assert(0);
        return 0;
index f53bcc96fd9ac8566c3a2fe45d37294247f37f7b..be8e800d99ca3e33fb520bd857c30684c4c43eaa 100644 (file)
@@ -1,3 +1,7 @@
+19 April 2018: Wouter
+       - Can set tls authentication with forward-addr: IP#tls.auth.name
+         And put the public cert bundle in tls-cert-bundle: "ca-bundle.pem".
+
 18 April 2018: Wouter
        - Fix auth-zone retry timer to be on schedule with retry timeout,
          with backoff.  Also time a refresh at the zone expiry.
index ecf88b293da1304f819b5291c52f0e3850fad17a..f88b3e115db38b216727c342b297d3395f6f0f11 100644 (file)
@@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
        }
        for(a = dp->target_list; a; a = a->next_target) {
                if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, 
-                       a->bogus, a->lame))
+                       a->bogus, a->lame, a->tls_auth_name))
                        return NULL;
        }
        return copy;
@@ -176,13 +176,13 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
                if(ns->got4 && ns->got6)
                        ns->resolved = 1;
        }
-       return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame);
+       return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);
 }
 
 int 
 delegpt_add_addr(struct delegpt* dp, struct regional* region, 
        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, 
-       uint8_t lame)
+       uint8_t lame, char* tls_auth_name)
 {
        struct delegpt_addr* a;
        log_assert(!dp->dp_type_mlc);
@@ -210,6 +210,13 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
        a->bogus = bogus;
        a->lame = lame;
        a->dnsseclame = 0;
+       if(tls_auth_name) {
+               a->tls_auth_name = regional_strdup(region, tls_auth_name);
+               if(!a->tls_auth_name)
+                       return 0;
+       } else {
+               a->tls_auth_name = NULL;
+       }
        return 1;
 }
 
@@ -276,11 +283,16 @@ void delegpt_log(enum verbosity_value v, struct delegpt* dp)
                        (ns->done_pside6?" PSIDE_AAAA":""));
                }
                for(a = dp->target_list; a; a = a->next_target) {
+                       char s[128];
                        const char* str = "  ";
                        if(a->bogus && a->lame) str = "  BOGUS ADDR_LAME ";
                        else if(a->bogus) str = "  BOGUS ";
                        else if(a->lame) str = "  ADDR_LAME ";
-                       log_addr(VERB_ALGO, str, &a->addr, a->addrlen);
+                       if(a->tls_auth_name)
+                               snprintf(s, sizeof(s), "%s[%s]", str,
+                                       a->tls_auth_name);
+                       else snprintf(s, sizeof(s), "%s", str);
+                       log_addr(VERB_ALGO, s, &a->addr, a->addrlen);
                }
        }
 }
@@ -539,6 +551,7 @@ void delegpt_free_mlc(struct delegpt* dp)
        a = dp->target_list;
        while(a) {
                na = a->next_target;
+               free(a->tls_auth_name);
                free(a);
                a = na;
        }
@@ -585,7 +598,7 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame)
 }
 
 int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
-       socklen_t addrlen, uint8_t bogus, uint8_t lame)
+       socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name)
 {
        struct delegpt_addr* a;
        log_assert(dp->dp_type_mlc);
@@ -612,6 +625,15 @@ int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
        a->bogus = bogus;
        a->lame = lame;
        a->dnsseclame = 0;
+       if(tls_auth_name) {
+               a->tls_auth_name = strdup(tls_auth_name);
+               if(!a->tls_auth_name) {
+                       free(a);
+                       return 0;
+               }
+       } else {
+               a->tls_auth_name = NULL;
+       }
        return 1;
 }
 
@@ -632,7 +654,7 @@ int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
                if(ns->got4 && ns->got6)
                        ns->resolved = 1;
        }
-       return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame);
+       return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame, NULL);
 }
 
 size_t delegpt_get_mem(struct delegpt* dp)
index 24f0574901d9ed1898453ea4e3440c7a5c85da30..354bd6177380c9409bec7a6896ea4bf715f40474 100644 (file)
@@ -151,6 +151,8 @@ struct delegpt_addr {
         * option is useful to mark the address dnsseclame.
         * This value is not copied in addr-copy and dp-copy. */
        uint8_t dnsseclame;
+       /** the TLS authentication name, (if not NULL) to use. */
+       char* tls_auth_name;
 };
 
 /**
@@ -259,11 +261,12 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
  * @param addrlen: the length of addr.
  * @param bogus: if address is bogus.
  * @param lame: if address is lame.
+ * @param tls_auth_name: TLS authentication name (or NULL).
  * @return false on error.
  */
 int delegpt_add_addr(struct delegpt* dp, struct regional* regional, 
        struct sockaddr_storage* addr, socklen_t addrlen,
-       uint8_t bogus, uint8_t lame);
+       uint8_t bogus, uint8_t lame, char* tls_auth_name);
 
 /** 
  * Find NS record in name list of delegation point.
@@ -394,10 +397,11 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame);
  * @param addrlen: the length of addr.
  * @param bogus: if address is bogus.
  * @param lame: if address is lame.
+ * @param tls_auth_name: TLS authentication name (or NULL).
  * @return false on error.
  */
 int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
-       socklen_t addrlen, uint8_t bogus, uint8_t lame);
+       socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name);
 
 /**
  * Add target address to the delegation point.
index 0ba6c6ddfa9ebffbe69bf4a630a3092910931d29..a44f54386dc4b4b89eaf57fda0b0be4c6a0f8e2b 100644 (file)
@@ -231,14 +231,16 @@ read_fwds_addr(struct config_stub* s, struct delegpt* dp)
        struct config_strlist* p;
        struct sockaddr_storage addr;
        socklen_t addrlen;
+       char* tls_auth_name;
        for(p = s->addrs; p; p = p->next) {
                log_assert(p->str);
-               if(!extstrtoaddr(p->str, &addr, &addrlen)) {
+               if(!authextstrtoaddr(p->str, &addr, &addrlen, &tls_auth_name)) {
                        log_err("cannot parse forward %s ip address: '%s'", 
                                s->name, p->str);
                        return 0;
                }
-               if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
+               if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
+                       tls_auth_name)) {
                        log_err("out of memory");
                        return 0;
                }
index 1d4c228fabc21bee0bc1102c8993f988a4c16f59..e8d09338e9749fd54eb5c2fe9f1b73a7281459c0 100644 (file)
@@ -244,14 +244,16 @@ read_stubs_addr(struct config_stub* s, struct delegpt* dp)
        struct config_strlist* p;
        struct sockaddr_storage addr;
        socklen_t addrlen;
+       char* auth_name;
        for(p = s->addrs; p; p = p->next) {
                log_assert(p->str);
-               if(!extstrtoaddr(p->str, &addr, &addrlen)) {
+               if(!authextstrtoaddr(p->str, &addr, &addrlen, &auth_name)) {
                        log_err("cannot parse stub %s ip address: '%s'", 
                                s->name, p->str);
                        return 0;
                }
-               if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
+               if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
+                       auth_name)) {
                        log_err("out of memory");
                        return 0;
                }
index 4e50457fd4f239828aa06fe4270d37dc5cdb0640..65bb7199fb1f52df7886880a2dc4f2d5ce64dbcb 100644 (file)
@@ -1799,7 +1799,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
                        for(a = p->target_list; a; a=a->next_target) {
                                (void)delegpt_add_addr(iq->dp, qstate->region,
                                        &a->addr, a->addrlen, a->bogus,
-                                       a->lame);
+                                       a->lame, a->tls_auth_name);
                        }
                }
                iq->dp->has_parent_side_NS = 1;
@@ -2387,7 +2387,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
                iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
                ie, iq), &target->addr, target->addrlen,
                iq->dp->name, iq->dp->namelen,
-               (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), qstate);
+               (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
+               target->tls_auth_name, qstate);
        if(!outq) {
                log_addr(VERB_DETAIL, "error sending query to auth server", 
                        &target->addr, target->addrlen);
index 155f987de25095692667cd15f8dba99afadc015d..090fd276e18a9f5a4aad9f1077db09a17d35b612 100644 (file)
@@ -846,7 +846,8 @@ void libworker_alloc_cleanup(void* arg)
 struct outbound_entry* libworker_send_query(struct query_info* qinfo,
        uint16_t flags, int dnssec, int want_dnssec, int nocaps,
        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
-       size_t zonelen, int ssl_upstream, struct module_qstate* q)
+       size_t zonelen, int ssl_upstream, char* tls_auth_name,
+       struct module_qstate* q)
 {
        struct libworker* w = (struct libworker*)q->env->worker;
        struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
@@ -856,8 +857,8 @@ struct outbound_entry* libworker_send_query(struct query_info* qinfo,
        e->qstate = q;
        e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
                want_dnssec, nocaps, q->env->cfg->tcp_upstream, ssl_upstream,
-               addr, addrlen, zone, zonelen, q, libworker_handle_service_reply,
-               e, w->back->udp_buff, q->env);
+               tls_auth_name, addr, addrlen, zone, zonelen, q,
+               libworker_handle_service_reply, e, w->back->udp_buff, q->env);
        if(!e->qsent) {
                return NULL;
        }
@@ -977,7 +978,8 @@ struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
        int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
        struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
        uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
-       int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
+       int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
+       struct module_qstate* ATTR_UNUSED(q))
 {
        log_assert(0);
        return 0;
index 88e1cf799d474a25897fbcf995602e564f9962be..7d2ede04ed09ca3996f8e4c0fbf4e09055375d0c 100644 (file)
@@ -63,6 +63,8 @@ struct query_info;
  * @param zone: delegation point name.
  * @param zonelen: length of zone name wireformat dname.
  * @param ssl_upstream: use SSL for upstream queries.
+ * @param tls_auth_name: if ssl_upstream, use this name with TLS
+ *     authentication.
  * @param q: wich query state to reactivate upon return.
  * @return: false on failure (memory or socket related). no query was
  *      sent.
@@ -70,7 +72,8 @@ struct query_info;
 struct outbound_entry* libworker_send_query(struct query_info* qinfo,
        uint16_t flags, int dnssec, int want_dnssec, int nocaps,
        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
-       size_t zonelen, int ssl_upstream, struct module_qstate* q);
+       size_t zonelen, int ssl_upstream, char* tls_auth_name,
+       struct module_qstate* q);
 
 /** process incoming replies from the network */
 int libworker_handle_reply(struct comm_point* c, void* arg, int error,
@@ -115,6 +118,8 @@ void worker_sighandler(int sig, void* arg);
  * @param zone: wireformat dname of the zone.
  * @param zonelen: length of zone name.
  * @param ssl_upstream: use SSL for upstream queries.
+ * @param tls_auth_name: if ssl_upstream, use this name with TLS
+ *     authentication.
  * @param q: wich query state to reactivate upon return.
  * @return: false on failure (memory or socket related). no query was
  *      sent.
@@ -122,7 +127,8 @@ void worker_sighandler(int sig, void* arg);
 struct outbound_entry* worker_send_query(struct query_info* qinfo,
        uint16_t flags, int dnssec, int want_dnssec, int nocaps,
        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
-       size_t zonelen, int ssl_upstream, struct module_qstate* q);
+       size_t zonelen, int ssl_upstream, char* tls_auth_name,
+       struct module_qstate* q);
 
 /** 
  * process control messages from the main thread. Frees the control 
index 748dec52db410378f0e191c11d09c3e8e9dd80b8..72e6d99c7cf2315b474579c656a5856efb5c08b2 100644 (file)
@@ -574,7 +574,7 @@ struct module_env {
     struct outbound_entry* (*send_query)(struct query_info* qinfo,
         uint16_t flags, int dnssec, int want_dnssec, int nocaps,
         struct sockaddr_storage* addr, socklen_t addrlen,
-        uint8_t* zone, size_t zonelen, int ssl_upstream,
+        uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
         struct module_qstate* q);
     void (*detach_subs)(struct module_qstate* qstate);
     int (*attach_sub)(struct module_qstate* qstate,
index 92212be02f0d7ac23d5306005bd93dcac8e1e044..63dfe49611830b7ba9a565e9bcb2c445d86a14b1 100644 (file)
@@ -364,6 +364,20 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
                comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
 #endif
                pend->c->ssl_shake_state = comm_ssl_shake_write;
+#ifdef HAVE_SSL_SET1_HOST
+               if(w->tls_auth_name) {
+                       SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
+                       /* setting the hostname makes openssl verify the
+                         * host name in the x509 certificate in the
+                         * SSL connection*/
+                        if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
+                                log_err("SSL_set1_host failed");
+                               pend->c->fd = s;
+                               comm_point_close(pend->c);
+                               return 0;
+                       }
+               }
+#endif /* HAVE_SSL_SET1_HOST */
        }
        w->pkt = NULL;
        w->next_waiting = (void*)pend;
@@ -851,6 +865,7 @@ serviced_node_del(rbnode_type* node, void* ATTR_UNUSED(arg))
        struct service_callback* p = sq->cblist, *np;
        free(sq->qbuf);
        free(sq->zone);
+       free(sq->tls_auth_name);
        edns_opt_list_free(sq->opt_list);
        while(p) {
                np = p->next;
@@ -1284,6 +1299,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
        w->cb = callback;
        w->cb_arg = callback_arg;
        w->ssl_upstream = sq->ssl_upstream;
+       w->tls_auth_name = sq->tls_auth_name;
 #ifndef S_SPLINT_S
        tv.tv_sec = timeout;
        tv.tv_usec = 0;
@@ -1357,8 +1373,8 @@ lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
 static struct serviced_query*
 serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
        int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream,
-       struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
-       size_t zonelen, int qtype, struct edns_option* opt_list)
+       char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
+       uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list)
 {
        struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
 #ifdef UNBOUND_DEBUG
@@ -1386,12 +1402,24 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
        sq->nocaps = nocaps;
        sq->tcp_upstream = tcp_upstream;
        sq->ssl_upstream = ssl_upstream;
+       if(tls_auth_name) {
+               sq->tls_auth_name = strdup(tls_auth_name);
+               if(!sq->tls_auth_name) {
+                       free(sq->zone);
+                       free(sq->qbuf);
+                       free(sq);
+                       return NULL;
+               }
+       } else {
+               sq->tls_auth_name = NULL;
+       }
        memcpy(&sq->addr, addr, addrlen);
        sq->addrlen = addrlen;
        sq->opt_list = NULL;
        if(opt_list) {
                sq->opt_list = edns_opt_copy_alloc(opt_list);
                if(!sq->opt_list) {
+                       free(sq->tls_auth_name);
                        free(sq->zone);
                        free(sq->qbuf);
                        free(sq);
@@ -2055,7 +2083,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
 struct serviced_query* 
 outnet_serviced_query(struct outside_network* outnet,
        struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
-       int nocaps, int tcp_upstream, int ssl_upstream,
+       int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
        size_t zonelen, struct module_qstate* qstate,
        comm_point_callback_type* callback, void* callback_arg, sldns_buffer* buff,
@@ -2078,8 +2106,9 @@ outnet_serviced_query(struct outside_network* outnet,
        if(!sq) {
                /* make new serviced query entry */
                sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps,
-                       tcp_upstream, ssl_upstream, addr, addrlen, zone,
-                       zonelen, (int)qinfo->qtype, qstate->edns_opts_back_out);
+                       tcp_upstream, ssl_upstream, tls_auth_name, addr,
+                       addrlen, zone, zonelen, (int)qinfo->qtype,
+                       qstate->edns_opts_back_out);
                if(!sq) {
                        free(cb);
                        return NULL;
index 09b2e6cedff62d4642207046a4eb42fc7b81f0d8..0853f15e23ba2b782c4d057f0532cd129dff114b 100644 (file)
@@ -290,6 +290,8 @@ struct waiting_tcp {
        void* cb_arg;
        /** if it uses ssl upstream */
        int ssl_upstream;
+       /** ref to the tls_auth_name from the serviced_query */
+       char* tls_auth_name;
 };
 
 /**
@@ -332,6 +334,9 @@ struct serviced_query {
        int nocaps;
        /** tcp upstream used, use tcp, or ssl_upstream for SSL */
        int tcp_upstream, ssl_upstream;
+       /** the name of the tls authentication name, eg. 'ns.example.com'
+        * or NULL */
+       char* tls_auth_name;
        /** where to send it */
        struct sockaddr_storage addr;
        /** length of addr field in use. */
@@ -501,7 +506,7 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
  */
 struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
        struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
-       int nocaps, int tcp_upstream, int ssl_upstream,
+       int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
        size_t zonelen, struct module_qstate* qstate,
        comm_point_callback_type* callback, void* callback_arg,
index e88e8c8d754b2f9367e922e2f7a09c20802b2208..dda94cc670cf0f5e0c8a2fab536d4952bf60732c 100644 (file)
@@ -105,7 +105,7 @@ struct outbound_entry* worker_send_query(
        int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
        socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
        size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
-       struct module_qstate* ATTR_UNUSED(q))
+       char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
 {
        log_assert(0);
        return 0;
@@ -137,7 +137,7 @@ struct outbound_entry* libworker_send_query(
        int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
        socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
        size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
-       struct module_qstate* ATTR_UNUSED(q))
+       char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
 {
        log_assert(0);
        return 0;
index 300a42c154ab304ac19aa6d4b4d6099cc6911484..860e2e81e3247432ccbf458cd24aad9e386b2bf6 100644 (file)
@@ -1161,10 +1161,11 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
        struct query_info* qinfo, uint16_t flags, int dnssec,
        int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
        int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
-       struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
-       size_t zonelen, struct module_qstate* qstate,
-       comm_point_callback_type* callback, void* callback_arg,
-       sldns_buffer* ATTR_UNUSED(buff), struct module_env* ATTR_UNUSED(env))
+       char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr,
+       socklen_t addrlen, uint8_t* zone, size_t zonelen,
+       struct module_qstate* qstate, comm_point_callback_type* callback,
+       void* callback_arg, sldns_buffer* ATTR_UNUSED(buff),
+       struct module_env* ATTR_UNUSED(env))
 {
        struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
        struct fake_pending* pend = (struct fake_pending*)calloc(1,
index 400a15de2ebb790f7477468d8d47d10eeb8112fd..302b6f7843ea2de3ae11253f074bafd3350f34d2 100644 (file)
@@ -311,7 +311,8 @@ int
 fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
        struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
        int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
-       uint8_t* zone, size_t zonelen, int ssl_upstream, struct module_qstate* q))
+       uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
+       struct module_qstate* q))
 {
        if(fptr == &worker_send_query) return 1;
        else if(fptr == &libworker_send_query) return 1;
index 39e3f2d7f21b48a0a493c1e6555126e89f5a1755..03c2b92b45aae3f5a313be9a5531cb185c030e81 100644 (file)
@@ -212,7 +212,8 @@ int fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr);
 int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
        struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
        int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
-       uint8_t* zone, size_t zonelen, int ssl_upstream, struct module_qstate* q));
+       uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
+       struct module_qstate* q));
 
 /**
  * Check function pointer whitelist for module_env detach_subs callback values.
index 73db994bd7a3ee6784708dc63f3055bb01f8e19d..c6e5164de6d6839091407dd8f75fad55b3e84b94 100644 (file)
@@ -338,6 +338,8 @@ struct module_env {
         * @param zone: delegation point name.
         * @param zonelen: length of zone name.
         * @param ssl_upstream: use SSL for upstream queries.
+        * @param tls_auth_name: if ssl_upstream, use this name with TLS
+        *      authentication.
         * @param q: wich query state to reactivate upon return.
         * @return: false on failure (memory or socket related). no query was
         *      sent. Or returns an outbound entry with qsent and qstate set.
@@ -348,7 +350,7 @@ struct module_env {
                uint16_t flags, int dnssec, int want_dnssec, int nocaps,
                struct sockaddr_storage* addr, socklen_t addrlen,
                uint8_t* zone, size_t zonelen, int ssl_upstream,
-               struct module_qstate* q);
+               char* tls_auth_name, struct module_qstate* q);
 
        /**
         * Detach-subqueries.
index 89939bf97db439f9d56a44a0de17d3657fb35d49..439c60fab4568a56ed06e4dc83acd9855d8cd1ec 100644 (file)
@@ -270,6 +270,49 @@ int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
        return 1;
 }
 
+int authextstrtoaddr(char* str, struct sockaddr_storage* addr, 
+       socklen_t* addrlen, char** auth_name)
+{
+       char* s;
+       int port = UNBOUND_DNS_PORT;
+       if((s=strchr(str, '@'))) {
+               char buf[MAX_ADDR_STRLEN];
+               size_t len = s-str;
+               char* hash = strchr(s+1, '#');
+               if(hash) {
+                       *auth_name = hash+1;
+               } else {
+                       *auth_name = NULL;
+               }
+               if(len >= MAX_ADDR_STRLEN) {
+                       return 0;
+               }
+               (void)strlcpy(buf, str, sizeof(buf));
+               buf[len] = 0;
+               port = atoi(s+1);
+               if(port == 0) {
+                       if(!hash && strcmp(s+1,"0")!=0)
+                               return 0;
+                       if(hash && strncmp(s+1,"0#",2)!=0)
+                               return 0;
+               }
+               return ipstrtoaddr(buf, port, addr, addrlen);
+       }
+       if((s=strchr(str, '#'))) {
+               char buf[MAX_ADDR_STRLEN];
+               size_t len = s-str;
+               if(len >= MAX_ADDR_STRLEN) {
+                       return 0;
+               }
+               (void)strlcpy(buf, str, sizeof(buf));
+               buf[len] = 0;
+               *auth_name = s+1;
+               return ipstrtoaddr(buf, port, addr, addrlen);
+       }
+       *auth_name = NULL;
+       return ipstrtoaddr(str, port, addr, addrlen);
+}
+
 /** store port number into sockaddr structure */
 void
 sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, int port)
index ba78c24865a2fa153ef9b60cce4c96f2c38ee4e8..5e0d3a62936e2dd1f5c556736e86c2596ac62e68 100644 (file)
@@ -201,6 +201,20 @@ int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
 int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
        socklen_t* addrlen, int* net);
 
+/**
+ * Convert address string, with "@port" appendix, to sockaddr.
+ * It can also have an "#tls-auth-name" appendix (after the port).
+ * The returned tls-auth-name string is a pointer into the input string.
+ * Uses DNS port by default.
+ * @param str: the string
+ * @param addr: where to store sockaddr.
+ * @param addrlen: length of stored sockaddr is returned.
+ * @param auth_name: returned pointer to tls_auth_name, or NULL if none.
+ * @return 0 on error.
+ */
+int authextstrtoaddr(char* str, struct sockaddr_storage* addr, 
+       socklen_t* addrlen, char** auth_name);
+
 /**
  * Store port number into sockaddr structure
  * @param addr: sockaddr structure, ip4 or ip6.