]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- xfr-tsig, tsig-key, with name, algorithm and secret options.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 13 Jun 2025 10:12:49 +0000 (12:12 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 13 Jun 2025 10:12:49 +0000 (12:12 +0200)
Makefile.in
daemon/daemon.c
libunbound/context.c
libunbound/libunbound.c
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y
util/module.h
util/tsig.c
util/tsig.h

index f2efa5d2cdb8e7db8f77631f7ddda213e232fbfe..095717e1608d83ab1cc54619db08d230d3b0d2d5 100644 (file)
@@ -937,8 +937,8 @@ config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/ut
 configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
  $(srcdir)/util/config_file.h util/configparser.h
 configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/rrdef.h
+ $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/tsig.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
 shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \
  $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
  $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
@@ -1299,7 +1299,7 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h
  $(srcdir)/util/edns.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
  $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h \
- $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/util/tsig.h $(srcdir)/sldns/keyraw.h \
  $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h
 remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
  $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
@@ -1509,7 +1509,7 @@ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbou
  $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
  $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h \
- $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/util/edns.h \
+ $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/util/edns.h $(srcdir)/util/tsig.h \
  $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h
 libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
  $(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
@@ -1517,7 +1517,7 @@ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbou
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/libworker.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \
- $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h $(srcdir)/util/edns.h \
+ $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h $(srcdir)/util/edns.h $(srcdir)/util/tsig.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
  $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
  $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/services/cache/rrset.h \
index f882bb9ad62ed1f4eb8ded38fa34115c89455c49..92d0d031b73d35ee0bf5feedba6e418fc70b7751 100644 (file)
@@ -89,6 +89,7 @@
 #include "util/random.h"
 #include "util/tube.h"
 #include "util/net_help.h"
+#include "util/tsig.h"
 #include "sldns/keyraw.h"
 #include "respip/respip.h"
 #include "iterator/iter_fwd.h"
@@ -320,6 +321,17 @@ daemon_init(void)
                free(daemon);
                return NULL;
        }
+       if(!(daemon->env->tsig_key_table = tsig_key_table_create())) {
+               auth_zones_delete(daemon->env->auth_zones);
+               acl_list_delete(daemon->acl_interface);
+               acl_list_delete(daemon->acl);
+               tcl_list_delete(daemon->tcl);
+               edns_known_options_delete(daemon->env);
+               edns_strings_delete(daemon->env->edns_strings);
+               free(daemon->env);
+               free(daemon);
+               return NULL;
+       }
        return daemon;  
 }
 
@@ -771,6 +783,10 @@ daemon_fork(struct daemon* daemon)
        daemon->use_response_ip = !respip_set_is_empty(
                daemon->env->respip_set) || have_view_respip_cfg;
 
+       /* setup tsig keys */
+       if(!tsig_key_table_apply_cfg(daemon->env->tsig_key_table, daemon->cfg))
+               fatal_exit("Could not set up TSIG keys");
+
        /* setup modules */
        daemon_setup_modules(daemon);
 
@@ -944,6 +960,7 @@ daemon_delete(struct daemon* daemon)
                edns_known_options_delete(daemon->env);
                edns_strings_delete(daemon->env->edns_strings);
                auth_zones_delete(daemon->env->auth_zones);
+               tsig_key_table_delete(daemon->env->tsig_key_table);
        }
        ub_randfree(daemon->rand);
        alloc_clear(&daemon->superalloc);
index a1a4adf98f0e8808948d12449778c74892786ce5..38b5dbf0015954dfc52fb49a5e60bbdfbf1ba388 100644 (file)
@@ -52,6 +52,7 @@
 #include "util/data/msgreply.h"
 #include "util/storage/slabhash.h"
 #include "util/edns.h"
+#include "util/tsig.h"
 #include "sldns/sbuffer.h"
 #include "iterator/iter_fwd.h"
 #include "iterator/iter_hints.h"
@@ -81,6 +82,8 @@ context_finalize(struct ub_ctx* ctx)
                return UB_INITFAIL;
        listen_setup_locks();
        log_edns_known_options(VERB_ALGO, ctx->env);
+       if(!tsig_key_table_apply_cfg(ctx->env->tsig_key_table, cfg))
+               return UB_INITFAIL;
        ctx->local_zones = local_zones_create();
        if(!ctx->local_zones)
                return UB_NOMEM;
