1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup ### #######
36 * @ingroup yadifad
37 * @brief
38 *
39 * @{
40 */
41
42 #include "server-config.h"
43
44 #include "zone-signature-policy.h"
45 #include "zone_desc.h"
46 #include "confs.h"
47
48 #include <dnscore/mutex.h>
49 #include <dnscore/ptr_set.h>
50 #include <dnscore/u32_set.h>
51 #include <dnscore/dnskey.h>
52 #include <dnscore/logger.h>
53 #include <dnscore/timems.h>
54 #include <dnscore/random.h>
55 #include <dnscore/packet_reader.h>
56 #include <dnscore/timeformat.h>
57 #include <dnscore/service.h>
58 #include <dnscore/threaded_dll_cw.h>
59
60 #include <dnsdb/dnssec-keystore.h>
61 #include <dnsdb/zdb_icmtl.h>
62 #include <dnsdb/nsec.h>
63 #include <dnsdb/nsec3.h>
64
65 #include "database-service-zone-resignature.h"
66
67 #if HAS_EVENT_DYNAMIC_MODULE
68 #include "dynamic-module-handler.h"
69 #endif
70
71 #ifndef HAS_DYNUPDATE_DIFF_ENABLED
72 #error "HAS_DYNUPDATE_DIFF_ENABLED not defined"
73 #endif
74
75 #define MODULE_MSG_HANDLE g_dnssec_logger
76 extern logger_handle *g_dnssec_logger;
77
78 #include "server_error.h"
79 #include "zone.h"
80
81 #define DNSECPOL_TAG 0x4c4f504345534e44
82 #define DPOLKYST_TAG 0x5453594b4c4f5044
83 #define DPOLKEY_TAG 0x0059454b4c4f5044
84 #define DPOLDNIL_TAG 0x4c494e444c4f5044
85 #define DPOLSALT_TAG 0x544c41534c4f5044
86 #define DPOLROLL_TAG 0x4c4c4f524c4f5044
87 #define DPOLRULE_TAG 0x454c55524c4f5044
88 #define DPOLQUEU_TAG 0x554555514c4f5044
89
90 #define KEY_POLICY_EPOCH_MATCH_MARGIN 180 // how close two epochs have to be to be considered a match
91
92 #define DEBUG_FORCE_INSANE_SIGNATURE_MAINTENANCE_PARAMETERS 0
93 #if DEBUG_FORCE_INSANE_SIGNATURE_MAINTENANCE_PARAMETERS
94 #pragma message("WARNING: DEBUG_FORCE_INSANE_SIGNATURE_MAINTENANCE_PARAMETERS enabled !")
95 #endif
96
97
98 static u32_set zone_policy_rule_definition_set = U32_SET_EMPTY;
99 static group_mutex_t zone_policy_rule_definition_set_mtx = GROUP_MUTEX_INITIALIZER;
100 static volatile u32 zone_policy_rule_definition_next_index = 0;
101
102 // local functions definitions
103
104 ya_result zone_policy_date_init_at_next_rule(zone_policy_date *date, const zone_policy_date *from, const zone_policy_date *rule);
105 ya_result zone_policy_date_init_at_prev_rule(zone_policy_date *date, const zone_policy_date *from, const zone_policy_date *rule);
106 ya_result zone_policy_date_init_from_rule(zone_policy_date *date, const zone_policy_date *from, const zone_policy_date *rule);
107 ya_result zone_policy_date_init_from_date(zone_policy_date *date, const zone_policy_date *from, const zone_policy_date *rule);
108 static ya_result dnssec_policy_alarm_handler(void *args, bool cancel);
109
110 //
111
112 static ptr_set origin_to_dnssec_policy_queue_set = PTR_SET_DNSNAME_EMPTY;
113 static mutex_t origin_to_dnssec_policy_queue_mtx = MUTEX_INITIALIZER;
114
115 //
116
117 static ptr_set dnssec_policy_roll_set = PTR_SET_ASCIIZ_EMPTY;
118 static group_mutex_t dnssec_policy_roll_set_mtx = GROUP_MUTEX_INITIALIZER;
119 static group_mutex_t dnssec_policy_roll_mtx = GROUP_MUTEX_INITIALIZER;
120
121 //
122
123 static ptr_set dnssec_policy_set = PTR_SET_ASCIIZ_EMPTY;
124 static group_mutex_t dnssec_policy_set_mtx = GROUP_MUTEX_INITIALIZER;
125 static group_mutex_t dnssec_policy_mtx = GROUP_MUTEX_INITIALIZER;
126
127 //
128
129 static ptr_set dnssec_denial_set = PTR_SET_ASCIIZ_EMPTY;
130 static group_mutex_t dnssec_denial_set_mtx = GROUP_MUTEX_INITIALIZER;
131 static group_mutex_t dnssec_denial_mtx = GROUP_MUTEX_INITIALIZER;
132
133 //
134
135 static ptr_set dnssec_policy_key_set = PTR_SET_ASCIIZ_EMPTY;
136 static group_mutex_t dnssec_policy_key_set_mtx = GROUP_MUTEX_INITIALIZER;
137 static group_mutex_t dnssec_policy_key_mtx = GROUP_MUTEX_INITIALIZER;
138
139 //
140
141 static ptr_set dnssec_policy_key_suite_set = PTR_SET_ASCIIZ_EMPTY;
142 static group_mutex_t dnssec_policy_key_suite_set_mtx = GROUP_MUTEX_INITIALIZER;
143 static group_mutex_t dnssec_policy_key_suite_mtx = GROUP_MUTEX_INITIALIZER;
144
145 //
146
147 static volatile int dnssec_policy_queue_serial = 0;
148
149 static void
zone_policy_date_format_handler_method(const void * restrict val,output_stream * os,s32 padding,char pad_char,bool left_justified,void * restrict reserved_for_method_parameters)150 zone_policy_date_format_handler_method(const void *restrict val, output_stream *os, s32 padding, char pad_char, bool left_justified, void * restrict reserved_for_method_parameters)
151 {
152 zone_policy_date *date = (zone_policy_date*)val;
153 (void)padding;
154 (void)pad_char;
155 (void)left_justified;
156 (void)reserved_for_method_parameters;
157
158 switch(date->type.type)
159 {
160 case ZONE_POLICY_ABSOLUTE:
161 {
162 osformat(os, "%4u-%02u-%02u %02u:%02u:00U", date->absolute.year + ZONE_POLICY_DATE_YEAR_BASE, date->absolute.month + 1, date->absolute.day + 1, date->absolute.hour, date->absolute.minute);
163 break;
164 }
165 case ZONE_POLICY_RELATIVE:
166 {
167 osformat(os, "(%u)+%us", date->relative.seconds, date->relative.relativeto);
168 break;
169 }
170 case ZONE_POLICY_RULE:
171 {
172 zone_policy_rule_definition_s *def = zone_policy_rule_definition_get_from_rule(date);
173 osformat(os, "[%016x %06x %08x %02x %x %x]", def->minute, def->hour, def->day, def->month, def->weekday, def->week);
174 break;
175 }
176 default:
177 {
178 output_stream_write(os, "?", 1);
179 break;
180 }
181 }
182 }
183
184 dnssec_policy_queue*
dnssec_policy_queue_new(const u8 * fqdn)185 dnssec_policy_queue_new(const u8 *fqdn)
186 {
187 dnssec_policy_queue *cmd;
188 ZALLOC_OBJECT_OR_DIE( cmd, dnssec_policy_queue, DPOLQUEU_TAG);
189 ZEROMEMORY(cmd, sizeof(dnssec_policy_queue));
190 cmd->origin = dnsname_zdup(fqdn); // weak
191 return cmd;
192 }
193
194 bool
dnssec_policy_queue_equals(const dnssec_policy_queue * a,const dnssec_policy_queue * b)195 dnssec_policy_queue_equals(const dnssec_policy_queue *a, const dnssec_policy_queue *b)
196 {
197 if(a->command == b->command)
198 {
199 switch(a->command)
200 {
201 case DNSSEC_POLICY_COMMAND_INIT:
202 {
203 return TRUE; // as time is "asap"
204 }
205 case DNSSEC_POLICY_COMMAND_GENERATE_KEY:
206 {
207 return (a->epoch == b->epoch) && (a->parameters.generate_key.suite == b->parameters.generate_key.suite);
208 }
209 default:
210 {
211 // not implemented
212 log_err("dnssec_policy_queue_equals: command not implemented");
213 abort();
214 }
215 }
216 }
217 else
218 {
219 return FALSE;
220 }
221 }
222
223 bool
dnssec_policy_queue_has_command(dnssec_policy_queue * cmd)224 dnssec_policy_queue_has_command(dnssec_policy_queue *cmd)
225 {
226 bool ret = FALSE;
227 mutex_lock(&origin_to_dnssec_policy_queue_mtx);
228
229 ptr_node *queue_node = ptr_set_find(&origin_to_dnssec_policy_queue_set, cmd->origin);
230 if(queue_node != NULL)
231 {
232 dnssec_policy_queue* cmdq = (dnssec_policy_queue*)queue_node->value;
233
234 while(cmdq != NULL)
235 {
236 if(dnssec_policy_queue_equals(cmdq, cmd))
237 {
238 ret = TRUE;
239 break;
240 }
241
242 cmdq = cmdq->next;
243 }
244 }
245 mutex_unlock(&origin_to_dnssec_policy_queue_mtx);
246 return ret;
247 }
248
249 bool
dnssec_policy_queue_has_command_type(const u8 * fqdn,int command)250 dnssec_policy_queue_has_command_type(const u8 *fqdn, int command)
251 {
252 bool ret = FALSE;
253
254 mutex_lock(&origin_to_dnssec_policy_queue_mtx);
255 ptr_node *queue_node = ptr_set_find(&origin_to_dnssec_policy_queue_set, fqdn);
256
257 if(queue_node != NULL)
258 {
259 dnssec_policy_queue* cmdq = (dnssec_policy_queue*)queue_node->value;
260
261 while(cmdq != NULL)
262 {
263 if(cmdq->command == command)
264 {
265 ret = TRUE;
266 break;
267 }
268
269 cmdq = cmdq->next;
270 }
271 }
272
273 mutex_unlock(&origin_to_dnssec_policy_queue_mtx);
274 return ret;
275 }
276
277 static int
dnssec_policy_queue_add_command(dnssec_policy_queue * cmd)278 dnssec_policy_queue_add_command(dnssec_policy_queue *cmd)
279 {
280 #if DEBUG
281 log_debug("dnssec-policy: %{dnsname}: add command %p", cmd->origin, cmd);
282 #endif
283
284 yassert(!cmd->queued);
285
286 mutex_lock(&origin_to_dnssec_policy_queue_mtx);
287 int ret = dnssec_policy_queue_serial;
288 dnssec_policy_queue_serial += 0x100;
289 ptr_node *queue_node = ptr_set_insert(&origin_to_dnssec_policy_queue_set, cmd->origin);
290 if(queue_node->value == NULL)
291 {
292 queue_node->key = dnsname_zdup(cmd->origin);
293 }
294 dnssec_policy_queue** cmdqp = (dnssec_policy_queue**)&queue_node->value;
295 cmd->next = *cmdqp;
296 cmd->queued = TRUE;
297 *cmdqp = cmd;
298
299 mutex_unlock(&origin_to_dnssec_policy_queue_mtx);
300 return ret;
301 }
302
303 void
dnssec_policy_queue_add_command_at_epoch(dnssec_policy_queue * cmd,alarm_t hndl,time_t at)304 dnssec_policy_queue_add_command_at_epoch(dnssec_policy_queue *cmd, alarm_t hndl, time_t at)
305 {
306 int serial = dnssec_policy_queue_add_command(cmd) | ALARM_KEY_DNSSEC_POLICY_EVENT;
307
308 alarm_event_node *event = alarm_event_new(
309 at,
310 serial,
311 dnssec_policy_alarm_handler,
312 cmd,
313 ALARM_DUP_REMOVE_LATEST,
314 "dnssec-policy-generate-key");
315
316 alarm_set(hndl, event);
317 }
318
319 void
dnssec_policy_queue_remove_command(dnssec_policy_queue * cmd)320 dnssec_policy_queue_remove_command(dnssec_policy_queue *cmd)
321 {
322 if(cmd->queued)
323 {
324 #if DEBUG
325 log_debug("dnssec-policy: %{dnsname}: remove command %p", cmd->origin, cmd);
326 #endif
327
328 mutex_lock(&origin_to_dnssec_policy_queue_mtx);
329
330 ptr_node *queue_node = ptr_set_insert(&origin_to_dnssec_policy_queue_set, cmd->origin);
331 dnssec_policy_queue** cmdqp = (dnssec_policy_queue**)&queue_node->value;
332
333 while(*cmdqp != NULL)
334 {
335 if(*cmdqp == cmd)
336 {
337 *cmdqp = cmd->next;
338 cmd->next = NULL;
339 cmd->queued = FALSE;
340 break;
341 }
342 cmdqp = &(*cmdqp)->next;
343 }
344
345 if(queue_node->value == NULL)
346 {
347 u8* key = (u8*)queue_node->key;
348 ptr_set_delete(&origin_to_dnssec_policy_queue_set, cmd->origin);
349 dnsname_zfree(key);
350 }
351
352 mutex_unlock(&origin_to_dnssec_policy_queue_mtx);
353 }
354 #if DEBUG
355 else
356 {
357 log_debug("dnssec-policy: %{dnsname}: remove command %p: not queued", cmd->origin, cmd);
358 }
359 #endif
360 }
361
362 void
dnssec_policy_queue_delete_command(dnssec_policy_queue * cmd)363 dnssec_policy_queue_delete_command(dnssec_policy_queue *cmd)
364 {
365 #if DEBUG
366 log_debug("dnssec-policy: %{dnsname}: delete command %p", cmd->origin, cmd);
367 #endif
368 dnssec_policy_queue_remove_command(cmd);
369
370 switch(cmd->command)
371 {
372 case DNSSEC_POLICY_COMMAND_INIT:
373 {
374 break;
375 }
376 case DNSSEC_POLICY_COMMAND_GENERATE_KEY:
377 {
378 if(cmd->parameters.generate_key.suite != NULL)
379 {
380 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
381 zone_release(cmd->parameters.generate_key.zone_desc);
382 }
383 break;
384 }
385 }
386
387 #if DEBUG
388 intptr cmd_address = (intptr)cmd;
389 #endif
390
391 dnsname_zfree(cmd->origin);
392 ZFREE_OBJECT(cmd);
393
394 #if DEBUG
395 log_debug("dnssec-policy: delete command %p: done", cmd_address); // scan-build false positive : the memory pointed by cmd is freed, but cmd's value is still valid.
396 #endif
397 }
398
399 ya_result
dnssec_policy_queue_add_generate_key_create_at(zone_desc_s * zone_desc,struct dnssec_policy_key_suite * kr,time_t epoch)400 dnssec_policy_queue_add_generate_key_create_at(zone_desc_s *zone_desc, struct dnssec_policy_key_suite *kr, time_t epoch)
401 {
402 zone_policy_table_s tbl;
403 zone_policy_date now_date;
404 ya_result ret;
405
406 ret = zone_policy_date_init_from_epoch(&now_date, epoch);
407
408 if(FAIL(ret))
409 {
410 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_table_init_from_date returned an error: %r", ret);
411 return ret;
412 }
413
414 ret = zone_policy_table_init_from_date(&tbl, &kr->roll->time_table, &now_date);
415
416 if(FAIL(ret))
417 {
418 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_table_init_from_date returned an error: %r", ret);
419 return ret;
420 }
421
422 #if DEBUG
423 format_writer n_fw = {zone_policy_date_format_handler_method, &now_date};
424 format_writer c_fw = {zone_policy_date_format_handler_method, &tbl.created};
425 format_writer p_fw = {zone_policy_date_format_handler_method, &tbl.publish};
426 format_writer a_fw = {zone_policy_date_format_handler_method, &tbl.activate};
427 format_writer d_fw = {zone_policy_date_format_handler_method, &tbl.inactive};
428 format_writer r_fw = {zone_policy_date_format_handler_method, &tbl.delete};
429
430 log_debug("dnssec-policy: %{dnsname}: %s: at %T = %U = %w: queued key: create=%w, publish=%w, activate=%w, deactivate=%w, remove=%w",
431 zone_origin(zone_desc), kr->name, epoch, epoch, &n_fw,
432 &c_fw, &p_fw, &a_fw, &d_fw, &r_fw);
433 #endif
434
435 #if 1
436 yassert(tbl.created.type.type == ZONE_POLICY_ABSOLUTE);
437
438 time_t alarm_epoch;
439
440 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.created, &alarm_epoch))) // note: created should be of type ZONE_POLICY_ABSOLUTE
441 {
442 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch returned an error: %r", ret);
443 return ret;
444 }
445
446 #if DEBUG
447 log_debug("dnssec-policy: %{dnsname}: %s: alarm set to %T", zone_origin(zone_desc), kr->name, alarm_epoch);
448 logger_flush();
449 #endif
450
451 dnssec_policy_queue *cmd = dnssec_policy_queue_new(zone_origin(zone_desc));
452 cmd->epoch = epoch;
453 cmd->command = DNSSEC_POLICY_COMMAND_GENERATE_KEY;
454 dnssec_policy_key_suite_acquire(kr);
455 cmd->parameters.generate_key.suite = kr; // must be done else the dnssec_policy_queue_has_command will fail
456 cmd->parameters.generate_key.zone_desc = zone_desc;
457 zone_acquire(zone_desc);
458
459 if(!dnssec_policy_queue_has_command(cmd))
460 {
461 log_debug("dnssec-policy: %{dnsname}: %s: at %T will generate a key with time parameter: %T", zone_origin(zone_desc), kr->name, alarm_epoch, epoch);
462
463 // add the command
464
465 zone_policy_key_suite_mark_processed(zone_desc, kr);
466
467 dnssec_policy_queue_add_command_at_epoch(cmd, zone_desc->loaded_zone->alarm_handle, alarm_epoch);
468 }
469 else
470 {
471 // note: kr is part of cmd, so it cannot be use dafter cmd has been deleted
472 log_debug("dnssec-policy: %{dnsname}: %s: key generation for policy already set", zone_origin(zone_desc), kr->name);
473
474 dnssec_policy_queue_delete_command(cmd);
475 }
476 #else
477 time_t created_epoch;
478 time_t publish_epoch;
479 time_t activate_epoch;
480 time_t deactivate_epoch;
481 time_t unpublish_epoch;
482
483 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.created, &created_epoch))) // note: created should be of type ZONE_POLICY_ABSOLUTE
484 {
485 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (created_epoch) returned an error: %r", ret);
486 return ret;
487 }
488
489 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.publish, &publish_epoch))) // note: publish should be of type ZONE_POLICY_ABSOLUTE
490 {
491 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (publish_epoch) returned an error: %r", ret);
492 return ret;
493 }
494
495 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.activate, &activate_epoch))) // note: activate should be of type ZONE_POLICY_ABSOLUTE
496 {
497 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (activate_epoch) returned an error: %r", ret);
498 return ret;
499 }
500
501 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.inactive, &deactivate_epoch))) // note: deactivate should be of type ZONE_POLICY_ABSOLUTE
502 {
503 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (deactivate_epoch) returned an error: %r", ret);
504 return ret;
505 }
506
507 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.delete, &unpublish_epoch))) // note: unpublish should be of type ZONE_POLICY_ABSOLUTE
508 {
509 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (unpublish_epoch) returned an error: %r", ret);
510 return ret;
511 }
512
513 keyroll_generate_dnskey_ex(keyroll, kr->key->size, kr->key->algorithm, ONE_SECOND_US * created_epoch, ONE_SECOND_US * publish_epoch, ONE_SECOND_US * activate_epoch,
514 ONE_SECOND_US * deactivate_epoch, ONE_SECOND_US * unpublish_epoch, (kr->key->flags == DNSKEY_FLAGS_KSK));
515
516 yassert(tbl.created.type.type == ZONE_POLICY_ABSOLUTE);
517
518 time_t alarm_epoch;
519
520 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.created, &alarm_epoch))) // note: created should be of type ZONE_POLICY_ABSOLUTE
521 {
522 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch returned an error: %r", ret);
523 return ret;
524 }
525
526 #if DEBUG
527 log_debug("dnssec-policy: %{dnsname}: %s: key created set at %T", zone_origin(zone_desc), kr->name, alarm_epoch);
528 #endif
529
530 #endif // #if 0 #else
531
532 return SUCCESS;
533 }
534
535 /**
536 * Works only with RULEs (cron) key suites
537 *
538 * @param zone_desc
539 * @param kr
540 * @param active_at
541 * @param will_be_inactive_at a pointer that'll receive the inactive epoch (can be NULL)
542 */
543
544 ya_result
dnssec_policy_queue_add_generate_key_active_at(zone_desc_s * zone_desc,struct dnssec_policy_key_suite * kr,time_t active_at,time_t * will_be_inactive_at)545 dnssec_policy_queue_add_generate_key_active_at(zone_desc_s *zone_desc, struct dnssec_policy_key_suite *kr, time_t active_at, time_t *will_be_inactive_at)
546 {
547 zone_policy_date creation_date;
548 zone_policy_date publish_date;
549 zone_policy_date activate_date;
550 zone_policy_date inactive_date;
551 zone_policy_date unpublish_date;
552 zone_policy_date now_date;
553
554 ya_result ret;
555
556 if(FAIL(ret = zone_policy_date_init_from_epoch(&now_date, active_at)))
557 {
558 return ret;
559 }
560
561 if(FAIL(ret = zone_policy_date_init_at_prev_rule(&activate_date, &now_date, &kr->roll->time_table.activate)))
562 {
563 return ret;
564 }
565
566 if(FAIL(ret = zone_policy_date_init_at_prev_rule(&publish_date, &activate_date, &kr->roll->time_table.publish)))
567 {
568 return ret;
569 }
570
571 if(FAIL(ret = zone_policy_date_init_at_prev_rule(&creation_date, &publish_date, &kr->roll->time_table.created)))
572 {
573 return ret;
574 }
575
576 time_t creation_epoch = 60;
577 time_t activate_epoch = 60;
578
579 if(FAIL(ret = zone_policy_date_get_epoch(&creation_date, &creation_epoch)))
580 {
581 return ret;
582 }
583
584 if(FAIL(ret = zone_policy_date_get_epoch(&activate_date, &activate_epoch)))
585 {
586 return ret;
587 }
588
589 #if DEBUG
590 format_writer c_fw = {zone_policy_date_format_handler_method, &creation_date};
591
592 {
593 format_writer a_fw0 = {zone_policy_date_format_handler_method, &activate_date};
594 format_writer p_fw0 = {zone_policy_date_format_handler_method, &publish_date};
595
596 log_debug1("dnssec-policy: %{dnsname}: %s: base %w <= %w <= %w : %T", zone_origin(zone_desc), kr->name, &c_fw, &p_fw0, &a_fw0, creation_epoch);
597 }
598 #endif
599
600 if(FAIL(ret = zone_policy_date_init_at_next_rule(&publish_date, &creation_date, &kr->roll->time_table.publish)))
601 {
602 return ret;
603 }
604
605 if(FAIL(ret = zone_policy_date_init_at_next_rule(&activate_date, &publish_date, &kr->roll->time_table.activate)))
606 {
607 return ret;
608 }
609
610 #if DEBUG
611 format_writer p_fw = {zone_policy_date_format_handler_method, &publish_date};
612 format_writer a_fw = {zone_policy_date_format_handler_method, &activate_date};
613 {
614 log_debug1("dnssec-policy: %{dnsname}: %s: base %w => %w => %w : %T (after forward correction)", zone_origin(zone_desc), kr->name, &c_fw, &p_fw, &a_fw, creation_epoch);
615 }
616 #endif
617
618 // compute the future key timings to ensure there will be no period without a signature
619
620 zone_policy_date next_creation_date;
621 zone_policy_date next_publish_date;
622 zone_policy_date next_activate_date;
623
624 if(FAIL(ret = zone_policy_date_init_at_next_rule(&next_creation_date, &activate_date, &kr->roll->time_table.created)))
625 {
626 return ret;
627 }
628
629 if(FAIL(ret = zone_policy_date_init_at_next_rule(&next_publish_date, &next_creation_date, &kr->roll->time_table.publish)))
630 {
631 return ret;
632 }
633
634 if(FAIL(ret = zone_policy_date_init_at_next_rule(&next_activate_date, &next_publish_date, &kr->roll->time_table.activate)))
635 {
636 return ret;
637 }
638
639 #if DEBUG
640 {
641 format_writer na_fw = {zone_policy_date_format_handler_method, &next_activate_date};
642 format_writer np_fw = {zone_policy_date_format_handler_method, &next_publish_date};
643 format_writer nc_fw = {zone_policy_date_format_handler_method, &next_creation_date};
644
645 log_debug1("dnssec-policy: %{dnsname}: %s: next %w => %w => %w", zone_origin(zone_desc), kr->name, &nc_fw, &np_fw, &na_fw);
646 }
647 #endif
648
649 // and use this next_activate as a base for the current deactivate
650
651 if(FAIL(ret = zone_policy_date_init_at_next_rule(&inactive_date, &next_activate_date, &kr->roll->time_table.inactive)))
652 {
653 return ret;
654 }
655
656 if(FAIL(ret = zone_policy_date_init_at_next_rule(&unpublish_date, &inactive_date, &kr->roll->time_table.delete)))
657 {
658 return ret;
659 }
660
661 time_t inactive_epoch = 0;
662
663 if(FAIL(ret = zone_policy_date_get_epoch(&inactive_date, &inactive_epoch)))
664 {
665 return ret;
666 }
667
668 if(inactive_epoch - activate_epoch < DNSSEC_POLICY_MINIMUM_ACTIVATED_TIME_SUGGESTION_SECONDS)
669 {
670 double d = inactive_epoch - activate_epoch;
671 d /= 86400.0;
672 double c = DNSSEC_POLICY_MINIMUM_ACTIVATED_TIME_SUGGESTION_SECONDS;
673 c /= 86400.0;
674 log_warn("dnssec-policy: %{dnsname}: %s: the key will only be activated for %.3f days, consider increasing this value to at least %.3f days", zone_origin(zone_desc), kr->name, d, c);
675 }
676
677 if(inactive_epoch < active_at)
678 {
679 log_err("dnssec-policy: %{dnsname}: %s: computing timings to be in the current activated time window produces an already expired key", zone_origin(zone_desc), kr->name );
680
681 return INVALID_STATE_ERROR;
682 }
683
684 if(will_be_inactive_at != NULL)
685 {
686 *will_be_inactive_at = inactive_epoch;
687 }
688
689 #if DEBUG
690 format_writer d_fw = {zone_policy_date_format_handler_method, &inactive_date};
691 zone_policy_date remove_date;
692 ret = zone_policy_date_init_at_next_rule(&remove_date, &inactive_date, &kr->roll->time_table.delete);
693 (void)ret;
694 format_writer r_fw = {zone_policy_date_format_handler_method, &unpublish_date};
695
696 log_debug("dnssec-policy: %{dnsname}: %s: rule key: create=%w, publish=%w, activate=%w, deactivate=%w, remove=%w",
697 zone_origin(zone_desc), kr->name,
698 &c_fw, &p_fw, &a_fw, &d_fw, &r_fw);
699 #endif
700
701 log_debug("dnssec-policy: %{dnsname}: %s: will generate a key at %T (rule new) to be active at %T", zone_origin(zone_desc), kr->name, creation_epoch, active_at);
702
703 #if DEBUG
704 logger_flush();
705 #endif
706
707 // add the command
708
709 ret = dnssec_policy_queue_add_generate_key_create_at(zone_desc, kr, creation_epoch);
710
711 return ret;
712 }
713
714 ya_result
dnssec_policy_roll_test_at(struct dnssec_policy_roll * kr,time_t active_at,time_t * will_be_inactive_at,bool print_text,bool log_text)715 dnssec_policy_roll_test_at(struct dnssec_policy_roll *kr, time_t active_at, time_t *will_be_inactive_at, bool print_text, bool log_text)
716 {
717 zone_policy_date creation_date;
718 zone_policy_date publish_date;
719 zone_policy_date activate_date;
720 zone_policy_date inactive_date;
721 zone_policy_date unpublish_date;
722 zone_policy_date now_date;
723
724 ya_result ret;
725
726 if(FAIL(ret = zone_policy_date_init_from_epoch(&now_date, active_at)))
727 {
728 return ret;
729 }
730
731 if(FAIL(ret = zone_policy_date_init_at_prev_rule(&activate_date, &now_date, &kr->time_table.activate)))
732 {
733 return ret;
734 }
735
736 if(FAIL(ret = zone_policy_date_init_at_prev_rule(&publish_date, &activate_date, &kr->time_table.publish)))
737 {
738 return ret;
739 }
740
741 if(FAIL(ret = zone_policy_date_init_at_prev_rule(&creation_date, &publish_date, &kr->time_table.created)))
742 {
743 return ret;
744 }
745
746 time_t creation_epoch = 60;
747 time_t activate_epoch = 60;
748
749 if(FAIL(ret = zone_policy_date_get_epoch(&creation_date, &creation_epoch)))
750 {
751 return ret;
752 }
753
754 if(FAIL(ret = zone_policy_date_get_epoch(&activate_date, &activate_epoch)))
755 {
756 return ret;
757 }
758
759 #if DEBUG
760 format_writer c_fw = {zone_policy_date_format_handler_method, &creation_date};
761
762 {
763 format_writer a_fw0 = {zone_policy_date_format_handler_method, &activate_date};
764 format_writer p_fw0 = {zone_policy_date_format_handler_method, &publish_date};
765
766 log_debug1("key-roll: %s: base %w <= %w <= %w : %T", kr->name, &c_fw, &p_fw0, &a_fw0, creation_epoch);
767 }
768 #endif
769
770 if(FAIL(ret = zone_policy_date_init_at_next_rule(&publish_date, &creation_date, &kr->time_table.publish)))
771 {
772 return ret;
773 }
774
775 if(FAIL(ret = zone_policy_date_init_at_next_rule(&activate_date, &publish_date, &kr->time_table.activate)))
776 {
777 return ret;
778 }
779
780 #if DEBUG
781 format_writer p_fw = {zone_policy_date_format_handler_method, &publish_date};
782 format_writer a_fw = {zone_policy_date_format_handler_method, &activate_date};
783 {
784 log_debug1("key-roll: %s: base %w => %w => %w : %T (after forward correction)", kr->name, &c_fw, &p_fw, &a_fw, creation_epoch);
785 }
786 #endif
787
788 // compute the future key timings to ensure there will be no period without a signature
789
790 zone_policy_date next_creation_date;
791 zone_policy_date next_publish_date;
792 zone_policy_date next_activate_date;
793
794 if(FAIL(ret = zone_policy_date_init_at_next_rule(&next_creation_date, &activate_date, &kr->time_table.created)))
795 {
796 return ret;
797 }
798
799 if(FAIL(ret = zone_policy_date_init_at_next_rule(&next_publish_date, &next_creation_date, &kr->time_table.publish)))
800 {
801 return ret;
802 }
803
804 if(FAIL(ret = zone_policy_date_init_at_next_rule(&next_activate_date, &next_publish_date, &kr->time_table.activate)))
805 {
806 return ret;
807 }
808
809 #if DEBUG
810 {
811 format_writer na_fw = {zone_policy_date_format_handler_method, &next_activate_date};
812 format_writer np_fw = {zone_policy_date_format_handler_method, &next_publish_date};
813 format_writer nc_fw = {zone_policy_date_format_handler_method, &next_creation_date};
814
815 log_debug1("key-roll: %s: next %w => %w => %w", kr->name, &nc_fw, &np_fw, &na_fw);
816 }
817 #endif
818
819 // and use this next_activate as a base for the current deactivate
820
821 if(FAIL(ret = zone_policy_date_init_at_next_rule(&inactive_date, &next_activate_date, &kr->time_table.inactive)))
822 {
823 return ret;
824 }
825
826 if(FAIL(ret = zone_policy_date_init_at_next_rule(&unpublish_date, &inactive_date, &kr->time_table.delete)))
827 {
828 return ret;
829 }
830
831 time_t inactive_epoch = 0;
832
833 if(FAIL(ret = zone_policy_date_get_epoch(&inactive_date, &inactive_epoch)))
834 {
835 return ret;
836 }
837
838 if(inactive_epoch - activate_epoch < DNSSEC_POLICY_MINIMUM_ACTIVATED_TIME_SUGGESTION_SECONDS)
839 {
840 double d = inactive_epoch - activate_epoch;
841 d /= 86400.0;
842 double c = DNSSEC_POLICY_MINIMUM_ACTIVATED_TIME_SUGGESTION_SECONDS;
843 c /= 86400.0;
844 if(log_text)
845 {
846 log_warn("key-roll: %s: the key will only be activated for %.3f days, consider increasing this value to at least %.3f days", kr->name, d, c);
847 }
848 if(print_text)
849 {
850 formatln("key-roll: %s: the key will only be activated for %.3f days, consider increasing this value to at least %.3f days", kr->name, d, c);
851 }
852 }
853
854 if(inactive_epoch < active_at)
855 {
856 if(log_text)
857 {
858 log_err("key-roll: %s: computing timings to be in the current activated time window produces an already expired key", kr->name);
859 }
860 if(print_text)
861 {
862 formatln("key-roll: %s: computing timings to be in the current activated time window produces an already expired key", kr->name);
863 }
864
865 return INVALID_STATE_ERROR;
866 }
867
868 if(will_be_inactive_at != NULL)
869 {
870 *will_be_inactive_at = inactive_epoch;
871 }
872
873 #if DEBUG
874 format_writer d_fw = {zone_policy_date_format_handler_method, &inactive_date};
875 zone_policy_date remove_date;
876 ret = zone_policy_date_init_at_next_rule(&remove_date, &inactive_date, &kr->time_table.delete);
877 (void)ret;
878 format_writer r_fw = {zone_policy_date_format_handler_method, &unpublish_date};
879
880 log_debug("key-roll: %s: rule key: create=%w, publish=%w, activate=%w, deactivate=%w, remove=%w",
881 kr->name,
882 &c_fw, &p_fw, &a_fw, &d_fw, &r_fw);
883 #endif
884
885 log_debug("key-roll: %s: will generate a key at %T (rule new) to be active at %T", kr->name, creation_epoch, active_at);
886
887 if(log_text || print_text)
888 {
889 format_writer c_fw0 = {zone_policy_date_format_handler_method, &creation_date};
890 format_writer p_fw0 = {zone_policy_date_format_handler_method, &publish_date};
891 format_writer a_fw0 = {zone_policy_date_format_handler_method, &activate_date};
892 format_writer i_fw0 = {zone_policy_date_format_handler_method, &inactive_date};
893 format_writer u_fw0 = {zone_policy_date_format_handler_method, &unpublish_date};
894 u32 delta_seconds = inactive_epoch - activate_epoch;
895 float delta_value;
896 const char *delta_units;
897
898 if(delta_seconds > 2592000)
899 {
900 delta_value = 1.0f * delta_seconds / 2592000.f;
901 delta_units = "months";
902 }
903 else if(delta_seconds > 604800)
904 {
905 delta_value = 1.f * delta_seconds / 604800.f;
906 delta_units = "weeks";
907 }
908 else if(delta_seconds > 86400)
909 {
910 delta_value = 1.f * delta_seconds / 86400.f;
911 delta_units = "days";
912 }
913 else if(delta_seconds > 3600)
914 {
915 delta_value = 1.f * delta_seconds / 3600.f;
916 delta_units = "hours";
917 }
918 else if(delta_seconds > 60)
919 {
920 delta_value = 1.f * delta_seconds / 60.f;
921 delta_units = "minutes";
922 }
923 else
924 {
925 delta_value = 1.f * delta_seconds;
926 delta_units = "seconds";
927 }
928
929 if(log_text)
930 {
931 log_info("key-roll: %s: creation at %w, publication at %w, activation at %w, deactivation at %w, removal at %w, %6.1f %s",
932 kr->name, &c_fw0, &p_fw0, &a_fw0, &i_fw0, &u_fw0, delta_value, delta_units);
933 }
934
935 if(print_text)
936 {
937 formatln("key-roll: %s: creation at %w, publication at %w, activation at %w, deactivation at %w, removal at %w, %6.1f %s",
938 kr->name, &c_fw0, &p_fw0, &a_fw0, &i_fw0, &u_fw0, delta_value, delta_units);
939 }
940 }
941
942 #if DEBUG
943 logger_flush();
944 #endif
945
946 return ret;
947 }
948
949 ya_result
dnssec_policy_roll_test(struct dnssec_policy_roll * kr,time_t active_at,u32 duration_seconds,bool print_text,bool log_text)950 dnssec_policy_roll_test(struct dnssec_policy_roll *kr, time_t active_at, u32 duration_seconds, bool print_text, bool log_text)
951 {
952 ya_result ret;
953 time_t end_at = active_at + duration_seconds;
954 time_t inactive_at = 0;
955
956 if(print_text)
957 {
958 formatln("key-roll: %s: testing policy sets of dates from %T to %T", kr->name, active_at, end_at);
959 }
960
961 if(log_text)
962 {
963 formatln("key-roll: %s: testing policy sets of dates from %T to %T", kr->name, active_at, end_at);
964 }
965
966 while(active_at < end_at)
967 {
968 if(FAIL(ret = dnssec_policy_roll_test_at(kr, active_at, &inactive_at, print_text, log_text)))
969 {
970 if(log_text)
971 {
972 log_info("key-roll: %s: could not find a matching set of dates from %T", kr->name, active_at);
973 }
974 if(print_text)
975 {
976 formatln("key-roll: %s: could not find a matching set of dates from %T", kr->name, active_at);
977 }
978 return ret;
979 }
980
981 active_at = inactive_at;
982 }
983
984 if(print_text)
985 {
986 formatln("key-roll: %s: policy sets of dates from %T to %T computed", kr->name, active_at, end_at);
987 }
988
989 if(log_text)
990 {
991 formatln("key-roll: %s: policy sets of dates from %T to %T computed", kr->name, active_at, end_at);
992 }
993
994 return SUCCESS;
995 }
996
997 /**
998 * Compare two dates together.
999 * Absolute with Absolute
1000 * Relative with Relative
1001 *
1002 * Any other combination will return -1
1003 *
1004 * @param d1 first date
1005 * @param d2 second date
1006 * @return <0,0,>0 if d1 is less than, equal to, or greater than d2
1007 */
1008
1009 int
zone_policy_date_compare(const zone_policy_date * d1,const zone_policy_date * d2)1010 zone_policy_date_compare(const zone_policy_date *d1, const zone_policy_date *d2)
1011 {
1012 int ret;
1013
1014 if(d1->type.type == ZONE_POLICY_ABSOLUTE && d2->type.type == ZONE_POLICY_ABSOLUTE)
1015 {
1016 ret = d1->absolute.year;
1017 ret -= d2->absolute.year;
1018
1019 if(ret == 0)
1020 {
1021 ret = d1->absolute.month;
1022 ret -= d2->absolute.month;
1023
1024 if(ret == 0)
1025 {
1026 ret = d1->absolute.day;
1027 ret -= d2->absolute.day;
1028
1029 if(ret == 0)
1030 {
1031 ret = d1->absolute.hour;
1032 ret -= d2->absolute.hour;
1033
1034 if(ret == 0)
1035 {
1036 ret = d1->absolute.minute;
1037 ret -= d2->absolute.minute;
1038 }
1039 }
1040 }
1041 }
1042
1043 return ret;
1044 }
1045 else if(d1->type.type == ZONE_POLICY_RELATIVE && d2->type.type == ZONE_POLICY_RELATIVE)
1046 {
1047 ret = d1->relative.seconds;
1048 ret -= d2->relative.seconds;
1049 return ret;
1050 }
1051
1052 return POLICY_ILLEGAL_DATE_COMPARE;
1053 }
1054
1055 /**
1056 * Retrieves the first day of the month.
1057 *
1058 * 0 is Sunday
1059 *
1060 * @param year 0-based
1061 * @param month 0-based
1062 * @param week 0 to 4, week of the day
1063 * @param wday 0 to 6, day of the week, 0 for Sunday
1064 * @return the number of the day of the month or an error code
1065 */
1066
1067 ya_result
zone_policy_get_mday_from_year_month_week_wday(int year,int month,int week,int wday)1068 zone_policy_get_mday_from_year_month_week_wday(int year, int month, int week, int wday)
1069 {
1070 int mday1 = time_first_day_of_month(year, month);
1071
1072 if(mday1 >= 0)
1073 {
1074 /**
1075 * @note this can obviously be simplified (++week) but I think it's clearer this way (for now)
1076 */
1077
1078 if(wday < mday1)
1079 {
1080 // 0 1 2 3 4 5 6
1081 //
1082 // X Y Z 1 2 3 4
1083 // 4[6]7 8 9 ...
1084
1085 return wday - mday1 + 7 * (week + 1);
1086 }
1087 else
1088 {
1089 // 0 1 2 3 4 5 6
1090 //
1091 // X Y Z 1 2 3 4
1092 // 4 6 7 8[9]...
1093
1094 return wday - mday1 + 7 * week;
1095 }
1096 }
1097 else
1098 {
1099 return POLICY_ILLEGAL_DATE;
1100 }
1101 }
1102
1103 /**
1104 * Initialises an absolute date from a year, month, week and week-day
1105 *
1106 * ie: 2nd Wednesday of January 2001
1107 *
1108 * 0 is Sunday
1109 *
1110 * @param date the date to initialise
1111 * @param year 0-based
1112 * @param month 0-based
1113 * @param week 0 to 4, week of the day
1114 * @param wday 0 to 6, day of the week, 0 for Sunday
1115 * @return an error code
1116 */
1117
1118 ya_result
zone_policy_date_init_from_year_month_week_wday(zone_policy_date * date,int year,int month,int week,int wday)1119 zone_policy_date_init_from_year_month_week_wday(zone_policy_date *date, int year, int month, int week, int wday)
1120 {
1121 struct tm tm;
1122 ZEROMEMORY(&tm, sizeof(struct tm));
1123 tm.tm_mday = 1;
1124 tm.tm_mon = month;
1125 tm.tm_year = year - 1900;
1126 time_t t = mkgmtime(&tm);
1127 if(t >= 0)
1128 {
1129 if(tm.tm_wday >= 0)
1130 {
1131 /**
1132 * @note this can obviously be simplified (++week) but I think it's clearer this way (for now)
1133 *
1134 * tm_wday is the first week-day of the month
1135 */
1136
1137 if(wday < tm.tm_wday) // [0 .. 7] < [1 .. 31] ?
1138 {
1139 // 0 1 2 3 4 5 6
1140 //
1141 // X Y Z 1 2 3 4
1142 // 4[6]7 8 9 ...
1143
1144 tm.tm_mday = wday - tm.tm_wday + 7 * (week + 1) + 1;
1145 }
1146 else
1147 {
1148 // 0 1 2 3 4 5 6
1149 //
1150 // X Y Z 1 2 3 4
1151 // 4 6 7 8[9]...
1152
1153 tm.tm_mday = wday - tm.tm_wday + 7 * week + 1;
1154 }
1155
1156 t = mkgmtime(&tm);
1157
1158 if(t >= 0)
1159 {
1160 if(tm.tm_year < 228)
1161 {
1162 date->type.type = ZONE_POLICY_ABSOLUTE;
1163 date->absolute.year = tm.tm_year - (ZONE_POLICY_DATE_YEAR_BASE - 1900); // 1900 based to 2000 based
1164 date->absolute.month = tm.tm_mon;
1165 date->absolute.day = tm.tm_mday - 1; // 1 based to 0 based
1166 date->absolute.hour = tm.tm_hour;
1167 date->absolute.minute = tm.tm_min;
1168
1169 return SUCCESS;
1170 }
1171 }
1172 }
1173 }
1174
1175 return POLICY_ILLEGAL_DATE_PARAMETERS;
1176 }
1177
1178 /**
1179 * Initialises an absolute date from a UNIX epoch
1180 *
1181 * @param date
1182 * @param epoch
1183 * @return an error code
1184 */
1185
1186 ya_result
zone_policy_date_init_from_epoch(zone_policy_date * date,time_t epoch)1187 zone_policy_date_init_from_epoch(zone_policy_date *date, time_t epoch)
1188 {
1189 time_t t = epoch;
1190 struct tm d;
1191
1192 // if it worked and there was no overflow ...
1193
1194 if((gmtime_r(&t, &d) != NULL) && (d.tm_year < 228))
1195 {
1196 date->type.type = ZONE_POLICY_ABSOLUTE;
1197 date->absolute.year = d.tm_year - (ZONE_POLICY_DATE_YEAR_BASE - 1900); // 1900 based to 2000 based
1198 date->absolute.month = d.tm_mon;
1199 date->absolute.day = d.tm_mday - 1; // 1 based to 0 based
1200 date->absolute.hour = d.tm_hour;
1201 date->absolute.minute = d.tm_min;
1202
1203 return SUCCESS;
1204 }
1205
1206 return POLICY_ILLEGAL_DATE_PARAMETERS;
1207 }
1208
1209 /**
1210 * Gets the UNIX epoch from an absolute date
1211 *
1212 * @param date
1213 * @param epoch a pointer to hold the result
1214 * @return an error code
1215 */
1216
1217 ya_result
zone_policy_date_get_epoch(const zone_policy_date * date,time_t * epoch)1218 zone_policy_date_get_epoch(const zone_policy_date *date, time_t *epoch)
1219 {
1220 time_t t;
1221 struct tm d;
1222
1223 yassert(epoch != NULL);
1224
1225 if(date->type.type != ZONE_POLICY_ABSOLUTE) // only works with absolute dates
1226 {
1227 return POLICY_ILLEGAL_DATE_TYPE;
1228 }
1229
1230 ZEROMEMORY(&d, sizeof(struct tm));
1231
1232 d.tm_year = date->absolute.year + (ZONE_POLICY_DATE_YEAR_BASE - 1900); // 2000 based to 1900 based
1233 d.tm_mon = date->absolute.month;
1234 d.tm_mday = date->absolute.day + 1; // 0 based to 1 based
1235 d.tm_hour = date->absolute.hour;
1236 d.tm_min = date->absolute.minute;
1237 d.tm_sec = 0;
1238
1239 t = mkgmtime(&d);
1240
1241 if(t != -1)
1242 {
1243 *epoch = t;
1244 return SUCCESS;
1245 }
1246 else
1247 {
1248 return MAKE_ERRNO_ERROR(EOVERFLOW);
1249 }
1250 }
1251
1252 /**
1253 * Initialises the absolute date with an epoch plus time in seconds.
1254 *
1255 * @param date
1256 * @param epoch an epoch to add the seconds to
1257 * @param seconds
1258 * @return an error code
1259 */
1260
1261 ya_result
zone_policy_date_init_after_epoch(zone_policy_date * date,time_t epoch,u32 seconds)1262 zone_policy_date_init_after_epoch(zone_policy_date *date, time_t epoch, u32 seconds)
1263 {
1264 ya_result ret = zone_policy_date_init_from_epoch(date, epoch + seconds);
1265 return ret;
1266 }
1267
1268 /**
1269 * Initialises the absolute date with an absolute date plus time in seconds.
1270 *
1271 * @param date
1272 * @param from an absolute date to add the seconds to
1273 * @param seconds
1274 * @return an error code
1275 */
1276
1277 ya_result
zone_policy_date_init_after_date(zone_policy_date * date,const zone_policy_date * from,u32 seconds)1278 zone_policy_date_init_after_date(zone_policy_date *date, const zone_policy_date *from, u32 seconds)
1279 {
1280 ya_result ret;
1281 time_t epoch;
1282 if(ISOK(ret = zone_policy_date_get_epoch(from, &epoch)))
1283 {
1284 ret = zone_policy_date_init_from_epoch(date, epoch + seconds);
1285 }
1286 return ret;
1287 }
1288
1289 /**
1290 * Initialises a date using a rule applied on an epoch
1291 *
1292 * @param result_date
1293 * @param rule_date
1294 * @param after_epoch
1295 * @return
1296 */
1297
1298 ya_result
zone_policy_date_init_from_rule_applied_with_epoch(zone_policy_date * result_date,const zone_policy_date * rule_date,time_t after_epoch)1299 zone_policy_date_init_from_rule_applied_with_epoch(zone_policy_date *result_date, const zone_policy_date *rule_date, time_t after_epoch)
1300 {
1301 zone_policy_date after_date;
1302 ya_result ret;
1303 if(ISOK(ret = zone_policy_date_init_from_epoch(&after_date, after_epoch)))
1304 {
1305 ret = zone_policy_date_init_at_next_date(result_date, &after_date, rule_date);
1306 }
1307
1308 return ret;
1309 }
1310
1311 /**
1312 * Initialises an epoch from a rule applied on an epoch
1313 *
1314 * @param rule_date
1315 * @param after_epoch
1316 * @param result_epoch
1317 * @return
1318 */
1319
1320 ya_result
zone_policy_get_epoch_from_rule_applied_with_epoch(const zone_policy_date * rule_date,time_t after_epoch,time_t * result_epoch)1321 zone_policy_get_epoch_from_rule_applied_with_epoch(const zone_policy_date *rule_date, time_t after_epoch, time_t *result_epoch)
1322 {
1323 zone_policy_date result_date;
1324 ya_result ret;
1325 if(ISOK(ret = zone_policy_date_init_from_rule_applied_with_epoch(&result_date, rule_date, after_epoch)))
1326 {
1327 ret = zone_policy_date_get_epoch(&result_date, result_epoch);
1328 }
1329 return ret;
1330 }
1331
1332 zone_policy_rule_definition_s*
zone_policy_rule_definition_get_from_index(u32 index)1333 zone_policy_rule_definition_get_from_index(u32 index)
1334 {
1335 zone_policy_rule_definition_s *ret = NULL;
1336 group_mutex_read_lock(&zone_policy_rule_definition_set_mtx);
1337 u32_node *node = u32_set_find(&zone_policy_rule_definition_set, index);
1338 if(node != NULL)
1339 {
1340 ret = (zone_policy_rule_definition_s*)node->value;
1341 }
1342 group_mutex_read_unlock(&zone_policy_rule_definition_set_mtx);
1343 return ret;
1344 }
1345
1346 zone_policy_rule_definition_s*
zone_policy_rule_definition_get_from_rule(const zone_policy_date * rule)1347 zone_policy_rule_definition_get_from_rule(const zone_policy_date *rule)
1348 {
1349 zone_policy_rule_definition_s *ret = NULL;
1350 if(rule->type.type == ZONE_POLICY_RULE)
1351 {
1352 ret = zone_policy_rule_definition_get_from_index(rule->rule.index);
1353 }
1354 return ret;
1355 }
1356
1357 void
zone_policy_rule_init(zone_policy_rule_s * rule,const zone_policy_rule_definition_s * rule_definition)1358 zone_policy_rule_init(zone_policy_rule_s *rule, const zone_policy_rule_definition_s *rule_definition)
1359 {
1360 group_mutex_write_lock(&zone_policy_rule_definition_set_mtx);
1361 yassert(zone_policy_rule_definition_next_index < 0x40000000);
1362
1363 for(;;)
1364 {
1365 ++zone_policy_rule_definition_next_index;
1366 if(zone_policy_rule_definition_next_index == 0x40000000)
1367 {
1368 zone_policy_rule_definition_next_index = 0;
1369 }
1370
1371 u32_node *node = u32_set_insert(&zone_policy_rule_definition_set, zone_policy_rule_definition_next_index);
1372
1373 if(node->value == NULL)
1374 {
1375 rule->index = zone_policy_rule_definition_next_index;
1376 rule->type = ZONE_POLICY_RULE;
1377
1378 zone_policy_rule_definition_s *new_rule_definition;
1379 ZALLOC_OBJECT_OR_DIE( new_rule_definition, zone_policy_rule_definition_s, DPOLRULE_TAG);
1380 memcpy(new_rule_definition, rule_definition, sizeof(zone_policy_rule_definition_s));
1381 node->value = new_rule_definition;
1382 break;
1383 }
1384 }
1385
1386 group_mutex_write_unlock(&zone_policy_rule_definition_set_mtx);
1387 }
1388
1389 void
zone_policy_rule_finalize(zone_policy_rule_s * rule)1390 zone_policy_rule_finalize(zone_policy_rule_s *rule)
1391 {
1392 group_mutex_write_lock(&zone_policy_rule_definition_set_mtx);
1393 u32_node *node = u32_set_find(&zone_policy_rule_definition_set, rule->index);
1394 if(node != NULL)
1395 {
1396 if(node->value != NULL)
1397 {
1398 ZFREE(node->value, zone_policy_rule_definition_s);
1399 }
1400
1401 u32_set_delete(&zone_policy_rule_definition_set, rule->index);
1402 }
1403 group_mutex_write_unlock(&zone_policy_rule_definition_set_mtx);
1404 }
1405
1406 void
zone_policy_date_init_from_rule_definition(zone_policy_date * date,const zone_policy_rule_definition_s * rule_definition)1407 zone_policy_date_init_from_rule_definition(zone_policy_date *date, const zone_policy_rule_definition_s *rule_definition)
1408 {
1409
1410 date->type.type = ZONE_POLICY_RULE;
1411 zone_policy_rule_init(&date->rule, rule_definition);
1412 }
1413
1414 /**
1415 * Initialises a date with the earliest matching of the rule starting after 'from'
1416 *
1417 * @param date
1418 * @param from
1419 * @param rule
1420 *
1421 * @return an error code
1422 */
1423 ya_result
zone_policy_date_init_at_next_date(zone_policy_date * date,const zone_policy_date * from,const zone_policy_date * rule)1424 zone_policy_date_init_at_next_date(zone_policy_date *date, const zone_policy_date *from, const zone_policy_date *rule)
1425 {
1426 ya_result ret;
1427
1428 if((((intptr)date) == 0) | (((intptr)from) == 0) | (((intptr)rule) == 0))
1429 {
1430 return UNEXPECTED_NULL_ARGUMENT_ERROR;
1431 }
1432
1433 #if DEBUG
1434 format_writer from_fw = {zone_policy_date_format_handler_method, from};
1435 format_writer rule_fw = {zone_policy_date_format_handler_method, rule};
1436 format_writer date_fw = {zone_policy_date_format_handler_method, date};
1437 #endif
1438
1439 if(from->type.type != ZONE_POLICY_ABSOLUTE)
1440 {
1441 #if DEBUG
1442 log_debug1("zone_policy_date_init_at_next_date(%p, %w, %w): can only work from an absolute time", date, &from_fw, &rule_fw);
1443 #endif
1444 return POLICY_ILLEGAL_DATE_TYPE;
1445 }
1446
1447 switch(rule->type.type)
1448 {
1449 case ZONE_POLICY_RELATIVE:
1450 {
1451 memcpy(date, from, sizeof(zone_policy_date));
1452 #if DEBUG
1453 log_debug1("zone_policy_date_init_at_next_date(%p, %w, %w): initialising relative time", date, &from_fw, &rule_fw);
1454 #endif
1455 ret = zone_policy_date_init_after_date(date, from, rule->relative.seconds); // +60 because it must be after and because of minute granularity
1456 #if DEBUG
1457 log_debug1("zone_policy_date_init_at_next_date: %w = %w + %w", &date_fw, &from_fw, &rule_fw);
1458 #endif
1459 return ret;
1460 }
1461 case ZONE_POLICY_RULE:
1462 {
1463 #if DEBUG
1464 log_debug1("zone_policy_date_init_at_next_date(%p, %w, %w): initialising rule-based time", date, &from_fw, &rule_fw);
1465 #endif
1466 ret = zone_policy_date_init_at_next_rule(date, from, rule);
1467 #if DEBUG
1468 log_debug1("zone_policy_date_init_at_next_date: %w = %w + %w", &date_fw, &from_fw, &rule_fw);
1469 #endif
1470 return ret;
1471 }
1472 default:
1473 {
1474 #if DEBUG
1475 log_debug1("zone_policy_date_init_at_next_date(%p, %w, %w): unexpected type", date, &from_fw, &rule_fw);
1476 #endif
1477 return POLICY_ILLEGAL_DATE_TYPE;
1478 }
1479 }
1480 }
1481
1482 static zone_policy_date*
zone_policy_table_get_date_by_index(zone_policy_table_s * tbl,int index)1483 zone_policy_table_get_date_by_index(zone_policy_table_s *tbl, int index)
1484 {
1485 switch(index)
1486 {
1487 case ZONE_POLICY_RELATIVE_TO_GENERATE:
1488 return &tbl->created;
1489 case ZONE_POLICY_RELATIVE_TO_PUBLISH:
1490 return &tbl->publish;
1491 case ZONE_POLICY_RELATIVE_TO_ACTIVATE:
1492 return &tbl->activate;
1493 case ZONE_POLICY_RELATIVE_TO_INACTIVE:
1494 return &tbl->inactive;
1495 case ZONE_POLICY_RELATIVE_TO_REMOVE:
1496 return &tbl->delete;
1497 #if HAS_DS_PUBLICATION_SUPPORT
1498 case ZONE_POLICY_RELATIVE_TO_DS_PUBLISH:
1499 return &tbl->ds_publish;
1500 case ZONE_POLICY_RELATIVE_TO_DS_REMOVE:
1501 return &tbl->ds_remove;
1502 #endif
1503 default:
1504 log_err("zone_policy_table_get_date_by_index(%p, %i): index out of range [%i, %i]", tbl, index, ZONE_POLICY_RELATIVE_TO_GENERATE, ZONE_POLICY_RELATIVE_TO_REMOVE);
1505 return NULL;
1506 }
1507 }
1508
1509 /**
1510 * This initialises a date with the earliest matching of the rule starting from 'from'
1511 *
1512 * @param date
1513 * @param from
1514 * @param rule
1515 *
1516 * @return an error code
1517 */
1518 ya_result
zone_policy_date_init_from_date(zone_policy_date * date,const zone_policy_date * from,const zone_policy_date * rule)1519 zone_policy_date_init_from_date(zone_policy_date *date, const zone_policy_date *from, const zone_policy_date *rule)
1520 {
1521 ya_result ret;
1522
1523 #if DEBUG
1524 format_writer from_fw = {zone_policy_date_format_handler_method, from};
1525 format_writer rule_fw = {zone_policy_date_format_handler_method, rule};
1526 format_writer date_fw = {zone_policy_date_format_handler_method, date};
1527 #endif
1528
1529 if(from->type.type != ZONE_POLICY_ABSOLUTE)
1530 {
1531 #if DEBUG
1532 log_debug1("zone_policy_date_init_from_date(%p, %w, %w): can only work from an absolute time", date, &from_fw, &rule_fw);
1533 #endif
1534 return POLICY_ILLEGAL_DATE_TYPE;
1535 }
1536
1537 switch(rule->type.type)
1538 {
1539 case ZONE_POLICY_RELATIVE:
1540 {
1541 memcpy(date, from, sizeof(zone_policy_date));
1542 #if DEBUG
1543 log_debug1("zone_policy_date_init_from_date(%p, %w, %w): initialising relative time", date, &from_fw, &rule_fw);
1544 #endif
1545 ret = zone_policy_date_init_after_date(date, from, rule->relative.seconds);
1546 #if DEBUG
1547 log_debug1("zone_policy_date_init_from_date: %w = %w + %w", &date_fw, &from_fw, &rule_fw);
1548 #endif
1549 return ret;
1550 }
1551 case ZONE_POLICY_RULE:
1552 {
1553 #if DEBUG
1554 log_debug1("zone_policy_date_init_from_date(%p, %w, %w): initialising rule-based time", date, &from_fw, &rule_fw);
1555 #endif
1556 ret = zone_policy_date_init_from_rule(date, from, rule);
1557 #if DEBUG
1558 log_debug1("zone_policy_date_init_from_date: %w = %w + %w", &date_fw, &from_fw, &rule_fw);
1559 #endif
1560 return ret;
1561 }
1562 default:
1563 {
1564 #if DEBUG
1565 log_debug1("zone_policy_date_init_from_date(%p, %w, %w): unexpected type", date, &from_fw, &rule_fw);
1566 #endif
1567 return POLICY_ILLEGAL_DATE_TYPE;
1568 }
1569 }
1570 }
1571
1572 ya_result
zone_policy_table_init_from_date(zone_policy_table_s * tbl,zone_policy_table_s * with,zone_policy_date * from)1573 zone_policy_table_init_from_date(zone_policy_table_s *tbl, zone_policy_table_s *with, zone_policy_date *from)
1574 {
1575 ya_result ret;
1576
1577 if(with->created.type.type == ZONE_POLICY_RULE)
1578 {
1579 if(ISOK(ret = zone_policy_date_init_from_date(&tbl->created, from, &with->created)))
1580 {
1581 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->publish, &tbl->created, &with->publish)))
1582 {
1583 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->activate, &tbl->publish, &with->activate)))
1584 {
1585 #if DEBUG
1586 format_writer c_fw = {zone_policy_date_format_handler_method, &tbl->created};
1587 format_writer p_fw = {zone_policy_date_format_handler_method, &tbl->publish};
1588 format_writer a_fw = {zone_policy_date_format_handler_method, &tbl->activate};
1589
1590 log_debug("zone_policy_table_init: base c:%w => p:%w => a:%w", &c_fw, &p_fw, &a_fw);
1591 #endif
1592 // compute the future key timings to ensure there will be no period without a signature
1593
1594 zone_policy_date next_creation_date;
1595 zone_policy_date next_publish_date;
1596 zone_policy_date next_activate_date;
1597
1598 if(ISOK(ret = zone_policy_date_init_at_next_date(&next_creation_date, &tbl->activate, &with->created)))
1599 {
1600 if(ISOK(ret = zone_policy_date_init_at_next_date(&next_publish_date, &next_creation_date, &with->publish)))
1601 {
1602 if(ISOK(ret = zone_policy_date_init_at_next_date(&next_activate_date, &next_publish_date, &with->activate)))
1603 {
1604 #if DEBUG
1605 format_writer na_fw = {zone_policy_date_format_handler_method, &next_activate_date};
1606 format_writer np_fw = {zone_policy_date_format_handler_method, &next_publish_date};
1607 format_writer nc_fw = {zone_policy_date_format_handler_method, &next_creation_date};
1608
1609 log_debug("zone_policy_table_init: next c:%w => p:%w => a:%w", &nc_fw, &np_fw, &na_fw);
1610 #endif
1611 if(ISOK(ret = zone_policy_date_init_from_date(&tbl->inactive, &next_activate_date, &with->inactive)))
1612 {
1613 #if HAS_DS_PUBLICATION_SUPPORT
1614 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->delete, &tbl->inactive, &with->delete)))
1615 {
1616 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->ds_add, &tbl->created, &with->ds_add)))
1617 {
1618 ret = zone_policy_date_init_at_next_date(&tbl->ds_del, &tbl->ds_add, &with->ds_del);
1619 }
1620 }
1621 #else
1622 ret = zone_policy_date_init_at_next_date(&tbl->delete, &tbl->inactive, &with->delete);
1623 #if DEBUG
1624 format_writer i_fw = {zone_policy_date_format_handler_method, &tbl->inactive};
1625 format_writer d_fw = {zone_policy_date_format_handler_method, &tbl->delete};
1626
1627 log_debug("zone_policy_table_init_from_date: base i:%w => d:%w", &i_fw, &d_fw);
1628 #endif
1629 #endif
1630 }
1631 }
1632 }
1633 }
1634 }
1635 }
1636 }
1637 }
1638 else if(with->created.type.type == ZONE_POLICY_RELATIVE)
1639 {
1640 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->created, from, &with->created))) // here !
1641 {
1642 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->publish, &tbl->created, &with->publish)))
1643 {
1644 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->activate, zone_policy_table_get_date_by_index(tbl, with->activate.relative.relativeto), &with->activate)))
1645 {
1646 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->inactive, zone_policy_table_get_date_by_index(tbl, with->inactive.relative.relativeto), &with->inactive)))
1647 {
1648 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->delete, zone_policy_table_get_date_by_index(tbl, with->delete.relative.relativeto), &with->delete)))
1649 {
1650 }
1651 }
1652 }
1653 }
1654 }
1655 }
1656 else
1657 {
1658 ret = POLICY_ILLEGAL_DATE_TYPE;
1659 }
1660
1661 return ret;
1662 }
1663
1664 ya_result
zone_policy_table_init_from_created_epoch(zone_policy_table_s * tbl,zone_policy_table_s * with,time_t created_epoch)1665 zone_policy_table_init_from_created_epoch(zone_policy_table_s *tbl, zone_policy_table_s *with, time_t created_epoch)
1666 {
1667 ya_result ret;
1668
1669 if(FAIL(ret = zone_policy_date_init_from_epoch(&tbl->created, created_epoch)))
1670 {
1671 return ret;
1672 }
1673
1674 if(with->created.type.type == ZONE_POLICY_RULE)
1675 {
1676 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->publish, &tbl->created, &with->publish)))
1677 {
1678 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->activate, &tbl->publish, &with->activate)))
1679 {
1680 #if DEBUG
1681 format_writer c_fw = {zone_policy_date_format_handler_method, &tbl->created};
1682 format_writer p_fw = {zone_policy_date_format_handler_method, &tbl->publish};
1683 format_writer a_fw = {zone_policy_date_format_handler_method, &tbl->activate};
1684
1685 log_debug("zone_policy_table_init: base %w => %w => %w", &c_fw, &p_fw, &a_fw);
1686 #endif
1687 // compute the future key timings to ensure there will be no period without a signature
1688
1689 zone_policy_date next_creation_date;
1690 zone_policy_date next_publish_date;
1691 zone_policy_date next_activate_date;
1692
1693 if(ISOK(ret = zone_policy_date_init_at_next_date(&next_creation_date, &tbl->activate, &with->created)))
1694 {
1695 if(ISOK(ret = zone_policy_date_init_at_next_date(&next_publish_date, &next_creation_date, &with->publish)))
1696 {
1697 if(ISOK(ret = zone_policy_date_init_at_next_date(&next_activate_date, &next_publish_date, &with->activate)))
1698 {
1699 #if DEBUG
1700 format_writer na_fw = {zone_policy_date_format_handler_method, &next_activate_date};
1701 format_writer np_fw = {zone_policy_date_format_handler_method, &next_publish_date};
1702 format_writer nc_fw = {zone_policy_date_format_handler_method, &next_creation_date};
1703
1704 log_debug("zone_policy_table_init: next %w => %w => %w", &nc_fw, &np_fw, &na_fw);
1705 #endif
1706 if(ISOK(ret = zone_policy_date_init_from_date(&tbl->inactive, &next_activate_date, &with->inactive)))
1707 {
1708 #if HAS_DS_PUBLICATION_SUPPORT
1709 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->delete, &tbl->inactive, &with->delete)))
1710 {
1711 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->ds_add, &tbl->created, &with->ds_add)))
1712 {
1713 ret = zone_policy_date_init_at_next_date(&tbl->ds_del, &tbl->ds_add, &with->ds_del);
1714 }
1715 }
1716 #else
1717 ret = zone_policy_date_init_at_next_date(&tbl->delete, &tbl->inactive, &with->delete);
1718 #endif
1719 }
1720 }
1721 }
1722 }
1723 }
1724 }
1725 }
1726 else if(with->created.type.type == ZONE_POLICY_RELATIVE)
1727 {
1728 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->publish, &tbl->created, &with->publish)))
1729 {
1730 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->activate, zone_policy_table_get_date_by_index(tbl, with->activate.relative.relativeto), &with->activate)))
1731 {
1732 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->inactive, zone_policy_table_get_date_by_index(tbl, with->inactive.relative.relativeto), &with->inactive)))
1733 {
1734 if(ISOK(ret = zone_policy_date_init_at_next_date(&tbl->delete, zone_policy_table_get_date_by_index(tbl, with->delete.relative.relativeto), &with->delete)))
1735 {
1736 }
1737 }
1738 }
1739 }
1740 }
1741 else
1742 {
1743 ret = POLICY_ILLEGAL_DATE_TYPE;
1744 }
1745
1746 return ret;
1747 }
1748
1749 ya_result
zone_policy_table_init_from_epoch(zone_policy_table_s * tbl,zone_policy_table_s * with,time_t created_epoch)1750 zone_policy_table_init_from_epoch(zone_policy_table_s *tbl, zone_policy_table_s *with, time_t created_epoch)
1751 {
1752 ya_result ret;
1753
1754 zone_policy_date epoch_date;
1755 zone_policy_date_init_from_epoch(&epoch_date, created_epoch);
1756 ret = zone_policy_table_init_from_date(tbl, with, &epoch_date);
1757
1758 return ret;
1759 }
1760
1761 static bool
zone_policy_key_roll_matches(const struct dnssec_policy_key_suite * kr,const dnssec_key * key)1762 zone_policy_key_roll_matches(const struct dnssec_policy_key_suite *kr, const dnssec_key *key)
1763 {
1764 yassert((kr->key->flags == DNSKEY_FLAGS_KSK) || (kr->key->flags == DNSKEY_FLAGS_ZSK));
1765
1766 if(dnskey_get_algorithm(key) == kr->key->algorithm)
1767 {
1768 // matches flags
1769
1770 if((dnskey_get_flags(key) & DNSKEY_FLAGS_KSK) == kr->key->flags)
1771 {
1772 int key_size = dnskey_get_size(key);
1773
1774 if((key_size - kr->key->size) < 48)
1775 {
1776 // algorithm, flags and size are matching
1777 // now what about the times
1778
1779 if((key->epoch_created != 0) &&
1780 (key->epoch_publish != 0) &&
1781 (key->epoch_activate != 0) &&
1782 (key->epoch_inactive != 0) &&
1783 (key->epoch_delete != 0))
1784 {
1785 log_debug1("dnssec-policy: %s: %s: key %05d/%d timings: %T %T %T %T %T",
1786 key->origin,
1787 kr->name,
1788 dnskey_get_tag_const(key), ntohs(key->flags),
1789 key->epoch_created, key->epoch_publish, key->epoch_activate, key->epoch_inactive, key->epoch_delete);
1790
1791 zone_policy_table_s key_tbl;
1792 if(ISOK(zone_policy_table_init_from_created_epoch(&key_tbl, &kr->roll->time_table, key->epoch_created)))
1793 {
1794 time_t key_created = 0, key_publish = 0, key_activate = 0, key_inactive = 0, key_delete = 0;
1795 zone_policy_date_get_epoch(&key_tbl.created, &key_created);
1796 zone_policy_date_get_epoch(&key_tbl.publish, &key_publish);
1797 zone_policy_date_get_epoch(&key_tbl.activate, &key_activate);
1798 zone_policy_date_get_epoch(&key_tbl.inactive, &key_inactive);
1799 zone_policy_date_get_epoch(&key_tbl.delete, &key_delete);
1800
1801 s64 pait = key_inactive - key_activate;
1802 s64 kait = key->epoch_inactive - key->epoch_activate;
1803 s64 dait = labs(pait - kait);
1804
1805 s64 pidt = key_delete - key_inactive;
1806 s64 kidt = key->epoch_delete - key->epoch_inactive;
1807 s64 didt = labs(pidt - kidt);
1808
1809 s64 dc = labs(key_created - key->epoch_created);
1810 s64 dp = labs(key_publish - key->epoch_publish);
1811 s64 da = labs(key_activate - key->epoch_activate);
1812 s64 di = labs(key_inactive - key->epoch_inactive);
1813 s64 dd = labs(key_delete - key->epoch_delete);
1814
1815 //bool match = (/*dc < KEY_POLICY_EPOCH_MATCH_MARGIN &&*/ dp < KEY_POLICY_EPOCH_MATCH_MARGIN && da < KEY_POLICY_EPOCH_MATCH_MARGIN && di < KEY_POLICY_EPOCH_MATCH_MARGIN && dd < KEY_POLICY_EPOCH_MATCH_MARGIN);
1816
1817 // This checks if the key matches were it counts. We already know flags & size are a match, now if it lives long enough and is deleted in time, then it is a match.
1818 // The next key generation will have to align to these timings to find when will be the next one.
1819
1820 bool match = (dait < KEY_POLICY_EPOCH_MATCH_MARGIN) && (didt < KEY_POLICY_EPOCH_MATCH_MARGIN);
1821
1822 log_debug2("dnssec-policy: %s: %s: key %05d/%d pkd: ai=%lli id=%lli, with a margin of %lli",
1823 key->origin,
1824 kr->name,
1825 dnskey_get_tag_const(key), ntohs(key->flags), dait, didt, KEY_POLICY_EPOCH_MATCH_MARGIN);
1826
1827 log_debug2("dnssec-policy: %s: %s: key %05d/%d deltas: (%lli) %lli %lli %lli %lli, with a margin of %lli",
1828 key->origin,
1829 kr->name,
1830 dnskey_get_tag_const(key), ntohs(key->flags), dc, dp, da, di, dd, KEY_POLICY_EPOCH_MATCH_MARGIN);
1831
1832 log_debug1("dnssec-policy: %s: %s: key %05d/%d expects: %T %T %T %T %T : %s",
1833 key->origin,
1834 kr->name,
1835 dnskey_get_tag_const(key), ntohs(key->flags),
1836 key_created, key_publish, key_activate, key_inactive, key_delete,
1837 ((match)?"MATCH":"DIFFERS"));
1838
1839 return match;
1840 } // else zone_policy_table_init_from_created_epoch failed and something is wrong => false
1841 else
1842 {
1843 log_err("dnssec-policy: %s: %s: key %05d/%d matching triggered an error in zone_policy_table_init_from_created_epoch",
1844 key->origin,
1845 kr->name,
1846 dnskey_get_tag_const(key), ntohs(key->flags));
1847 }
1848 }
1849 else
1850 {
1851 log_debug1("dnssec-policy: %s: %s: key %05d/%d is not a match as it has no time table (skipping)",
1852 key->origin,
1853 kr->name,
1854 dnskey_get_tag_const(key), ntohs(key->flags));
1855 }
1856 }
1857 else
1858 {
1859 log_debug1("dnssec-policy: %s: %s: key %05d/%d of size %i is not a match as the expected size is %i (skipping for this key roll)",
1860 key->origin,
1861 kr->name,
1862 dnskey_get_tag_const(key), ntohs(key->flags), key_size, kr->key->size);
1863 }
1864 }
1865 else
1866 {
1867 log_debug1("dnssec-policy: %s: %s: key %05d/%d is not a match as the expected flags is %i (skipping for this key roll)",
1868 key->origin,
1869 kr->name,
1870 dnskey_get_tag_const(key), ntohs(key->flags), ntohs(kr->key->flags));
1871 }
1872 }
1873 else
1874 {
1875 log_debug1("dnssec-policy: %s: %s: key %05d/%d is not a match as the expected algorithm is %i (skipping for this key roll)",
1876 key->origin,
1877 kr->name,
1878 dnskey_get_tag_const(key), ntohs(key->flags), kr->key->algorithm);
1879 }
1880
1881 return FALSE;
1882 }
1883
1884 /**
1885 * Compares keys by activation time, inactivation time and tag.
1886 * Handles 0 epoch as "never" (as expected)
1887 *
1888 * @param a_
1889 * @param b_
1890 * @return
1891 */
1892
zone_policy_dnssec_key_ptr_vector_qsort_by_activation_time_callback(const void * a_,const void * b_)1893 static int zone_policy_dnssec_key_ptr_vector_qsort_by_activation_time_callback(const void *a_, const void *b_)
1894 {
1895 const dnssec_key *a = (const dnssec_key*)a_;
1896 const dnssec_key *b = (const dnssec_key*)b_;
1897
1898 s64 a_a = a->epoch_activate;
1899 if(a_a == 0)
1900 {
1901 a_a = MAX_S64;
1902 }
1903
1904 s64 b_a = b->epoch_activate;
1905 if(b_a == 0)
1906 {
1907 b_a = MAX_S64;
1908 }
1909
1910 s64 r = a_a - b_a;
1911
1912 if(r == 0)
1913 {
1914 s64 a_i = a->epoch_inactive;
1915 if(a_i == 0)
1916 {
1917 a_i = MAX_S64;
1918 }
1919
1920 s64 b_i = b->epoch_inactive;
1921 if(b_i == 0)
1922 {
1923 b_i = MAX_S64;
1924 }
1925
1926 r = a_i - b_i;
1927
1928 if(r == 0)
1929 {
1930 r = dnskey_get_tag_const(a) - dnskey_get_tag_const(b);
1931 }
1932 }
1933
1934 return r;
1935 }
1936
1937 static void
zone_policy_log_debug_key(const char * prefix,const dnssec_key * key)1938 zone_policy_log_debug_key(const char *prefix, const dnssec_key *key)
1939 {
1940 EPOCHZ_DEF2(created, key->epoch_created);
1941 EPOCHZ_DEF2(publish, key->epoch_publish);
1942 EPOCHZ_DEF2(activate, key->epoch_activate);
1943 EPOCHZ_DEF2(inactive, key->epoch_inactive);
1944 EPOCHZ_DEF2(delete, key->epoch_delete);
1945 #if 0 /* fix */
1946 #else
1947 log_debug("%sK%{dnsname}+%03d+%05d/%d created=%1w publish=%1w activate=%1w inactive=%1w delete=%1w",
1948 prefix,
1949 key->owner_name,
1950 key->algorithm,
1951 dnskey_get_tag_const(key),
1952 ntohs(key->flags),
1953 EPOCHZ_REF(created),
1954 EPOCHZ_REF(publish),
1955 EPOCHZ_REF(activate),
1956 EPOCHZ_REF(inactive),
1957 EPOCHZ_REF(delete));
1958 #endif
1959 }
1960
1961 static struct service_s dnssec_policy_command_service_handler = UNINITIALIZED_SERVICE;
1962 static threaded_dll_cw dnssec_policy_command_service_handler_queue;
1963 static bool dnssec_policy_command_service_handler_initialised = FALSE;
1964
1965 static ya_result dnssec_policy_alarm_command_generate_key(dnssec_policy_queue *cmd);
1966 void dnssec_policy_queue_delete_command(dnssec_policy_queue *cmd);
1967
dnssec_policy_command_service(struct service_worker_s * worker)1968 static int dnssec_policy_command_service(struct service_worker_s *worker)
1969 {
1970 log_info("dnssec-policy: command execution service started");
1971
1972 while(service_should_run(worker))
1973 {
1974 dnssec_policy_queue *cmd = (dnssec_policy_queue*)threaded_dll_cw_dequeue(&dnssec_policy_command_service_handler_queue);
1975
1976 if(cmd == NULL)
1977 {
1978 break;
1979 }
1980
1981 switch(cmd->command)
1982 {
1983 case DNSSEC_POLICY_COMMAND_INIT:
1984 {
1985 #if DEBUG
1986 log_debug("dnssec-policy: init command");
1987 #endif
1988 dnssec_policy_queue_delete_command(cmd);
1989 break;
1990 }
1991 case DNSSEC_POLICY_COMMAND_GENERATE_KEY:
1992 {
1993 #if DEBUG
1994 log_debug("dnssec-policy: generate key command");
1995 #endif
1996 dnssec_policy_alarm_command_generate_key(cmd); // deletes the command
1997 break;
1998 }
1999 default:
2000 {
2001 log_err("dnssec-policy: unknown command %i", cmd->command);
2002 dnssec_policy_queue_delete_command(cmd);
2003 break;
2004 }
2005 }
2006
2007 }
2008
2009 log_info("dnssec-policy: command execution service stopped");
2010
2011 return SUCCESS;
2012 }
2013
2014 void
dnssec_policy_command_service_start()2015 dnssec_policy_command_service_start()
2016 {
2017 ya_result ret;
2018 if(!dnssec_policy_command_service_handler_initialised)
2019 {
2020 if(ISOK(ret = service_init_ex(&dnssec_policy_command_service_handler, dnssec_policy_command_service, "dpcmd", 8)))
2021 {
2022 threaded_dll_cw_init(&dnssec_policy_command_service_handler_queue, 1000000);
2023 dnssec_policy_command_service_handler_initialised = TRUE;
2024 }
2025
2026 service_start(&dnssec_policy_command_service_handler);
2027 }
2028 }
2029
2030 void
dnssec_policy_command_service_stop()2031 dnssec_policy_command_service_stop()
2032 {
2033 threaded_dll_cw_finalize(&dnssec_policy_command_service_handler_queue);
2034 }
2035
2036 void
dnssec_policy_command_queue(dnssec_policy_queue * cmd)2037 dnssec_policy_command_queue(dnssec_policy_queue *cmd)
2038 {
2039 threaded_dll_cw_enqueue(&dnssec_policy_command_service_handler_queue, cmd);
2040 }
2041
2042 static ya_result
dnssec_policy_alarm_command_generate_key(dnssec_policy_queue * cmd)2043 dnssec_policy_alarm_command_generate_key(dnssec_policy_queue *cmd)
2044 {
2045 zone_policy_table_s tbl;
2046 zone_policy_date from;
2047 const char *algorithm_name = dns_encryption_algorithm_get_name(cmd->parameters.generate_key.suite->key->algorithm);
2048 char domain[MAX_DOMAIN_LENGTH];
2049 // from ... the time to take as a base for generation, which is the previous
2050
2051
2052 log_info("dnssec-policy: %{dnsname}: generating %s key of size %hu with time parameter %T",
2053 cmd->origin,
2054 algorithm_name,
2055 cmd->parameters.generate_key.suite->key->size,
2056 cmd->epoch);
2057
2058 dnsname_to_cstr(domain, cmd->origin);
2059
2060 ya_result ret;
2061
2062 if(FAIL(ret = zone_policy_date_init_from_epoch(&from, cmd->epoch)))
2063 {
2064 log_err("dnssec-policy: %{dnsname}: failed to generate %s key of size %hu with time parameter %T: %r",
2065 cmd->origin,
2066 algorithm_name,
2067 cmd->parameters.generate_key.suite->key->size,
2068 cmd->epoch,
2069 ret);
2070
2071 zone_policy_key_suite_unmark_processed(cmd->parameters.generate_key.zone_desc, cmd->parameters.generate_key.suite);
2072
2073 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
2074 cmd->parameters.generate_key.suite = NULL;
2075
2076 dnssec_policy_queue_delete_command(cmd);
2077
2078 return ret;
2079 }
2080
2081 if(FAIL(ret = zone_policy_table_init_from_date(&tbl, &cmd->parameters.generate_key.suite->roll->time_table, &from)))
2082 {
2083 log_err("dnssec-policy: %{dnsname}: failed to generate time-table for %s key of size %hu with time parameter %T: %r",
2084 cmd->origin,
2085 algorithm_name,
2086 cmd->parameters.generate_key.suite->key->size,
2087 cmd->epoch,
2088 ret);
2089
2090 zone_policy_key_suite_unmark_processed(cmd->parameters.generate_key.zone_desc, cmd->parameters.generate_key.suite);
2091 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
2092 cmd->parameters.generate_key.suite = NULL;
2093 dnssec_policy_queue_delete_command(cmd);
2094
2095 return ret;
2096 }
2097
2098 log_debug("dnssec-policy: %{dnsname}: time-table for %s key of size %hu with time parameter %T generated",
2099 cmd->origin,
2100 algorithm_name,
2101 cmd->parameters.generate_key.suite->key->size,
2102 cmd->epoch);
2103
2104 time_t created_epoch;
2105 time_t publish_epoch;
2106 time_t activate_epoch;
2107 time_t deactivate_epoch;
2108 time_t unpublish_epoch;
2109
2110 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.created, &created_epoch))) // note: created should be of type ZONE_POLICY_ABSOLUTE
2111 {
2112 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (created_epoch) returned an error: %r", ret);
2113 zone_policy_key_suite_unmark_processed(cmd->parameters.generate_key.zone_desc, cmd->parameters.generate_key.suite);
2114 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
2115 cmd->parameters.generate_key.suite = NULL;
2116 dnssec_policy_queue_delete_command(cmd);
2117 return ret;
2118 }
2119
2120 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.publish, &publish_epoch))) // note: publish should be of type ZONE_POLICY_ABSOLUTE
2121 {
2122 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (publish_epoch) returned an error: %r", ret);
2123 zone_policy_key_suite_unmark_processed(cmd->parameters.generate_key.zone_desc, cmd->parameters.generate_key.suite);
2124 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
2125 cmd->parameters.generate_key.suite = NULL;
2126 dnssec_policy_queue_delete_command(cmd);
2127 return ret;
2128 }
2129
2130 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.activate, &activate_epoch))) // note: activate should be of type ZONE_POLICY_ABSOLUTE
2131 {
2132 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (activate_epoch) returned an error: %r", ret);
2133 zone_policy_key_suite_unmark_processed(cmd->parameters.generate_key.zone_desc, cmd->parameters.generate_key.suite);
2134 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
2135 cmd->parameters.generate_key.suite = NULL;
2136 dnssec_policy_queue_delete_command(cmd);
2137 return ret;
2138 }
2139
2140 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.inactive, &deactivate_epoch))) // note: deactivate should be of type ZONE_POLICY_ABSOLUTE
2141 {
2142 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (deactivate_epoch) returned an error: %r", ret);
2143 zone_policy_key_suite_unmark_processed(cmd->parameters.generate_key.zone_desc, cmd->parameters.generate_key.suite);
2144 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
2145 cmd->parameters.generate_key.suite = NULL;
2146 dnssec_policy_queue_delete_command(cmd);
2147 return ret;
2148 }
2149
2150 if(FAIL(ret = zone_policy_date_get_epoch(&tbl.delete, &unpublish_epoch))) // note: unpublish should be of type ZONE_POLICY_ABSOLUTE
2151 {
2152 log_err("dnssec_policy_queue_add_generate_key_create_at: zone_policy_date_get_epoch (unpublish_epoch) returned an error: %r", ret);
2153 zone_policy_key_suite_unmark_processed(cmd->parameters.generate_key.zone_desc, cmd->parameters.generate_key.suite);
2154 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
2155 cmd->parameters.generate_key.suite = NULL;
2156 dnssec_policy_queue_delete_command(cmd);
2157 return ret;
2158 }
2159
2160 dnssec_key *key;
2161 ret = dnssec_keystore_new_key(cmd->parameters.generate_key.suite->key->algorithm,
2162 cmd->parameters.generate_key.suite->key->size,
2163 cmd->parameters.generate_key.suite->key->flags|DNSKEY_FLAGS_ZSK,
2164 domain,
2165 &key);
2166
2167 if(ISOK(ret))
2168 {
2169 key->epoch_created = created_epoch;
2170 key->epoch_publish = publish_epoch;
2171 key->epoch_activate = activate_epoch;
2172 key->epoch_inactive = deactivate_epoch;
2173 key->epoch_delete = unpublish_epoch;
2174
2175 key->status |= DNSKEY_KEY_HAS_SMART_FIELD_CREATED|DNSKEY_KEY_HAS_SMART_FIELD_PUBLISH|DNSKEY_KEY_HAS_SMART_FIELD_DELETE|DNSKEY_KEY_HAS_SMART_FIELD_ACTIVATE|DNSKEY_KEY_HAS_SMART_FIELD_INACTIVE;
2176
2177 dnssec_keystore_store_private_key(key);
2178 dnssec_keystore_store_public_key(key);
2179
2180 log_info("dnssec-policy: %{dnsname}: key K%{dnsname}+%03d+%05d/%d generated from %T: created at %T, publish at %T, activate at %T, inactive at %T, delete at %T",
2181 cmd->origin, cmd->origin, key->algorithm, dnskey_get_tag(key), ntohs(key->flags), cmd->epoch,
2182 key->epoch_created, key->epoch_publish, key->epoch_activate, key->epoch_inactive, key->epoch_delete
2183 );
2184
2185 #if HAS_EVENT_DYNAMIC_MODULE
2186 if(dynamic_module_dnskey_interface_chain_available())
2187 {
2188 dynamic_module_on_dnskey_created(key);
2189 }
2190 #endif
2191 zdb_zone* zone = zdb_acquire_zone_read_from_fqdn(g_config->database, cmd->origin);
2192 if(zone != NULL)
2193 {
2194 database_service_zone_dnskey_set_alarms(zone);
2195 zdb_zone_release(zone);
2196 }
2197
2198 zone_desc_s *zone_desc = cmd->parameters.generate_key.zone_desc;
2199 dnssec_policy_key_suite *kr = cmd->parameters.generate_key.suite;
2200
2201 if(kr->roll->time_table.created.type.type == ZONE_POLICY_RELATIVE)
2202 {
2203 if(FAIL(ret = dnssec_policy_queue_add_generate_key_create_at(zone_desc, kr, key->epoch_created)))
2204 {
2205 log_err("dnssec-policy: %{dnsname}: %s: failed to setup key generation from previous key: %r", zone_origin(zone_desc), kr->name, ret);
2206 }
2207 }
2208 else if(kr->roll->time_table.created.type.type == ZONE_POLICY_RULE)
2209 {
2210 if(FAIL(ret = dnssec_policy_queue_add_generate_key_active_at(zone_desc, kr, key->epoch_inactive, NULL)))
2211 {
2212 log_err("dnssec-policy: %{dnsname}: %s: failed to setup key generation from previous end period: %r", zone_origin(zone_desc), kr->name, ret);
2213 }
2214 }
2215
2216 dnskey_release(key);
2217 }
2218 else
2219 {
2220 log_err("dnssec-policy: %{dnsname}: failed to generate key: %r This is likely to break the policy maintenance state for the zone.", cmd->origin, ret);
2221 }
2222
2223 zone_policy_key_suite_unmark_processed(cmd->parameters.generate_key.zone_desc, cmd->parameters.generate_key.suite);
2224
2225 dnssec_policy_key_suite_release(cmd->parameters.generate_key.suite);
2226 cmd->parameters.generate_key.suite = NULL;
2227
2228 dnssec_policy_queue_delete_command(cmd);
2229
2230 return ret;
2231 }
2232
2233 static ya_result
dnssec_policy_alarm_handler(void * args,bool cancel)2234 dnssec_policy_alarm_handler(void *args, bool cancel)
2235 {
2236 dnssec_policy_queue *cmd = (dnssec_policy_queue*)args;
2237
2238 #if DEBUG
2239 log_debug("dnssec-policy: alarm(%p,%i)", cmd, cancel);
2240 #endif
2241
2242 if(cancel)
2243 {
2244 dnssec_policy_queue_remove_command(cmd);
2245 dnssec_policy_queue_delete_command(cmd);
2246 return SUCCESS;
2247 }
2248
2249 dnssec_policy_command_queue(cmd);
2250
2251 return SUCCESS;
2252 }
2253
2254 static void
zone_policy_nsec_enable(zdb_zone * zone)2255 zone_policy_nsec_enable(zdb_zone *zone)
2256 {
2257 //zdb_zone_double_lock();
2258 zdb_zone_double_lock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER, ZDB_ZONE_MUTEX_DYNUPDATE);
2259 zdb_rr_label_flag_or(zone->apex, ZDB_RR_LABEL_NSEC);
2260 if(zdb_rr_label_has_rrset(zone->apex, TYPE_DNSKEY))
2261 {
2262 nsec_zone_set_status(zone, ZDB_ZONE_MUTEX_DYNUPDATE, NSEC_ZONE_ENABLED|NSEC_ZONE_GENERATING);
2263 }
2264 zdb_zone_double_unlock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER, ZDB_ZONE_MUTEX_DYNUPDATE);
2265 }
2266
2267 static void
zone_policy_nsec3_enable(zdb_zone * zone,dnssec_denial * denial)2268 zone_policy_nsec3_enable(zdb_zone *zone, dnssec_denial *denial)
2269 {
2270 u8 *salt;
2271 u8 salt_len;
2272 u8 salt_buffer[256];
2273
2274 if(denial->salt != NULL)
2275 {
2276 salt = denial->salt;
2277 salt_len = denial->salt_length;
2278 }
2279 else
2280 {
2281 random_ctx rnd = random_init_auto();
2282
2283 salt = &salt_buffer[0];
2284 salt_len = denial->salt_length;
2285 for(int i = 0; i < salt_len; ++i)
2286 {
2287 salt[i] = random_next(rnd);
2288 }
2289
2290 random_finalize(rnd);
2291 }
2292
2293 u8 flags = (denial->optout)?1:0;
2294 u8 current_status = 0;
2295
2296 zdb_zone_lock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER);
2297
2298 if(zdb_rr_label_has_rrset(zone->apex, TYPE_DNSKEY))
2299 {
2300 ya_result got_status = nsec3_zone_get_status(zone, denial->algorithm, flags, denial->iterations, salt, salt_len, ¤t_status);
2301 zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER);
2302 if(got_status == 1)
2303 {
2304 if(current_status & NSEC3_ZONE_ENABLED)
2305 {
2306 return;
2307 }
2308 }
2309 zdb_zone_double_lock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER, ZDB_ZONE_MUTEX_DYNUPDATE);
2310 nsec3_zone_set_status(zone, ZDB_ZONE_MUTEX_DYNUPDATE, denial->algorithm, flags, denial->iterations, salt, salt_len, NSEC3_ZONE_ENABLED|NSEC3_ZONE_GENERATING);
2311 zdb_zone_double_unlock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER, ZDB_ZONE_MUTEX_DYNUPDATE);
2312 }
2313 else
2314 {
2315 zdb_zone_unlock(zone, ZDB_ZONE_MUTEX_SIMPLEREADER);
2316 }
2317 }
2318
2319 ya_result
zone_policy_roll_create_from_rules(const char * id,const zone_policy_rule_definition_s * generate,const zone_policy_rule_definition_s * publish,const zone_policy_rule_definition_s * activate,const zone_policy_rule_definition_s * inactive,const zone_policy_rule_definition_s * remove,const zone_policy_rule_definition_s * ds_publish,const zone_policy_rule_definition_s * ds_remove)2320 zone_policy_roll_create_from_rules(const char *id,
2321 const zone_policy_rule_definition_s *generate,
2322 const zone_policy_rule_definition_s *publish,
2323 const zone_policy_rule_definition_s *activate,
2324 const zone_policy_rule_definition_s *inactive,
2325 const zone_policy_rule_definition_s *remove,
2326 const zone_policy_rule_definition_s *ds_publish,
2327 const zone_policy_rule_definition_s *ds_remove)
2328 {
2329 log_debug("dnssec-policy-roll: %s: (rules stuff)", id);
2330
2331 dnssec_policy_roll *dpr;
2332 ZALLOC_OBJECT_OR_DIE( dpr, dnssec_policy_roll, DPOLROLL_TAG);
2333 dpr->name = strdup(id);
2334
2335 group_mutex_write_lock(&dnssec_policy_roll_set_mtx);
2336 ptr_node *node = ptr_set_insert(&dnssec_policy_roll_set, dpr->name);
2337
2338 if(node->value != NULL)
2339 {
2340 dnssec_policy_roll_release((dnssec_policy_roll*)node->value);
2341 node->key = dpr->name;
2342 }
2343
2344 zone_policy_rule_init(&dpr->time_table.created.rule, generate);
2345 zone_policy_rule_init(&dpr->time_table.publish.rule, publish);
2346 zone_policy_rule_init(&dpr->time_table.activate.rule, activate);
2347 zone_policy_rule_init(&dpr->time_table.inactive.rule, inactive);
2348 zone_policy_rule_init(&dpr->time_table.delete.rule, remove);
2349 #if HAS_DS_PUBLICATION_SUPPORT
2350 zone_policy_rule_init(&dpr->time_table.ds_add.rule, ds_publish);
2351 zone_policy_rule_init(&dpr->time_table.ds_del.rule, ds_remove);
2352 #else
2353 (void)ds_publish;
2354 (void)ds_remove;
2355 #endif
2356 dpr->rc = 1;
2357 node->value = dpr;
2358
2359 group_mutex_write_unlock(&dnssec_policy_roll_set_mtx);
2360 return 0;
2361 }
2362
2363 ya_result
zone_policy_roll_create_from_relatives(const char * id,const zone_policy_relative_s * generate,u8 generate_from,const zone_policy_relative_s * publish,u8 publish_from,const zone_policy_relative_s * activate,u8 activate_from,const zone_policy_relative_s * inactive,u8 inactive_from,const zone_policy_relative_s * remove,u8 remove_from,const zone_policy_relative_s * ds_publish,u8 ds_publish_from,const zone_policy_relative_s * ds_remove,u8 ds_remove_from)2364 zone_policy_roll_create_from_relatives(const char *id,
2365 const zone_policy_relative_s *generate,
2366 u8 generate_from,
2367 const zone_policy_relative_s *publish,
2368 u8 publish_from,
2369 const zone_policy_relative_s *activate,
2370 u8 activate_from,
2371 const zone_policy_relative_s *inactive,
2372 u8 inactive_from,
2373 const zone_policy_relative_s *remove,
2374 u8 remove_from
2375 #if HAS_DS_PUBLICATION_SUPPORT
2376 ,
2377 const zone_policy_relative_s *ds_publish,
2378 u8 ds_publish_from,
2379 const zone_policy_relative_s *ds_remove,
2380 u8 ds_remove_from
2381 #endif
2382 )
2383 {
2384 log_debug("dnssec-policy-roll: %s: (relative stuff)", id);
2385
2386 if(generate->seconds < 60)
2387 {
2388 log_err("dnssec-policy: %s: generate parameter cannot be less than one minute", id);
2389 return POLICY_ILLEGAL_DATE_PARAMETERS;
2390 }
2391
2392 if(inactive->seconds - activate->seconds < 60)
2393 {
2394 log_err("dnssec-policy: %s: key appears to not be activated for even one minute", id);
2395 return POLICY_ILLEGAL_DATE_PARAMETERS;
2396 }
2397
2398 if(generate->seconds < 3600)
2399 {
2400 log_warn("dnssec-policy: %s: key is generated every %i seconds. Keys are expected to be generated every few weeks, months or years.", id, generate->seconds);
2401 }
2402
2403 if(inactive->seconds - activate->seconds < generate->seconds)
2404 {
2405 log_warn("dnssec-policy: %s: key appears to not be activated for less time than the generation period", id);
2406 }
2407
2408 dnssec_policy_roll *dpr;
2409 ZALLOC_OBJECT_OR_DIE( dpr, dnssec_policy_roll, DPOLROLL_TAG);
2410 dpr->name = strdup(id);
2411
2412 group_mutex_write_lock(&dnssec_policy_roll_set_mtx);
2413 ptr_node *node = ptr_set_insert(&dnssec_policy_roll_set, dpr->name);
2414
2415 if(node->value != NULL)
2416 {
2417 dnssec_policy_roll_release((dnssec_policy_roll*)node->value);
2418 node->value = NULL;
2419 }
2420
2421 dpr->time_table.created.relative = *generate;
2422 dpr->time_table.publish.relative = *publish;
2423 dpr->time_table.activate.relative = *activate;
2424 dpr->time_table.inactive.relative = *inactive;
2425 dpr->time_table.delete.relative = *remove;
2426
2427 dpr->time_table.created.relative.seconds += 59;
2428 dpr->time_table.created.relative.seconds -= (dpr->time_table.created.relative.seconds % 60);
2429
2430 dpr->time_table.publish.relative.seconds += 59;
2431 dpr->time_table.publish.relative.seconds -= (dpr->time_table.publish.relative.seconds % 60);
2432
2433 dpr->time_table.activate.relative.seconds += 59;
2434 dpr->time_table.activate.relative.seconds -= (dpr->time_table.activate.relative.seconds % 60);
2435
2436 dpr->time_table.inactive.relative.seconds += 59;
2437 dpr->time_table.inactive.relative.seconds -= (dpr->time_table.inactive.relative.seconds % 60);
2438
2439 dpr->time_table.delete.relative.seconds += 59;
2440 dpr->time_table.delete.relative.seconds -= (dpr->time_table.delete.relative.seconds % 60);
2441
2442 #if HAS_DS_PUBLICATION_SUPPORT
2443 dpr->time_table.ds_add.relative = *ds_publish;
2444 dpr->time_table.ds_del.relative = *ds_remove;
2445 #endif
2446
2447 yassert(publish_from <= ZONE_POLICY_RELATIVE_TO_GENERATE);
2448 yassert(activate_from <= ZONE_POLICY_RELATIVE_TO_PUBLISH);
2449 yassert(inactive_from <= ZONE_POLICY_RELATIVE_TO_INACTIVE);
2450 yassert(remove_from <= ZONE_POLICY_RELATIVE_TO_REMOVE);
2451 #if HAS_DS_PUBLICATION_SUPPORT
2452 yassert(ds_publish_from <= ZONE_POLICY_RELATIVE_TO_DS_PUBLISH);
2453 yassert(ds_remove_from <= ZONE_POLICY_RELATIVE_TO_DS_REMOVE);
2454 #endif
2455
2456 dpr->time_table.created.relative.relativeto = generate_from;
2457 dpr->time_table.publish.relative.relativeto = publish_from;
2458 dpr->time_table.activate.relative.relativeto = activate_from;
2459 dpr->time_table.inactive.relative.relativeto = inactive_from;
2460 dpr->time_table.delete.relative.relativeto = remove_from;
2461 #if HAS_DS_PUBLICATION_SUPPORT
2462 dpr->time_table.ds_add.relative.relativeto = ds_publish_from;
2463 dpr->time_table.ds_del.relative.relativeto = ds_remove_from;
2464 #endif
2465
2466 dpr->rc = 1;
2467 node->key = dpr->name;
2468 node->value = dpr;
2469
2470 group_mutex_write_unlock(&dnssec_policy_roll_set_mtx);
2471
2472 return 0;
2473 }
2474
2475 dnssec_policy_roll *
dnssec_policy_roll_acquire_from_name(const char * id)2476 dnssec_policy_roll_acquire_from_name(const char *id)
2477 {
2478 dnssec_policy_roll *dpr = NULL;
2479
2480 group_mutex_read_lock(&dnssec_policy_roll_set_mtx);
2481
2482 ptr_node *node = ptr_set_find(&dnssec_policy_roll_set, id);
2483 if(node != NULL)
2484 {
2485 dpr = (dnssec_policy_roll*)node->value;
2486 group_mutex_write_lock(&dnssec_policy_roll_mtx);
2487 ++dpr->rc;
2488 group_mutex_write_unlock(&dnssec_policy_roll_mtx);
2489 }
2490
2491 group_mutex_read_unlock(&dnssec_policy_roll_set_mtx);
2492
2493 return dpr;
2494 }
2495
2496 ya_result
dnssec_policy_roll_test_all(time_t active_at,u32 duration_seconds,bool print_text,bool log_text)2497 dnssec_policy_roll_test_all(time_t active_at, u32 duration_seconds, bool print_text, bool log_text)
2498 {
2499 ya_result ret = SUCCESS;
2500
2501 group_mutex_read_lock(&dnssec_policy_roll_set_mtx);
2502
2503 ptr_set_iterator iter;
2504 ptr_set_iterator_init(&dnssec_policy_roll_set, &iter);
2505 while(ptr_set_iterator_hasnext(&iter))
2506 {
2507 ptr_node *node = ptr_set_iterator_next_node(&iter);
2508 if(node->value != NULL)
2509 {
2510 dnssec_policy_roll *dpr = (dnssec_policy_roll*)node->value;
2511 if(FAIL(ret = dnssec_policy_roll_test(dpr, active_at, duration_seconds, print_text, log_text)))
2512 {
2513 break;
2514 }
2515 }
2516 }
2517
2518 group_mutex_read_unlock(&dnssec_policy_roll_set_mtx);
2519
2520 return ret;
2521 }
2522
2523 dnssec_policy_roll *
dnssec_policy_roll_acquire_from_index(int index)2524 dnssec_policy_roll_acquire_from_index(int index)
2525 {
2526 dnssec_policy_roll *dpr = NULL;
2527
2528 if(index >= 0)
2529 {
2530 group_mutex_read_lock(&dnssec_policy_roll_set_mtx);
2531
2532 ptr_set_iterator iter;
2533 ptr_set_iterator_init(&dnssec_policy_roll_set, &iter);
2534 while(ptr_set_iterator_hasnext(&iter))
2535 {
2536 ptr_node *node = ptr_set_iterator_next_node(&iter);
2537 if(index == 0)
2538 {
2539 if(node->value != NULL)
2540 {
2541 dpr = (dnssec_policy_roll*)node->value;
2542 group_mutex_write_lock(&dnssec_policy_roll_mtx);
2543 ++dpr->rc;
2544 group_mutex_write_unlock(&dnssec_policy_roll_mtx);
2545 }
2546
2547 break;
2548 }
2549
2550 --index;
2551 }
2552
2553 group_mutex_read_unlock(&dnssec_policy_roll_set_mtx);
2554 }
2555
2556 return dpr;
2557 }
2558
2559
2560 void
dnssec_policy_roll_release(dnssec_policy_roll * dpr)2561 dnssec_policy_roll_release(dnssec_policy_roll *dpr)
2562 {
2563 group_mutex_write_lock(&dnssec_policy_roll_mtx);
2564 if(--dpr->rc == 0)
2565 {
2566 // destroy the table
2567 if(dpr->time_table.created.type.type == ZONE_POLICY_RULE)
2568 {
2569 zone_policy_rule_finalize(&dpr->time_table.created.rule);
2570 }
2571 if(dpr->time_table.publish.type.type == ZONE_POLICY_RULE)
2572 {
2573 zone_policy_rule_finalize(&dpr->time_table.publish.rule);
2574 }
2575 if(dpr->time_table.activate.type.type == ZONE_POLICY_RULE)
2576 {
2577 zone_policy_rule_finalize(&dpr->time_table.activate.rule);
2578 }
2579 if(dpr->time_table.inactive.type.type == ZONE_POLICY_RULE)
2580 {
2581 zone_policy_rule_finalize(&dpr->time_table.inactive.rule);
2582 }
2583 if(dpr->time_table.delete.type.type == ZONE_POLICY_RULE)
2584 {
2585 zone_policy_rule_finalize(&dpr->time_table.delete.rule);
2586 }
2587 #if HAS_DS_PUBLICATION_SUPPORT
2588 if(dpr->time_table.ds_add.type.type == ZONE_POLICY_RULE)
2589 {
2590 zone_policy_rule_finalize(&dpr->time_table.ds_add.rule);
2591 }
2592 if(dpr->time_table.ds_del.type.type == ZONE_POLICY_RULE)
2593 {
2594 zone_policy_rule_finalize(&dpr->time_table.ds_del.rule);
2595 }
2596 #endif
2597 free(dpr->name);
2598 ZFREE_OBJECT(dpr);
2599 }
2600 group_mutex_write_unlock(&dnssec_policy_roll_mtx);
2601 }
2602
2603 dnssec_denial *
dnssec_policy_denial_create(const char * id,u8 algorithm,u16 iterations,const u8 * salt,u8 salt_length,u32 resalting,bool optout)2604 dnssec_policy_denial_create(const char *id, u8 algorithm, u16 iterations, const u8 *salt, u8 salt_length, u32 resalting, bool optout)
2605 {
2606 log_debug("dnssec-policy-denial: %s: algorithm=%hhu, iterations=%hu, salt@%p, salt_length=%hhu, resalting=%u",
2607 id, algorithm, iterations, salt, salt_length, resalting);
2608
2609 dnssec_denial *dd = NULL;
2610 ZALLOC_OBJECT_OR_DIE( dd, dnssec_denial, DPOLDNIL_TAG);
2611 dd->name = strdup(id);
2612 if(salt != NULL && salt_length > 0)
2613 {
2614 ZALLOC_ARRAY_OR_DIE(u8*, dd->salt, salt_length, DPOLSALT_TAG);
2615 memcpy(dd->salt, salt, salt_length);
2616 }
2617 else
2618 {
2619 dd->salt = NULL;
2620 }
2621
2622 dd->resalting = resalting;
2623 dd->iterations = iterations;
2624 dd->algorithm = algorithm;
2625 dd->salt_length = salt_length;
2626 dd->optout = optout;
2627 dd->rc = 1;
2628
2629 group_mutex_write_lock(&dnssec_denial_set_mtx);
2630 ptr_node *node = ptr_set_insert(&dnssec_denial_set, dd->name);
2631 if(node->value != NULL)
2632 {
2633 dnssec_policy_denial_release((dnssec_denial*)node->value);
2634 }
2635 node->key = dd->name;
2636 node->value = dd;
2637 group_mutex_write_unlock(&dnssec_denial_set_mtx);
2638
2639 return dd;
2640 }
2641
2642
2643 dnssec_denial *
dnssec_policy_denial_acquire(const char * id)2644 dnssec_policy_denial_acquire(const char *id)
2645 {
2646 dnssec_denial *dd = NULL;
2647 group_mutex_read_lock(&dnssec_denial_set_mtx);
2648 ptr_node *node = ptr_set_find(&dnssec_denial_set, id);
2649 if(node != NULL && node->value != NULL)
2650 {
2651 dd = (dnssec_denial*)node->value;
2652 group_mutex_write_lock(&dnssec_denial_mtx);
2653 ++dd->rc;
2654 group_mutex_write_unlock(&dnssec_denial_mtx);
2655 }
2656 group_mutex_read_unlock(&dnssec_denial_set_mtx);
2657
2658 return dd;
2659 }
2660
2661 void
dnssec_policy_denial_release(dnssec_denial * dd)2662 dnssec_policy_denial_release(dnssec_denial *dd)
2663 {
2664 if(dd == NULL) return;
2665
2666 group_mutex_write_lock(&dnssec_denial_mtx);
2667 if(--dd->rc == 0)
2668 {
2669 if(dd->salt != NULL)
2670 {
2671 ZFREE_ARRAY(dd->salt, dd->salt_length);
2672 }
2673 free(dd->name);
2674 ZFREE_OBJECT(dd);
2675 }
2676 group_mutex_write_unlock(&dnssec_denial_mtx);
2677 }
2678
2679 dnssec_policy_key *
dnssec_policy_key_create(const char * id,u8 algorithm,u16 size,bool ksk,char * engine)2680 dnssec_policy_key_create(const char *id, u8 algorithm, u16 size, bool ksk, char* engine)
2681 {
2682 log_debug("dnssec-policy-key: %s: algorithm=%hhu, size=%hu, ksk=%i, engine=%s",
2683 id, algorithm, size, ksk, STRNULL(engine));
2684
2685 (void)engine;
2686 dnssec_policy_key *dpk = NULL;
2687
2688 ZALLOC_OBJECT_OR_DIE( dpk, dnssec_policy_key, DPOLKEY_TAG);
2689 dpk->name = strdup(id);
2690
2691 dpk->flags = (ksk)?DNSKEY_FLAGS_KSK:DNSKEY_FLAGS_ZSK;
2692 dpk->size = size;
2693 dpk->algorithm = algorithm;
2694 dpk->rc = 1;
2695
2696 group_mutex_write_lock(&dnssec_policy_key_set_mtx);
2697 ptr_node *node = ptr_set_insert(&dnssec_policy_key_set, dpk->name);
2698 if(node->value != NULL)
2699 {
2700 dnssec_policy_key_release((dnssec_policy_key*)node->value);
2701 node->key = dpk->name;
2702 }
2703 node->value = dpk;
2704 group_mutex_write_unlock(&dnssec_policy_key_set_mtx);
2705
2706 return dpk;
2707 }
2708
2709 dnssec_policy_key *
dnssec_policy_key_acquire_from_name(const char * id)2710 dnssec_policy_key_acquire_from_name(const char *id)
2711 {
2712 dnssec_policy_key *dpk = NULL;
2713
2714 group_mutex_read_lock(&dnssec_policy_key_set_mtx);
2715 ptr_node *node = ptr_set_find(&dnssec_policy_key_set, id);
2716 if(node != NULL && node->value != NULL)
2717 {
2718 dpk = (dnssec_policy_key*)node->value;
2719 group_mutex_write_lock(&dnssec_policy_key_mtx);
2720 ++dpk->rc;
2721 group_mutex_write_unlock(&dnssec_policy_key_mtx);
2722 }
2723 group_mutex_read_unlock(&dnssec_policy_key_set_mtx);
2724 return dpk;
2725 }
2726
2727 void
dnssec_policy_key_release(dnssec_policy_key * dpk)2728 dnssec_policy_key_release(dnssec_policy_key *dpk)
2729 {
2730 group_mutex_write_lock(&dnssec_policy_key_mtx);
2731 if(--dpk->rc == 0)
2732 {
2733 free(dpk->name);
2734 ZFREE_OBJECT(dpk);
2735 }
2736 group_mutex_write_unlock(&dnssec_policy_key_mtx);
2737 }
2738
2739 dnssec_policy_key_suite *
dnssec_policy_key_suite_create(const char * id,dnssec_policy_key * dpk,dnssec_policy_roll * dpr)2740 dnssec_policy_key_suite_create(const char *id, dnssec_policy_key *dpk, dnssec_policy_roll *dpr)
2741 {
2742 log_debug("dnssec-policy-key-suite: %s: policy-key=%s, policy-roll=%s", id, dpk->name, dpr->name);
2743
2744 dnssec_policy_key_suite *dpks = NULL;
2745
2746 ZALLOC_OBJECT_OR_DIE( dpks, dnssec_policy_key_suite, DPOLKYST_TAG);
2747 dpks->name = strdup(id);
2748 dpks->key = dnssec_policy_key_acquire_from_name(dpk->name);
2749 dpks->roll = dnssec_policy_roll_acquire_from_name(dpr->name);
2750 dpks->rc = 1;
2751
2752 group_mutex_write_lock(&dnssec_policy_key_suite_set_mtx);
2753 ptr_node *node = ptr_set_insert(&dnssec_policy_key_suite_set, dpks->name);
2754 if(node->value != NULL)
2755 {
2756 dnssec_policy_key_suite_release((dnssec_policy_key_suite*)node->value);
2757 }
2758 node->key = dpks->name;
2759 node->value = dpks;
2760 group_mutex_write_unlock(&dnssec_policy_key_suite_set_mtx);
2761
2762 return dpks;
2763 }
2764
2765 dnssec_policy_key_suite *
dnssec_policy_key_suite_acquire_from_name(const char * id)2766 dnssec_policy_key_suite_acquire_from_name(const char *id)
2767 {
2768 dnssec_policy_key_suite *dpks = NULL;
2769
2770 group_mutex_read_lock(&dnssec_policy_key_suite_set_mtx);
2771 ptr_node *node = ptr_set_find(&dnssec_policy_key_suite_set, id);
2772 if(node != NULL && node->value != NULL)
2773 {
2774 dpks = (dnssec_policy_key_suite*)node->value;
2775 group_mutex_write_lock(&dnssec_policy_key_suite_mtx);
2776 ++dpks->rc;
2777 group_mutex_write_unlock(&dnssec_policy_key_suite_mtx);
2778 }
2779 group_mutex_read_unlock(&dnssec_policy_key_suite_set_mtx);
2780 return dpks;
2781 }
2782
2783 void
dnssec_policy_key_suite_acquire(dnssec_policy_key_suite * dpks)2784 dnssec_policy_key_suite_acquire(dnssec_policy_key_suite *dpks)
2785 {
2786 group_mutex_write_lock(&dnssec_policy_key_suite_mtx);
2787 ++dpks->rc;
2788 group_mutex_write_unlock(&dnssec_policy_key_suite_mtx);
2789 }
2790
2791
2792 void
dnssec_policy_key_suite_release(dnssec_policy_key_suite * dpks)2793 dnssec_policy_key_suite_release(dnssec_policy_key_suite *dpks)
2794 {
2795 group_mutex_write_lock(&dnssec_policy_key_suite_mtx);
2796 if(--dpks->rc == 0)
2797 {
2798 free(dpks->name);
2799 dnssec_policy_key_release(dpks->key);
2800 dnssec_policy_roll_release(dpks->roll);
2801 ZFREE_OBJECT(dpks);
2802 }
2803 group_mutex_write_unlock(&dnssec_policy_key_suite_mtx);
2804 }
2805
2806 dnssec_policy *
dnssec_policy_create(char * name,dnssec_denial * dd,ptr_vector * key_suite)2807 dnssec_policy_create(char *name, dnssec_denial *dd, ptr_vector *key_suite)
2808 {
2809 dnssec_policy *dp = NULL;
2810
2811 log_debug("dnssec-policy: %s: denial=%s", name, (dd!=NULL)?dd->name:"nsec");
2812 bool has_zsk = FALSE;
2813 ZALLOC_OBJECT_OR_DIE( dp, dnssec_policy, DNSECPOL_TAG);
2814 dp->name = strdup(name);
2815 dp->denial= (dd!=NULL)?dnssec_policy_denial_acquire(dd->name):NULL;
2816 ptr_vector_init_ex(&dp->key_suite, ptr_vector_size(key_suite));
2817 for(int i = 0; i <= ptr_vector_last_index(key_suite); ++i)
2818 {
2819 dnssec_policy_key_suite *dpks = (dnssec_policy_key_suite*)ptr_vector_get(key_suite, i);
2820 if((dpks->key->flags & DNSKEY_FLAGS_KSK) != DNSKEY_FLAGS_KSK)
2821 {
2822 has_zsk = TRUE;
2823 }
2824
2825 dnssec_policy_key_suite *dpks_a = dnssec_policy_key_suite_acquire_from_name(dpks->name);
2826
2827 for(int j = 0; j <= ptr_vector_last_index(&dp->key_suite); ++j)
2828 {
2829 dnssec_policy_key_suite* dpks_b = (dnssec_policy_key_suite*)ptr_vector_get(&dp->key_suite, j);
2830 if(dpks_a == dpks_b)
2831 {
2832 // dup
2833 log_warn("dnssec-policy: %s: key-suite %s is a duplicate entry", name, dpks->name);
2834 dnssec_policy_key_suite_release(dpks_a);
2835 dpks_a = NULL;
2836 break;
2837 }
2838 }
2839
2840 if(dpks_a != NULL)
2841 {
2842 ptr_vector_append(&dp->key_suite, dpks_a);
2843 log_debug("dnssec-policy: %s: key-suite %s added", name, dpks->name);
2844 }
2845 }
2846 dp->rc = 1;
2847
2848 if(has_zsk)
2849 {
2850 log_warn("dnssec-policy: %s: no key-signing-key in the key-suite", name);
2851 }
2852
2853 group_mutex_write_lock(&dnssec_policy_set_mtx);
2854 ptr_node *node = ptr_set_insert(&dnssec_policy_set, dp->name);
2855 if(node->value != NULL)
2856 {
2857 dnssec_policy_release((dnssec_policy*)node->value);
2858 node->key = dp->name;
2859 }
2860 node->value = dp;
2861 group_mutex_write_unlock(&dnssec_policy_set_mtx);
2862
2863 return dp;
2864 }
2865
2866 dnssec_policy *
dnssec_policy_acquire_from_name(const char * id)2867 dnssec_policy_acquire_from_name(const char *id)
2868 {
2869 dnssec_policy *dp = NULL;
2870
2871 group_mutex_read_lock(&dnssec_policy_set_mtx);
2872 ptr_node *node = ptr_set_find(&dnssec_policy_set, id);
2873 if(node != NULL && node->value != NULL)
2874 {
2875 dp = (dnssec_policy*)node->value;
2876 group_mutex_write_lock(&dnssec_policy_mtx);
2877 ++dp->rc;
2878 group_mutex_write_unlock(&dnssec_policy_mtx);
2879 }
2880 group_mutex_read_unlock(&dnssec_policy_set_mtx);
2881 return dp;
2882 }
2883
2884 void
dnssec_policy_acquire(dnssec_policy * dp)2885 dnssec_policy_acquire(dnssec_policy *dp)
2886 {
2887 group_mutex_write_lock(&dnssec_policy_mtx);
2888 ++dp->rc;
2889 group_mutex_write_unlock(&dnssec_policy_mtx);
2890 }
2891
2892 void
dnssec_policy_release(dnssec_policy * dp)2893 dnssec_policy_release(dnssec_policy *dp)
2894 {
2895 group_mutex_write_lock(&dnssec_policy_mtx);
2896 if(--dp->rc == 0)
2897 {
2898 free(dp->name);
2899 dnssec_policy_denial_release(dp->denial);
2900 for(int i = 0; i <= ptr_vector_last_index(&dp->key_suite); ++i)
2901 {
2902 dnssec_policy_key_suite *dpks = (dnssec_policy_key_suite*)ptr_vector_get(&dp->key_suite, i);
2903 dnssec_policy_key_suite_release(dpks);
2904 }
2905 ptr_vector_destroy(&dp->key_suite);
2906 ZFREE_OBJECT(dp);
2907 }
2908 group_mutex_write_unlock(&dnssec_policy_mtx);
2909 }
2910
2911 ya_result
dnssec_policy_zone_desc_config(const char * value,void * dest,anytype sizeoftarget)2912 dnssec_policy_zone_desc_config(const char *value, void *dest, anytype sizeoftarget)
2913 {
2914 (void)sizeoftarget;
2915 dnssec_policy **dp = (dnssec_policy**)dest;
2916 if(*dp != NULL)
2917 {
2918 dnssec_policy_release(*dp);
2919 }
2920 if(value != NULL)
2921 {
2922 *dp = dnssec_policy_acquire_from_name(value);
2923 return (*dp != NULL)?SUCCESS:POLICY_UNDEFINED;
2924 }
2925 else
2926 {
2927 return POLICY_NULL_REQUESTED;
2928 }
2929 }
2930
2931 static void
zone_policy_process_release_keys_cb(void * ptr)2932 zone_policy_process_release_keys_cb(void *ptr)
2933 {
2934 dnssec_key *key = (dnssec_key*)ptr;
2935 if(key != NULL)
2936 {
2937 dnskey_release(key);
2938 }
2939 }
2940
2941 ////////////////////////////////////////////////////////////////////////////////////////////////
2942 //
2943 // This is where yadifad and the keyroll fundamentally differs
2944 //
2945 ////////////////////////////////////////////////////////////////////////////////////////////////
2946
2947 /**
2948 * Sets the DNSSEC mode of the zone using the policy.
2949 */
2950
2951 ya_result
zone_policy_process_dnssec_chain(zone_desc_s * zone_desc)2952 zone_policy_process_dnssec_chain(zone_desc_s *zone_desc)
2953 {
2954 zdb_zone *zone = zone_desc->loaded_zone;
2955
2956 if(zone == NULL)
2957 {
2958 return INVALID_STATE_ERROR;
2959 }
2960
2961 const dnssec_policy *policy = zone_desc->dnssec_policy;
2962
2963 if(policy == NULL)
2964 {
2965 return SUCCESS; // nothing to do
2966 }
2967
2968 u8 zone_dnssec_type = zone_policy_guess_dnssec_type(zone);
2969
2970 if(policy->denial == NULL)
2971 {
2972 // zone is expected to be NSEC
2973
2974 zone_set_maintain_mode(zone, ZDB_ZONE_MAINTAIN_NSEC);
2975
2976 switch(zone_dnssec_type)
2977 {
2978 case ZONE_DNSSEC_FL_NOSEC:
2979 {
2980 // generate NSEC now
2981 log_info("dnssec-policy: %{dnsname}: zone will be secured with NSEC", zone_origin(zone_desc));
2982 zone_policy_nsec_enable(zone);
2983 break;
2984 }
2985 case ZONE_DNSSEC_FL_NSEC:
2986 {
2987 // do nothing
2988 if((zone->nsec.nsec->children.lr.right == NULL) && (zone->nsec.nsec->children.lr.left == NULL))
2989 {
2990 log_info("dnssec-policy: %{dnsname}: zone is NSEC, chain is probably incomplete", zone_origin(zone_desc));
2991 zone_policy_nsec_enable(zone);
2992 }
2993 else
2994 {
2995 log_info("dnssec-policy: %{dnsname}: zone is NSEC", zone_origin(zone_desc));
2996 }
2997 break;
2998 }
2999 case ZONE_DNSSEC_FL_NSEC3:
3000 case ZONE_DNSSEC_FL_NSEC3_OPTOUT:
3001 {
3002 log_warn("dnssec-policy: %{dnsname}: zone is secured by NSEC3 but policy is made for NSEC", zone_origin(zone_desc));
3003 break;
3004 }
3005 }
3006 }
3007 else
3008 {
3009 if(policy->denial->optout)
3010 {
3011 zone_set_maintain_mode(zone, ZDB_ZONE_MAINTAIN_NSEC3_OPTOUT);
3012 }
3013 else
3014 {
3015 zone_set_maintain_mode(zone, ZDB_ZONE_MAINTAIN_NSEC3);
3016 }
3017
3018 // zone is expected to be NSEC3
3019 switch(zone_dnssec_type)
3020 {
3021 case ZONE_DNSSEC_FL_NOSEC:
3022 {
3023 // generate NSEC now
3024 log_info("dnssec-policy: %{dnsname}: zone will be secured with NSEC3", zone_origin(zone_desc));
3025
3026 zone_policy_nsec3_enable(zone, policy->denial);
3027
3028 break;
3029 }
3030 case ZONE_DNSSEC_FL_NSEC:
3031 {
3032 // do nothing
3033 log_warn("dnssec-policy: %{dnsname}: zone is an NSEC type but policy is made for NSEC3", zone_origin(zone_desc));
3034 break;
3035 }
3036 case ZONE_DNSSEC_FL_NSEC3:
3037 case ZONE_DNSSEC_FL_NSEC3_OPTOUT:
3038 {
3039 if((zone->nsec.nsec3->items->children.lr.left == NULL) && (zone->nsec.nsec3->items->children.lr.right == NULL))
3040 {
3041 log_info("dnssec-policy: %{dnsname}: zone is NSEC3, chain is probably incomplete", zone_origin(zone_desc));
3042 zone_policy_nsec3_enable(zone, policy->denial);
3043 }
3044 else
3045 {
3046 log_info("dnssec-policy: %{dnsname}: zone is NSEC3", zone_origin(zone_desc));
3047 }
3048 break;
3049 }
3050 }
3051 }
3052
3053 return SUCCESS;
3054 }
3055
3056 ya_result
zone_policy_process(zone_desc_s * zone_desc)3057 zone_policy_process(zone_desc_s *zone_desc)
3058 {
3059 // the policy is referenced by the zone desc
3060 // and the zone desc by the parent
3061 // no need to acquire anything here
3062
3063 ya_result final_ret = SUCCESS;
3064 ya_result ret;
3065
3066 dnssec_policy_initialise();
3067
3068 log_debug("dnssec-policy: %{dnsname} process", zone_origin(zone_desc));
3069
3070 if(zone_desc->type != ZT_MASTER)
3071 {
3072 log_debug("dnssec-policy: %{dnsname} is not a master zone", zone_origin(zone_desc));
3073
3074 return INVALID_STATE_ERROR; // not a master zone
3075 }
3076
3077 const dnssec_policy *policy = zone_desc->dnssec_policy;
3078
3079 if(policy == NULL)
3080 {
3081 log_debug("dnssec-policy: %{dnsname} has no policy", zone_origin(zone_desc));
3082
3083 zone_lock(zone_desc, ZONE_LOCK_READONLY);
3084 zdb_zone *zone = zone_desc->loaded_zone;
3085 if(zone != NULL)
3086 {
3087 zdb_zone_acquire(zone);
3088
3089 if(zdb_zone_isvalid(zone))
3090 {
3091 /*
3092 if(zone_desc->dnssec_mode != 0)
3093 {
3094 zdb_zone_set_maintained(zone, TRUE);
3095 //zone_desc_dnssec_mode = zone_desc->dnssec_mode << ZDB_ZONE_DNSSEC_SHIFT;
3096 }
3097 */
3098 }
3099 zdb_zone_release(zone);
3100 }
3101
3102 zone_unlock(zone_desc, ZONE_LOCK_READONLY);
3103
3104 return SUCCESS;
3105 }
3106
3107 // Look in the commands for a full init. If one is present then nothing more can be done.
3108
3109 if(dnssec_policy_queue_has_command_type(zone_origin(zone_desc), DNSSEC_POLICY_COMMAND_INIT))
3110 {
3111 log_debug("dnssec-policy: %{dnsname} is already marked for full generation", zone_origin(zone_desc));
3112 return SUCCESS;
3113 }
3114
3115 const char *denial_name = (policy->denial == NULL)?"nsec":policy->denial->name;
3116
3117 log_debug("dnssec-policy: %{dnsname} has policy %s/%s with %i keys", zone_origin(zone_desc), policy->name, denial_name, ptr_vector_size(&policy->key_suite));
3118
3119 // get the current DNSSEC status of the zone
3120
3121 zone_lock(zone_desc, ZONE_LOCK_READONLY);
3122 zdb_zone *zone = zone_desc->loaded_zone;
3123 if(zone != NULL)
3124 {
3125 zdb_zone_acquire(zone);
3126 zone_unlock(zone_desc, ZONE_LOCK_READONLY);
3127 }
3128 else
3129 {
3130 log_warn("dnssec-policy: %{dnsname}: settings are not linked to a loaded zone", zone_origin(zone_desc));
3131 zone_unlock(zone_desc, ZONE_LOCK_READONLY);
3132 return POLICY_ZONE_NOT_READY;
3133 }
3134
3135 log_debug("dnssec-policy: %{dnsname} zone acquired", zone->origin);
3136
3137 if(zdb_zone_isvalid(zone))
3138 {
3139 zone->sig_validity_regeneration_seconds = zone_desc->signature.sig_validity_regeneration * SIGNATURE_VALIDITY_REGENERATION_S;
3140 zone->sig_validity_interval_seconds = zone_desc->signature.sig_validity_interval * SIGNATURE_VALIDITY_INTERVAL_S;
3141 zone->sig_validity_jitter_seconds = zone_desc->signature.sig_validity_jitter * SIGNATURE_VALIDITY_JITTER_S;
3142
3143 #if DEBUG_FORCE_INSANE_SIGNATURE_MAINTENANCE_PARAMETERS
3144 zone->sig_validity_regeneration_seconds = 90;
3145 zone->sig_validity_interval_seconds = 180;
3146 zone->sig_validity_jitter_seconds = 5;
3147 #endif
3148
3149 zdb_zone_set_maintained(zone, TRUE);
3150
3151 // set DNSSEC mode using the policy
3152
3153 zone_policy_process_dnssec_chain(zone_desc);
3154 }
3155 else // zone is not valid
3156 {
3157 log_err("dnssec-policy: %{dnsname}: unable to manage DNSSEC status of invalid zone", zone_origin(zone_desc));
3158 log_debug("dnssec-policy: %{dnsname} released", zone->origin);
3159 zdb_zone_release(zone);
3160 return INVALID_STATE_ERROR;
3161 }
3162
3163 // enumerate the available keys and if they are in the zone and being used and so on.
3164
3165 // KEEP, IGNORE, REMOVE
3166
3167 ptr_vector key_roll_keys[DNSSEC_POLICY_KEY_ROLL_COUNT_MAXIMUM];
3168
3169 for(int i = 0; i < DNSSEC_POLICY_KEY_ROLL_COUNT_MAXIMUM; ++i)
3170 {
3171 ptr_vector_init_ex(&key_roll_keys[i], 0); // with an initial capacity set to 0, no allocation is made until at least one item is added
3172 }
3173
3174 yassert(ptr_vector_size(&policy->key_suite) <= 8);
3175
3176 for(int i = 0; ; ++i)
3177 {
3178 dnssec_key *key = dnssec_keystore_acquire_key_from_fqdn_at_index(zone_origin(zone_desc), i);
3179
3180 if(key == NULL)
3181 {
3182 break;
3183 }
3184
3185 zone_policy_log_debug_key("dnssec-policy: found ", key);
3186
3187 /*
3188 * @note 20160425 edf -- care must be taken here, keys may be generated in an another thread.
3189 * also, a key can only effectively be found after its generation (which discards the idea of virtual key)
3190 * so whatever is done here, pending key creation tasks should be taken into account (other operations are "real time")
3191 *
3192 * If the key is expired,
3193 * ignore it (it should be handled by the smart signing).
3194 * If the key is out of the expected parameters (size/alg) and it is not acceptable,
3195 * edit the times of the keys and remember the smart signing should be triggered.
3196 * If the key is valid, keep it on the side.
3197 *
3198 */
3199
3200 if(dnskey_is_expired_now(key) ||
3201
3202 (key->epoch_publish == 0) ||
3203 (key->epoch_inactive == 0))
3204 {
3205 zone_policy_log_debug_key("dnssec-policy: ignore ", key);
3206 // this key is irrelevant. It will be released after this control block.
3207 }
3208
3209 else
3210 {
3211 // for all key suite, if the key matches the suite, add the key to the suite array
3212 for(int j = 0; j <= ptr_vector_last_index(&policy->key_suite); ++j)
3213 {
3214 const struct dnssec_policy_key_suite *kr = (const struct dnssec_policy_key_suite*)ptr_vector_get(&policy->key_suite, j);
3215
3216 if(zone_policy_key_suite_is_marked_processed(zone_desc, kr))
3217 {
3218 continue;
3219 }
3220
3221 if(zone_policy_key_roll_matches(kr, key))
3222 {
3223 char tmp[512];
3224 snformat(tmp,sizeof(tmp), "dnssec-policy: matches %s", policy->name);
3225 zone_policy_log_debug_key(tmp, key);
3226
3227 dnskey_acquire(key);
3228 ptr_vector_append(&key_roll_keys[j], key);
3229 }
3230 }
3231 }
3232
3233 dnskey_release(key);
3234 }
3235
3236 /*
3237 * For all key suites ...
3238 *
3239 * sort-out the remaining keys
3240 * trigger the generation of keys
3241 *
3242 * keys of the array are matching the policy
3243 */
3244 for(int ksi = 0; ksi <= ptr_vector_last_index(&policy->key_suite); ++ksi)
3245 {
3246 struct dnssec_policy_key_suite *kr = (struct dnssec_policy_key_suite*)ptr_vector_get(&policy->key_suite, ksi);
3247
3248 if(zone_policy_key_suite_is_marked_processed(zone_desc, kr))
3249 {
3250 log_debug("dnssec-policy: %{dnsname}: %s: key suite is already being processed", zone_origin(zone_desc), kr->name);
3251 continue;
3252 }
3253
3254 log_debug("dnssec-policy: %{dnsname}: %s: key suite has %i matching keys", zone_origin(zone_desc), kr->name, ptr_vector_size(&key_roll_keys[ksi]));
3255
3256 if(ptr_vector_size(&key_roll_keys[ksi]) > 0)
3257 {
3258 // sort array by time
3259
3260 if(ptr_vector_size(&key_roll_keys[ksi]) > 1) // avoids the call but ptr_vector_qsort already checks this
3261 {
3262 ptr_vector_qsort(&key_roll_keys[ksi], zone_policy_dnssec_key_ptr_vector_qsort_by_activation_time_callback);
3263 }
3264
3265 // ensure we have continuity
3266 // start with a base period
3267
3268 dnssec_key *previous_key = NULL;
3269 s64 previous_begin_period;
3270 s64 previous_next_period;
3271 s64 previous_end_period;
3272
3273 {
3274 previous_key = (dnssec_key*)ptr_vector_get(&key_roll_keys[ksi], 0);
3275
3276 #if DEBUG
3277 log_debug("dnssec-policy: %s: %s: key %05d/%d timings: %T %T %T %T %T [0]",
3278 previous_key->origin,
3279 kr->name,
3280 dnskey_get_tag_const(previous_key), ntohs(previous_key->flags),
3281 previous_key->epoch_created, previous_key->epoch_publish, previous_key->epoch_activate, previous_key->epoch_inactive, previous_key->epoch_delete);
3282 #endif
3283
3284 database_service_zone_dnskey_set_alarms_for_key(zone, previous_key);
3285
3286 previous_begin_period = previous_key->epoch_activate;
3287 previous_next_period = previous_begin_period;
3288 previous_end_period = previous_key->epoch_inactive;
3289 }
3290
3291 log_debug("dnssec-policy: %{dnsname}: %s: first key will be inactive at %T", zone_origin(zone_desc), kr->name, previous_end_period);
3292
3293 for(int i = 1; i <= ptr_vector_last_index(&key_roll_keys[ksi]); ++i)
3294 {
3295 dnssec_key *key = (dnssec_key*)ptr_vector_get(&key_roll_keys[ksi], i);
3296 #if DEBUG
3297 log_debug("dnssec-policy: %s: %s: key %05d/%d timings: %T %T %T %T %T [%i]",
3298 key->origin,
3299 kr->name,
3300 dnskey_get_tag_const(key), ntohs(key->flags),
3301 key->epoch_created, key->epoch_publish, key->epoch_activate, key->epoch_inactive, key->epoch_delete, i);
3302 #endif
3303 previous_next_period = key->epoch_activate;
3304
3305 // ensure the key chains with this interval
3306 if(key->epoch_activate > previous_end_period /*|| key->epoch_inactive < begin_period irrelevant because of the sort */)
3307 {
3308 // bad
3309 log_warn("dnssec-policy: timeline hole of %d seconds from %d to %d", key->epoch_activate - previous_end_period , previous_end_period, key->epoch_activate);
3310 zone_policy_log_debug_key("dnssec-policy: unchained ", key);
3311
3312 /*
3313 * This case happens if there is at least one key K with timings in the future but the last key L of the valid chain is made inactive
3314 * before K is being made active.
3315 *
3316 * _ Create key(s) for the gap ?
3317 * _ Only create one key to fill that gap <- probably the best solution
3318 */
3319 break;
3320 }
3321 else // the key chains fine
3322 {
3323 // if the previous key ends before this one we keep it
3324
3325 if(previous_end_period < key->epoch_inactive)
3326 {
3327 database_service_zone_dnskey_set_alarms_for_key(zone, key);
3328
3329 previous_key = key;
3330 previous_end_period = key->epoch_inactive;
3331 }
3332 else
3333 {
3334 // else the key is irrelevant for the chain
3335 }
3336 }
3337 }
3338
3339 log_debug("dnssec-policy: %{dnsname}: %s: covered from %T to %T, last key activates at %T", zone_origin(zone_desc), kr->name, previous_begin_period, previous_end_period, previous_next_period);
3340
3341 time_t now = time(NULL);
3342
3343 if(previous_key->epoch_created <= now)
3344 {
3345 if(kr->roll->time_table.created.type.type == ZONE_POLICY_RELATIVE)
3346 {
3347 if(FAIL(ret = dnssec_policy_queue_add_generate_key_create_at(zone_desc, kr, previous_key->epoch_created)))
3348 {
3349 log_err("dnssec-policy: %{dnsname}: %s: failed to setup key generation from previous key: %r", zone_origin(zone_desc), kr->name, ret);
3350 final_ret = ret;
3351 }
3352 }
3353 else if(kr->roll->time_table.created.type.type == ZONE_POLICY_RULE)
3354 {
3355 if(FAIL(ret = dnssec_policy_queue_add_generate_key_active_at(zone_desc, kr, previous_end_period, NULL)))
3356 {
3357 log_err("dnssec-policy: %{dnsname}: %s: failed to setup key generation from previous end period: %r", zone_origin(zone_desc), kr->name, ret);
3358 final_ret = ret;
3359 }
3360 }
3361 else
3362 {
3363 log_err("dnssec-policy: %{dnsname}: %s: is not supported by this version of the policies", zone_origin(zone_desc), kr->name);
3364 }
3365 }
3366 ptr_vector_callback_and_destroy(&key_roll_keys[ksi], zone_policy_process_release_keys_cb);
3367 }
3368 else
3369 {
3370 // no key at all ? do a full init (with (re)signature)
3371
3372 log_info("dnssec-policy: %{dnsname}: %s: will be completely initialised", zone_origin(zone_desc), kr->name);
3373
3374 // for relative rules: do it now
3375 // for cron rules: generate it back-dated
3376
3377 if(kr->roll->time_table.created.type.type == ZONE_POLICY_RELATIVE)
3378 {
3379 // now
3380
3381 time_t now = time(NULL);
3382
3383 // add the command, aim to be active "now"
3384
3385 s64 delta = kr->roll->time_table.created.relative.seconds + // from the previous created key ...
3386 kr->roll->time_table.publish.relative.seconds +
3387 kr->roll->time_table.activate.relative.seconds ;
3388
3389 if(delta > (s64)now)
3390 {
3391 delta = (s64)now; //
3392 }
3393
3394 time_t first_key_create = now - (s32)delta;
3395
3396 if(ISOK(ret = dnssec_policy_queue_add_generate_key_create_at(zone_desc, kr, first_key_create))) // works on any kind of dates
3397 {
3398 log_debug("dnssec-policy: %{dnsname}: %s: will generate a first key at %T minus %i = %T", zone_origin(zone_desc), kr->name, now, (s32)delta, first_key_create);
3399
3400 // scan-build false-positive : kr isn't freed here (scan-build missed the acquire before the release)
3401
3402 }
3403 else
3404 {
3405 log_err("dnssec-policy: %{dnsname}: %s: failed to setup key generation before now: %r", zone_origin(zone_desc), kr->name, ret);
3406 final_ret = ret;
3407 }
3408 }
3409 else if(kr->roll->time_table.created.type.type == ZONE_POLICY_RULE)
3410 {
3411 // compute the back-dated epoch
3412
3413 time_t now = time(NULL);
3414 time_t will_be_inactive_at = 0;
3415 if(ISOK(ret = dnssec_policy_queue_add_generate_key_active_at(zone_desc, kr, now, &will_be_inactive_at))) // @note : only works on rules
3416 {
3417 log_debug("dnssec-policy: %{dnsname}: %s: will generate a first key that'll be inactive at %T", zone_origin(zone_desc), kr->name, will_be_inactive_at);
3418
3419 // scan-build false-positive : kr isn't freed here (scan-build missed the acquire before the release)
3420
3421 }
3422 else
3423 {
3424 log_err("dnssec-policy: %{dnsname}: %s: failed to setup key generation from now: %r", zone_origin(zone_desc), kr->name, ret);
3425 final_ret = ret;
3426 }
3427 }
3428 else
3429 {
3430 log_err("dnssec-policy: %{dnsname}: %s: don't know how to proceed", zone_origin(zone_desc), kr->name);
3431 }
3432 }
3433 } // for all key suites
3434
3435 zdb_zone_release(zone);
3436
3437 log_debug("dnssec-policy: %{dnsname} released", zone_origin(zone_desc));
3438
3439 for(int i = 0; i < DNSSEC_POLICY_KEY_ROLL_COUNT_MAXIMUM; ++i)
3440 {
3441 ptr_vector_callback_and_destroy(&key_roll_keys[i], zone_policy_process_release_keys_cb);
3442 }
3443
3444 // decide what to do
3445
3446 return final_ret; // returns success or the last error from the key generation part
3447 }
3448
3449 void
dnssec_policy_initialise()3450 dnssec_policy_initialise()
3451 {
3452 dnssec_policy_command_service_start();
3453 }
3454
3455 void
dnssec_policy_finalize()3456 dnssec_policy_finalize()
3457 {
3458 ptr_set_iterator iter;
3459
3460 //
3461
3462 group_mutex_write_lock(&dnssec_policy_set_mtx);
3463 ptr_set_iterator_init(&dnssec_policy_set, &iter);
3464 while(ptr_set_iterator_hasnext(&iter))
3465 {
3466 ptr_node *node = ptr_set_iterator_next_node(&iter);
3467 dnssec_policy *dp = (dnssec_policy*)node->value;
3468 group_mutex_write_lock(&dnssec_policy_mtx);
3469 int rc = dp->rc;
3470 group_mutex_write_unlock(&dnssec_policy_mtx);
3471 if(rc == 1)
3472 {
3473 // destroy it
3474 log_debug("dnssec-policy: %s: policy released", dp->name);
3475 dnssec_policy_release(dp);
3476 }
3477 else
3478 {
3479 log_warn("dnssec-policy: %s: policy is still referenced %i times", dp->name, rc);
3480 }
3481 }
3482
3483 ptr_set_destroy(&dnssec_policy_set);
3484
3485 group_mutex_write_unlock(&dnssec_policy_set_mtx);
3486
3487 //
3488
3489 group_mutex_write_lock(&dnssec_policy_key_suite_set_mtx);
3490 ptr_set_iterator_init(&dnssec_policy_key_suite_set, &iter);
3491 while(ptr_set_iterator_hasnext(&iter))
3492 {
3493 ptr_node *node = ptr_set_iterator_next_node(&iter);
3494 dnssec_policy_key_suite *dpks = (dnssec_policy_key_suite*)node->value;
3495 group_mutex_write_lock(&dnssec_policy_key_suite_mtx);
3496 int rc = dpks->rc;
3497 group_mutex_write_unlock(&dnssec_policy_key_suite_mtx);
3498 if(rc == 1)
3499 {
3500 // destroy it
3501 log_debug("dnssec-policy: %s: key suite released", dpks->name);
3502 dnssec_policy_key_suite_release(dpks);
3503 }
3504 else
3505 {
3506 log_warn("dnssec-policy: %s: key suite is still referenced %i times", dpks->name, rc);
3507 }
3508 }
3509
3510 ptr_set_destroy(&dnssec_policy_key_suite_set);
3511
3512 group_mutex_write_unlock(&dnssec_policy_key_suite_set_mtx);
3513
3514 //
3515
3516 group_mutex_write_lock(&dnssec_policy_key_set_mtx);
3517 ptr_set_iterator_init(&dnssec_policy_key_set, &iter);
3518 while(ptr_set_iterator_hasnext(&iter))
3519 {
3520 ptr_node *node = ptr_set_iterator_next_node(&iter);
3521 dnssec_policy_key *dpk = (dnssec_policy_key*)node->value;
3522 group_mutex_write_lock(&dnssec_policy_key_mtx);
3523 int rc = dpk->rc;
3524 group_mutex_write_unlock(&dnssec_policy_key_mtx);
3525 if(rc == 1)
3526 {
3527 // destroy it
3528 log_debug("dnssec-policy: %s: key released", dpk->name);
3529 dnssec_policy_key_release(dpk);
3530 }
3531 else
3532 {
3533 log_warn("dnssec-policy: %s: key is still referenced %i times", dpk->name, rc);
3534 }
3535 }
3536
3537 ptr_set_destroy(&dnssec_policy_key_set);
3538
3539 group_mutex_write_unlock(&dnssec_policy_key_set_mtx);
3540
3541 //
3542
3543 group_mutex_write_lock(&dnssec_policy_roll_set_mtx);
3544 ptr_set_iterator_init(&dnssec_policy_roll_set, &iter);
3545 while(ptr_set_iterator_hasnext(&iter))
3546 {
3547 ptr_node *node = ptr_set_iterator_next_node(&iter);
3548 dnssec_policy_roll *dpr = (dnssec_policy_roll*)node->value;
3549 group_mutex_write_lock(&dnssec_policy_roll_mtx);
3550 int rc = dpr->rc;
3551 group_mutex_write_unlock(&dnssec_policy_roll_mtx);
3552 if(rc == 1)
3553 {
3554 // destroy it
3555 log_debug("dnssec-policy: %s: roll released", dpr->name);
3556 dnssec_policy_roll_release(dpr);
3557 }
3558 else
3559 {
3560 log_warn("dnssec-policy: %s: roll is still referenced %i times", dpr->name, rc);
3561 }
3562 }
3563
3564 ptr_set_destroy(&dnssec_policy_roll_set);
3565
3566 group_mutex_write_unlock(&dnssec_policy_roll_set_mtx);
3567 //
3568
3569 group_mutex_write_lock(&dnssec_denial_set_mtx);
3570 ptr_set_iterator_init(&dnssec_denial_set, &iter);
3571 while(ptr_set_iterator_hasnext(&iter))
3572 {
3573 ptr_node *node = ptr_set_iterator_next_node(&iter);
3574 dnssec_denial *dd = (dnssec_denial*)node->value;
3575 group_mutex_write_lock(&dnssec_denial_mtx);
3576 int rc = dd->rc;
3577 group_mutex_write_unlock(&dnssec_denial_mtx);
3578 if(rc == 1)
3579 {
3580 // destroy it
3581 log_debug("dnssec-policy: %s: denial released", dd->name);
3582 dnssec_policy_denial_release(dd);
3583 }
3584 else
3585 {
3586 log_warn("dnssec-policy: %s: denial is still referenced %i times", dd->name, rc);
3587 }
3588 }
3589
3590 ptr_set_destroy(&dnssec_denial_set);
3591
3592 mutex_lock(&origin_to_dnssec_policy_queue_mtx);
3593 ptr_set_iterator_init(&origin_to_dnssec_policy_queue_set, &iter);
3594 while(ptr_set_iterator_hasnext(&iter))
3595 {
3596 ptr_node *node = ptr_set_iterator_next_node(&iter);
3597 dnsname_zfree(node->key);
3598 dnssec_policy_queue* cmd = (dnssec_policy_queue*)node->value;
3599 while(cmd != NULL)
3600 {
3601 dnssec_policy_queue *tmp = cmd;
3602 dnsname_zfree(cmd->origin);
3603 cmd = cmd->next;
3604 ZFREE_OBJECT(tmp);
3605 }
3606 }
3607 ptr_set_destroy(&origin_to_dnssec_policy_queue_set);
3608 mutex_unlock(&origin_to_dnssec_policy_queue_mtx);
3609
3610 group_mutex_write_unlock(&dnssec_denial_set_mtx);
3611 }
3612
3613
3614
3615 /**
3616 * @}
3617 */
3618