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 // YYYY MM DD hh mm
43 //    7  4  5  5  6 : 27 bits : one bit is not worth it, shifts it is
44 //        134217728 :
45 //         68567040 : 26.031 bits => 27 bits
46 
47 #pragma once
48 
49 
50 #include <dnscore/sys_types.h>
51 #include <dnscore/ptr_vector.h>
52 
53 #include <time.h>
54 
55 #include "zone_desc.h"
56 
57 #define ZONE_POLICY_DATE_YEAR_BASE 2000
58 
59 #define DNSSEC_POLICY_KEY_ROLL_COUNT_MAXIMUM 4
60 
61 #define DNSSEC_POLICY_MINIMUM_ACTIVATED_TIME_SUGGESTION_SECONDS (7*86400)
62 
63 #define ZONE_POLICY_ABSOLUTE 1
64 #define ZONE_POLICY_RELATIVE 2
65 #define ZONE_POLICY_RULE     3 // index to a rule
66 
67 typedef struct zone_policy_rule_definition_s zone_policy_rule_definition_s;
68 
69 #define ZONE_POLICY_RULE_ANYMINUTE          0x0fffffffffffffffLL
70 #define ZONE_POLICY_RULE_ANYWEEK            0x0000000f
71 #define ZONE_POLICY_RULE_ANYHOUR            0x00ffffff
72 #define ZONE_POLICY_RULE_ANYDAY             0x7fffffff
73 #define ZONE_POLICY_RULE_ANYWEEKDAY         0x0000007f
74 #define ZONE_POLICY_RULE_ANYMONTH           0x00000fff
75 
76 #define ZONE_POLICY_RELATIVE_TO_GENERATE    0
77 #define ZONE_POLICY_RELATIVE_TO_PUBLISH     1
78 #define ZONE_POLICY_RELATIVE_TO_ACTIVATE    2
79 #define ZONE_POLICY_RELATIVE_TO_INACTIVE    3
80 #define ZONE_POLICY_RELATIVE_TO_REMOVE      4
81 #define ZONE_POLICY_RELATIVE_TO_DS_PUBLISH  5
82 #define ZONE_POLICY_RELATIVE_TO_DS_REMOVE   6
83 
84 #define DNSSEC_POLICY_FLAGS_REMOVE_OTHER_KEYS   0x01 // remove keys not matching a policy
85 
86 struct zone_policy_rule_definition_s   // rule-like match
87 {
88     u64 minute:60,week:4;           // 64 / 0 minutes, nth dayname of month
89     u64 hour:24,day:31,weekday:7;   // 62 / 2 hours, day of month, day of week
90     u16 month:12;                   // 12 / 4 month of year
91 };
92 
93 struct zone_policy_time_type_s
94 {
95     u32 reserved:30,type:2;
96 };
97 
98 struct zone_policy_absolute_s // all zero-based except year 2000-based
99 {
100     u32 minute:6,hour:5,day:5,month:4,year:7,zeroes:3,type:2;
101 };
102 
103 // 60 + 24 + 31 + 12 + 7 + 4 = 138
104 
105 typedef struct zone_policy_rule_s zone_policy_rule_s;
106 
107 struct zone_policy_rule_s           // points to a rule-like match
108 {
109     u32 index:30,type:2;
110 };
111 
112 typedef struct zone_policy_relative_s zone_policy_relative_s;
113 
114 struct zone_policy_relative_s
115 {   // 25 bits ~ 1 year, 26 2, 27 ~ 4
116 
117     u32 seconds:27, relativeto:3, type:2;
118 };
119 
120 typedef union zone_policy_date zone_policy_date;
121 
122 union zone_policy_date
123 {
124     struct zone_policy_time_type_s type;
125     struct zone_policy_absolute_s absolute;
126     struct zone_policy_rule_s rule;
127     struct zone_policy_relative_s relative;
128 };
129 
130 typedef struct zone_policy_table_s zone_policy_table_s;
131 
132 struct zone_policy_table_s
133 {
134     zone_policy_date created;          // from previous created ?
135     zone_policy_date publish;          // from created
136     zone_policy_date activate;         // from publish
137     zone_policy_date inactive;         // from activate
138     zone_policy_date delete;           // from inactive
139 #if HAS_DS_PUBLICATION_SUPPORT
140     zone_policy_date ds_add;           // from publish
141     zone_policy_date ds_del;           // from delete
142 #endif
143 };
144 
145 typedef struct dnssec_denial dnssec_denial;
146 
147 struct dnssec_denial
148 {
149     char *name;
150     u8 *salt;
151     u32 resalting;
152     u16 iterations;
153     u8 algorithm;       // hash algorithm: 1
154     u8 salt_length;
155     bool optout;        //
156     volatile int rc;
157 };
158 
159 typedef struct dnssec_policy_key dnssec_policy_key;
160 
161 struct dnssec_policy_key
162 {
163     char *name;   // default
164     u16   size;         // 1024
165     u16   flags;        // 0
166     u8    algorithm;          // RSA-SHA256
167     volatile int   rc;
168 };
169 
170 
171 typedef struct dnssec_policy_roll dnssec_policy_roll;
172 
173 struct dnssec_policy_roll
174 {
175     char *name;   // default
176     struct zone_policy_table_s time_table;
177     volatile int rc;
178 };
179 
180 typedef struct dnssec_policy_key_suite dnssec_policy_key_suite;
181 
182 struct dnssec_policy_key_suite
183 {
184     char *name;
185     dnssec_policy_key *key;
186     dnssec_policy_roll *roll;
187     volatile int rc;
188 };
189 
190 struct dnssec_policy
191 {
192     char *name; // default
193     struct dnssec_denial *denial;
194     ptr_vector key_suite;
195     u8 flags;
196     u8 dnskey_count_max;
197     volatile int rc;
198 };
199 
200 typedef struct dnssec_policy dnssec_policy;
201 
202 #define DNSSEC_POLICY_COMMAND_INIT 0
203 #define DNSSEC_POLICY_COMMAND_GENERATE_KEY 1
204 
205 #define ALARM_KEY_DNSSEC_POLICY_EVENT 16
206 
207 struct dnssec_policy_queue_parameter_generate_key
208 {
209     struct dnssec_policy_key_suite *suite;
210     zone_desc_s *zone_desc;
211 };
212 
213 typedef struct dnssec_policy_queue dnssec_policy_queue;
214 
215 struct dnssec_policy_queue
216 {
217     struct dnssec_policy_queue *next;
218     u8 *origin;
219     time_t epoch; // 0 for ASAP
220 
221     // create one key with these parameters ...
222     // first signature of a zone ... (with or without key generation)
223     // ...
224 
225     u8 command;
226     bool queued;
227     union
228     {
229         struct dnssec_policy_queue_parameter_generate_key generate_key;
230     }
231     parameters;
232 };
233 
234 /**
235  * Compare two dates together.
236  * Absolute with Absolute
237  * Relative with Relative
238  *
239  * Any other combination will return -1
240  *
241  * @param d1 first date
242  * @param d2 second date
243  * @return <0,0,>0 if d1 is less than, equal to, or greater than d2
244  */
245 
246 int zone_policy_date_compare(const zone_policy_date *d1, const zone_policy_date *d2);
247 
248 /**
249  * Retrieves the first day of the month.
250  *
251  * 0 is Sunday
252  *
253  * @param year 0-based
254  * @param month 0-based
255  * @return the number of the day of the month or an error code
256  */
257 
258 ya_result zone_policy_get_first_day_from_year_month(int year, int month);
259 
260 /**
261  * Retrieves the first day of the month.
262  *
263  * 0 is Sunday
264  *
265  * @param year 0-based
266  * @param month 0-based
267  * @param week 0 to 4, week of the day
268  * @param wday 0 to 6, day of the week, 0 for Sunday
269  * @return the number of the day of the month or an error code
270  */
271 
272 ya_result zone_policy_get_mday_from_year_month_week_wday(int year, int month, int week, int wday);
273 
274 /**
275  * Initialises an absolute date from a year, month, week and week-day
276  *
277  * ie: 2nd Wednesday of January 2001
278  *
279  * 0 is Sunday
280  *
281  * @param date the date to initialise
282  * @param year 0-based
283  * @param month 0-based
284  * @param week 0 to 4, week of the day
285  * @param wday 0 to 6, day of the week, 0 for Sunday
286  * @return an error code
287  */
288 
289 ya_result zone_policy_date_init_from_year_month_week_wday(zone_policy_date *date, int year, int month, int week, int wday);
290 
291 /**
292  * Initialises an absolute date from a UNIX epoch
293  *
294  * @param date
295  * @param epoch
296  * @return an error code
297  */
298 
299 ya_result zone_policy_date_init_from_epoch(zone_policy_date *date, time_t epoch);
300 
301 /**
302  * Gets the UNIX epoch from an absolute date
303  *
304  * @param date
305  * @param epoch a pointer to hold the result
306  * @return an error code
307  */
308 
309 ya_result zone_policy_date_get_epoch(const zone_policy_date *date, time_t *epoch);
310 
311 /**
312  * Initialises the absolute date with an epoch plus time in seconds.
313  *
314  * @param date
315  * @param epoch an epoch to add the seconds to
316  * @param seconds
317  * @return an error code
318  */
319 
320 ya_result zone_policy_date_init_after_epoch(zone_policy_date *date, time_t epoch, u32 seconds);
321 
322 /**
323  * Initialises the absolute date with an absolute date plus time in seconds.
324  *
325  * @param date
326  * @param from an absolute date to add the seconds to
327  * @param seconds
328  * @return an error code
329  */
330 
331 ya_result zone_policy_date_init_after_date(zone_policy_date *date, const zone_policy_date *from, u32 seconds);
332 
333 /**
334  * Initialises a date using a rule applied on an epoch
335  *
336  * @param result_date
337  * @param rule_date
338  * @param after_epoch
339  * @return
340  */
341 
342 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);
343 
344 /**
345  * Initialises an epoch from a rule applied on an epoch
346  *
347  * @param rule_date
348  * @param after_epoch
349  * @param result_epoch
350  * @return
351  */
352 
353 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);
354 
355 zone_policy_rule_definition_s *zone_policy_rule_definition_get_from_index(u32 index);
356 
357 zone_policy_rule_definition_s *zone_policy_rule_definition_get_from_rule(const zone_policy_date *rule);
358 
359 /**
360  * This complicated functions initialises a date with the earliest matching of the rule starting from 'from'
361  *
362  * @param date
363  * @param from
364  * @param rule
365  *
366  * @return an error code
367  */
368 
369 ya_result zone_policy_date_init_at_next_date(zone_policy_date *date, const zone_policy_date *from, const zone_policy_date *rule);
370 
371 ya_result zone_policy_table_init_from_date(zone_policy_table_s *tbl, zone_policy_table_s *with, zone_policy_date *from);
372 
373 /**
374  * Sets the DNSSEC mode of the zone using the policy.
375  *
376  * Expects zone_desc to be locked (for reading).
377  */
378 
379 ya_result zone_policy_process_dnssec_chain(zone_desc_s *zone_desc);
380 
381 ya_result zone_policy_process(zone_desc_s *zone_desc);
382 
383 
384 ya_result zone_policy_roll_create_from_rules(const char *id,
385                                              const zone_policy_rule_definition_s *generate,
386                                              const zone_policy_rule_definition_s *publish,
387                                              const zone_policy_rule_definition_s *activate,
388                                              const zone_policy_rule_definition_s *inactive,
389                                              const zone_policy_rule_definition_s *remove,
390                                              const zone_policy_rule_definition_s *ds_publish,
391                                              const zone_policy_rule_definition_s *ds_remove);
392 
393 ya_result zone_policy_roll_create_from_relatives(const char *id,
394                                                  const zone_policy_relative_s *generate,
395                                                  u8 generate_from,
396                                                  const zone_policy_relative_s *publish,
397                                                  u8 publish_from,
398                                                  const zone_policy_relative_s *activate,
399                                                  u8 activate_from,
400                                                  const zone_policy_relative_s *inactive,
401                                                  u8 inactive_from,
402                                                  const zone_policy_relative_s *remove,
403                                                  u8 remove_from
404 #if HAS_DS_PUBLICATION_SUPPORT
405                                                  ,
406                                                  const zone_policy_relative_s *ds_publish,
407                                                  u8 ds_publish_from,
408                                                  const zone_policy_relative_s *ds_remove,
409                                                  u8 ds_remove_from
410 #endif
411                                                  );
412 
413 dnssec_policy_roll *dnssec_policy_roll_acquire_from_name(const char *id);
414 void dnssec_policy_roll_release(dnssec_policy_roll *dpr);
415 ya_result dnssec_policy_roll_test_all(time_t active_at, u32 duration_seconds, bool print_text, bool log_text);
416 
417 dnssec_denial *dnssec_policy_denial_create(const char *id, u8 algorithm, u16 iterations, const u8 *salt, u8 salt_length, u32 resalting, bool optout);
418 dnssec_denial *dnssec_policy_denial_acquire(const char *id);
419 void dnssec_policy_denial_release(dnssec_denial *dd);
420 
421 dnssec_policy_key *dnssec_policy_key_create(const char *id, u8 algorithm, u16 size, bool ksk, char* engine);
422 dnssec_policy_key *dnssec_policy_key_acquire_from_name(const char *id);
423 void dnssec_policy_key_release(dnssec_policy_key *dpk);
424 
425 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);
426 ya_result dnssec_policy_roll_test(struct dnssec_policy_roll *kr, time_t active_at, u32 duration_seconds, bool print_text, bool log_text);
427 
428 dnssec_policy_key_suite *dnssec_policy_key_suite_create(const char *id, dnssec_policy_key *dpk, dnssec_policy_roll *dpr);
429 dnssec_policy_key_suite *dnssec_policy_key_suite_acquire_from_name(const char *id);
430 void dnssec_policy_key_suite_acquire(dnssec_policy_key_suite *dpks);
431 void dnssec_policy_key_suite_release(dnssec_policy_key_suite *dpks);
432 
433 dnssec_policy *dnssec_policy_create(char *name, dnssec_denial *denial, ptr_vector *key_suite);
434 dnssec_policy *dnssec_policy_acquire_from_name(const char *id);
435 void dnssec_policy_acquire(dnssec_policy *dp);
436 void dnssec_policy_release(dnssec_policy *dp);
437 
438 #define CONFIG_DNSSEC_POLICY(fieldname_) {#fieldname_,offsetof(CONFIG_TYPE, fieldname_), (config_set_field_function*)dnssec_policy_zone_desc_config, NULL,{._intptr=0}, sizeof(dnssec_policy), sizeof(((CONFIG_TYPE*)0)->fieldname_), CONFIG_TABLE_SOURCE_NONE, CONFIG_FIELD_ALLOCATION_DIRECT },
439 
440 ya_result dnssec_policy_zone_desc_config(const char *value, void *dest, anytype sizeoftarget);
441 
442 void  dnssec_policy_initialise();
443 
444 // remove all previously defined policies
445 void dnssec_policy_finalize();
446 
447 /**
448  * @}
449  */
450