From: W.C.A. Wijngaards Date: Thu, 12 Jun 2025 14:05:10 +0000 (+0200) Subject: - xfr-tsig, key table. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d9242b3d36b42e5baae236548be459541832e24;p=thirdparty%2Funbound.git - xfr-tsig, key table. --- diff --git a/Makefile.in b/Makefile.in index de02a4e8e..f2efa5d2c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -970,7 +970,7 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ - $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ + $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tsig.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index c6f3ca24a..464ab0138 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -72,6 +72,7 @@ #include "libunbound/libworker.h" #include "libunbound/context.h" #include "libunbound/worker.h" +#include "util/tsig.h" #include "util/tube.h" #include "util/config_file.h" #include "daemon/remote.h" @@ -262,6 +263,7 @@ fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *)) else if(fptr == &auth_zone_cmp) return 1; else if(fptr == &auth_data_cmp) return 1; else if(fptr == &auth_xfer_cmp) return 1; + else if(fptr == &tsig_key_compare) return 1; #ifdef HAVE_NGTCP2 else if(fptr == &doq_conn_cmp) return 1; else if(fptr == &doq_conid_cmp) return 1; diff --git a/util/tsig.c b/util/tsig.c index 59ea4b671..bde331926 100644 --- a/util/tsig.c +++ b/util/tsig.c @@ -50,6 +50,69 @@ #include #include +int +tsig_key_compare(const void* v1, const void* v2) +{ + struct tsig_key* a = (struct tsig_key*)v1; + struct tsig_key* b = (struct tsig_key*)v2; + + return query_dname_compare(a->name, b->name); +} + +struct tsig_key_table* +tsig_key_table_create(void) +{ + struct tsig_key_table* key_table; + key_table = (struct tsig_key_table*)calloc(1, sizeof(*key_table)); + if(!key_table) + return NULL; + key_table->tree = rbtree_create(&tsig_key_compare); + if(!key_table->tree) { + free(key_table); + return NULL; + } + lock_rw_init(&key_table->lock); + lock_protect(&key_table->lock, key_table->tree, + sizeof(*key_table->tree)); + return key_table; +} + +/** Delete the tsig key table key. */ +static void +tsig_key_table_delete_key(rbnode_type* node, void* ATTR_UNUSED(arg)) +{ + struct tsig_key* key = (struct tsig_key*)node->key; + tsig_key_delete(key); +} + +void +tsig_key_table_delete(struct tsig_key_table* key_table) +{ + if(!key_table) + return; + lock_rw_destroy(&key_table->lock); + if(key_table->tree) { + traverse_postorder(key_table->tree, &tsig_key_table_delete_key, + NULL); + free(key_table->tree); + } + free(key_table); +} + +void tsig_key_delete(struct tsig_key* key) +{ + if(!key) + return; + free(key->name_str); + free(key->name); + if(key->data) { + /* The secret data is removed. */ + explicit_bzero(key->data, key->data_len); + free(key->data); + } + free(key); +} + /** * Skip packet query rr. * @param pkt: the packet, position before the rr, ends after the rr. diff --git a/util/tsig.h b/util/tsig.h index 21bb18878..4b49fa242 100644 --- a/util/tsig.h +++ b/util/tsig.h @@ -41,6 +41,8 @@ #ifndef UTIL_TSIG_H #define UTIL_TSIG_H +#include "util/locks.h" +#include "util/rbtree.h" struct sldns_buffer; /** @@ -95,10 +97,10 @@ struct tsig_algorithm { * TSIG key. This is used to sign and verify packets. */ struct tsig_key { + /** the rbtree node */ + rbnode_type node; /** name of the key as string */ char* name_str; - /** algorithm string */ - char* algo_str; /** the algorithm structure */ struct tsig_algorithm* algo; /** @@ -116,6 +118,35 @@ struct tsig_key { size_t data_len; }; +/** + * The TSIG key storage. Keys are stored by name. + * They are read from config. + */ +struct tsig_key_table { + /* Lock on the tsig key table and all keys. */ + lock_rw_type lock; + /* Tree of tsig keys, by wireformat name. */ + struct rbtree_type* tree; +}; + +/** + * Create TSIG key table. + * @return NULL on alloc failure. + */ +struct tsig_key_table* tsig_key_table_create(void); + +/** + * Delete TSIG key table. And the keys in it. + * @param key_table: to delete. + */ +void tsig_key_table_delete(struct tsig_key_table* key_table); + +/** + * Delete TSIG key. + * @param key: to delete + */ +void tsig_key_delete(struct tsig_key* key); + /** * Verify pkt with the name (domain name), algorithm and key. * out 0 on success, an error code otherwise. @@ -124,4 +155,7 @@ int tsig_verify(struct sldns_buffer* pkt, const uint8_t* name, const uint8_t* alg, const uint8_t* secret, size_t secret_len, uint64_t now); +/** Compare function for the key table keys. */ +int tsig_key_compare(const void* v1, const void* v2); + #endif /* UTIL_TSIG_H */