OpenDNSSEC-enforcer  2.0.3
signconf.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
3  * Copyright (c) 2014 OpenDNSSEC AB (svb)
4  * All rights reserved.
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  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
29 #include "log.h"
30 #include "str.h"
31 #include "clientpipe.h"
32 #include "duration.h"
33 #include "db/key_data.h"
34 #include "db/hsm_key.h"
35 #include "utils/kc_helper.h"
36 
37 #include "signconf/signconf.h"
38 
39 #include <libxml/parser.h>
40 #include <libxml/tree.h>
41 #include <limits.h>
42 #include <unistd.h>
43 
54 static int signconf_export(int sockfd, const policy_t* policy, zone_t* zone, int force);
55 
56 int signconf_export_all(int sockfd, const db_connection_t* connection, int force) {
58  zone_t* zone;
59  int ret;
60  const policy_t* policy = NULL;
61  int cmp;
62  int change = 0;
63 
64  if (!connection) {
66  }
67 
68  if (!(zone_list = zone_list_new(connection))
69  || zone_list_get(zone_list))
70  {
71  if (zone_list) {
72  zone_list_free(zone_list);
74  }
76  }
77 
78  for (zone = zone_list_get_next(zone_list); zone; zone = zone_list_get_next(zone_list)) {
79  if (policy) {
80  /*
81  * If we already have a policy object; If policy_id compare fails
82  * or if they are not the same, free the policy object so we will
83  * later retrieve the correct policy
84  */
85  if (db_value_cmp(policy_id(policy), zone_policy_id(zone), &cmp)
86  || cmp)
87  {
88  policy_free(policy);
89  policy = NULL;
90  }
91  }
92  if (!policy) {
93  if (!(policy = zone_get_policy(zone))) {
94  zone_free(zone);
95  zone_list_free(zone_list);
97  }
98  }
99 
100  ret = signconf_export(sockfd, policy, zone, force);
101  if (ret == SIGNCONF_EXPORT_OK) {
102  change = 1;
103  }
104  else if (ret != SIGNCONF_EXPORT_NO_CHANGE) {
105  zone_free(zone);
106  zone_list_free(zone_list);
107  return ret;
108  }
109  zone_free(zone);
110  }
111  policy_free(policy);
112  zone_list_free(zone_list);
113 
114  if (change) {
115  return SIGNCONF_EXPORT_OK;
116  }
118 }
119 
120 static int __free(char **p) {
121  if (!p || !*p) {
122  return 1;
123  }
124  free(*p);
125  *p = NULL;
126  return 0;
127 }
128 
129 static int signconf_export(int sockfd, const policy_t* policy, zone_t* zone, int force) {
130  char path[PATH_MAX];
131  xmlDocPtr doc;
132  xmlNodePtr root;
133  xmlNodePtr node;
134  xmlNodePtr node2;
135  xmlNodePtr node3;
136  xmlNodePtr node4;
137  xmlNodePtr node5;
138  xmlNodePtr keys;
139  duration_type* duration;
140  char* duration_text = NULL;
141  char text[1024];
143  const key_data_t* key_data;
145  int error;
146 
147  if (!policy) {
149  }
150  if (!zone) {
152  }
153 
154  if (!force && !zone_signconf_needs_writing(zone)) {
156  }
157 
158  if (snprintf(path, sizeof(path), "%s.new", zone_signconf_path(zone)) >= (int)sizeof(path)) {
159  ods_log_error("[signconf_export] Unable to write updated XML for zone %s, path to long!", zone_name(zone));
160  if (sockfd > -1) client_printf_err(sockfd, "Unable to write updated XML for zone %s, path to long!\n", zone_name(zone));
162  }
163 
164  if (!(duration = duration_create())) {
165  ods_log_error("[signconf_export] Unable to process signconf for zone %s, memory allocation error!", zone_name(zone));
166  if (sockfd > -1) client_printf_err(sockfd, "Unable to process signconf for zone %s, memory allocation error!\n", zone_name(zone));
168  }
169 
170  if (!(doc = xmlNewDoc((xmlChar*)"1.0"))
171  || !(root = xmlNewNode(NULL, (xmlChar*)"SignerConfiguration"))
172  || !(node = xmlNewChild(root, NULL, (xmlChar*)"Zone", NULL)))
173  {
174  ods_log_error("[signconf_export] Unable to create XML elements for zone %s, memory allocation error!", zone_name(zone));
175  if (sockfd > -1) client_printf_err(sockfd, "Unable to create XML elements for zone %s, memory allocation error!\n", zone_name(zone));
176  if (doc) {
177  xmlFreeDoc(doc);
178  }
179  duration_cleanup(duration);
181  }
182 
183  xmlDocSetRootElement(doc, root);
184 
185  error = 1;
186  if (!xmlNewProp(node, (xmlChar*)"name", (xmlChar*)zone_name(zone))
187  || !(error = 26)
188  || (policy_passthrough(policy) && !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Passthrough", NULL)))
189  || !(error = 2)
190  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Signatures", NULL))
191  || !(error = 3)
192  || duration_set_time(duration, policy_signatures_resign(policy))
193  || !(duration_text = duration2string(duration))
194  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Resign", (xmlChar*)duration_text))
195  || __free(&duration_text)
196  || !(error = 4)
197  || duration_set_time(duration, policy_signatures_refresh(policy))
198  || !(duration_text = duration2string(duration))
199  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Refresh", (xmlChar*)duration_text))
200  || __free(&duration_text)
201  || !(error = 5)
202  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Validity", NULL))
203  || !(error = 6)
204  || duration_set_time(duration, policy_signatures_validity_default(policy))
205  || !(duration_text = duration2string(duration))
206  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Default", (xmlChar*)duration_text))
207  || __free(&duration_text)
208  || !(error = 7)
209  || duration_set_time(duration, policy_signatures_validity_denial(policy))
210  || !(duration_text = duration2string(duration))
211  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Denial", (xmlChar*)duration_text))
212  || __free(&duration_text)
213  || !(error = 8)
214  || (policy_signatures_validity_keyset(policy) > 0 ?
215  duration_set_time(duration, policy_signatures_validity_keyset(policy))
216  || !(duration_text = duration2string(duration))
217  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Keyset", (xmlChar*)duration_text))
218  || __free(&duration_text)
219  || !(error = 100) : 0)
220  || duration_set_time(duration, policy_signatures_jitter(policy))
221  || !(duration_text = duration2string(duration))
222  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Jitter", (xmlChar*)duration_text))
223  || __free(&duration_text)
224  || !(error = 9)
225  || duration_set_time(duration, policy_signatures_inception_offset(policy))
226  || !(duration_text = duration2string(duration))
227  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"InceptionOffset", (xmlChar*)duration_text))
228  || __free(&duration_text)
229  || !(error = 10)
231  && (duration_set_time(duration, policy_signatures_max_zone_ttl(policy))
232  || !(duration_text = duration2string(duration))
233  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"MaxZoneTTL", (xmlChar*)duration_text))
234  || __free(&duration_text)))
235 
236  || !(error = 11)
237  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Denial", NULL))
238  || !(error = 12)
240  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"NSEC", NULL)))
241  || !(error = 13)
243  && (!(node3 = xmlNewChild(node2, NULL, (xmlChar*)"NSEC3", NULL))
244  || !(error = 14)
245  || (policy_denial_ttl(policy)
246  && (duration_set_time(duration, policy_denial_ttl(policy))
247  || !(duration_text = duration2string(duration))
248  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
249  || __free(&duration_text)))
250  || !(error = 15)
251  || (policy_denial_optout(policy)
252  && !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"OptOut", NULL)))
253  || !(error = 16)
254  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Hash", NULL))
255  || !(error = 17)
256  || snprintf(text, sizeof(text), "%u", policy_denial_algorithm(policy)) >= (int)sizeof(text)
257  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
258  || !(error = 18)
259  || snprintf(text, sizeof(text), "%u", policy_denial_iterations(policy)) >= (int)sizeof(text)
260  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Iterations", (xmlChar*)text))
261  || !(error = 19)
262  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Salt", (xmlChar*)policy_denial_salt(policy)))))
263 
264  || !(error = 20)
265  || !(keys = xmlNewChild(node, NULL, (xmlChar*)"Keys", NULL))
266  || !(error = 21)
267  || duration_set_time(duration, policy_keys_ttl(policy))
268  || !(duration_text = duration2string(duration))
269  || !(node3 = xmlNewChild(keys, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
270  || __free(&duration_text)
271 
272  || !(error = 22)
273  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"SOA", NULL))
274  || !(error = 23)
275  || duration_set_time(duration, policy_zone_soa_ttl(policy))
276  || !(duration_text = duration2string(duration))
277  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
278  || __free(&duration_text)
279  || !(error = 24)
280  || duration_set_time(duration, policy_zone_soa_minimum(policy))
281  || !(duration_text = duration2string(duration))
282  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Minimum", (xmlChar*)duration_text))
283  || __free(&duration_text)
284  || !(error = 25)
285  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Serial", (xmlChar*)policy_zone_soa_serial_text(policy)))
286  )
287  {
288  ods_log_error("[signconf_export] Unable to create XML elements for zone %s! [%d]", zone_name(zone), error);
289  if (sockfd > -1) client_printf_err(sockfd, "Unable to create XML elements for zone %s!\n", zone_name(zone));
290  __free(&duration_text);
291  duration_cleanup(duration);
292  xmlFreeDoc(doc);
294  }
295  __free(&duration_text);
296  duration_cleanup(duration);
297 
298  if (!(key_data_list = zone_get_keys(zone))) {
299  ods_log_error("[signconf_export] Unable to get keys for zone %s!", zone_name(zone));
300  if (sockfd > -1) client_printf_err(sockfd, "Unable to get keys for zone %s!\n", zone_name(zone));
301  xmlFreeDoc(doc);
303  }
304 
305  for (key_data = key_data_list_next(key_data_list); key_data; key_data = key_data_list_next(key_data_list)) {
306  if (!(hsm_key = key_data_get_hsm_key(key_data))) {
307  ods_log_error("[signconf_export] Unable to get HSM key from database for zone %s!", zone_name(zone));
308  if (sockfd > -1) client_printf_err(sockfd, "Unable to get HSM key from database for zone %s!\n", zone_name(zone));
309  key_data_list_free(key_data_list);
310  xmlFreeDoc(doc);
312  }
313  error = 100;
314  if (!(node2 = xmlNewChild(keys, NULL, (xmlChar*)"Key", NULL))
315  || !(error = 101)
316  || (key_data_role(key_data) == KEY_DATA_ROLE_ZSK
317  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Flags", (xmlChar*)"256")))
318  || !(error = 102)
319  || (key_data_role(key_data) != KEY_DATA_ROLE_ZSK
320  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Flags", (xmlChar*)"257")))
321  || !(error = 103)
322  || snprintf(text, sizeof(text), "%u", key_data_algorithm(key_data)) >= (int)sizeof(text)
323  || !(error = 104)
324  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
325  || !(error = 105)
326  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Locator",(xmlChar*)hsm_key_locator(hsm_key)))
327  || !(error = 106)
328  || (key_data_active_ksk(key_data)
329  && (key_data_role(key_data) == KEY_DATA_ROLE_KSK
330  || key_data_role(key_data) == KEY_DATA_ROLE_CSK)
331  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"KSK", NULL)))
332  || !(error = 107)
333  || (key_data_active_zsk(key_data)
334  && (key_data_role(key_data) == KEY_DATA_ROLE_ZSK
335  || key_data_role(key_data) == KEY_DATA_ROLE_CSK)
336  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ZSK", NULL)))
337  || !(error = 108)
338  || (key_data_publish(key_data)
339  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Publish", NULL)))
340  /* TODO:
341  * What about <Deactivate/> ?
342  */
343  )
344  {
345  ods_log_error("[signconf_export] Unable to create key XML elements for zone %s! [%d]", zone_name(zone), error);
346  if (sockfd > -1) client_printf_err(sockfd, "Unable to create key XML elements for zone %s!\n", zone_name(zone));
347  hsm_key_free(hsm_key);
348  key_data_list_free(key_data_list);
349  xmlFreeDoc(doc);
351  }
352  hsm_key_free(hsm_key);
353  }
354  key_data_list_free(key_data_list);
355 
356  unlink(path);
357  if (xmlSaveFormatFileEnc(path, doc, "UTF-8", 1) == -1) {
358  ods_log_error("[signconf_export] Unable to write signconf for zone %s, LibXML error!", zone_name(zone));
359  if (sockfd > -1) client_printf_err(sockfd, "Unable to write signconf for zone %s, LibXML error!\n", zone_name(zone));
360  xmlFreeDoc(doc);
362  }
363  xmlFreeDoc(doc);
364 
365  if (check_rng(path, OPENDNSSEC_SCHEMA_DIR "/signconf.rng", 0)) {
366  ods_log_error("[signconf_export] Unable to validate the exported signconf XML for zone %s!", zone_name(zone));
367  if (sockfd > -1) client_printf_err(sockfd, "Unable to validate the exported signconf XML for zone %s!\n", zone_name(zone));
369  }
370 
371  if (rename(path, zone_signconf_path(zone))) {
372  ods_log_error("[signconf_export] Unable to write signconf for zone %s, rename failed!", zone_name(zone));
373  if (sockfd > -1) client_printf_err(sockfd, "Unable to write signconf for zone %s, rename failed!\n", zone_name(zone));
374  unlink(path);
376  }
377 
379  zone_update(zone);
380 
381  return SIGNCONF_EXPORT_OK;
382 }
key_data_role
Definition: key_data.h:40
#define SIGNCONF_EXPORT_ERR_MEMORY
Definition: signconf.h:56
const char * zone_signconf_path(const zone_t *zone)
Definition: zone.c:798
const db_value_t * zone_policy_id(const zone_t *zone)
Definition: zone.c:736
hsm_key_t * key_data_get_hsm_key(const key_data_t *key_data)
Definition: key_data.c:649
#define SIGNCONF_EXPORT_ERR_XML
Definition: signconf.h:48
#define SIGNCONF_EXPORT_OK
Definition: signconf.h:40
unsigned int key_data_publish(const key_data_t *key_data)
Definition: key_data.c:743
unsigned int key_data_active_zsk(const key_data_t *key_data)
Definition: key_data.c:735
#define SIGNCONF_EXPORT_ERR_ARGS
Definition: signconf.h:44
int zone_update(zone_t *zone)
Definition: zone.c:1589
policy_t * zone_get_policy(const zone_t *zone)
Definition: zone.c:744
unsigned int policy_signatures_max_zone_ttl(const policy_t *policy)
Definition: policy.c:885
void zone_list_free(zone_list_t *zone_list)
Definition: zone.c:1989
unsigned int policy_denial_algorithm(const policy_t *policy)
Definition: policy.c:925
unsigned int policy_signatures_refresh(const policy_t *policy)
Definition: policy.c:837
key_data_list_t * zone_get_keys(const zone_t *zone)
Definition: zone_ext.c:38
unsigned int policy_signatures_validity_default(const policy_t *policy)
Definition: policy.c:861
int zone_set_signconf_needs_writing(zone_t *zone, unsigned int signconf_needs_writing)
Definition: zone.c:959
void ods_log_error(const char *format,...)
Definition: log.c:69
unsigned int policy_signatures_validity_denial(const policy_t *policy)
Definition: policy.c:869
unsigned int policy_passthrough(const policy_t *policy)
Definition: policy.c:1085
unsigned int policy_signatures_jitter(const policy_t *policy)
Definition: policy.c:845
policy_denial_type
Definition: policy.h:40
int check_rng(const char *filename, const char *rngfilename, int verbose)
Definition: kc_helper.c:88
unsigned int policy_signatures_inception_offset(const policy_t *policy)
Definition: policy.c:853
void zone_free(zone_t *zone)
Definition: zone.c:325
unsigned int policy_denial_iterations(const policy_t *policy)
Definition: policy.c:933
int db_value_cmp(const db_value_t *value_a, const db_value_t *value_b, int *result)
Definition: db_value.c:102
zone_list_t * zone_list_new(const db_connection_t *connection)
Definition: zone.c:1946
unsigned int policy_zone_soa_ttl(const policy_t *policy)
Definition: policy.c:1013
void policy_free(policy_t *policy)
Definition: policy.c:518
unsigned int zone_signconf_needs_writing(const zone_t *zone)
Definition: zone.c:790
const key_data_t * key_data_list_next(key_data_list_t *key_data_list)
Definition: key_data.c:2359
const char * hsm_key_locator(const hsm_key_t *hsm_key)
Definition: hsm_key.c:520
const char * policy_zone_soa_serial_text(const policy_t *policy)
Definition: policy.c:1029
const char * zone_name(const zone_t *zone)
Definition: zone.c:782
unsigned int policy_denial_ttl(const policy_t *policy)
Definition: policy.c:909
#define SIGNCONF_EXPORT_NO_CHANGE
Definition: signconf.h:64
zone_t * zone_list_get_next(zone_list_t *zone_list)
Definition: zone.c:2666
unsigned int policy_denial_optout(const policy_t *policy)
Definition: policy.c:901
void key_data_list_free(key_data_list_t *key_data_list)
Definition: key_data.c:1694
int zone_list_get(zone_list_t *zone_list)
Definition: zone.c:2360
int signconf_export_all(int sockfd, const db_connection_t *connection, int force)
Definition: signconf.c:56
void hsm_key_free(hsm_key_t *hsm_key)
Definition: hsm_key.c:286
unsigned int key_data_active_ksk(const key_data_t *key_data)
Definition: key_data.c:751
Definition: policy.h:60
Definition: zone.h:46
unsigned int key_data_algorithm(const key_data_t *key_data)
Definition: key_data.c:687
const char * policy_denial_salt(const policy_t *policy)
Definition: policy.c:949
#define SIGNCONF_EXPORT_ERR_FILE
Definition: signconf.h:60
unsigned int policy_signatures_validity_keyset(const policy_t *policy)
Definition: policy.c:877
const db_value_t * policy_id(const policy_t *policy)
Definition: policy.c:805
unsigned int policy_zone_soa_minimum(const policy_t *policy)
Definition: policy.c:1021
#define SIGNCONF_EXPORT_ERR_DATABASE
Definition: signconf.h:52
unsigned int policy_keys_ttl(const policy_t *policy)
Definition: policy.c:965
unsigned int policy_signatures_resign(const policy_t *policy)
Definition: policy.c:829