Commit 7d6f73df authored by Lubos Slovak's avatar Lubos Slovak
Browse files

Fixed changeset signing after UPDATE.

Was ignoring RRSIGs related to a RRSet that was completely removed.
This was a relict of old code when RRSIGs were connected to their
RRSets.

Also simplified the function
(and function sign_rr_should_be_signed()) and did some minor
refactoring and polishing.
parent 5cb4f333
......@@ -241,9 +241,8 @@ static bool node_should_be_signed_nsec3(const knot_node_t *n)
continue;
}
bool should_sign = false;
int ret = knot_zone_sign_rr_should_be_signed(n,
node_rrsets[i],
NULL, &should_sign);
int ret = knot_zone_sign_rr_should_be_signed(n, node_rrsets[i],
&should_sign);
assert(ret == KNOT_EOK); // No tree inside the function, no fail
if (should_sign) {
return true;
......
......@@ -196,8 +196,8 @@ int knot_dnssec_sign_changeset(const knot_zone_contents_t *zone,
// Init needed structures
knot_zone_keys_t zone_keys = { '\0' };
knot_dnssec_policy_t policy = { '\0' };
int ret = init_dnssec_structs(zone, zone_config, &zone_keys, &policy, soa_up,
false);
int ret = init_dnssec_structs(zone, zone_config, &zone_keys, &policy,
soa_up, false);
if (ret != KNOT_EOK) {
return ret;
}
......
......@@ -350,16 +350,16 @@ static int add_missing_rrsigs(const knot_rrset_t *covered,
*
* \return Error code, KNOT_EOK if successful.
*/
static int remove_rrset_rrsigs(const knot_rrset_t *rrset,
static int remove_rrset_rrsigs(const knot_dname_t *owner, uint16_t type,
const knot_rrset_t *rrsigs,
knot_changeset_t *changeset)
{
assert(rrset);
assert(owner);
assert(changeset);
knot_rrset_t *synth_rrsig = NULL;
int ret = knot_rrset_synth_rrsig(rrset->owner, rrset->type,
rrsigs, &synth_rrsig, NULL);
int ret = knot_rrset_synth_rrsig(owner, type, rrsigs, &synth_rrsig,
NULL);
if (ret != KNOT_EOK) {
if (ret != KNOT_ENOENT) {
return ret;
......@@ -367,7 +367,8 @@ static int remove_rrset_rrsigs(const knot_rrset_t *rrset,
return KNOT_EOK;
}
ret = knot_changeset_add_rrset(changeset, synth_rrsig, KNOT_CHANGESET_REMOVE);
ret = knot_changeset_add_rrset(changeset, synth_rrsig,
KNOT_CHANGESET_REMOVE);
if (ret != KNOT_EOK) {
knot_rrset_deep_free(&synth_rrsig, true, NULL);
}
......@@ -394,7 +395,8 @@ static int force_resign_rrset(const knot_rrset_t *covered,
assert(covered);
if (rrsigs) {
int result = remove_rrset_rrsigs(covered, rrsigs, changeset);
int result = remove_rrset_rrsigs(covered->owner, covered->type,
rrsigs, changeset);
if (result != KNOT_EOK) {
return result;
}
......@@ -501,7 +503,7 @@ static int sign_node_rrsets(const knot_node_t *node,
continue;
}
bool should_sign = false;
result = knot_zone_sign_rr_should_be_signed(node, rrset, NULL,
result = knot_zone_sign_rr_should_be_signed(node, rrset,
&should_sign);
if (result != KNOT_EOK) {
return result;
......@@ -955,7 +957,8 @@ static int update_dnskeys_rrsigs(const knot_rrset_t *dnskeys,
}
if (dnskeys) {
result = remove_rrset_rrsigs(dnskeys, rrsigs, changeset);
result = remove_rrset_rrsigs(dnskeys->owner, dnskeys->type,
rrsigs, changeset);
}
fail:
......@@ -1152,48 +1155,65 @@ static int rr_already_signed(const knot_rrset_t *rrset, hattrie_t *t,
static int sign_changeset_wrap(knot_rrset_t *chg_rrset, void *data)
{
changeset_signing_data_t *args = (changeset_signing_data_t *)data;
bool rr_signed = false;
// Find RR's node in zone, find out if we need to sign this RR
const knot_node_t *node =
knot_zone_contents_find_node(args->zone, chg_rrset->owner);
// If node is not in zone, all its RRSIGs were dropped - no-op
if (node) {
const knot_rrset_t *rrsigs = knot_node_rrset(node, KNOT_RRTYPE_RRSIG);
const knot_rrset_t *rrsigs = knot_node_rrset(node,
KNOT_RRTYPE_RRSIG);
const knot_rrset_t *zone_rrset =
knot_node_rrset(node, chg_rrset->type);
bool should_sign = false;
int ret = knot_zone_sign_rr_should_be_signed(node, zone_rrset,
args->signed_tree,
&should_sign);
if (ret != KNOT_EOK) {
return ret;
}
// Check for RRSet in the 'already_signed' table
/*!
* \todo Describe why it this here and what it does.
*/
if (args->signed_tree && (should_sign && zone_rrset == NULL)) {
bool already_signed = false;
int ret = rr_already_signed(chg_rrset, args->signed_tree,
&already_signed);
if (ret != KNOT_EOK) {
return ret;
}
if (already_signed) {
/* Do not sign again. */
should_sign = false;
}
}
if (should_sign) {
return force_resign_rrset(zone_rrset, rrsigs, args->zone_keys,
return force_resign_rrset(zone_rrset, rrsigs,
args->zone_keys,
args->policy,
args->changeset);
} else if (zone_rrset && knot_node_rrtype_is_signed(node, zone_rrset->type)) {
/*!
} else {
/*
* If RRSet in zone DOES have RRSIGs although we
* should not sign it, DDNS-caused change to node/rr
* occured and we have to drop all RRSIGs.
*
* OR
*
* The whole RRSet was removed, but RRSIGs remained in
* the zone. Also we need to drop them.
*/
return remove_rrset_rrsigs(zone_rrset, rrsigs, args->changeset);
} else {
/*!
* RRSet dropped from zone using update, or should not
* be signed, but it could create a new node, so we
* have to mark the change.
*/
int ret = rr_already_signed(chg_rrset,
args->signed_tree,
&rr_signed);
if (ret != KNOT_EOK) {
return ret;
}
return remove_rrset_rrsigs(chg_rrset->owner,
chg_rrset->type, rrsigs,
args->changeset);
}
} else {
// Update changes
bool rr_signed = false; // Placeholder
int ret = rr_already_signed(chg_rrset, args->signed_tree,
&rr_signed);
if (ret != KNOT_EOK) {
......@@ -1320,7 +1340,8 @@ int knot_zone_sign_update_soa(const knot_rrset_t *soa,
// remove signatures for old SOA (if there are any)
if (rrsigs) {
result = remove_rrset_rrsigs(soa, rrsigs, changeset);
result = remove_rrset_rrsigs(soa->owner, soa->type, rrsigs,
changeset);
if (result != KNOT_EOK) {
return result;
}
......@@ -1435,7 +1456,7 @@ int knot_zone_sign_nsecs_in_changeset(const knot_zone_keys_t *zone_keys,
*/
int knot_zone_sign_rr_should_be_signed(const knot_node_t *node,
const knot_rrset_t *rrset,
hattrie_t *tree, bool *should_sign)
bool *should_sign)
{
if (should_sign == NULL) {
return KNOT_EINVAL;
......@@ -1476,18 +1497,6 @@ int knot_zone_sign_rr_should_be_signed(const knot_node_t *node,
return KNOT_EOK;
}
// Check for RRSet in the 'already_signed' table
if (tree) {
bool already_signed = false;
int ret = rr_already_signed(rrset, tree, &already_signed);
if (ret != KNOT_EOK) {
return ret;
}
if (already_signed) {
return KNOT_EOK;
}
}
*should_sign = true;
return KNOT_EOK;
}
......
......@@ -139,7 +139,7 @@ int knot_zone_sign_nsecs_in_changeset(const knot_zone_keys_t *zone_keys,
*/
int knot_zone_sign_rr_should_be_signed(const knot_node_t *node,
const knot_rrset_t *rrset,
hattrie_t *trie, bool *should_sign);
bool *should_sign);
void knot_zone_clear_sorted_changes(hattrie_t *t);
......
......@@ -1188,9 +1188,6 @@ static int knot_ddns_process_rem_rr(const knot_rrset_t *rr,
* use the RRSet from the packet for this - copy it, set CLASS
* and TTL.
*
* Special handling of RRSIGs is required in that the RRSet containing
* them must be copied as well. However, copying of RRSet copies also
* the RRSIGs, so copying the base RRSet is enough for both cases!
*/
assert(type != KNOT_RRTYPE_SOA);
......
......@@ -1524,10 +1524,8 @@ static int add_rdata_to_rrsig(knot_rrset_t *new_sig, uint16_t type,
const uint16_t type_covered =
knot_rdata_rrsig_type_covered(rrsigs, i);
if (type_covered == type) {
int ret = knot_rrset_add_rr_from_rrset(new_sig,
rrsigs,
i,
mm);
int ret = knot_rrset_add_rr_from_rrset(new_sig, rrsigs,
i, mm);
if (ret != KNOT_EOK) {
return ret;
}
......
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