]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- xfr-tsig, primary-tsig: addr tsig and allow-notify-tsig: addr tsig.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 31 Jul 2025 12:43:43 +0000 (14:43 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 31 Jul 2025 12:43:43 +0000 (14:43 +0200)
daemon/remote.c
doc/example.conf.in
doc/unbound.conf.rst
services/authzone.c
services/authzone.h
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y

index c17254bb5e21ae4665a01638b7fa04104c85db81..22475c4682475cccaf2a9bab8068476bc9f0b743 100644 (file)
@@ -4696,6 +4696,8 @@ getmem_config_auth(struct config_auth* p)
                        + getmem_config_strlist(s->masters)
                        + getmem_config_strlist(s->urls)
                        + getmem_config_strlist(s->allow_notify)
+                       + getmem_config_str2list(s->masters_tsig)
+                       + getmem_config_str2list(s->allow_notify_tsig)
                        + getmem_str(s->zonefile)
                        + s->rpz_taglistlen
                        + getmem_str(s->rpz_action_override)
@@ -4947,6 +4949,12 @@ xfr_auth_master_equal(struct auth_master* m1, struct auth_master* m2)
                return 0;
        if(m1->port != m2->port)
                return 0;
+
+       if((m1->tsig_key_name && !m2->tsig_key_name) || (!m1->tsig_key_name && m2->tsig_key_name))
+               return 0;
+       if(m1->tsig_key_name && m2->tsig_key_name && strcmp(m1->tsig_key_name, m2->tsig_key_name) != 0)
+               return 0;
+
        return 1;
 }
 
index bdfdc64507fb7e7d9ecd7496acabe276ea7f983e..cb8a24e38c01f685bb5518360dcdf309e371304a 100644 (file)
@@ -1226,7 +1226,8 @@ remote-control:
 # authoritatively.  zonefile: reads from file (and writes to it if you also
 # download it), primary: fetches with AXFR and IXFR, or url to zonefile.
 # With allow-notify: you can give additional (apart from primaries and urls)
-# sources of notifies.
+# sources of notifies. primary-tsig: and allow-notify-tsig: use addr keyname,
+# with the name of the TSIG key to use, declared as a tsig-key:.
 # auth-zone:
 #      name: "."
 #      primary: 170.247.170.2        # b.root-servers.net
@@ -1405,6 +1406,7 @@ remote-control:
 # and drop.  Policies can be loaded from a file, or using zone
 # transfer, or using HTTP. The respip module needs to be added
 # to the module-config, e.g.: module-config: "respip validator iterator".
+# Can also use primary-tsig: and allow-notify-tsig:
 # rpz:
 #     name: "rpz.example.com"
 #     zonefile: "rpz.example.com"
index c1a8406e50d08536645505a59e9641af089e81ae..522542e21e8126ad5ef772469414fb9ab284b350 100644 (file)
@@ -3691,6 +3691,12 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
     Alternate syntax for :ref:`primary<unbound.conf.auth.primary>`.
 
 
+@@UAHL@unbound.conf.auth@primary-tsig@@: *<IP address or host name>* *<tsig key>*
+    Similar to :ref:`primary<unbound.conf.auth.primary>` and the tsig key
+    is used for TSIG.
+    The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
+
+
 @@UAHL@unbound.conf.auth@url@@: *<URL to zone file>*
     Where to download a zonefile for the zone.
     With HTTP or HTTPS.
@@ -3737,6 +3743,12 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
         default.
 
 
+@@UAHL@unbound.conf.auth@allow-notify-tsig@@: *<IP address or host name or netblockIP/prefix>* *<tsig key>*
+    Similar to :ref:`allow-notify<unbound.conf.auth.allow-notify>` and the
+    tsig key is used for TSIG.
+    The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
+
+
 @@UAHL@unbound.conf.auth@fallback-enabled@@: *<yes or no>*
     If enabled, Unbound falls back to querying the internet as a resolver for
     this zone when lookups fail.
@@ -4840,6 +4852,12 @@ The RPZ zones can be configured in the config file with these settings in the
     Alternate syntax for :ref:`primary<unbound.conf.rpz.primary>`.
 
 
+@@UAHL@unbound.conf.rpz@primary-tsig@@: *<IP address or host name>* *<tsig key>*
+    Similar to :ref:`primary<unbound.conf.rpz.primary>` and the tsig key
+    is used for TSIG.
+    The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
+
+
 @@UAHL@unbound.conf.rpz@url@@: *<url to zonefile>*
     Where to download a zonefile for the zone.
     With HTTP or HTTPS.
@@ -4877,6 +4895,12 @@ The RPZ zones can be configured in the config file with these settings in the
         default.
 
 
