OpenDNSSEC-enforcer  2.0.2
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  return POLICY_EXPORT_ERR_XML;
345  }
346  __free(&duration_text);
347  break;
348 
349  case POLICY_KEY_ROLE_CSK:
350  error = 300;
351  if (!(node2 = xmlNewChild(keys, NULL, (xmlChar*)"CSK", NULL))
352  || !(error = 301)
353  || snprintf(text, sizeof(text), "%u", policy_key_algorithm(policy_key)) >= (int)sizeof(text)
354  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Algorithm", (xmlChar*)text))
355  || !(error = 302)
356  || snprintf(text, sizeof(text), "%u", policy_key_bits(policy_key)) >= (int)sizeof(text)
357  || !xmlNewProp(node3, (xmlChar*)"length", (xmlChar*)text)
358  || !(error = 303)
359  || duration_set_time(duration, policy_key_lifetime(policy_key))
360  || !(duration_text = duration2string(duration))
361  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Lifetime", (xmlChar*)duration_text))
362  || __free(&duration_text)
363  || !(error = 304)
364  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Repository", (xmlChar*)policy_key_repository(policy_key)))
365  || !(error = 305)
366  || (policy_key_standby(policy_key)
367  && (snprintf(text, sizeof(text), "%u", policy_key_standby(policy_key)) >= (int)sizeof(text)
368  || !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"Standby", (xmlChar*)text))))
369  || !(error = 306)
370  || (policy_key_manual_rollover(policy_key)
371  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"ManualRollover", NULL)))
372  || !(error = 307)
374  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskDoubleRRset")))
375  || !(error = 308)
377  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskSingleSignature")))
378  || !(error = 309)
380  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskDoubleDS")))
381  || !(error = 310)
383  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskDoubleSignature")))
384  || !(error = 311)
386  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"CskRollType", (xmlChar*)"CskPrePublication")))
387  || !(error = 312)
388  || (policy_key_rfc5011(policy_key)
389  && !(node3 = xmlNewChild(node2, NULL, (xmlChar*)"RFC5011", NULL)))
390  )
391  {
392  client_printf_err(sockfd, "Unable to create XML elements, error code %d!\n", error);
393  __free(&duration_text);
394  duration_cleanup(duration);
395  return POLICY_EXPORT_ERR_XML;
396  }
397  __free(&duration_text);
398  break;
399 
400  default:
401  policy_key_list_free(policy_key_list);
402  duration_cleanup(duration);
404  }
405  }
406  policy_key_list_free(policy_key_list);
407 
408  duration_cleanup(duration);
409  return POLICY_EXPORT_OK;
410 }
411 
412 int policy_export_all(int sockfd, const db_connection_t* connection, const char* filename) {
414  const policy_t* policy;
415  xmlDocPtr doc;
416  xmlNodePtr root = NULL;
417  int ret;
418  char path[PATH_MAX];
419  xmlChar* xml = NULL;
420  char* xml_out;
421  int xml_length = 0;
422  int xml_write;
423  char* dirname, *dirlast;
424 
425  if (!connection) {
426  return POLICY_EXPORT_ERR_ARGS;
427  }
428 
429  if (filename) {
430  if (access(filename, W_OK)) {
431  if (errno == ENOENT) {
432  if ((dirname = strdup(filename))) {
433  if ((dirlast = strrchr(dirname, '/'))) {
434  *dirlast = 0;
435  if (access(dirname, W_OK)) {
436  client_printf_err(sockfd, "Write access to directory denied: %s\n", strerror(errno));
437  free(dirname);
438  return POLICY_EXPORT_ERR_FILE;
439  }
440  }
441  free(dirname);
442  }
443  }
444  else {
445  client_printf_err(sockfd, "Write access to file denied!\n");
446  return POLICY_EXPORT_ERR_FILE;
447  }
448  }
449 
450  if (snprintf(path, sizeof(path), "%s.new", filename) >= (int)sizeof(path)) {
451  client_printf_err(sockfd, "Unable to write XML to %s, path to long!\n", filename);
453  }
454  }
455 
456  if (!(doc = xmlNewDoc((xmlChar*)"1.0"))
457  || !(root = xmlNewNode(NULL, (xmlChar*)"KASP")))
458  {
459  client_printf_err(sockfd, "Unable to create XML elements, memory allocation error!\n");
460  if (doc) {
461  xmlFreeDoc(doc);
462  }
464  }
465 
466  xmlDocSetRootElement(doc, root);
467 
468  if (!(policy_list = policy_list_new(connection))
469  || policy_list_get(policy_list))
470  {
471  xmlFreeDoc(doc);
472  if (policy_list) {
473  policy_list_free(policy_list);
475  }
477  }
478 
479  for (policy = policy_list_next(policy_list); policy; policy = policy_list_next(policy_list)) {
480  ret = __policy_export(sockfd, policy, root);
481  if (ret != POLICY_EXPORT_OK) {
482  policy_list_free(policy_list);
483  xmlFreeDoc(doc);
484  return ret;
485  }
486  }
487  policy_list_free(policy_list);
488 
489  if (filename) {
490  unlink(path);
491  if (xmlSaveFormatFileEnc(path, doc, "UTF-8", 1) == -1) {
492  client_printf_err(sockfd, "Unable to write policy, LibXML error!\n");
493  xmlFreeDoc(doc);
494  return POLICY_EXPORT_ERR_FILE;
495  }
496  xmlFreeDoc(doc);
497 
498  if (check_kasp(path, NULL, 0, 0, NULL, NULL)) {
499  client_printf_err(sockfd, "Unable to validate the exported policy XML!\n");
500  unlink(path);
501  return POLICY_EXPORT_ERR_XML;
502  }
503 
504  if (rename(path, filename)) {
505  client_printf_err(sockfd, "Unable to write policy, rename failed!\n");
506  unlink(path);
507  return POLICY_EXPORT_ERR_FILE;
508  }
509  }
510  else {
511  xmlDocDumpFormatMemoryEnc(doc, &xml, &xml_length, "UTF-8", 1);
512  xmlFreeDoc(doc);
513  if (xml && xml_length) {
514  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) {
515  client_printf(sockfd, "%.*s", POLICY_EXPORT_MAX_LENGHT, xml_out);
516  }
517  if (xml_write) {
518  client_printf(sockfd, "%.*s", xml_write, xml_out);
519  }
520  xmlFree(xml);
521  }
522  else {
523  client_printf_err(sockfd, "Unable to create policy XML, LibXML error!\n");
524  return POLICY_EXPORT_ERR_XML;
525  }
526  }
527 
528  return POLICY_EXPORT_OK;
529 }
530 
531 int policy_export(int sockfd, const policy_t* policy, const char* filename) {
532  xmlDocPtr doc;
533  xmlNodePtr root = NULL;
534  int ret;
535  char path[PATH_MAX];
536  xmlChar* xml = NULL;
537  char* xml_out;
538  int xml_length = 0;
539  int xml_write;
540  char* dirname, *dirlast;
541 
542  if (!policy) {
543  return POLICY_EXPORT_ERR_ARGS;
544  }
545 
546  if (filename) {
547  if (access(filename, W_OK)) {
548  if (errno == ENOENT) {
549  if ((dirname = strdup(filename))) {
550  if ((dirlast = strrchr(dirname, '/'))) {
551  *dirlast = 0;
552  if (access(dirname, W_OK)) {
553  client_printf_err(sockfd, "Write access to directory denied: %s\n", strerror(errno));
554  free(dirname);
555  return POLICY_EXPORT_ERR_FILE;
556  }
557  }
558  free(dirname);
559  }
560  }
561  else {
562  client_printf_err(sockfd, "Write access to file denied!\n");
563  return POLICY_EXPORT_ERR_FILE;
564  }
565  }
566 
567  if (snprintf(path, sizeof(path), "%s.new", filename) >= (int)sizeof(path)) {
568  client_printf_err(sockfd, "Unable to write XML to %s, path to long!\n", filename);
570  }
571  }
572 
573  if (!(doc = xmlNewDoc((xmlChar*)"1.0"))
574  || !(root = xmlNewNode(NULL, (xmlChar*)"KASP")))
575  {
576  client_printf_err(sockfd, "Unable to create XML elements, memory allocation error!\n");
577  if (doc) {
578  xmlFreeDoc(doc);
579  }
581  }
582 
583  xmlDocSetRootElement(doc, root);
584 
585  ret = __policy_export(sockfd, policy, root);
586  if (ret != POLICY_EXPORT_OK) {
587  xmlFreeDoc(doc);
588  return ret;
589  }
590 
591  if (filename) {
592  unlink(path);
593  if (xmlSaveFormatFileEnc(path, doc, "UTF-8", 1) == -1) {
594  client_printf_err(sockfd, "Unable to write policy, LibXML error!\n");
595  xmlFreeDoc(doc);
596  return POLICY_EXPORT_ERR_FILE;
597  }
598  xmlFreeDoc(doc);
599 
600  if (check_kasp(path, NULL, 0, 0, NULL, NULL)) {
601  client_printf_err(sockfd, "Unable to validate the exported policy XML!\n");
602  unlink(path);
603  return POLICY_EXPORT_ERR_XML;
604  }
605 
606  if (rename(path, filename)) {
607  client_printf_err(sockfd, "Unable to write policy, rename failed!\n");
608  unlink(path);
609  return POLICY_EXPORT_ERR_FILE;
610  }
611  }
612  else {
613  xmlDocDumpFormatMemoryEnc(doc, &xml, &xml_length, "UTF-8", 1);
614  xmlFreeDoc(doc);
615  if (xml && xml_length) {
616  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) {
617  client_printf(sockfd, "%.*s", POLICY_EXPORT_MAX_LENGHT, xml_out);
618  }
619  if (xml_write) {
620  client_printf(sockfd, "%.*s", xml_write, xml_out);
621  }
622  xmlFree(xml);
623  }
624  else {
625  client_printf_err(sockfd, "Unable to create policy XML, LibXML error!\n");
626  return POLICY_EXPORT_ERR_XML;
627  }
628  }
629 
630  return POLICY_EXPORT_OK;
631 }
int policy_list_get(policy_list_t *policy_list)
Definition: policy.c:3037
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:1755
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:1248
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:3211
#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