OpenDNSSEC-enforcer  2.1.3
policy_export.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/policy_key.h"
34 #include "utils/kc_helper.h"
35 
36 #include "policy/policy_export.h"
37 
38 #include <libxml/parser.h>
39 #include <libxml/tree.h>
40 #include <limits.h>
41 #include <unistd.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <errno.h>
45 
46 #define POLICY_EXPORT_MAX_LENGHT 1000
47 
48 static int __free(char **p) {
49  if (!p || !*p) {
50  return 1;
51  }
52  free(*p);
53  *p = NULL;
54  return 0;
55 }
56 
57 static int __policy_export(int sockfd, const policy_t* policy, xmlNodePtr root) {
58  xmlNodePtr node;
59  xmlNodePtr node2;
60  xmlNodePtr node3;
61  xmlNodePtr node4;
62  xmlNodePtr node5;
63  xmlNodePtr keys;
64  int error;
65  duration_type* duration;
66  char* duration_text = NULL;
67  char text[1024];
69  const policy_key_t* policy_key;
70 
71  if (!(duration = duration_create())) {
72  client_printf_err(sockfd, "Unable to export KASP XML, memory allocation error!\n");
74  }
75 
76  error = 1;
77  if (!(node = xmlNewChild(root, NULL, (xmlChar*)"Policy", NULL))
78  || !(error = 2)
79  || !xmlNewProp(node, (xmlChar*)"name", (xmlChar*)policy_name(policy))
80  || !(error = 3)
81  || !xmlNewChild(node, NULL, (xmlChar*)"Description", (xmlChar*)policy_description(policy))
82 
83  || !(error = 4)
84  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Signatures", NULL))
85  || !(error = 5)
86  || duration_set_time(duration, policy_signatures_resign(policy))
87  || !(duration_text = duration2string(duration))
88  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Resign", (xmlChar*)duration_text))
89  || __free(&duration_text)
90  || !(error = 6)
91  || duration_set_time(duration, policy_signatures_refresh(policy))
92  || !(duration_text = duration2string(duration))
93  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Refresh", (xmlChar*)duration_text))
94  || __free(&duration_text)
95  || !(error = 7)
96  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Validity", NULL))
97  || !(error = 8)
98  || duration_set_time(duration, policy_signatures_validity_default(policy))
99  || !(duration_text = duration2string(duration))
100  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Default", (xmlChar*)duration_text))
101  || __free(&duration_text)
102  || !(error = 9)
103  || duration_set_time(duration, policy_signatures_validity_denial(policy))
104  || !(duration_text = duration2string(duration))
105  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Denial", (xmlChar*)duration_text))
106  || __free(&duration_text)
107  || !(error = 10)
108  || !( policy_signatures_validity_keyset(policy) == 0 ||
109  !(duration_set_time(duration, policy_signatures_validity_keyset(policy))
110  || !(duration_text = duration2string(duration))
111  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Keyset", (xmlChar*)duration_text))
112  || __free(&duration_text)
113  || !(error = 10)))
114  || duration_set_time(duration, policy_signatures_jitter(policy))
115  || !(duration_text = duration2string(duration))
116  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Jitter", (xmlChar*)duration_text))
117  || __free(&duration_text)
118  || !(error = 11)
119  || duration_set_time(duration, policy_signatures_inception_offset(policy))
120  || !(duration_text = duration2string(duration))
121  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"InceptionOffset", (xmlChar*)duration_text))
122  || __free(&duration_text)
123  || !(error = 12)
124  || (duration_set_time(duration, policy_signatures_max_zone_ttl(policy))
125  || !(duration_text = duration2string(duration))
126  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"MaxZoneTTL", (xmlChar*)duration_text))
127  || __free(&duration_text))
128 
129  || !(error = 13)
130  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Denial", NULL))
131  || !(error = 14)
133  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"NSEC", NULL)))
134  || !(error = 15)
136  && (!(node3 = xmlNewChild(node2, NULL, (xmlChar*)"NSEC3", NULL))
137  || !(error = 16)
138  || (policy_denial_ttl(policy)
139  && (duration_set_time(duration, policy_denial_ttl(policy))
140  || !(duration_text = duration2string(duration))
141  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
142  || __free(&duration_text)))
143  || !(error = 17)
144  || (policy_denial_optout(policy)
145  && !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"OptOut", NULL)))
146  || !(error = 18)
147  || (policy_denial_resalt(policy)
148  && (duration_set_time(duration, policy_denial_resalt(policy))
149  || !(duration_text = duration2string(duration))
150  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Resalt", (xmlChar*)duration_text))
151  || __free(&duration_text)))
152  || !(error = 19)
153  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Hash", NULL))
154  || !(error = 20)
155  || snprintf(text, sizeof(text), "%u", policy_denial_algorithm(policy)) >= (int)sizeof(text)
156  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
157  || !(error = 21)
158  || snprintf(text, sizeof(text), "%u", policy_denial_iterations(policy)) >= (int)sizeof(text)
159  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Iterations", (xmlChar*)text))
160  || !(error = 22)
161  || !(node5 = xmlNewChild(node4, NULL, (xmlChar*)"Salt", NULL))
162  || !(error = 23)
163  || snprintf(text, sizeof(text), "%u", policy_denial_salt_length(policy)) >= (int)sizeof(text)
164  || !xmlNewProp(node5, (xmlChar*)"length", (xmlChar*)text)))
165 
166  || !(error = 24)
167  || !(keys = xmlNewChild(node, NULL, (xmlChar*)"Keys", NULL))
168  || !(error = 25)
169  || duration_set_time(duration, policy_keys_ttl(policy))
170  || !(duration_text = duration2string(duration))
171  || !(node3 = xmlNewChild(keys, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
172  || __free(&duration_text)
173  || !(error = 26)
174  || duration_set_time(duration, policy_keys_retire_safety(policy))
175  || !(duration_text = duration2string(duration))
176  || !(node3 = xmlNewChild(keys, NULL, (xmlChar*)"RetireSafety", (xmlChar*)duration_text))
177  || __free(&duration_text)
178  || !(error = 27)
179  || duration_set_time(duration, policy_keys_publish_safety(policy))
180  || !(duration_text = duration2string(duration))
181  || !(node3 = xmlNewChild(keys, NULL, (xmlChar*)"PublishSafety", (xmlChar*)duration_text))
182  || __free(&duration_text)
183  || !(error = 28)
184  || (policy_keys_shared(policy)
185  && !(node3 = xmlNewChild(keys, NULL, (xmlChar*)"ShareKeys", NULL)))
186  || !(error = 29)
187  || (policy_keys_purge_after(policy)
188  && (duration_set_time(duration, policy_keys_purge_after(policy))
189  || !(duration_text = duration2string(duration))
190  || !(node3 = xmlNewChild(keys, NULL, (xmlChar*)"Purge", (xmlChar*)duration_text))
191  || __free(&duration_text)))
192 
193  || !(error = 30)
194  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Zone", NULL))
195  || !(error = 31)
196  || duration_set_time(duration, policy_zone_propagation_delay(policy))
197  || !(duration_text = duration2string(duration))
198  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"PropagationDelay", (xmlChar*)duration_text))
199  || __free(&duration_text)
200  || !(error = 32)
201  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"SOA", NULL))
202  || !(error = 33)
203  || duration_set_time(duration, policy_zone_soa_ttl(policy))
204  || !(duration_text = duration2string(duration))
205  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
206  || __free(&duration_text)
207  || !(error = 34)
208  || duration_set_time(duration, policy_zone_soa_minimum(policy))
209  || !(duration_text = duration2string(duration))
210  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Minimum", (xmlChar*)duration_text))
211  || __free(&duration_text)
212  || !(error = 35)
213  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Serial", (xmlChar*)policy_zone_soa_serial_text(policy)))
214 
215  || !(error = 36)
216  || !(node2 = xmlNewChild(node, NULL, (xmlChar*)"Parent", NULL))
217  || !(error = 37)
219  && (duration_set_time(duration, policy_parent_registration_delay(policy))
220  || !(duration_text = duration2string(duration))
221  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"RegistrationDelay", (xmlChar*)duration_text))
222  || __free(&duration_text)))
223  || !(error = 38)
224  || duration_set_time(duration, policy_parent_propagation_delay(policy))
225  || !(duration_text = duration2string(duration))
226  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"PropagationDelay", (xmlChar*)duration_text))
227  || __free(&duration_text)
228  || !(error = 39)
229  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"DS", NULL))
230  || !(error = 40)
231  || duration_set_time(duration, policy_parent_ds_ttl(policy))
232  || !(duration_text = duration2string(duration))
233  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
234  || __free(&duration_text)
235  || !(error = 41)
236  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"SOA", NULL))
237  || !(error = 42)
238  || duration_set_time(duration, policy_parent_soa_ttl(policy))
239  || !(duration_text = duration2string(duration))
240  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"TTL", (xmlChar*)duration_text))
241  || __free(&duration_text)
242  || !(error = 43)
243  || duration_set_time(duration, policy_parent_soa_minimum(policy))
244  || !(duration_text = duration2string(duration))
245  || !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"Minimum", (xmlChar*)duration_text))
246  || __free(&duration_text)
247  )
248  {
249  client_printf_err(sockfd, "Unable to create XML elements, error code %d!\n", error);
250  __free(&duration_text);
251  duration_cleanup(duration);
252  return POLICY_EXPORT_ERR_XML;
253  }
254  __free(&duration_text);
255 
256  if (!(policy_key_list = policy_get_policy_keys(policy))) {
257  duration_cleanup(duration);
259  }
260 
261  for (policy_key = policy_key_list_next(policy_key_list); policy_key; policy_key = policy_key_list_next(policy_key_list)) {
262  switch (policy_key_role(policy_key)) {
263  case POLICY_KEY_ROLE_ZSK:
264  error = 100;
265  if (!(node2 = xmlNewChild(keys, NULL, (xmlChar*)"ZSK", NULL))
266  || !(error = 101)
267  || snprintf(text, sizeof(text), "%u", policy_key_algorithm(policy_key)) >= (int)sizeof(text)
268  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
269  || !(error = 102)
270  || snprintf(text, sizeof(text), "%u", policy_key_bits(policy_key)) >= (int)sizeof(text)
271  || !xmlNewProp(node3, (xmlChar*)"length", (xmlChar*)text)
272  || !(error = 103)
273  || duration_set_time(duration, policy_key_lifetime(policy_key))
274  || !(duration_text = duration2string(duration))
275  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Lifetime", (xmlChar*)duration_text))
276  || __free(&duration_text)
277  || !(error = 104)
278  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Repository", (xmlChar*)policy_key_repository(policy_key)))
279  || !(error = 105)
280  || (policy_key_standby(policy_key) != -1
281  && (snprintf(text, sizeof(text), "%u", policy_key_standby(policy_key)) >= (int)sizeof(text)
282  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Standby", (xmlChar*)text))))
283  || !(error = 106)
284  || (policy_key_manual_rollover(policy_key)
285  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ManualRollover", NULL)))
286  || !(error = 107)
288  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ZskRollType", (xmlChar*)"ZskDoubleSignature")))
289  || !(error = 108)
291  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ZskRollType", (xmlChar*)"ZskPrePublication")))
292  || !(error = 109)
294  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ZskRollType", (xmlChar*)"ZskDoubleRRsig")))
295  )
296  {
297  client_printf_err(sockfd, "Unable to create XML elements, error code %d!\n", error);
298  __free(&duration_text);
299  duration_cleanup(duration);
300  return POLICY_EXPORT_ERR_XML;
301  }
302  __free(&duration_text);
303  break;
304 
305  case POLICY_KEY_ROLE_KSK:
306  error = 200;
307  if (!(node2 = xmlNewChild(keys, NULL, (xmlChar*)"KSK", NULL))
308  || !(error = 201)
309  || snprintf(text, sizeof(text), "%u", policy_key_algorithm(policy_key)) >= (int)sizeof(text)
310  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
311  || !(error = 202)
312  || snprintf(text, sizeof(text), "%u", policy_key_bits(policy_key)) >= (int)sizeof(text)
313  || !xmlNewProp(node3, (xmlChar*)"length", (xmlChar*)text)
314  || !(error = 203)
315  || duration_set_time(duration, policy_key_lifetime(policy_key))
316  || !(duration_text = duration2string(duration))
317  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Lifetime", (xmlChar*)duration_text))
318  || __free(&duration_text)
319  || !(error = 204)
320  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Repository", (xmlChar*)policy_key_repository(policy_key)))
321  || !(error = 205)
322  || (policy_key_standby(policy_key) != -1
323  && (snprintf(text, sizeof(text), "%u", policy_key_standby(policy_key)) >= (int)sizeof(text)
324  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Standby", (xmlChar*)text))))
325  || !(error = 206)
326  || (policy_key_manual_rollover(policy_key)
327  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ManualRollover", NULL)))
328  || !(error = 207)
330  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"KskRollType", (xmlChar*)"KskDoubleRRset")))
331  || !(error = 208)
333  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"KskRollType", (xmlChar*)"KskDoubleDS")))
334  || !(error = 209)
336  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"KskRollType", (xmlChar*)"KskDoubleSignature")))
337  || !(error = 210)
338  || (policy_key_rfc5011(policy_key)
339  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"RFC5011", NULL)))
340  )
341  {
342  client_printf_err(sockfd, "Unable to create XML elements, error code %d!\n", error);
343  __free(&duration_text);
344  duration_cleanup(duration);
345  return POLICY_EXPORT_ERR_XML;
346  }
347  __free(&duration_text);
348  break;
349 
350  case POLICY_KEY_ROLE_CSK:
351  error = 300;
352  if (!(node2 = xmlNewChild(keys, NULL, (xmlChar*)"CSK", NULL))
353  || !(error = 301)
354  || snprintf(text, sizeof(text), "%u", policy_key_algorithm(policy_key)) >= (int)sizeof(text)
355  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
356  || !(error = 302)
357  || snprintf(text, sizeof(text), "%u", policy_key_bits(policy_key)) >= (int)sizeof(text)
358  || !xmlNewProp(node3, (xmlChar*)"length", (xmlChar*)text)
359  || !(error = 303)
360  || duration_set_time(duration, policy_key_lifetime(policy_key))
361  || !(duration_text = duration2string(duration))
362  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Lifetime", (xmlChar*)duration_text))
363  || __free(&duration_text)
364  || !(error = 304)
365  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Repository", (xmlChar*)policy_key_repository(policy_key)))
366  || !(error = 305)
367  || (policy_key_standby(policy_key)
368  && (snprintf(text, sizeof(text), "%u", policy_key_standby(policy_key)) >= (int)sizeof(text)
369  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Standby", (xmlChar*)text))))
370  || !(error = 306)
371  || (policy_key_manual_rollover(policy_key)
372  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ManualRollover", NULL)))
373  || !(error = 307)
375  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskDoubleRRset")))
376  || !(error = 308)
378  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskSingleSignature")))
379  || !(error = 309)
381  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskDoubleDS")))
382  || !(error = 310)
384  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskDoubleSignature")))
385  || !(error = 311)
387  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskPrePublication")))
388  || !(error = 312)
389  || (policy_key_rfc5011(policy_key)
390  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"RFC5011", NULL)))
391  )
392  {
393  client_printf_err(sockfd, "Unable to create XML elements, error code %d!\n", error);
394  __free(&duration_text);
395  duration_cleanup(duration);
396  return POLICY_EXPORT_ERR_XML;
397  }
398  __free(&duration_text);
399  break;
400 
401  default:
402  policy_key_list_free(policy_key_list);
403  duration_cleanup(duration);
405  }
406  }
407  policy_key_list_free(policy_key_list);
408 
409  duration_cleanup(duration);
410  return POLICY_EXPORT_OK;
411 }
412 
413 int policy_export_all(int sockfd, const db_connection_t* connection, const char* filename) {
415  const policy_t* policy;
416  xmlDocPtr doc;
417  xmlNodePtr root = NULL;
418  int ret;
419  char path[PATH_MAX];
420  xmlChar* xml = NULL;
421  char* xml_out;
422  int xml_length = 0;
423  int xml_write;
424  char* dirname, *dirlast;
425 
426  if (!connection) {
427  return POLICY_EXPORT_ERR_ARGS;
428  }
429 
430  if (filename) {
431  if (access(filename, W_OK)) {
432  if (errno == ENOENT) {
433  if ((dirname = strdup(filename))) {
434  if ((dirlast = strrchr(dirname, '/'))) {
435  *dirlast = 0;
436  if (access(dirname, W_OK)) {
437  client_printf_err(sockfd, "Write access to directory denied: %s\n", strerror(errno));
438  free(dirname);
439  return POLICY_EXPORT_ERR_FILE;
440  }
441  }
442  free(dirname);
443  }
444  }
445  else {
446  client_printf_err(sockfd, "Write access to file denied!\n");
447  return POLICY_EXPORT_ERR_FILE;
448  }
449  }
450 
451  if (snprintf(path, sizeof(path), "%s.new", filename) >= (int)sizeof(path)) {
452  client_printf_err(sockfd, "Unable to write XML to %s, path to long!\n", filename);
454  }
455  }
456 
457  if (!(doc = xmlNewDoc((xmlChar*)"1.0"))
458  || !(root = xmlNewNode(NULL, (xmlChar*)"KASP")))
459  {
460  client_printf_err(sockfd, "Unable to create XML elements, memory allocation error!\n");
461  if (doc) {
462  xmlFreeDoc(doc);
463  }
465  }
466 
467  xmlDocSetRootElement(doc, root);
468 
469  if (!(policy_list = policy_list_new(connection))
470  || policy_list_get(policy_list))
471  {
472  xmlFreeDoc(doc);
473  if (policy_list) {
474  policy_list_free(policy_list);
476  }
478  }
479 
480  for (policy = policy_list_next(policy_list); policy; policy = policy_list_next(policy_list)) {
481  ret = __policy_export(sockfd, policy, root);
482  if (ret != POLICY_EXPORT_OK) {
483  policy_list_free(policy_list);
484  xmlFreeDoc(doc);
485  return ret;
486  }
487  }
488  policy_list_free(policy_list);
489 
490  if (filename) {
491  unlink(path);
492  if (xmlSaveFormatFileEnc(path, doc, "UTF-8", 1) == -1) {
493  client_printf_err(sockfd, "Unable to write policy, LibXML error!\n");
494  xmlFreeDoc(doc);
495  return POLICY_EXPORT_ERR_FILE;
496  }
497  xmlFreeDoc(doc);
498 
499  if (check_kasp(path, NULL, 0, 0, NULL, NULL)) {
500  client_printf_err(sockfd, "Unable to validate the exported policy XML!\n");
501  unlink(path);
502  return POLICY_EXPORT_ERR_XML;
503  }
504 
505  if (rename(path, filename)) {
506  client_printf_err(sockfd, "Unable to write policy, rename failed!\n");
507  unlink(path);
508  return POLICY_EXPORT_ERR_FILE;
509  }
510  }
511  else {
512  xmlDocDumpFormatMemoryEnc(doc, &xml, &xml_length, "UTF-8", 1);
513  xmlFreeDoc(doc);
514  if (xml && xml_length) {
515  for (xml_out = (char*)xml, xml_write = xml_length; xml_write > POLICY_EXPORT_MAX_LENGHT; xml_write -= POLICY_EXPORT_MAX_LENGHT, xml_out += POLICY_EXPORT_MAX_LENGHT) {
516  client_printf(sockfd, "%.*s", POLICY_EXPORT_MAX_LENGHT, xml_out);
517  }
518  if (xml_write) {
519  client_printf(sockfd, "%.*s", xml_write, xml_out);
520  }
521  xmlFree(xml);
522  }
523  else {
524  client_printf_err(sockfd, "Unable to create policy XML, LibXML error!\n");
525  return POLICY_EXPORT_ERR_XML;
526  }
527  }
528 
529  return POLICY_EXPORT_OK;
530 }
531 
532 int policy_export(int sockfd, const policy_t* policy, const char* filename) {
533  xmlDocPtr doc;
534  xmlNodePtr root = NULL;
535  int ret;
536  char path[PATH_MAX];
537  xmlChar* xml = NULL;
538  char* xml_out;
539  int xml_length = 0;
540  int xml_write;
541  char* dirname, *dirlast;
542 
543  if (!policy) {
544  return POLICY_EXPORT_ERR_ARGS;
545  }
546 
547  if (filename) {
548  if (access(filename, W_OK)) {
549  if (errno == ENOENT) {
550  if ((dirname = strdup(filename))) {
551  if ((dirlast = strrchr(dirname, '/'))) {
552  *dirlast = 0;
553  if (access(dirname, W_OK)) {
554  client_printf_err(sockfd, "Write access to directory denied: %s\n", strerror(errno));
555  free(dirname);
556  return POLICY_EXPORT_ERR_FILE;
557  }
558  }
559  free(dirname);
560  }
561  }
562  else {
563  client_printf_err(sockfd, "Write access to file denied!\n");
564  return POLICY_EXPORT_ERR_FILE;
565  }
566  }
567 
568  if (snprintf(path, sizeof(path), "%s.new", filename) >= (int)sizeof(path)) {
569  client_printf_err(sockfd, "Unable to write XML to %s, path to long!\n", filename);
571  }
572  }
573 
574  if (!(doc = xmlNewDoc((xmlChar*)"1.0"))
575  || !(root = xmlNewNode(NULL, (xmlChar*)"KASP")))
576  {
577  client_printf_err(sockfd, "Unable to create XML elements, memory allocation error!\n");
578  if (doc) {
579  xmlFreeDoc(doc);
580  }
582  }
583 
584  xmlDocSetRootElement(doc, root);
585 
586  ret = __policy_export(sockfd, policy, root);
587  if (ret != POLICY_EXPORT_OK) {
588  xmlFreeDoc(doc);
589  return ret;
590  }
591 
592  if (filename) {
593  unlink(path);
594  if (xmlSaveFormatFileEnc(path, doc, "UTF-8", 1) == -1) {
595  client_printf_err(sockfd, "Unable to write policy, LibXML error!\n");
596  xmlFreeDoc(doc);
597  return POLICY_EXPORT_ERR_FILE;
598  }
599  xmlFreeDoc(doc);
600 
601  if (check_kasp(path, NULL, 0, 0, NULL, NULL)) {
602  client_printf_err(sockfd, "Unable to validate the exported policy XML!\n");
603  unlink(path);
604  return POLICY_EXPORT_ERR_XML;
605  }
606 
607  if (rename(path, filename)) {
608  client_printf_err(sockfd, "Unable to write policy, rename failed!\n");
609  unlink(path);
610  return POLICY_EXPORT_ERR_FILE;
611  }
612  }
613  else {
614  xmlDocDumpFormatMemoryEnc(doc, &xml, &xml_length, "UTF-8", 1);
615  xmlFreeDoc(doc);
616  if (xml && xml_length) {
617  for (xml_out = (char*)xml, xml_write = xml_length; xml_write > POLICY_EXPORT_MAX_LENGHT; xml_write -= POLICY_EXPORT_MAX_LENGHT, xml_out += POLICY_EXPORT_MAX_LENGHT) {
618  client_printf(sockfd, "%.*s", POLICY_EXPORT_MAX_LENGHT, xml_out);
619  }
620  if (xml_write) {
621  client_printf(sockfd, "%.*s", xml_write, xml_out);
622  }
623  xmlFree(xml);
624  }
625  else {
626  client_printf_err(sockfd, "Unable to create policy XML, LibXML error!\n");
627  return POLICY_EXPORT_ERR_XML;
628  }
629  }
630 
631  return POLICY_EXPORT_OK;
632 }
int policy_list_get(policy_list_t *policy_list)
Definition: policy.c:3040
const policy_key_t * policy_key_list_next(policy_key_list_t *policy_key_list)
Definition: policy_key.c:1378
#define POLICY_EXPORT_OK
Definition: policy_export.h:38
void policy_list_free(policy_list_t *policy_list)
Definition: policy.c:2664
unsigned int policy_denial_resalt(const policy_t *policy)
Definition: policy.c:917
unsigned int policy_parent_registration_delay(const policy_t *policy)
Definition: policy.c:1045
const char * policy_name(const policy_t *policy)
Definition: policy.c:813
int check_kasp(const char *kasp, char **repo_list, int repo_count, int verbose, char ***policy_names_out, int *policy_count_out)
Definition: kc_helper.c:1740
unsigned int policy_signatures_max_zone_ttl(const policy_t *policy)
Definition: policy.c:885
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
#define POLICY_KEY_MINIMIZE_RRSIG
unsigned int policy_signatures_validity_default(const policy_t *policy)
Definition: policy.c:861
#define POLICY_EXPORT_MAX_LENGHT
Definition: policy_export.c:46
unsigned int policy_parent_propagation_delay(const policy_t *policy)
Definition: policy.c:1053
unsigned int policy_signatures_validity_denial(const policy_t *policy)
Definition: policy.c:869
unsigned int policy_signatures_jitter(const policy_t *policy)
Definition: policy.c:845
unsigned int policy_key_rfc5011(const policy_key_t *policy_key)
Definition: policy_key.c:558
policy_denial_type
Definition: policy.h:40
unsigned int policy_signatures_inception_offset(const policy_t *policy)
Definition: policy.c:853
unsigned int policy_zone_propagation_delay(const policy_t *policy)
Definition: policy.c:1005
unsigned int policy_denial_iterations(const policy_t *policy)
Definition: policy.c:933
const char * policy_key_repository(const policy_key_t *policy_key)
Definition: policy_key.c:534
unsigned int policy_zone_soa_ttl(const policy_t *policy)
Definition: policy.c:1013
unsigned int policy_key_lifetime(const policy_key_t *policy_key)
Definition: policy_key.c:526
#define POLICY_EXPORT_ERR_ARGS
Definition: policy_export.h:42
unsigned int policy_keys_publish_safety(const policy_t *policy)
Definition: policy.c:981
int policy_export_all(int sockfd, const db_connection_t *connection, const char *filename)
policy_key_list_t * policy_get_policy_keys(const policy_t *policy)
Definition: policy_ext.c:1241
unsigned int policy_parent_ds_ttl(const policy_t *policy)
Definition: policy.c:1061
unsigned int policy_key_minimize(const policy_key_t *policy_key)
Definition: policy_key.c:566
const char * policy_zone_soa_serial_text(const policy_t *policy)
Definition: policy.c:1029
unsigned int policy_denial_ttl(const policy_t *policy)
Definition: policy.c:909
#define POLICY_EXPORT_ERR_MEMORY
Definition: policy_export.h:54
int policy_key_standby(const policy_key_t *policy_key)
Definition: policy_key.c:542
unsigned int policy_parent_soa_minimum(const policy_t *policy)
Definition: policy.c:1077
unsigned int policy_denial_optout(const policy_t *policy)
Definition: policy.c:901
unsigned int policy_keys_retire_safety(const policy_t *policy)
Definition: policy.c:973
policy_list_t * policy_list_new(const db_connection_t *connection)
Definition: policy.c:2621
unsigned int policy_key_manual_rollover(const policy_key_t *policy_key)
Definition: policy_key.c:550
#define POLICY_EXPORT_ERR_DATABASE
Definition: policy_export.h:50
#define POLICY_EXPORT_ERR_FILE
Definition: policy_export.h:58
const char * policy_description(const policy_t *policy)
Definition: policy.c:821
const policy_t * policy_list_next(policy_list_t *policy_list)
Definition: policy.c:3214
#define POLICY_KEY_MINIMIZE_DS
#define POLICY_EXPORT_ERR_XML
Definition: policy_export.h:46
int policy_export(int sockfd, const policy_t *policy, const char *filename)
Definition: policy.h:60
unsigned int policy_denial_salt_length(const policy_t *policy)
Definition: policy.c:941
unsigned int policy_key_algorithm(const policy_key_t *policy_key)
Definition: policy_key.c:510
unsigned int policy_parent_soa_ttl(const policy_t *policy)
Definition: policy.c:1069
#define POLICY_KEY_MINIMIZE_DS_AND_RRSIG
unsigned int policy_signatures_validity_keyset(const policy_t *policy)
Definition: policy.c:877
unsigned int policy_keys_shared(const policy_t *policy)
Definition: policy.c:989
policy_key_role
Definition: policy_key.h:40
unsigned int policy_key_bits(const policy_key_t *policy_key)
Definition: policy_key.c:518
void policy_key_list_free(policy_key_list_t *policy_key_list)
Definition: policy_key.c:1006
unsigned int policy_zone_soa_minimum(const policy_t *policy)
Definition: policy.c:1021
unsigned int policy_keys_purge_after(const policy_t *policy)
Definition: policy.c:997
#define POLICY_KEY_MINIMIZE_NONE
#define POLICY_KEY_MINIMIZE_DNSKEY
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