Commit 33b2de00 authored by Libor Peltan's avatar Libor Peltan Committed by Daniel Salzman
Browse files

dnssec/sharedKSK: fix creating new KSK if policylast is dangling

parent 5004ea79
......@@ -457,12 +457,7 @@ int kasp_db_get_policy_last(knot_lmdb_db_t *db, const char *policy_string,
}
knot_lmdb_abort(&txn);
free(k.mv_data);
if (txn.ret != KNOT_EOK) {
free(*lp_zone);
*lp_zone = NULL;
free(*lp_keyid);
*lp_keyid = NULL;
}
return txn.ret;
}
......
......@@ -186,6 +186,8 @@ int kasp_db_load_serial(knot_lmdb_db_t *db, const knot_dname_t *zone_name,
* \param lp_zone out: the zone owning the last generated key
* \param lp_keyid out: the ID of the last generated key
*
* \note lp_zone and lp_keyid must be freed even when an error is returned
*
* \return KNOT_E*
*/
int kasp_db_get_policy_last(knot_lmdb_db_t *db, const char *policy_string,
......
......@@ -124,6 +124,8 @@ static int share_or_generate_key(kdnssec_ctx_t *ctx, kdnssec_generate_flags_t fl
int ret = kasp_db_get_policy_last(ctx->kasp_db, ctx->policy->string,
&borrow_zone, &borrow_key);
if (ret != KNOT_EOK && ret != KNOT_ENOENT) {
free(borrow_zone);
free(borrow_key);
return ret;
}
......
......@@ -251,6 +251,7 @@ int keymgr_generate_key(kdnssec_ctx_t *ctx, int argc, char *argv[])
&last_policy_last);
knot_dname_free(unused, NULL);
if (ret != KNOT_EOK && ret != KNOT_ENOENT) {
free(last_policy_last);
return ret;
}
......
......@@ -5,37 +5,74 @@ Test shared KSK among zones.
from dnstest.utils import *
from dnstest.test import Test
def add_shared(test, server, zones, refzone):
test.link(zones, server)
for z in zones:
server.dnssec(z).enable = True
knot.dnssec(z).ksk_shared = True
knot.dnssec(z).shared_policy_with = refzone.name
def query_ksk(server, zone): # returns KSK hash
resp = server.dig(zone.name, "DNSKEY")
resp.check(rcode="NOERROR")
resp.check_count(2, rtype="DNSKEY")
for rr in resp.resp.answer[0].to_rdataset():
fields = rr.to_text().split()
if fields[0] == "257":
return fields[3]
return "error"
t = Test()
def check_ksks(server, zones, refzone):
server.zones_wait(zones)
server.flush(wait=True)
shared_ksk = query_ksk(server, refzone)
for z in zones:
z_ksk = query_ksk(server, z)
if z_ksk != shared_ksk:
set_err("KSK NOT SHARED (%s versus %s)" % (z.name, refzone.name))
detail_log("KSK NOT SHARED (%s versus %s)" % (z.name, refzone.name))
knot.zone_verify(z)
t = Test()
knot = t.server("knot")
zones = t.zone_rnd(5, dnssec=False, records=10)
t.link(zones, knot)
for z in zones:
knot.dnssec(z).enable = True
knot.dnssec(z).ksk_shared = True
knot.dnssec(z).shared_policy_with = zones[0].name
# testcase 1: shared policy
zones0 = t.zone_rnd(5, dnssec=False, records=10)
add_shared(t, knot, zones0, zones0[0])
t.start()
knot.zones_wait(zones)
knot.flush(wait=True)
check_ksks(knot, zones0, zones0[1])
# testcase 2: adding zones to shared policy
zones_add1 = t.zone_rnd(5, dnssec=False, records=10)
add_shared(t, knot, zones_add1, zones0[0])
knot.gen_confile()
knot.reload()
check_ksks(knot, zones0 + zones_add1, zones0[1])
# testcase 3: adding zones to damaged shared policy .. generate new KSK and continue
# now purge zones keys in order to create dangling policy_last
for z in zones0:
knot.ctl("zone-purge -f +kaspdb " + z.name)
shared_ksk = query_ksk(knot, zones[1])
zones_add2 = t.zone_rnd(5, dnssec=False, records=10)
add_shared(t, knot, zones_add2, zones0[0])
for z in zones:
z_ksk = query_ksk(knot, z)
if z_ksk != shared_ksk:
set_err("KSK NOT SHARED (%s versus %s)" % (z.name, zones[1].name))
knot.gen_confile()
knot.reload()
check_ksks(knot, zones_add1, zones_add1[1])
check_ksks(knot, zones_add2, zones_add2[1])
knot.zone_verify(z)
add1_ksk = query_ksk(knot, zones_add1[1])
add2_ksk = query_ksk(knot, zones_add2[1])
if add1_ksk == add2_ksk:
set_err("KSK NOT DIFFERENT (%s versus %s)" % (zones_add1[1].name, zones_add2[1].name))
t.end()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment