mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-18 18:25:10 -05:00
- xfr-tsig, check that tsig keys exist at startup and in unbound-checkconf.
This commit is contained in:
parent
3b88577dd1
commit
b1bb4a4592
9 changed files with 85 additions and 14 deletions
|
|
@ -961,7 +961,7 @@ authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/service
|
|||
$(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)/daemon/stats.h \
|
||||
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \
|
||||
$(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/tsig.h \
|
||||
$(srcdir)/services/cache/dns.h $(srcdir)/services/outside_network.h \
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
|
||||
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h $(srcdir)/validator/val_nsec3.h \
|
||||
|
|
@ -1483,7 +1483,7 @@ memstats.lo memstats.o: $(srcdir)/testcode/memstats.c config.h $(srcdir)/util/lo
|
|||
unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c config.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.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/net_help.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/tsig.h \
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/localzone.h \
|
||||
|
|
|
|||
|
|
@ -792,7 +792,8 @@ daemon_fork(struct daemon* daemon)
|
|||
|
||||
/* read auth zonefiles */
|
||||
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
|
||||
&daemon->use_rpz, daemon->env, &daemon->mods))
|
||||
&daemon->use_rpz, daemon->env, &daemon->mods,
|
||||
daemon->env->tsig_key_table))
|
||||
fatal_exit("auth_zones could not be setup");
|
||||
|
||||
/* Set-up EDNS strings */
|
||||
|
|
|
|||
|
|
@ -5159,7 +5159,8 @@ fr_construct_from_config(struct fast_reload_thread* fr,
|
|||
return 0;
|
||||
}
|
||||
if(!auth_zones_apply_cfg(ct->auth_zones, newcfg, 1, &ct->use_rpz,
|
||||
fr->worker->daemon->env, &fr->worker->daemon->mods)) {
|
||||
fr->worker->daemon->env, &fr->worker->daemon->mods,
|
||||
fr->worker->daemon->env->tsig_key_table)) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ context_finalize(struct ub_ctx* ctx)
|
|||
if(!local_zones_apply_cfg(ctx->local_zones, cfg))
|
||||
return UB_INITFAIL;
|
||||
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz,
|
||||
ctx->env, &ctx->mods))
|
||||
ctx->env, &ctx->mods, ctx->env->tsig_key_table))
|
||||
return UB_INITFAIL;
|
||||
if(!(ctx->env->fwds = forwards_create()) ||
|
||||
!forwards_apply_cfg(ctx->env->fwds, cfg))
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "util/log.h"
|
||||
#include "util/module.h"
|
||||
#include "util/random.h"
|
||||
#include "util/tsig.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
|
|
@ -2091,7 +2092,8 @@ auth_zones_setup_zones(struct auth_zones* az)
|
|||
|
||||
/** set config items and create zones */
|
||||
static int
|
||||
auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
||||
auth_zones_cfg(struct auth_zones* az, struct config_auth* c,
|
||||
struct tsig_key_table* tsig_key_table)
|
||||
{
|
||||
struct auth_zone* z;
|
||||
struct auth_xfer* x = NULL;
|
||||
|
|
@ -2171,12 +2173,14 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
|||
if(x) {
|
||||
z->zone_is_slave = 1;
|
||||
/* set options on xfer zone */
|
||||
if(!xfer_set_masters(&x->task_probe->masters, c, 0)) {
|
||||
if(!xfer_set_masters(&x->task_probe->masters, c, 0,
|
||||
tsig_key_table)) {
|
||||
lock_basic_unlock(&x->lock);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
if(!xfer_set_masters(&x->task_transfer->masters, c, 1)) {
|
||||
if(!xfer_set_masters(&x->task_transfer->masters, c, 1,
|
||||
tsig_key_table)) {
|
||||
lock_basic_unlock(&x->lock);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
|
|
@ -2244,7 +2248,7 @@ az_delete_deleted_zones(struct auth_zones* az)
|
|||
|
||||
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
int setup, int* is_rpz, struct module_env* env,
|
||||
struct module_stack* mods)
|
||||
struct module_stack* mods, struct tsig_key_table* tsig_key_table)
|
||||
{
|
||||
struct config_auth* p;
|
||||
az_setall_deleted(az);
|
||||
|
|
@ -2254,7 +2258,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
|||
continue;
|
||||
}
|
||||
*is_rpz = (*is_rpz || p->isrpz);
|
||||
if(!auth_zones_cfg(az, p)) {
|
||||
if(!auth_zones_cfg(az, p, tsig_key_table)) {
|
||||
log_err("cannot config auth zone %s", p->name);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -7284,9 +7288,30 @@ parse_url(char* url, char** host, char** file, int* port, int* ssl)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** Check the tsig key exists */
|
||||
static int
|
||||
check_tsig_key_exists(struct tsig_key_table* tsig_key_table,
|
||||
const char* optname, char* str, char* str2)
|
||||
{
|
||||
struct tsig_key* key;
|
||||
if(!tsig_key_table)
|
||||
return 1;
|
||||
|
||||
lock_rw_rdlock(&tsig_key_table->lock);
|
||||
key = tsig_key_table_search_fromstr(tsig_key_table, str2);
|
||||
lock_rw_unlock(&tsig_key_table->lock);
|
||||
|
||||
if(!key) {
|
||||
log_err("could not find tsig-key for %s: %s %s",
|
||||
optname, str, str2);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
int with_http)
|
||||
int with_http, struct tsig_key_table* tsig_key_table)
|
||||
{
|
||||
struct auth_master* m;
|
||||
struct config_strlist* p;
|
||||
|
|
@ -7322,6 +7347,9 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
|||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
if(!check_tsig_key_exists(tsig_key_table, "primary-tsig",
|
||||
p2->str, p2->str2))
|
||||
return 0;
|
||||
m->tsig_key_name = strdup(p2->str2);
|
||||
if(!m->tsig_key_name) {
|
||||
log_err("malloc failure");
|
||||
|
|
@ -7347,6 +7375,9 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
|||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
if(!check_tsig_key_exists(tsig_key_table, "allow-notify-tsig",
|
||||
p2->str, p2->str2))
|
||||
return 0;
|
||||
m->tsig_key_name = strdup(p2->str2);
|
||||
if(!m->tsig_key_name) {
|
||||
log_err("malloc failure");
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct query_info;
|
|||
struct dns_msg;
|
||||
struct edns_data;
|
||||
struct module_env;
|
||||
struct tsig_key_table;
|
||||
struct worker;
|
||||
struct comm_point;
|
||||
struct comm_timer;
|
||||
|
|
@ -488,11 +489,13 @@ struct auth_zones* auth_zones_create(void);
|
|||
* @param is_rpz: set to 1 if at least one RPZ zone is configured.
|
||||
* @param env: environment for offline verification.
|
||||
* @param mods: modules in environment.
|
||||
* @param tsig_key_table: tsig key table to check if tsig keys exist.
|
||||
* If NULL, no check is performed.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
int setup, int* is_rpz, struct module_env* env,
|
||||
struct module_stack* mods);
|
||||
struct module_stack* mods, struct tsig_key_table* tsig_key_table);
|
||||
|
||||
/** initial pick up of worker timeouts, ties events to worker event loop
|
||||
* @param az: auth zones structure
|
||||
|
|
@ -669,10 +672,12 @@ struct auth_xfer* auth_xfer_create(struct auth_zones* az, struct auth_zone* z);
|
|||
* @param list: pointer to start of list. The malloced list is returned here.
|
||||
* @param c: the config items to copy over.
|
||||
* @param with_http: if true, http urls are also included, before the masters.
|
||||
* @param tsig_key_table: if nonNULL, used to check that tsig keys exist in
|
||||
* the key table.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
int with_http);
|
||||
int with_http, struct tsig_key_table* tsig_key_table);
|
||||
|
||||
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
|
||||
void auth_xfer_timer(void* arg);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/tsig.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
|
|
@ -1003,13 +1004,23 @@ static void
|
|||
check_auth(struct config_file* cfg)
|
||||
{
|
||||
int is_rpz = 0;
|
||||
struct tsig_key_table* tsig_key_table;
|
||||
struct auth_zones* az = auth_zones_create();
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL)) {
|
||||
|
||||
/* construct tsig key table for tsig key name checks, and it
|
||||
* also checks the TSIG key name and algorithm and base64 syntax. */
|
||||
tsig_key_table = tsig_key_table_create();
|
||||
if(!tsig_key_table || !tsig_key_table_apply_cfg(tsig_key_table, cfg))
|
||||
fatal_exit("Could not set up TSIG keys");
|
||||
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL,
|
||||
tsig_key_table)) {
|
||||
fatal_exit("Could not setup authority zones");
|
||||
}
|
||||
if(is_rpz && !strstr(cfg->module_conf, "respip"))
|
||||
fatal_exit("RPZ requires the respip module");
|
||||
auth_zones_delete(az);
|
||||
tsig_key_table_delete(tsig_key_table);
|
||||
}
|
||||
|
||||
/** check config file */
|
||||
|
|
|
|||
12
util/tsig.c
12
util/tsig.c
|
|
@ -252,6 +252,18 @@ tsig_key_table_search(struct tsig_key_table* key_table, uint8_t* name,
|
|||
return (struct tsig_key*)node->key;
|
||||
}
|
||||
|
||||
struct tsig_key*
|
||||
tsig_key_table_search_fromstr(struct tsig_key_table* key_table, char* name)
|
||||
{
|
||||
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
|
||||
size_t len = sizeof(buf);
|
||||
if(sldns_str2wire_dname_buf(name, buf, &len) != 0) {
|
||||
log_err("could not parse '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
return tsig_key_table_search(key_table, buf, len);
|
||||
}
|
||||
|
||||
void tsig_key_delete(struct tsig_key* key)
|
||||
{
|
||||
if(!key)
|
||||
|
|
|
|||
10
util/tsig.h
10
util/tsig.h
|
|
@ -217,6 +217,16 @@ int tsig_key_table_apply_cfg(struct tsig_key_table* key_table,
|
|||
struct tsig_key* tsig_key_table_search(struct tsig_key_table* key_table,
|
||||
uint8_t* name, size_t namelen);
|
||||
|
||||
/**
|
||||
* Find key in key table. Caller must hold lock on the table.
|
||||
* @param key_table: the tsig key table.
|
||||
* @param name: the name in string format, it is parsed to wireformat.
|
||||
* @return the found key or NULL if not found or NULL on parse error of the
|
||||
* key name as a domain name. The item is locked by the key_table lock.
|
||||
*/
|
||||
struct tsig_key* tsig_key_table_search_fromstr(
|
||||
struct tsig_key_table* key_table, char* name);
|
||||
|
||||
/**
|
||||
* Delete TSIG key.
|
||||
* @param key: to delete
|
||||
|
|
|
|||
Loading…
Reference in a new issue