OpenDNSSEC-enforcer 2.1.13
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
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
48static int __free(char **p) {
49 if (!p || !*p) {
50 return 1;
51 }
52 free(*p);
53 *p = NULL;
54 return 0;
55}
56
57static 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];
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)
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)
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)
145 && !(node4 = xmlNewChild(node3, NULL, (xmlChar*)"OptOut", NULL)))
146 || !(error = 18)
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)
185 && !(node3 = xmlNewChild(keys, NULL, (xmlChar*)"ShareKeys", NULL)))
186 || !(error = 29)
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);
253 }
254 __free(&duration_text);
255
257 duration_cleanup(duration);
259 }
260
262 switch (policy_key_role(policy_key)) {
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)
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)
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);
301 }
302 __free(&duration_text);
303 break;
304
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)
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)
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)
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);
346 }
347 __free(&duration_text);
348 break;
349
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)
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)
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)
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);
397 }
398 __free(&duration_text);
399 break;
400
401 default:
403 duration_cleanup(duration);
405 }
406 }
408
409 duration_cleanup(duration);
410 return POLICY_EXPORT_OK;
411}
412
413int 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) {
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);
440 }
441 }
442 free(dirname);
443 }
444 }
445 else {
446 client_printf_err(sockfd, "Write access to file denied!\n");
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))
471 {
472 xmlFreeDoc(doc);
473 if (policy_list) {
476 }
478 }
479
481 ret = __policy_export(sockfd, policy, root);
482 if (ret != POLICY_EXPORT_OK) {
484 xmlFreeDoc(doc);
485 return ret;
486 }
487 }
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);
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);
503 }
504
505 if (rename(path, filename)) {
506 client_printf_err(sockfd, "Unable to write policy, rename failed!\n");
507 unlink(path);
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");
526 }
527 }
528
529 return POLICY_EXPORT_OK;
530}
531
532int 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) {
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);
557 }
558 }
559 free(dirname);
560 }
561 }
562 else {
563 client_printf_err(sockfd, "Write access to file denied!\n");
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);
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);
605 }
606
607 if (rename(path, filename)) {
608 client_printf_err(sockfd, "Unable to write policy, rename failed!\n");
609 unlink(path);
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");
628 }
629 }
630
631 return POLICY_EXPORT_OK;
632}
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:1772
unsigned int policy_denial_salt_length(const policy_t *policy)
Definition policy.c:941
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
unsigned int policy_denial_optout(const policy_t *policy)
Definition policy.c:901
unsigned int policy_parent_soa_minimum(const policy_t *policy)
Definition policy.c:1077
unsigned int policy_signatures_validity_denial(const policy_t *policy)
Definition policy.c:869
unsigned int policy_keys_purge_after(const policy_t *policy)
Definition policy.c:997
unsigned int policy_parent_ds_ttl(const policy_t *policy)
Definition policy.c:1061
unsigned int policy_signatures_resign(const policy_t *policy)
Definition policy.c:829
void policy_list_free(policy_list_t *policy_list)
Definition policy.c:2664
unsigned int policy_keys_ttl(const policy_t *policy)
Definition policy.c:965
const policy_t * policy_list_next(policy_list_t *policy_list)
Definition policy.c:3214
unsigned int policy_parent_propagation_delay(const policy_t *policy)
Definition policy.c:1053
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_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
const char * policy_name(const policy_t *policy)
Definition policy.c:813
unsigned int policy_keys_shared(const policy_t *policy)
Definition policy.c:989
unsigned int policy_signatures_jitter(const policy_t *policy)
Definition policy.c:845
policy_list_t * policy_list_new(const db_connection_t *connection)
Definition policy.c:2621
unsigned int policy_parent_registration_delay(const policy_t *policy)
Definition policy.c:1045
unsigned int policy_signatures_inception_offset(const policy_t *policy)
Definition policy.c:853
unsigned int policy_parent_soa_ttl(const policy_t *policy)
Definition policy.c:1069
int policy_list_get(policy_list_t *policy_list)
Definition policy.c:3040
const char * policy_zone_soa_serial_text(const policy_t *policy)
Definition policy.c:1029
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
const char * policy_description(const policy_t *policy)
Definition policy.c:821
unsigned int policy_denial_resalt(const policy_t *policy)
Definition policy.c:917
unsigned int policy_keys_publish_safety(const policy_t *policy)
Definition policy.c:981
unsigned int policy_keys_retire_safety(const policy_t *policy)
Definition policy.c:973
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
#define POLICY_EXPORT_MAX_LENGHT
int policy_export(int sockfd, const policy_t *policy, const char *filename)
int policy_export_all(int sockfd, const db_connection_t *connection, const char *filename)
#define POLICY_EXPORT_ERR_DATABASE
#define POLICY_EXPORT_ERR_ARGS
#define POLICY_EXPORT_ERR_FILE
#define POLICY_EXPORT_OK
#define POLICY_EXPORT_ERR_XML
#define POLICY_EXPORT_ERR_MEMORY
policy_key_list_t * policy_get_policy_keys(const policy_t *policy)
unsigned int policy_key_minimize(const policy_key_t *policy_key)
Definition policy_key.c:566
unsigned int policy_key_lifetime(const policy_key_t *policy_key)
Definition policy_key.c:526
unsigned int policy_key_manual_rollover(const policy_key_t *policy_key)
Definition policy_key.c:550
const policy_key_t * policy_key_list_next(policy_key_list_t *policy_key_list)
const char * policy_key_repository(const policy_key_t *policy_key)
Definition policy_key.c:534
void policy_key_list_free(policy_key_list_t *policy_key_list)
unsigned int policy_key_algorithm(const policy_key_t *policy_key)
Definition policy_key.c:510
unsigned int policy_key_rfc5011(const policy_key_t *policy_key)
Definition policy_key.c:558
unsigned int policy_key_bits(const policy_key_t *policy_key)
Definition policy_key.c:518
int policy_key_standby(const policy_key_t *policy_key)
Definition policy_key.c:542
policy_key_role
Definition policy_key.h:40
@ POLICY_KEY_ROLE_KSK
Definition policy_key.h:42
@ POLICY_KEY_ROLE_CSK
Definition policy_key.h:44
@ POLICY_KEY_ROLE_ZSK
Definition policy_key.h:43
#define POLICY_KEY_MINIMIZE_DS
#define POLICY_KEY_MINIMIZE_NONE
#define POLICY_KEY_MINIMIZE_DNSKEY
#define POLICY_KEY_MINIMIZE_DS_AND_RRSIG
#define POLICY_KEY_MINIMIZE_RRSIG