OpenDNSSEC-signer 2.1.13
zonelistparser.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 NLNet Labs. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
32#include "adapter/adapter.h"
34#include "file.h"
35#include "log.h"
36#include "status.h"
37#include "signer/zonelist.h"
38#include "signer/zone.h"
39
40#include <libxml/xpath.h>
41#include <libxml/xmlreader.h>
42#include <stdlib.h>
43#include <string.h>
44
45static const char* parser_str = "parser";
46
47
52static const char*
53parse_zonelist_element(xmlXPathContextPtr xpathCtx, xmlChar* expr)
54{
55 xmlXPathObjectPtr xpathObj = NULL;
56 const char* str = NULL;
57
58 ods_log_assert(xpathCtx);
59 ods_log_assert(expr);
60
61 xpathObj = xmlXPathEvalExpression(expr, xpathCtx);
62 if (xpathObj == NULL) {
63 ods_log_error("[%s] unable to evaluate xpath expression %s",
64 parser_str, expr);
65 return NULL;
66 }
67 str = (const char*) xmlXPathCastToString(xpathObj);
68 xmlXPathFreeObject(xpathObj);
69 return str;
70}
71
72
77static adapter_type*
78zlp_adapter(xmlNode* curNode, adapter_mode type, unsigned inbound)
79{
80 const char* file = NULL;
81 adapter_type* adapter = NULL;
82 file = (const char*) xmlNodeGetContent(curNode);
83 if (!file) {
84 ods_log_error("[%s] unable to read %s adapter", parser_str,
85 inbound?"input":"output");
86 return NULL;
87 }
88 adapter = adapter_create(file, type, inbound);
89 free((void*)file);
90 return adapter;
91}
92
93
98static adapter_type*
99parse_zonelist_adapter(xmlXPathContextPtr xpathCtx, xmlChar* expr,
100 int inbound)
101{
102 xmlXPathObjectPtr xpathObj = NULL;
103 xmlNode* curNode = NULL;
104 xmlChar* type = NULL;
105 adapter_type* adapter = NULL;
106 int i = 0;
107
108 if (!xpathCtx || !expr) {
109 return NULL;
110 }
111 xpathObj = xmlXPathEvalExpression(expr, xpathCtx);
112 if (xpathObj == NULL) {
113 ods_log_error("[%s] unable to parse adapter: xmlPathEvalExpression() "
114 "failed (expr %s)", parser_str, expr);
115 return NULL;
116 }
117 if (xpathObj->nodesetval) {
118 for (i=0; i < xpathObj->nodesetval->nodeNr; i++) {
119 curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
120 while (curNode) {
121 if (xmlStrEqual(curNode->name, (const xmlChar*)"File")) {
122 adapter = zlp_adapter(curNode, ADAPTER_FILE, inbound);
123 } else if (xmlStrEqual(curNode->name,
124 (const xmlChar*)"Adapter")) {
125 type = xmlGetProp(curNode, (const xmlChar*)"type");
126 if (xmlStrEqual(type, (const xmlChar*)"File")) {
127 adapter = zlp_adapter(curNode, ADAPTER_FILE, inbound);
128 } else if (xmlStrEqual(type, (const xmlChar*)"DNS")) {
129 adapter = zlp_adapter(curNode, ADAPTER_DNS, inbound);
130 } else {
131 ods_log_error("[%s] unable to parse %s adapter: "
132 "unknown type", parser_str, (const char*) type);
133 }
134 free((void*)type);
135 type = NULL;
136 }
137 if (adapter) {
138 xmlXPathFreeObject(xpathObj);
139 return adapter;
140 }
141 curNode = curNode->next;
142 }
143 }
144 }
145 xmlXPathFreeObject(xpathObj);
146 return NULL;
147}
148
149
154static void
155parse_zonelist_adapters(xmlXPathContextPtr xpathCtx, zone_type* zone)
156{
157 xmlChar* i_expr = (xmlChar*) "//Zone/Adapters/Input";
158 xmlChar* o_expr = (xmlChar*) "//Zone/Adapters/Output";
159
160 if (!xpathCtx || !zone) {
161 return;
162 }
163 zone->adinbound = parse_zonelist_adapter(xpathCtx, i_expr, 1);
164 zone->adoutbound = parse_zonelist_adapter(xpathCtx, o_expr, 0);
165}
166
167
172ods_status
173parse_zonelist_zones(void* zlist, const char* zlfile)
174{
175 char* tag_name = NULL;
176 char* zone_name = NULL;
177 zone_type* new_zone = NULL;
178 int ret = 0;
179 int error = 0;
180 xmlTextReaderPtr reader = NULL;
181 xmlDocPtr doc = NULL;
182 xmlXPathContextPtr xpathCtx = NULL;
183 xmlChar* name_expr = (unsigned char*) "name";
184 xmlChar* policy_expr = (unsigned char*) "//Zone/Policy";
185 xmlChar* signconf_expr = (unsigned char*) "//Zone/SignerConfiguration";
186
187 if (!zlist || !zlfile) {
188 ods_log_error("[%s] unable to parse zonelist: no storage or no filename",
189 parser_str);
190 return ODS_STATUS_ASSERT_ERR;
191 }
192 reader = xmlNewTextReaderFilename(zlfile);
193 if (!reader) {
194 ods_log_error("[%s] unable to parse zonelist: failed to open file %s",
195 parser_str, zlfile);
196 return ODS_STATUS_XML_ERR;
197 }
198 ret = xmlTextReaderRead(reader);
199 while (ret == XML_READER_TYPE_ELEMENT) {
200 tag_name = (char*) xmlTextReaderLocalName(reader);
201 if (ods_strcmp(tag_name, "Zone") == 0 &&
202 ods_strcmp(tag_name, "ZoneList") != 0 &&
203 xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
204 /* Found a zone */
205 zone_name = (char*) xmlTextReaderGetAttribute(reader,
206 name_expr);
207 if (!zone_name || strlen(zone_name) <= 0) {
208 ods_log_alert("[%s] unable to extract zone name from "
209 "zonelist %s, skipping...", parser_str, zlfile);
210 if (zone_name) {
211 free((void*) zone_name);
212 }
213 free((void*) tag_name);
214 ret = xmlTextReaderRead(reader);
215 continue;
216 }
217 /* Expand this node to get the rest of the info */
218 xmlTextReaderExpand(reader);
219 doc = xmlTextReaderCurrentDoc(reader);
220 if (doc) {
221 xpathCtx = xmlXPathNewContext(doc);
222 }
223 if (doc == NULL || xpathCtx == NULL) {
224 ods_log_alert("[%s] unable to read zone %s, skipping...",
225 parser_str, zone_name);
226 ret = xmlTextReaderRead(reader);
227 free((void*) zone_name);
228 free((void*) tag_name);
229 continue;
230 }
231 /* That worked, now read out the contents... */
232 new_zone = zone_create(zone_name, LDNS_RR_CLASS_IN);
233 if (new_zone) {
234 new_zone->policy_name = parse_zonelist_element(xpathCtx,
235 policy_expr);
236 new_zone->signconf_filename = parse_zonelist_element(xpathCtx,
237 signconf_expr);
238 parse_zonelist_adapters(xpathCtx, new_zone);
239 if (!new_zone->policy_name || !new_zone->signconf_filename ||
240 !new_zone->adinbound || !new_zone->adoutbound) {
241 zone_cleanup(new_zone);
242 new_zone = NULL;
243 ods_log_crit("[%s] unable to create zone %s", parser_str,
244 zone_name);
245 error = 1;
246 } else if (zonelist_add_zone((zonelist_type*) zlist, new_zone)
247 == NULL) {
248 ods_log_crit("[%s] unable to add zone %s", parser_str,
249 zone_name);
250 zone_cleanup(new_zone);
251 new_zone = NULL;
252 error = 1;
253 }
254 } else {
255 ods_log_crit("[%s] unable to create zone %s", parser_str,
256 zone_name);
257 error = 1;
258 }
259 xmlXPathFreeContext(xpathCtx);
260 xpathCtx = NULL;
261 free((void*) zone_name);
262 if (error) {
263 free((void*) tag_name);
264 tag_name = NULL;
265 ret = 1;
266 break;
267 }
268 ods_log_debug("[%s] zone %s added", parser_str, new_zone->name);
269 }
270 free((void*) tag_name);
271 ret = xmlTextReaderRead(reader);
272 }
273 /* no more zones */
274 ods_log_debug("[%s] no more zones", parser_str);
275 xmlFreeTextReader(reader);
276 if (doc) {
277 xmlFreeDoc(doc);
278 }
279 if (ret != 0) {
280 ods_log_error("[%s] unable to parse zonelist: parse error in %s",
281 parser_str, zlfile);
282 return ODS_STATUS_PARSE_ERR;
283 }
284 return ODS_STATUS_OK;
285}
adapter_type * adapter_create(const char *str, adapter_mode type, unsigned in)
Definition adapter.c:48
enum adapter_mode_enum adapter_mode
Definition adapter.h:44
@ ADAPTER_DNS
Definition adapter.h:42
@ ADAPTER_FILE
Definition adapter.h:41
const char * policy_name
Definition zone.h:70
adapter_type * adinbound
Definition zone.h:74
const char * signconf_filename
Definition zone.h:71
const char * name
Definition zone.h:69
adapter_type * adoutbound
Definition zone.h:75
void zone_cleanup(zone_type *zone)
Definition zone.c:759
zone_type * zone_create(char *name, ldns_rr_class klass)
Definition zone.c:55
zone_type * zonelist_add_zone(zonelist_type *zlist, zone_type *zone)
Definition zonelist.c:201
ods_status parse_zonelist_zones(void *zlist, const char *zlfile)