index 9c6a3e309717076e3f895e2336c48f818d816d30..e5b340013cd3db0116136f6960c6d22612e4a46f 100644 (file)
@@ -59,6 +59,7 @@
 #include "util/tube.h"
 #include "util/ub_event.h"
 #include "util/edns.h"
+#include "util/tsig.h"
 #include "services/modstack.h"
 #include "services/localzone.h"
 #include "services/cache/infra.h"
@@ -168,6 +169,18 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
                errno = ENOMEM;
                return NULL;
        }
+       ctx->env->tsig_key_table = tsig_key_table_create();
+       if(!ctx->env->tsig_key_table) {
+               auth_zones_delete(ctx->env->auth_zones);
+               edns_known_options_delete(ctx->env);
+               edns_strings_delete(ctx->env->edns_strings);
+               config_delete(ctx->env->cfg);
+               free(ctx->env);
+               ub_randfree(ctx->seed_rnd);
+               free(ctx);
+               errno = ENOMEM;
+               return NULL;
+       }
 
        ctx->env->alloc = &ctx->superalloc;
        ctx->env->worker = NULL;
@@ -388,6 +401,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
                config_delete(ctx->env->cfg);
                edns_known_options_delete(ctx->env);
                edns_strings_delete(ctx->env->edns_strings);
+               tsig_key_table_delete(ctx->env->tsig_key_table);
                forwards_delete(ctx->env->fwds);
                hints_delete(ctx->env->hints);
                auth_zones_delete(ctx->env->auth_zones);
index b1e767b3b2a71173fdae36d0b80d6ee34f45487e..89e8760ce7bf6a9a0905b228a4a9e6145113ac68 100644 (file)
@@ -222,6 +222,7 @@ config_create(void)
        cfg->stubs = NULL;
        cfg->forwards = NULL;
        cfg->auths = NULL;
+       cfg->tsig_keys = NULL;
 #ifdef CLIENT_SUBNET
        cfg->client_subnet = NULL;
        cfg->client_subnet_zone = NULL;
@@ -928,7 +929,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
                 * max-client-subnet-ipv4, max-client-subnet-ipv6,
                 * min-client-subnet-ipv4, min-client-subnet-ipv6,
                 * max-ecs-tree-size-ipv4, max-ecs-tree-size-ipv6, ipsecmod_hook,
-                * ipsecmod_whitelist. */
+                * ipsecmod_whitelist, tsig-key. */
                return 0;
        }
        return 1;
@@ -1433,6 +1434,7 @@ config_get_option(struct config_file* cfg, const char* opt,
         * local-data-ptr - converted to local-data entries
         * stub-zone, name, stub-addr, stub-host, stub-prime
         * forward-zone, name, forward-addr, forward-host
+        * tsig-key
         */
        else return 0;
        return 1;
@@ -1704,6 +1706,27 @@ config_delviews(struct config_view* p)
        }
 }
 
