Commit b4d78091 authored by Marek Vavrusa's avatar Marek Vavrusa
Browse files

dnssec: zone signing changed to accept contents and zone configuration

Old API required to create duplicate fake zone with switched contents.
parent b8fc04e0
......@@ -27,7 +27,8 @@
#include "libknot/util/debug.h"
#include "knot/zone/zone.h"
static int init_dnssec_structs(const zone_t *zone,
static int init_dnssec_structs(const knot_zone_contents_t *zone,
conf_zone_t *config,
knot_zone_keys_t *zone_keys,
knot_dnssec_policy_t *policy,
knot_update_serial_t soa_up, bool force)
......@@ -35,17 +36,15 @@ static int init_dnssec_structs(const zone_t *zone,
assert(zone);
assert(zone_keys);
assert(policy);
conf_zone_t *config = zone->conf;
assert(config);
// Read zone keys from disk
bool nsec3_enabled = knot_is_nsec3_enabled(zone->contents);
bool nsec3_enabled = knot_is_nsec3_enabled(zone);
int result = knot_load_zone_keys(config->dnssec_keydir,
zone->contents->apex->owner,
zone->apex->owner,
nsec3_enabled, zone_keys);
if (result != KNOT_EOK) {
char *zname = knot_dname_to_str(zone->name);
char *zname = knot_dname_to_str(zone->apex->owner);
log_zone_error("DNSSEC: Zone %s - %s\n", zname,
knot_strerror(result));
free(zname);
......@@ -66,17 +65,15 @@ static int init_dnssec_structs(const zone_t *zone,
return KNOT_EOK;
}
static int zone_sign(zone_t *zone, knot_changeset_t *out_ch, bool force,
static int zone_sign(knot_zone_contents_t *zone, conf_zone_t *zone_config,
knot_changeset_t *out_ch, bool force,
knot_update_serial_t soa_up, uint32_t *refresh_at,
uint32_t new_serial)
{
assert(zone);
assert(zone->contents);
assert(out_ch);
char *zname = knot_dname_to_str(zone->name);
char *msgpref = sprintf_alloc("DNSSEC: Zone %s -", zname);
free(zname);
char *msgpref = sprintf_alloc("DNSSEC: Zone %s -", zone_config->name);
if (msgpref == NULL) {
return KNOT_ENOMEM;
}
......@@ -84,16 +81,10 @@ static int zone_sign(zone_t *zone, knot_changeset_t *out_ch, bool force,
dbg_dnssec_verb("Changeset empty before generating NSEC chain: %d\n",
knot_changeset_is_empty(out_ch));
if (!zone->conf->dnssec_enable) {
log_zone_warning("%s DNSSEC not enabled.\n", msgpref);
free(msgpref);
return KNOT_EOK;
}
// Init needed structs
knot_zone_keys_t zone_keys = { '\0' };
knot_dnssec_policy_t policy = { '\0' };
int result = init_dnssec_structs(zone, &zone_keys, &policy, soa_up,
int result = init_dnssec_structs(zone, zone_config, &zone_keys, &policy, soa_up,
force);
if (result != KNOT_EOK) {
free(msgpref);
......@@ -101,7 +92,7 @@ static int zone_sign(zone_t *zone, knot_changeset_t *out_ch, bool force,
}
// generate NSEC records
result = knot_zone_create_nsec_chain(zone->contents, out_ch,
result = knot_zone_create_nsec_chain(zone, out_ch,
&zone_keys, &policy);
if (result != KNOT_EOK) {
log_zone_error("%s Could not create NSEC(3) chain (%s).\n",
......@@ -114,7 +105,7 @@ static int zone_sign(zone_t *zone, knot_changeset_t *out_ch, bool force,
knot_changeset_is_empty(out_ch));
// add missing signatures
result = knot_zone_sign(zone->contents, &zone_keys, &policy, out_ch,
result = knot_zone_sign(zone, &zone_keys, &policy, out_ch,
refresh_at);
if (result != KNOT_EOK) {
log_zone_error("%s Error while signing (%s).\n",
......@@ -128,7 +119,7 @@ static int zone_sign(zone_t *zone, knot_changeset_t *out_ch, bool force,
// Check if only SOA changed
if (knot_changeset_is_empty(out_ch) &&
!knot_zone_sign_soa_expired(zone->contents, &zone_keys, &policy)) {
!knot_zone_sign_soa_expired(zone, &zone_keys, &policy)) {
log_zone_info("%s No signing performed, zone is valid.\n",
msgpref);
free(msgpref);
......@@ -138,7 +129,7 @@ static int zone_sign(zone_t *zone, knot_changeset_t *out_ch, bool force,
}
// update SOA if there were any changes
const knot_rrset_t *soa = knot_node_rrset(zone->contents->apex,
const knot_rrset_t *soa = knot_node_rrset(zone->apex,
KNOT_RRTYPE_SOA);
assert(soa);
result = knot_zone_sign_update_soa(soa, &zone_keys, &policy,
......@@ -159,30 +150,32 @@ static int zone_sign(zone_t *zone, knot_changeset_t *out_ch, bool force,
return KNOT_EOK;
}
int knot_dnssec_zone_sign(zone_t *zone, knot_changeset_t *out_ch,
int knot_dnssec_zone_sign(knot_zone_contents_t *zone, conf_zone_t *zone_config,
knot_changeset_t *out_ch,
knot_update_serial_t soa_up, uint32_t *refresh_at,
uint32_t new_serial)
{
if (zone == NULL || zone->contents == NULL || out_ch == NULL) {
if (zone == NULL || zone_config == NULL || out_ch == NULL) {
return KNOT_EINVAL;
}
return zone_sign(zone, out_ch, false, soa_up, refresh_at, new_serial);
return zone_sign(zone, zone_config, out_ch, false, soa_up, refresh_at, new_serial);
}
int knot_dnssec_zone_sign_force(zone_t *zone,
int knot_dnssec_zone_sign_force(knot_zone_contents_t *zone, conf_zone_t *zone_config,
knot_changeset_t *out_ch, uint32_t *refresh_at,
uint32_t new_serial)
{
if (zone == NULL || zone->contents == NULL || out_ch == NULL) {
if (zone == NULL || zone_config == NULL || out_ch == NULL) {
return KNOT_EINVAL;
}
return zone_sign(zone, out_ch, true, KNOT_SOA_SERIAL_UPDATE, refresh_at,
return zone_sign(zone, zone_config, out_ch, true, KNOT_SOA_SERIAL_UPDATE, refresh_at,
new_serial);
}
int knot_dnssec_sign_changeset(const zone_t *zone,
int knot_dnssec_sign_changeset(const knot_zone_contents_t *zone,
conf_zone_t *zone_config,
const knot_changeset_t *in_ch,
knot_changeset_t *out_ch,
knot_update_serial_t soa_up,
......@@ -194,10 +187,6 @@ int knot_dnssec_sign_changeset(const zone_t *zone,
return KNOT_EINVAL;
}
if (!conf()->dnssec_enable) {
return KNOT_EOK;
}
if (zone == NULL || in_ch == NULL || out_ch == NULL) {
return KNOT_EINVAL;
}
......@@ -205,13 +194,13 @@ int knot_dnssec_sign_changeset(const zone_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_keys, &policy, soa_up,
int ret = init_dnssec_structs(zone, zone_config, &zone_keys, &policy, soa_up,
false);
if (ret != KNOT_EOK) {
return ret;
}
char *zname = knot_dname_to_str(zone->name);
char *zname = knot_dname_to_str(zone->apex->owner);
char *msgpref = sprintf_alloc("DNSSEC: Zone %s -", zname);
free(zname);
if (msgpref == NULL) {
......@@ -231,7 +220,7 @@ int knot_dnssec_sign_changeset(const zone_t *zone,
assert(sorted_changes);
// Fix NSEC(3) chain
ret = knot_zone_fix_nsec_chain(zone->contents,
ret = knot_zone_fix_nsec_chain(zone,
*sorted_changes, out_ch,
&zone_keys, &policy);
if (ret != KNOT_EOK) {
......@@ -254,7 +243,7 @@ int knot_dnssec_sign_changeset(const zone_t *zone,
}
// Update SOA RRSIGs
ret = knot_zone_sign_update_soa(knot_node_rrset(zone->contents->apex,
ret = knot_zone_sign_update_soa(knot_node_rrset(zone->apex,
KNOT_RRTYPE_SOA),
&zone_keys, &policy, new_serial,
out_ch);
......
......@@ -35,14 +35,17 @@
* \brief DNSSEC resign zone, store new records into changeset. Valid signatures
* and NSEC(3) records will not be changed.
*
* \param zone Zone to be signed.
* \param zone Zone contents to be signed.
* \param zone_config Zone/DNSSEC configuration.
* \param out_ch New records will be added to this changeset.
* \param soa_up SOA serial update policy.
* \param refresh_at Signature refresh time of the oldest signature in zone.
* \param new_serial
*
* \return Error code, KNOT_EOK if successful.
*/
int knot_dnssec_zone_sign(zone_t *zone, knot_changeset_t *out_ch,
int knot_dnssec_zone_sign(knot_zone_contents_t *zone, conf_zone_t *zone_config,
knot_changeset_t *out_ch,
knot_update_serial_t soa_up, uint32_t *refresh_at,
uint32_t new_serial);
......@@ -50,19 +53,23 @@ int knot_dnssec_zone_sign(zone_t *zone, knot_changeset_t *out_ch,
* \brief DNSSEC sign zone, store new records into changeset. Even valid
* signatures will be dropped.
*
* \param zone Zone to be signed.
* \param zone Zone contents to be signed.
* \param zone_config Zone/DNSSEC configuration.
* \param out_ch New records will be added to this changeset.
* \param expires_at Signature refresh time of the oldest signature in zone.
* \param refresh_at Signature refresh time of the oldest signature in zone.
* \param new_serial
*
* \return Error code, KNOT_EOK if successful.
*/
int knot_dnssec_zone_sign_force(zone_t *zone, knot_changeset_t *out_ch,
int knot_dnssec_zone_sign_force(knot_zone_contents_t *zone, conf_zone_t *zone_config,
knot_changeset_t *out_ch,
uint32_t *refresh_at, uint32_t new_serial);
/*!
* \brief Sign changeset created by DDNS or zone-diff.
*
* \param zone Updated zone (AFTER DDNS has been applied to it).
* \param zone Zone contents to be signed.
* \param zone_config Zone/DNSSEC configuration.
* \param in_ch Changeset created bvy DDNS or zone-diff
* \param out_ch New records will be added to this changeset.
* \param soa_up SOA serial update policy.
......@@ -72,7 +79,8 @@ int knot_dnssec_zone_sign_force(zone_t *zone, knot_changeset_t *out_ch,
*
* \return Error code, KNOT_EOK if successful.
*/
int knot_dnssec_sign_changeset(const zone_t *zone,
int knot_dnssec_sign_changeset(const knot_zone_contents_t *zone,
conf_zone_t *zone_config,
const knot_changeset_t *in_ch,
knot_changeset_t *out_ch,
knot_update_serial_t soa_up,
......
......@@ -1302,7 +1302,7 @@ int knot_zone_sign_update_soa(const knot_rrset_t *soa,
/*!
* \brief Sign changeset created by DDNS or zone-diff.
*/
int knot_zone_sign_changeset(const zone_t *zone,
int knot_zone_sign_changeset(const knot_zone_contents_t *zone,
const knot_changeset_t *in_ch,
knot_changeset_t *out_ch,
hattrie_t **sorted_changes,
......@@ -1315,7 +1315,7 @@ int knot_zone_sign_changeset(const zone_t *zone,
}
// Create args for wrapper function - hattrie for duplicate sigs
changeset_signing_data_t args = { .zone = zone->contents,
changeset_signing_data_t args = { .zone = zone,
.zone_keys = zone_keys,
.policy = policy,
.changeset = out_ch,
......
......@@ -96,7 +96,7 @@ bool knot_zone_sign_soa_expired(const knot_zone_contents_t *zone,
/*!
* \brief Sign changeset created by DDNS or zone-diff.
*
* \param zone Updated zone (with *new* contents).
* \param zone New zone contents.
* \param in_ch Changeset created bvy DDNS or zone-diff
* \param out_ch New records will be added to this changeset.
* \param sorted_changes Sorted representation of changes.
......@@ -105,7 +105,7 @@ bool knot_zone_sign_soa_expired(const knot_zone_contents_t *zone,
*
* \return Error code, KNOT_EOK if successful.
*/
int knot_zone_sign_changeset(const zone_t *zone,
int knot_zone_sign_changeset(const knot_zone_contents_t *zone,
const knot_changeset_t *in_ch,
knot_changeset_t *out_ch,
hattrie_t **sorted_changes,
......
......@@ -886,27 +886,6 @@ static bool zones_nsec3param_changed(const knot_zone_contents_t *old_contents,
return apex_rr_changed(old_contents, new_contents, KNOT_RRTYPE_NSEC3PARAM);
}
/*!
* \todo Just a rewrite of existing code, I don't know what is the purpose of this.
*/
static zone_t *create_fake_zone(zone_t *zone)
Please register or sign in to reply
{
conf_zone_t *conf = malloc(sizeof(conf_zone_t));
if (!conf) {
return NULL;
}
conf_init_zone(conf);
conf->name = strdup(zone->conf->name);
zone_t *fake = zone_new(conf);
// steal the zone content
fake->contents = zone->contents;
return fake;
}
/*! \brief Process UPDATE query.
*
* Functions expects that the query is already authenticated
......@@ -993,17 +972,6 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
}
}
zone_t *fake_zone = create_fake_zone(zone);
if (fake_zone == NULL) {
log_zone_error("%s: Failed to apply changesets (%s)\n",
msg, knot_strerror(KNOT_ENOMEM));
xfrin_rollback_update(zone->contents, &new_contents,
chgsets->changes);
knot_changesets_free(&chgsets);
free(msg);
return KNOT_ENOMEM;
}
// Apply changeset to zone created by DDNS processing
hattrie_t *sorted_changes = NULL;
......@@ -1017,12 +985,13 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
*/
if (zones_dnskey_changed(old_contents, new_contents) ||
zones_nsec3param_changed(old_contents, new_contents)) {
ret = knot_dnssec_zone_sign(fake_zone, sec_ch,
ret = knot_dnssec_zone_sign(new_contents, zone->conf,
sec_ch,
KNOT_SOA_SERIAL_KEEP,
&refresh_at, new_serial);
} else {
// Sign the created changeset
ret = knot_dnssec_sign_changeset(fake_zone,
ret = knot_dnssec_sign_changeset(new_contents, zone->conf,
knot_changesets_get_last(chgsets),
sec_ch, KNOT_SOA_SERIAL_KEEP,
&refresh_at,
......@@ -1037,7 +1006,6 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
knot_changesets_free(&chgsets);
knot_changesets_free(&sec_chs);
free(msg);
zone_free(&fake_zone);
return ret;
}
......@@ -1056,7 +1024,6 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
chgsets->changes);
zones_free_merged_changesets(chgsets, sec_chs);
free(msg);
zone_free(&fake_zone);
return ret;
}
......@@ -1101,8 +1068,6 @@ int zones_process_update_auth(zone_t *zone, knot_pkt_t *query,
}
}
zone_free(&fake_zone);
dbg_zones_verb("%s: DNSSEC changes applied\n", msg);
// Commit transaction.
......@@ -2004,10 +1969,11 @@ int zones_dnssec_sign(zone_t *zone, bool force, uint32_t *refresh_at)
uint32_t new_serial = zones_next_serial(zone);
if (force) {
ret = knot_dnssec_zone_sign_force(zone, ch, refresh_at,
new_serial);
ret = knot_dnssec_zone_sign_force(zone->contents, zone->conf,
ch, refresh_at, new_serial);
} else {
ret = knot_dnssec_zone_sign(zone, ch, KNOT_SOA_SERIAL_UPDATE,
ret = knot_dnssec_zone_sign(zone->contents, zone->conf,
ch, KNOT_SOA_SERIAL_UPDATE,
refresh_at, new_serial);
}
if (ret != KNOT_EOK) {
......@@ -2430,7 +2396,8 @@ int zones_do_diff_and_sign(const conf_zone_t *z, zone_t *zone, zone_t *old_zone,
* Update serial even if diff did that. This way it's always
* possible to flush the changes to zonefile.
*/
int ret = knot_dnssec_zone_sign(zone, sec_ch,
int ret = knot_dnssec_zone_sign(zone->contents, zone->conf,
sec_ch,
KNOT_SOA_SERIAL_UPDATE,
&refresh_at, new_serial);
if (ret != KNOT_EOK) {
......
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