+@@UAHL@unbound.conf.rpz@allow-notify-tsig@@: *<IP address or host name or netblockIP/prefix>* *<tsig key>*
+    Similar to :ref:`allow-notify<unbound.conf.rpz.allow-notify>` and the
+    tsig key is used for TSIG.
+    The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
+
+
 @@UAHL@unbound.conf.rpz@zonefile@@: *<filename>*
     The filename where the zone is stored.
     If not given then no zonefile is used.
index 591a76cd98d996857a35e192ce3a816a5eeae075..e59d384f241c4eec7720930f6b31561131914eb1 100644 (file)
@@ -2110,7 +2110,7 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
                }
                return 0;
        }
-       if(c->masters || c->urls) {
+       if(c->masters || c->masters_tsig || c->urls) {
                if(!(x=auth_zones_find_or_add_xfer(az, z))) {
                        lock_rw_unlock(&az->lock);
                        lock_rw_unlock(&z->lock);
@@ -2312,6 +2312,7 @@ auth_free_masters(struct auth_master* list)
                auth_free_master_addrs(list->list);
                free(list->host);
                free(list->file);
+               free(list->tsig_key_name);
                free(list);
                list = n;
        }
@@ -3978,9 +3979,20 @@ auth_master_copy(struct auth_master* o)
                        return NULL;
                }
        }
+       if(m->tsig_key_name) {
+               m->tsig_key_name = strdup(m->tsig_key_name);
+               if(!m->tsig_key_name) {
+                       free(m->file);
+                       free(m->host);
+                       free(m);
+                       log_err("malloc failure");
+                       return NULL;
+               }
+       }
        if(m->list) {
                m->list = auth_addr_list_copy(m->list);
                if(!m->list) {
+                       free(m->tsig_key_name);
                        free(m->file);
                        free(m->host);
                        free(m);
@@ -7278,6 +7290,7 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
 {
        struct auth_master* m;
        struct config_strlist* p;
+       struct config_str2list* p2;
        /* list points to the first, or next pointer for the new element */
        while(*list) {
                list = &( (*list)->next );
@@ -7300,6 +7313,21 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
                        return 0;
                }
        }
+       for(p2 = c->masters_tsig; p2; p2 = p2->next) {
+               m = auth_master_new(&list);
+               if(!m) return 0;
+               m->ixfr = 1; /* this flag is not configurable */
+               m->host = strdup(p2->str);
+               if(!m->host) {
+                       log_err("malloc failure");
+                       return 0;
+               }
+               m->tsig_key_name = strdup(p2->str2);
+               if(!m->tsig_key_name) {
+                       log_err("malloc failure");
+                       return 0;
+               }
+       }
        for(p = c->allow_notify; p; p = p->next) {
                m = auth_master_new(&list);
                if(!m) return 0;
@@ -7310,6 +7338,21 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
                        return 0;
                }
        }
+       for(p2 = c->allow_notify_tsig; p2; p2 = p2->next) {
+               m = auth_master_new(&list);
+               if(!m) return 0;
+               m->allow_notify = 1;
+               m->host = strdup(p2->str);
+               if(!m->host) {
+                       log_err("malloc failure");
+                       return 0;
+               }
+               m->tsig_key_name = strdup(p2->str2);
+               if(!m->tsig_key_name) {
+                       log_err("malloc failure");
+                       return 0;
+               }
+       }
        return 1;
 }
 
@@ -8645,6 +8688,8 @@ auth_primaries_get_mem(struct auth_master* list)
                        m += strlen(n->host)+1;
                if(n->file)
                        m += strlen(n->file)+1;
+               if(n->tsig_key_name)
+                       m += strlen(n->tsig_key_name)+1;
        }
        return m;
 }
index b11e7f1449e0038cfbbf8f3354d16ad62dcda7d1..00e6343f21521635159b621334d8b2a0fc1a4e60 100644 (file)
@@ -457,6 +457,8 @@ struct auth_master {
        int ssl;
        /** the port number (for urls) */
        int port;
+       /** the tsig key name (if any, or NULL) */
+       char* tsig_key_name;
        /** if the host is a hostname, the list of resolved addrs, if any*/
        struct auth_addr* list;
 };
index 89e8760ce7bf6a9a0905b228a4a9e6145113ac68..a862c6a65cfeab464a6e06a925a0edab0551b1d6 100644 (file)
@@ -1641,6 +1641,8 @@ config_delauth(struct config_auth* p)
        config_delstrlist(p->masters);
        config_delstrlist(p->urls);
        config_delstrlist(p->allow_notify);
+       config_deldblstrlist(p->masters_tsig);
+       config_deldblstrlist(p->allow_notify_tsig);
        free(p->zonefile);
        free(p->rpz_taglist);
        free(p->rpz_action_override);