+void
+config_deltsig_key(struct config_tsig_key* p)
+{
+       if(!p) return;
+       free(p->name);
+       free(p->algorithm);
+       free(p->secret);
+       free(p);
+}
+
+void
+config_deltsig_keys(struct config_tsig_key* p)
+{
+       struct config_tsig_key* np;
+       while(p) {
+               np = p->next;
+               config_deltsig_key(p);
+               p = np;
+       }
+}
+
 void
 config_del_strarray(char** array, int num)
 {
@@ -1758,6 +1781,7 @@ config_delete(struct config_file* cfg)
        config_delstubs(cfg->forwards);
        config_delauths(cfg->auths);
        config_delviews(cfg->views);
+       config_deltsig_keys(cfg->tsig_keys);
        config_delstrlist(cfg->donotqueryaddrs);
        config_delstrlist(cfg->root_hints);
 #ifdef CLIENT_SUBNET
index 44ac036b88df9eaa074c984b2fb37ce415fdf506..9e631456128f1ca60bb961ffe62bf3778dfc195b 100644 (file)
@@ -45,6 +45,7 @@
 struct config_stub;
 struct config_auth;
 struct config_view;
+struct config_tsig_key;
 struct config_strlist;
 struct config_str2list;
 struct config_str3list;
@@ -260,6 +261,8 @@ struct config_file {
        struct config_auth* auths;
        /** the views definitions, linked list */
        struct config_view* views;
+       /** the tsig-key definitions, linked list */
+       struct config_tsig_key* tsig_keys;
        /** list of donotquery addresses, linked list */
        struct config_strlist* donotqueryaddrs;
 #ifdef CLIENT_SUBNET
@@ -904,6 +907,20 @@ struct config_view {
        struct config_str2list* respip_data;
 };
 
+/**
+ * Tsig-key config options
+ */
+struct config_tsig_key {
+       /** next in list */
+       struct config_tsig_key* next;
+       /** name of the tsig key */
+       char* name;
+       /** algorithm */
+       char* algorithm;
+       /** secret date, in base64 */
+       char* secret;
+};
+
 /**
  * List of strings for config options
  */
@@ -1216,6 +1233,18 @@ void config_delview(struct config_view* p);
  */
 void config_delviews(struct config_view* list);
 
+/**
+ * Delete a tsig_key item
+ * @param p: tsig_key item
+ */
+void config_deltsig_key(struct config_tsig_key* p);
+
+/**
+ * Delete items in config tsig_key list.
+ * @param list: list.
+ */
+void config_deltsig_keys(struct config_tsig_key* list);
+
 /** check if config for remote control turns on IP-address interface
  * with certificates or a named pipe without certificates. */
 int options_remote_is_address(struct config_file* cfg);
index bc258673d712c0e1e23b4d91cae635484dc71acb..d415e7a040eb8cd3b32b2fda00841331fc4d5039 100644 (file)
@@ -606,6 +606,9 @@ proxy-protocol-port{COLON}  { YDVAR(1, VAR_PROXY_PROTOCOL_PORT) }
 iter-scrub-ns{COLON}           { YDVAR(1, VAR_ITER_SCRUB_NS) }
 iter-scrub-cname{COLON}                { YDVAR(1, VAR_ITER_SCRUB_CNAME) }
 max-global-quota{COLON}                { YDVAR(1, VAR_MAX_GLOBAL_QUOTA) }
+tsig-key{COLON}                        { YDVAR(0, VAR_TSIG_KEY) }
+algorithm{COLON}               { YDVAR(1, VAR_ALGORITHM) }
+secret{COLON}                  { YDVAR(1, VAR_SECRET) }
 <INITIAL,val>{NEWLINE}         { LEXOUT(("NL\n")); cfg_parser->line++; }
 
        /* Quoted strings. Strip leading and ending quotes */
index ebb23f41cbd359044c4f94f7cc91389a2fb81f53..9638740c9b318b38ff2550924306a02d4479e32a 100644 (file)
@@ -47,7 +47,9 @@
 #include "util/configyyrename.h"
 #include "util/config_file.h"
 #include "util/net_help.h"
+#include "util/tsig.h"
 #include "sldns/str2wire.h"
+#include "sldns/parseutil.h"
 
 int ub_c_lex(void);
 void ub_c_error(const char *message);
@@ -215,6 +217,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED
 %token VAR_COOKIE_SECRET_FILE VAR_ITER_SCRUB_NS VAR_ITER_SCRUB_CNAME
 %token VAR_MAX_GLOBAL_QUOTA VAR_HARDEN_UNVERIFIED_GLUE VAR_LOG_TIME_ISO
+%token VAR_TSIG_KEY VAR_ALGORITHM VAR_SECRET
 
 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -223,7 +226,7 @@ toplevelvar: serverstart contents_server | stub_clause |
        rcstart contents_rc | dtstart contents_dt | view_clause |
        dnscstart contents_dnsc | cachedbstart contents_cachedb |
        ipsetstart contents_ipset | authstart contents_auth |
-       rpzstart contents_rpz | dynlibstart contents_dl |
+       rpzstart contents_rpz | dynlibstart contents_dl | tsig_key_clause |
        force_toplevel
        ;
 force_toplevel: VAR_FORCE_TOPLEVEL
@@ -3732,6 +3735,82 @@ dl_file: VAR_DYNLIB_FILE STRING_ARG
                        yyerror("out of memory");
        }
        ;
+tsig_key_clause: tsig_key_start contents_tsig_key
+       {
+               /* tsig-key end */
+               if(cfg_parser->cfg->tsig_keys) {
+                       if(!cfg_parser->cfg->tsig_keys->name)
+                               yyerror("tsig-key without name");
+                       else if(!cfg_parser->cfg->tsig_keys->algorithm)
+                               ub_c_error_msg("tsig-key %s has no algorithm",
+                                       cfg_parser->cfg->tsig_keys->name);
+                       else if(!cfg_parser->cfg->tsig_keys->secret)
+                               ub_c_error_msg("tsig-key %s has no secret blob",
+                                       cfg_parser->cfg->tsig_keys->name);
+               }
+       }
+       ;
+tsig_key_start: VAR_TSIG_KEY
+       {
+               struct config_tsig_key* s;
+               OUTYY(("\nP(tsig-key:)\n"));
+               cfg_parser->started_toplevel = 1;
+               s = (struct config_tsig_key*)calloc(1,
+                       sizeof(struct config_tsig_key));
+               if(s) {
+                       s->next = cfg_parser->cfg->tsig_keys;
+                       cfg_parser->cfg->tsig_keys = s;
+               } else {
+                       yyerror("out of memory");
+               }
+       }
+       ;
+contents_tsig_key: contents_tsig_key content_tsig_key
+       | ;
+content_tsig_key: tsig_key_name | tsig_key_algorithm | tsig_key_secret
+       ;
+tsig_key_name: VAR_NAME STRING_ARG
+       {
+               uint8_t buf[LDNS_MAX_DOMAINLEN+1];
+               size_t len = sizeof(buf);
+               int r;
+
+               OUTYY(("P(name:%s)\n", $2));
+               free(cfg_parser->cfg->tsig_keys->name);
+               cfg_parser->cfg->tsig_keys->name = $2;
+
+               if((r=sldns_str2wire_dname_buf($2, buf, &len))!=0)
+                       ub_c_error_msg("could not parse tsig key name"
+                               " '%s':%d: %s", $2, LDNS_WIREPARSE_OFFSET(r),
+                               sldns_get_errorstr_parse(r));
+       }
+tsig_key_algorithm: VAR_ALGORITHM STRING_ARG
+       {
+               OUTYY(("P(algorithm:%s)\n", $2));
+               free(cfg_parser->cfg->tsig_keys->algorithm);
+               cfg_parser->cfg->tsig_keys->algorithm = $2;
+               if(!tsig_algo_check_name($2))
+                       ub_c_error_msg("could not parse tsig key algorithm '%s'",
+                               $2);
+       }
+tsig_key_secret: VAR_SECRET STRING_ARG
+       {
+               uint8_t data[16384];
+               int size;
+
+               OUTYY(("P(secret:%s)\n", $2));
+               free(cfg_parser->cfg->tsig_keys->secret);
+               cfg_parser->cfg->tsig_keys->secret = $2;
+
+               size = sldns_b64_pton($2, data, sizeof(data));
+               if(size == -1) {
+                       ub_c_error_msg("cannot base64 decode tsig secret %s",
+                               cfg_parser->cfg->tsig_keys->name?
+                               cfg_parser->cfg->tsig_keys->name:"");
+               } else if(size != 0) {
+                       explicit_bzero(data, size);
+               }
+       }
 server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
        {
                OUTYY(("P(disable_dnssec_lame_check:%s)\n", $2));
index edce4a523759ee13085decd8a2a65887acc3cba6..aa7508ac2bef2ce285d3d87030967509d55189d2 100644 (file)
@@ -181,6 +181,7 @@ struct views;
 struct respip_set;
 struct respip_client_info;
 struct respip_addr_info;
+struct tsig_key_table;
 struct module_stack;
 
 /** Maximum number of modules in operation */
@@ -529,6 +530,8 @@ struct module_env {
        struct views* views;
        /** response-ip set with associated actions and tags. */
        struct respip_set* respip_set;
+       /** the TSIG keys */
+       struct tsig_key_table* tsig_key_table;
        /** module specific data. indexed by module id. */
        void* modinfo[MAX_MODULE];
 
index 81309699d993a8eeab2d9ede0b47c463e7e25aa1..79438adc02c161f594b581a1fbbd5d4eb163a887 100644 (file)
 
 #include "config.h"
 #include "util/tsig.h"
+#include "util/config_file.h"
 #include "util/log.h"
+#include "sldns/parseutil.h"
 #include "sldns/pkthdr.h"
 #include "sldns/rrdef.h"
 #include "sldns/sbuffer.h"
+#include "sldns/str2wire.h"
 #include "util/data/msgparse.h"
 #include "util/data/dname.h"
 #include <openssl/evp.h>
@@ -114,6 +117,95 @@ tsig_key_table_delete(struct tsig_key_table* key_table)
        free(key_table);
 }
 
+/** Create a tsig_key */
+static struct tsig_key*
+tsig_key_create(const char* name, const char* algorithm, const char* secret)
+{
+       struct tsig_key* key = (struct tsig_key*)calloc(1, sizeof(*key));
+       int ret;
+       if(!key) {
+               log_err("out of memory");
+               return NULL;
+       }
+       key->node.key = key;
+       key->name_str = strdup(name);
+       if(!key->name_str) {
+               log_err("out of memory");
+               tsig_key_delete(key);
+               return NULL;
+       }
+       key->algo = tsig_algo_find_name(algorithm);
+       if(!key->algo) {
+               log_err("tsig key %s could not parse algorithm '%s'",
+                       name, algorithm);
+               tsig_key_delete(key);
+               return NULL;
+       }
+       key->name = sldns_str2wire_dname(name, &key->name_len);
+       if(!key->name) {
+               log_err("tsig key %s could not parse name into wireformat",
+                       name);
+               tsig_key_delete(key);
+               return NULL;
+       }
+
+       key->data_len = sldns_b64_pton_calculate_size(strlen(secret));
+       if(key->data_len == 0)
+               key->data = NULL;
+       else    key->data = malloc(key->data_len);
+       if(!key->data) {
+               log_err("out of memory");
+               tsig_key_delete(key);
+               return NULL;
+       }
+       ret = sldns_b64_pton(secret, key->data, key->data_len);
+       if(ret == -1 || ret > (int)key->data_len) {
+               log_err("tsig key %s could not base64 decode secret blob",
+                       name);
+               tsig_key_delete(key);
+               return NULL;
+       }
+       key->data_len = ret;
+
+       return key;
+}
+
+/** Add a key to the TSIG key table. */
+static int
+tsig_key_table_add_key(struct tsig_key_table* key_table,
+       struct config_tsig_key* s)
+{
+       struct tsig_key* key;
+       key = tsig_key_create(s->name, s->algorithm, s->secret);
+       if(!key)
+               return 0;
+       /* Wipe the secret from config, it is in the key_table. */
+       if(s->secret[0] != 0)
+               explicit_bzero(s->secret, strlen(s->secret));
+
+       lock_rw_wrlock(&key_table->lock);
+       if(!rbtree_insert(key_table->tree, &key->node)) {
+               log_warn("duplicate tsig-key: %s", key->name_str);
+               lock_rw_unlock(&key_table->lock);
+               tsig_key_delete(key);
+               return 0;
+       }
+       lock_rw_unlock(&key_table->lock);
+       return 1;
+}
+
+int
+tsig_key_table_apply_cfg(struct tsig_key_table* key_table,
+       struct config_file* cfg)
+{
+       struct config_tsig_key* s;
+       for(s = cfg->tsig_keys; s; s = s->next) {
+               if(!tsig_key_table_add_key(key_table, s))
+                       return 0;
+       }
+       return 1;
+}
+
 void tsig_key_delete(struct tsig_key* key)
 {
        if(!key)
@@ -122,7 +214,8 @@ void tsig_key_delete(struct tsig_key* key)
        free(key->name);
        if(key->data) {
                /* The secret data is removed. */
-               explicit_bzero(key->data, key->data_len);
+               if(key->data_len > 0)
+                       explicit_bzero(key->data, key->data_len);
                free(key->data);
        }
        free(key);
index eb4391d758b990cf346997da12dc0dc508d077c1..b6ac605ddb83438bdd2a2b6c273e7304eddf8b9c 100644 (file)
@@ -44,6 +44,7 @@
 #include "util/locks.h"
 #include "util/rbtree.h"
 struct sldns_buffer;
+struct config_file;
 
 /**
  * TSIG record, the RR that is in the packet.
@@ -146,6 +147,15 @@ struct tsig_key_table* tsig_key_table_create(void);
  */
 void tsig_key_table_delete(struct tsig_key_table* key_table);
 
+/**
+ * Apply config to the tsig key table.
+ * @param key_table: the tsig key table.
+ * @param cfg: the config to read.
+ * @return false on failure.
+ */
+int tsig_key_table_apply_cfg(struct tsig_key_table* key_table,
+       struct config_file* cfg);
+
 /**
  * Delete TSIG key.
  * @param key: to delete