OpenDNSSEC-enforcer  2.1.9
signconf_xml.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_xml.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_xml_export(int sockfd, const policy_t* policy, zone_db_t* zone, int force);
55 
56 int
57 signconf_export_zone(char const *zonename, db_connection_t* dbconn)
58 {
59  zone_db_t* zone;
60  int ret;
62 
63  zone = zone_db_new_get_by_name(dbconn, zonename);
64  if (!zone) {
65  ods_log_error("[signconf_export] Unable to fetch zone %s from"
66  " database", zonename);
68  }
69  policy = zone_db_get_policy(zone);
70  if (!policy) {
71  ods_log_error("[signconf_export] Unable to fetch policy for zone"
72  " %s from database", zonename);
73  zone_db_free(zone);
75  }
76 
77  /* We always force. Since now it is scheduled per zone */
78  ret = signconf_xml_export(-1, policy, zone, 1);
80  zone_db_free(zone);
81  return ret;
82 }
83 
84 int signconf_export_all(int sockfd, const db_connection_t* connection, int force) {
85  zone_list_db_t* zone_list;
86  zone_db_t* zone;
87  int ret;
88  policy_t *policy = NULL;
89  int cmp;
90  int change = 0;
91 
92  if (!connection) {
94  }
95 
96  if (!(zone_list = zone_list_db_new(connection))
97  || zone_list_db_get(zone_list))
98  {
99  if (zone_list) {
100  zone_list_db_free(zone_list);
102  }
104  }
105 
106  for (zone = zone_list_db_get_next(zone_list); zone; zone = zone_list_db_get_next(zone_list)) {
107  if (policy) {
108  /*
109  * If we already have a policy object; If policy_id compare fails
110  * or if they are not the same, free the policy object so we will
111  * later retrieve the correct policy
112  */
114  || cmp)
115  {
117  policy = NULL;
118  }
119  }
120  if (!policy) {
121  if (!(policy = zone_db_get_policy(zone))) {
122  zone_db_free(zone);
123  zone_list_db_free(zone_list);
125  }
126  }
127 
128  ret = signconf_xml_export(sockfd, policy, zone, force);
129  if (ret == SIGNCONF_EXPORT_OK) {
130  change = 1;
131  }
132  else if (ret != SIGNCONF_EXPORT_NO_CHANGE) {
133  zone_db_free(zone);
134  zone_list_db_free(zone_list);
135  return ret;
136  }
137  zone_db_free(zone);
138  }
140  zone_list_db_free(zone_list);
141 
142  if (change) {
143  return SIGNCONF_EXPORT_OK;
144  }
146 }
147 
148 static int __free(char **p) {
149  if (!p || !*p) {
150  return 1;
151  }
152  free(*p);
153  *p = NULL;
154  return 0;
155 }
156 
157 static int signconf_xml_export(int sockfd, const policy_t* policy, zone_db_t* zone, int force) {
158  char path[PATH_MAX];
159  xmlDocPtr doc;
160  xmlNodePtr root;
161  xmlNodePtr node;
162  xmlNodePtr node2;
163  xmlNodePtr node3;
164  xmlNodePtr node4;
165  xmlNodePtr node5;
166  xmlNodePtr keys;
167  duration_type* duration;
168  char* duration_text = NULL;
169  char text[1024];
171  const key_data_t* key_data;
173  int error;
174 
175  if (!policy) {
177  }
178  if (!zone) {
180  }
181 
182  if (!force && !zone_db_signconf_needs_writing(zone)) {
184  }
185 
186  if (snprintf(path, sizeof(path), "%s.new", zone_db_signconf_path(zone)) >= (int)sizeof(path)) {
187  ods_log_error("[signconf_export] Unable to write updated XML for zone %s, path to long!", zone_db_name(zone));
188  if (sockfd > -1) client_printf_err(sockfd, "Unable to write updated XML for zone %s, path to long!\n", zone_db_name(zone));
190  }
191 
192  if (!(duration = duration_create())) {
193  ods_log_error("[signconf_export] Unable to process signconf for zone %s, memory allocation error!", zone_db_name(zone));
194  if (sockfd > -1) client_printf_err(sockfd, "Unable to process signconf for zone %s, memory allocation error!\n", zone_db_name(zone));
196  }
197 
198  if (!(doc = xmlNewDoc((xmlChar*)"1.0"))
199  || !(root = xmlNewNode(NULL, (xmlChar*)"SignerConfiguration"))
200  || !(node = xmlNewChild(root, NULL, (xmlChar*)"Zone", NULL)))
201  {
202  ods_log_error("[signconf_export] Unable to create XML elements for zone %s, memory allocation error!", zone_db_name(zone));
203  if (sockfd > -1) client_printf_err(sockfd, "Unable to create XML elements for zone %s, memory allocation error!\n", zone_db_name(zone));
204  if (doc) {
205  xmlFreeDoc(doc);
206  }
207  duration_cleanup(duration);
209  }
210 
211  xmlDocSetRootElement(doc, root);
212 
213  error = 1;
214  if (!xmlNewProp(node, (xmlChar*)"name", (xmlChar*)zone_db_name(zone))
215  || !(error = 26)
216  || (policy_passthrough(policy) && !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Passthrough", NULL)))
217  || !(error = 2)
218  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Signatures", NULL))
219  || !(error = 3)
220  || duration_set_time(duration, policy_signatures_resign(policy))
221  || !(duration_text = duration2string(duration))
222  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Resign", (xmlChar*)duration_text))
223  || __free(&duration_text)
224  || !(error = 4)
225  || duration_set_time(duration, policy_signatures_refresh(policy))
226  || !(duration_text = duration2string(duration))
227  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Refresh", (xmlChar*)duration_text))
228  || __free(&duration_text)
229  || !(error = 5)
230  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Validity", NULL))
231  || !(error = 6)
232  || duration_set_time(duration, policy_signatures_validity_default(policy))
233  || !(duration_text = duration2string(duration))
234  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Default", (xmlChar*)duration_text))
235  || __free(&duration_text)
236  || !(error = 7)
237  || duration_set_time(duration, policy_signatures_validity_denial(policy))
238  || !(duration_text = duration2string(duration))
239  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Denial", (xmlChar*)duration_text))
240  || __free(&duration_text)
241  || !(error = 8)
243  duration_set_time(duration, policy_signatures_validity_keyset(policy))
244  || !(duration_text = duration2string(duration))
245  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Keyset", (xmlChar*)duration_text))
246  || __free(&duration_text)
247  || !(error = 100) : 0)
248  || duration_set_time(duration, policy_signatures_jitter(policy))
249  || !(duration_text = duration2string(duration))
250  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Jitter", (xmlChar*)duration_text))
251  || __free(&duration_text)
252  || !(error = 9)
253  || duration_set_time(duration, policy_signatures_inception_offset(policy))
254  || !(duration_text = duration2string(duration))
255  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"InceptionOffset", (xmlChar*)duration_text))
256  || __free(&duration_text)
257  || !(error = 10)
259  && (duration_set_time(duration, policy_signatures_max_zone_ttl(policy))
260  || !(duration_text = duration2string(duration))
261  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"MaxZoneTTL", (xmlChar*)duration_text))
262  || __free(&duration_text)))
263 
264  || !(error = 11)
265  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Denial", NULL))
266  || !(error = 12)
268  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"NSEC", NULL)))
269  || !(error = 13)
271  && (!(node3 = xmlNewChild(node2, NULL, (xmlChar*)"NSEC3", NULL))
272  || !(error = 14)
274  && (duration_set_time(duration, policy_denial_ttl(policy))
275  || !(duration_text = duration2string(duration))
276  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
277  || __free(&duration_text)))
278  || !(error = 15)
280  && !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"OptOut", NULL)))
281  || !(error = 16)
282  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Hash", NULL))
283  || !(error = 17)
284  || snprintf(text, sizeof(text), "%u", policy_denial_algorithm(policy)) >= (int)sizeof(text)
285  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
286  || !(error = 18)
287  || snprintf(text, sizeof(text), "%u", policy_denial_iterations(policy)) >= (int)sizeof(text)
288  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Iterations", (xmlChar*)text))
289  || !(error = 19)
290  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Salt", (xmlChar*)policy_denial_salt(policy)))))
291 
292  || !(error = 20)
293  || !(keys = xmlNewChild(node, NULL, (xmlChar*)"Keys", NULL))
294  || !(error = 21)
295  || duration_set_time(duration, policy_keys_ttl(policy))
296  || !(duration_text = duration2string(duration))
297  || !(node3 = xmlNewChild(keys, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
298  || __free(&duration_text)
299 
300  || !(error = 22)
301  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"SOA", NULL))
302  || !(error = 23)
303  || duration_set_time(duration, policy_zone_soa_ttl(policy))
304  || !(duration_text = duration2string(duration))
305  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
306  || __free(&duration_text)
307  || !(error = 24)
308  || duration_set_time(duration, policy_zone_soa_minimum(policy))
309  || !(duration_text = duration2string(duration))
310  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Minimum", (xmlChar*)duration_text))
311  || __free(&duration_text)
312  || !(error = 25)
313  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Serial", (xmlChar*)policy_zone_soa_serial_text(policy)))
314  )
315  {
316  ods_log_error("[signconf_export] Unable to create XML elements for zone %s! [%d]", zone_db_name(zone), error);
317  if (sockfd > -1) client_printf_err(sockfd, "Unable to create XML elements for zone %s!\n", zone_db_name(zone));
318  __free(&duration_text);
319  duration_cleanup(duration);
320  xmlFreeDoc(doc);
322  }
323  __free(&duration_text);
324  duration_cleanup(duration);
325 
326  if (!(key_data_list = zone_db_get_keys(zone))) {
327  ods_log_error("[signconf_export] Unable to get keys for zone %s!", zone_db_name(zone));
328  if (sockfd > -1) client_printf_err(sockfd, "Unable to get keys for zone %s!\n", zone_db_name(zone));
329  xmlFreeDoc(doc);
331  }
332 
335  ods_log_error("[signconf_export] Unable to get HSM key from database for zone %s!", zone_db_name(zone));
336  if (sockfd > -1) client_printf_err(sockfd, "Unable to get HSM key from database for zone %s!\n", zone_db_name(zone));
338  xmlFreeDoc(doc);
340  }
341  error = 100;
342  if (!(node2 = xmlNewChild(keys, NULL, (xmlChar*)"Key", NULL))
343  || !(error = 101)
345  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Flags", (xmlChar*)"256")))
346  || !(error = 102)
348  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Flags", (xmlChar*)"257")))
349  || !(error = 103)
350  || snprintf(text, sizeof(text), "%u", key_data_algorithm(key_data)) >= (int)sizeof(text)
351  || !(error = 104)
352  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
353  || !(error = 105)
354  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Locator",(xmlChar*)hsm_key_locator(hsm_key)))
355  || !(error = 106)
359  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"KSK", NULL)))
360  || !(error = 107)
364  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ZSK", NULL)))
365  || !(error = 108)
367  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Publish", NULL)))
368  /* TODO:
369  * What about <Deactivate/> ?
370  */
371  )
372  {
373  ods_log_error("[signconf_export] Unable to create key XML elements for zone %s! [%d]", zone_db_name(zone), error);
374  if (sockfd > -1) client_printf_err(sockfd, "Unable to create key XML elements for zone %s!\n", zone_db_name(zone));
377  xmlFreeDoc(doc);
379  }
381  }
383 
384  unlink(path);
385  if (xmlSaveFormatFileEnc(path, doc, "UTF-8", 1) == -1) {
386  ods_log_error("[signconf_export] Unable to write signconf for zone %s, LibXML error!", zone_db_name(zone));
387  if (sockfd > -1) client_printf_err(sockfd, "Unable to write signconf for zone %s, LibXML error!\n", zone_db_name(zone));
388  xmlFreeDoc(doc);
390  }
391  xmlFreeDoc(doc);
392 
393  if (check_rng(path, OPENDNSSEC_SCHEMA_DIR "/signconf.rng", 0)) {
394  ods_log_error("[signconf_export] Unable to validate the exported signconf XML for zone %s!", zone_db_name(zone));
395  if (sockfd > -1) client_printf_err(sockfd, "Unable to validate the exported signconf XML for zone %s!\n", zone_db_name(zone));
397  }
398 
399  if (rename(path, zone_db_signconf_path(zone))) {
400  ods_log_error("[signconf_export] Unable to write signconf for zone %s, rename failed!", zone_db_name(zone));
401  if (sockfd > -1) client_printf_err(sockfd, "Unable to write signconf for zone %s, rename failed!\n", zone_db_name(zone));
402  unlink(path);
404  }
405 
407  zone_db_update(zone);
408 
409  return SIGNCONF_EXPORT_OK;
410 }
int db_value_cmp(const db_value_t *value_a, const db_value_t *value_b, int *result)
Definition: db_value.c:102
void hsm_key_free(hsm_key_t *hsm_key)
Definition: hsm_key.c:286
const char * hsm_key_locator(const hsm_key_t *hsm_key)
Definition: hsm_key.c:520
int check_rng(const char *filename, const char *rngfilename, int verbose)
Definition: kc_helper.c:88
unsigned int key_data_active_ksk(const key_data_t *key_data)
Definition: key_data.c:751
const key_data_t * key_data_list_next(key_data_list_t *key_data_list)
Definition: key_data.c:2359
unsigned int key_data_publish(const key_data_t *key_data)
Definition: key_data.c:743
void key_data_list_free(key_data_list_t *key_data_list)
Definition: key_data.c:1694
unsigned int key_data_active_zsk(const key_data_t *key_data)
Definition: key_data.c:735
unsigned int key_data_algorithm(const key_data_t *key_data)
Definition: key_data.c:687
hsm_key_t * key_data_get_hsm_key(const key_data_t *key_data)
Definition: key_data.c:649
key_data_role
Definition: key_data.h:40
@ KEY_DATA_ROLE_ZSK
Definition: key_data.h:43
@ KEY_DATA_ROLE_KSK
Definition: key_data.h:42
@ KEY_DATA_ROLE_CSK
Definition: key_data.h:44
unsigned int policy_denial_iterations(const policy_t *policy)
Definition: policy.c:933
unsigned int policy_denial_optout(const policy_t *policy)
Definition: policy.c:901
unsigned int policy_signatures_validity_denial(const policy_t *policy)
Definition: policy.c:869
unsigned int policy_signatures_resign(const policy_t *policy)
Definition: policy.c:829
unsigned int policy_keys_ttl(const policy_t *policy)
Definition: policy.c:965
unsigned int policy_zone_soa_ttl(const policy_t *policy)
Definition: policy.c:1013
unsigned int policy_zone_soa_minimum(const policy_t *policy)
Definition: policy.c:1021
unsigned int policy_passthrough(const policy_t *policy)
Definition: policy.c:1085
const db_value_t * policy_id(const policy_t *policy)
Definition: policy.c:805
unsigned int policy_signatures_refresh(const policy_t *policy)
Definition: policy.c:837
unsigned int policy_denial_ttl(const policy_t *policy)
Definition: policy.c:909
unsigned int policy_signatures_max_zone_ttl(const policy_t *policy)
Definition: policy.c:885
unsigned int policy_signatures_jitter(const policy_t *policy)
Definition: policy.c:845
unsigned int policy_signatures_inception_offset(const policy_t *policy)
Definition: policy.c:853
const char * policy_denial_salt(const policy_t *policy)
Definition: policy.c:949
unsigned int policy_denial_algorithm(const policy_t *policy)
Definition: policy.c:925
unsigned int policy_signatures_validity_default(const policy_t *policy)
Definition: policy.c:861
void policy_free(policy_t *policy)
Definition: policy.c:518
const char * policy_zone_soa_serial_text(const policy_t *policy)
Definition: policy.c:1029
unsigned int policy_signatures_validity_keyset(const policy_t *policy)
Definition: policy.c:877
policy_denial_type
Definition: policy.h:40
@ POLICY_DENIAL_TYPE_NSEC
Definition: policy.h:42
@ POLICY_DENIAL_TYPE_NSEC3
Definition: policy.h:43
int signconf_export_zone(char const *zonename, db_connection_t *dbconn)
Definition: signconf_xml.c:57
int signconf_export_all(int sockfd, const db_connection_t *connection, int force)
Definition: signconf_xml.c:84
#define SIGNCONF_EXPORT_ERR_DATABASE
Definition: signconf_xml.h:52
#define SIGNCONF_EXPORT_ERR_MEMORY
Definition: signconf_xml.h:56
#define SIGNCONF_EXPORT_NO_CHANGE
Definition: signconf_xml.h:64
#define SIGNCONF_EXPORT_ERR_ARGS
Definition: signconf_xml.h:44
#define SIGNCONF_EXPORT_ERR_FILE
Definition: signconf_xml.h:60
#define SIGNCONF_EXPORT_OK
Definition: signconf_xml.h:40
#define SIGNCONF_EXPORT_ERR_XML
Definition: signconf_xml.h:48
Definition: policy.h:60
void zone_db_free(zone_db_t *zone)
Definition: zone_db.c:325
int zone_db_set_signconf_needs_writing(zone_db_t *zone, unsigned int signconf_needs_writing)
Definition: zone_db.c:959
const char * zone_db_name(const zone_db_t *zone)
Definition: zone_db.c:782
const char * zone_db_signconf_path(const zone_db_t *zone)
Definition: zone_db.c:798
policy_t * zone_db_get_policy(const zone_db_t *zone)
Definition: zone_db.c:744
int zone_db_update(zone_db_t *zone)
Definition: zone_db.c:1589
int zone_list_db_get(zone_list_db_t *zone_list)
Definition: zone_db.c:2363
zone_list_db_t * zone_list_db_new(const db_connection_t *connection)
Definition: zone_db.c:1946
zone_db_t * zone_list_db_get_next(zone_list_db_t *zone_list)
Definition: zone_db.c:2669
unsigned int zone_db_signconf_needs_writing(const zone_db_t *zone)
Definition: zone_db.c:790
void zone_list_db_free(zone_list_db_t *zone_list)
Definition: zone_db.c:1989
const db_value_t * zone_db_policy_id(const zone_db_t *zone)
Definition: zone_db.c:736
zone_db_t * zone_db_new_get_by_name(const db_connection_t *connection, const char *name)
Definition: zone_db.c:1569
key_data_list_t * zone_db_get_keys(const zone_db_t *zone)
Definition: zone_db_ext.c:56