index 9e631456128f1ca60bb961ffe62bf3778dfc195b..f512cde546bf431c8275742e9471ccba0894beaa 100644 (file)
@@ -848,6 +848,10 @@ struct config_auth {
        struct config_strlist* urls;
        /** list of allow-notify */
        struct config_strlist* allow_notify;
+       /** list of masters with tsig key */
+       struct config_str2list* masters_tsig;
+       /** list of allow-notify with tsig key */
+       struct config_str2list* allow_notify_tsig;
        /** zonefile (or NULL) */
        char* zonefile;
        /** provide downstream answers */
index d415e7a040eb8cd3b32b2fda00841331fc4d5039..9ddc5c1bca3084bebd8cc1525e969f22ee131ada 100644 (file)
@@ -361,8 +361,11 @@ rpz-signal-nxdomain-ra{COLON}      { YDVAR(1, VAR_RPZ_SIGNAL_NXDOMAIN_RA) }
 zonefile{COLON}                        { YDVAR(1, VAR_ZONEFILE) }
 master{COLON}                  { YDVAR(1, VAR_MASTER) }
 primary{COLON}                 { YDVAR(1, VAR_MASTER) }
+master-tsig{COLON}             { YDVAR(2, VAR_MASTER_TSIG) }
+primary-tsig{COLON}            { YDVAR(2, VAR_MASTER_TSIG) }
 url{COLON}                     { YDVAR(1, VAR_URL) }
 allow-notify{COLON}            { YDVAR(1, VAR_ALLOW_NOTIFY) }
+allow-notify-tsig{COLON}       { YDVAR(2, VAR_ALLOW_NOTIFY_TSIG) }
 for-downstream{COLON}          { YDVAR(1, VAR_FOR_DOWNSTREAM) }
 for-upstream{COLON}            { YDVAR(1, VAR_FOR_UPSTREAM) }
 fallback-enabled{COLON}                { YDVAR(1, VAR_FALLBACK_ENABLED) }
index 9638740c9b318b38ff2550924306a02d4479e32a..0233ec30c9dd6a660c1e13747be8787bbbc9c765 100644 (file)
@@ -192,6 +192,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_CACHEDB_REDISCONNECTTIMEOUT VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT
 %token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
 %token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
+%token VAR_MASTER_TSIG VAR_ALLOW_NOTIFY_TSIG
 %token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
 %token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
 %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
@@ -465,9 +466,10 @@ authstart: VAR_AUTH_ZONE
        ;
 contents_auth: contents_auth content_auth
        | ;
-content_auth: auth_name | auth_zonefile | auth_master | auth_url |
-       auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
-       auth_allow_notify | auth_zonemd_check | auth_zonemd_reject_absence
+content_auth: auth_name | auth_zonefile | auth_master | auth_master_tsig |
+       auth_url | auth_for_downstream | auth_for_upstream |
+       auth_fallback_enabled | auth_allow_notify | auth_allow_notify_tsig |
+       auth_zonemd_check | auth_zonemd_reject_absence
        ;
 
 rpz_tag: VAR_TAGS STRING_ARG
@@ -562,9 +564,10 @@ rpzstart: VAR_RPZ
        ;
 contents_rpz: contents_rpz content_rpz
        | ;
-content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url |
-          auth_allow_notify | rpz_action_override | rpz_cname_override |
-          rpz_log | rpz_log_name | rpz_signal_nxdomain_ra | auth_for_downstream
+content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master |
+       auth_master_tsig | auth_url | auth_allow_notify |
+       auth_allow_notify_tsig | rpz_action_override | rpz_cname_override |
+       rpz_log | rpz_log_name | rpz_signal_nxdomain_ra | auth_for_downstream
        ;
 server_num_threads: VAR_NUM_THREADS STRING_ARG
        {
@@ -3252,6 +3255,14 @@ auth_master: VAR_MASTER STRING_ARG
                        yyerror("out of memory");
        }
        ;
+auth_master_tsig: VAR_MASTER_TSIG STRING_ARG STRING_ARG
+       {
+               OUTYY(("P(master-tsig:%s)\n", $2));
+               if(!cfg_str2list_insert(&cfg_parser->cfg->auths->masters_tsig,
+                       $2, $3))
+                       yyerror("out of memory");
+       }
+       ;
 auth_url: VAR_URL STRING_ARG
        {
                OUTYY(("P(url:%s)\n", $2));
@@ -3267,6 +3278,14 @@ auth_allow_notify: VAR_ALLOW_NOTIFY STRING_ARG
                        yyerror("out of memory");
        }
        ;
+auth_allow_notify_tsig: VAR_ALLOW_NOTIFY_TSIG STRING_ARG STRING_ARG
+       {
+               OUTYY(("P(allow-notify-tsig:%s)\n", $2));
+               if(!cfg_str2list_insert(
+                       &cfg_parser->cfg->auths->allow_notify_tsig, $2, $3))
+                       yyerror("out of memory");
+       }
+       ;
 auth_zonemd_check: VAR_ZONEMD_CHECK STRING_ARG
        {
                OUTYY(("P(zonemd-check:%s)\n", $2));