OpenDNSSEC-signer  1.4.9
addnsparser.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 "parser/addnsparser.h"
33 #include "shared/log.h"
34 
35 #include <libxml/xpath.h>
36 #include <libxml/xmlreader.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 static const char* parser_str = "parser";
41 
42 
47 static acl_type*
48 parse_addns_remote(allocator_type* allocator, const char* filename,
49  tsig_type* tsig, char* expr)
50 {
51  acl_type* acl = NULL;
52  acl_type* new_acl = NULL;
53  int i = 0;
54  char* address = NULL;
55  char* port = NULL;
56  char* key = NULL;
57  xmlDocPtr doc = NULL;
58  xmlXPathContextPtr xpathCtx = NULL;
59  xmlXPathObjectPtr xpathObj = NULL;
60  xmlNode* curNode = NULL;
61  xmlChar* xexpr = NULL;
62 
63  if (!allocator || !filename || !expr) {
64  return NULL;
65  }
66  /* Load XML document */
67  doc = xmlParseFile(filename);
68  if (doc == NULL) {
69  ods_log_error("[%s] could not parse %s: xmlParseFile() failed",
70  parser_str, expr);
71  return NULL;
72  }
73  /* Create xpath evaluation context */
74  xpathCtx = xmlXPathNewContext(doc);
75  if(xpathCtx == NULL) {
76  xmlFreeDoc(doc);
77  ods_log_error("[%s] could not parse %s: xmlXPathNewContext() failed",
78  parser_str, expr);
79  return NULL;
80  }
81  /* Evaluate xpath expression */
82  xexpr = (xmlChar*) expr;
83  xpathObj = xmlXPathEvalExpression(xexpr, xpathCtx);
84  if(xpathObj == NULL) {
85  xmlXPathFreeContext(xpathCtx);
86  xmlFreeDoc(doc);
87  ods_log_error("[%s] could not parse %s: xmlXPathEvalExpression() "
88  "failed", parser_str, expr);
89  return NULL;
90  }
91  /* Parse interfaces */
92  if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr > 0) {
93  for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
94  address = NULL;
95  port = NULL;
96  key = NULL;
97 
98  curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
99  while (curNode) {
100  if (xmlStrEqual(curNode->name, (const xmlChar *)"Address")) {
101  address = (char *) xmlNodeGetContent(curNode);
102  } else if (xmlStrEqual(curNode->name,
103  (const xmlChar *)"Port")) {
104  port = (char *) xmlNodeGetContent(curNode);
105  } else if (xmlStrEqual(curNode->name,
106  (const xmlChar *)"Key")) {
107  key = (char *) xmlNodeGetContent(curNode);
108  }
109  curNode = curNode->next;
110  }
111  if (address) {
112  new_acl = acl_create(allocator, address, port, key, tsig);
113  if (!new_acl) {
114  ods_log_error("[%s] unable to add server %s:%s %s to list "
115  "%s: acl_create() failed", parser_str, address,
116  port?port:"", key?key:"", (char*) expr);
117  } else {
118  new_acl->next = acl;
119  acl = new_acl;
120  ods_log_debug("[%s] added server %s:%s %s to list %s",
121  parser_str, address, port?port:"", key?key:"",
122  (char*) expr);
123  }
124  }
125  free((void*)address);
126  free((void*)port);
127  free((void*)key);
128  }
129  }
130  xmlXPathFreeObject(xpathObj);
131  xmlXPathFreeContext(xpathCtx);
132  if (doc) {
133  xmlFreeDoc(doc);
134  }
135  return acl;
136 }
137 
138 
143 static acl_type*
144 parse_addns_acl(allocator_type* allocator, const char* filename,
145  tsig_type* tsig, char* expr)
146 {
147  acl_type* acl = NULL;
148  acl_type* new_acl = NULL;
149  int i = 0;
150  char* prefix = NULL;
151  char* key = NULL;
152  xmlDocPtr doc = NULL;
153  xmlXPathContextPtr xpathCtx = NULL;
154  xmlXPathObjectPtr xpathObj = NULL;
155  xmlNode* curNode = NULL;
156  xmlChar* xexpr = NULL;
157 
158  if (!allocator || !filename || !expr) {
159  return NULL;
160  }
161  /* Load XML document */
162  doc = xmlParseFile(filename);
163  if (doc == NULL) {
164  ods_log_error("[%s] could not parse %s: xmlParseFile() failed",
165  parser_str, expr);
166  return NULL;
167  }
168  /* Create xpath evaluation context */
169  xpathCtx = xmlXPathNewContext(doc);
170  if(xpathCtx == NULL) {
171  xmlFreeDoc(doc);
172  ods_log_error("[%s] could not parse %s: xmlXPathNewContext() failed",
173  parser_str, expr);
174  return NULL;
175  }
176  /* Evaluate xpath expression */
177  xexpr = (xmlChar*) expr;
178  xpathObj = xmlXPathEvalExpression(xexpr, xpathCtx);
179  if(xpathObj == NULL) {
180  xmlXPathFreeContext(xpathCtx);
181  xmlFreeDoc(doc);
182  ods_log_error("[%s] could not parse %s: xmlXPathEvalExpression() "
183  "failed", parser_str, expr);
184  return NULL;
185  }
186  /* Parse interfaces */
187  if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr > 0) {
188  for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
189  prefix = NULL;
190  key = NULL;
191 
192  curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
193  while (curNode) {
194  if (xmlStrEqual(curNode->name, (const xmlChar *)"Prefix")) {
195  prefix = (char *) xmlNodeGetContent(curNode);
196  } else if (xmlStrEqual(curNode->name,
197  (const xmlChar *)"Key")) {
198  key = (char *) xmlNodeGetContent(curNode);
199  }
200  curNode = curNode->next;
201  }
202  if (prefix || key) {
203  new_acl = acl_create(allocator, prefix, NULL, key, tsig);
204  if (!new_acl) {
205  ods_log_error("[%s] unable to add acl for %s %s to list "
206  "%s: acl_create() failed", parser_str, prefix?prefix:"",
207  key?key:"", (char*) expr);
208  } else {
209  new_acl->next = acl;
210  acl = new_acl;
211  ods_log_debug("[%s] added %s %s interface to list %s",
212  parser_str, prefix?prefix:"", key?key:"", (char*) expr);
213  }
214  }
215  free((void*)prefix);
216  free((void*)key);
217  }
218  }
219  xmlXPathFreeObject(xpathObj);
220  xmlXPathFreeContext(xpathCtx);
221  if (doc) {
222  xmlFreeDoc(doc);
223  }
224  return acl;
225 }
226 
227 
232 static tsig_type*
233 parse_addns_tsig_static(allocator_type* allocator, const char* filename,
234  char* expr)
235 {
236  tsig_type* tsig = NULL;
237  tsig_type* new_tsig = NULL;
238  int i = 0;
239  char* name = NULL;
240  char* algo = NULL;
241  char* secret = NULL;
242  xmlDocPtr doc = NULL;
243  xmlXPathContextPtr xpathCtx = NULL;
244  xmlXPathObjectPtr xpathObj = NULL;
245  xmlNode* curNode = NULL;
246  xmlChar* xexpr = NULL;
247 
248  if (!allocator || !filename || !expr) {
249  return NULL;
250  }
251  /* Load XML document */
252  doc = xmlParseFile(filename);
253  if (doc == NULL) {
254  ods_log_error("[%s] could not parse %s: xmlParseFile() failed",
255  parser_str, expr);
256  return NULL;
257  }
258  /* Create xpath evaluation context */
259  xpathCtx = xmlXPathNewContext(doc);
260  if(xpathCtx == NULL) {
261  xmlFreeDoc(doc);
262  ods_log_error("[%s] could not parse %s: xmlXPathNewContext() failed",
263  parser_str, expr);
264  return NULL;
265  }
266  /* Evaluate xpath expression */
267  xexpr = (xmlChar*) expr;
268  xpathObj = xmlXPathEvalExpression(xexpr, xpathCtx);
269  if(xpathObj == NULL) {
270  xmlXPathFreeContext(xpathCtx);
271  xmlFreeDoc(doc);
272  ods_log_error("[%s] could not parse %s: xmlXPathEvalExpression() "
273  "failed", parser_str, expr);
274  return NULL;
275  }
276  /* Parse interfaces */
277  if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr > 0) {
278  for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
279  name = NULL;
280  algo = NULL;
281  secret = NULL;
282 
283  curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
284  while (curNode) {
285  if (xmlStrEqual(curNode->name, (const xmlChar *)"Name")) {
286  name = (char *) xmlNodeGetContent(curNode);
287  } else if (xmlStrEqual(curNode->name,
288  (const xmlChar *)"Algorithm")) {
289  algo = (char *) xmlNodeGetContent(curNode);
290  } else if (xmlStrEqual(curNode->name,
291  (const xmlChar *)"Secret")) {
292  secret = (char *) xmlNodeGetContent(curNode);
293  }
294  curNode = curNode->next;
295  }
296  if (name && algo && secret) {
297  new_tsig = tsig_create(allocator, name, algo, secret);
298  if (!new_tsig) {
299  ods_log_error("[%s] unable to add tsig %s: "
300  "tsig_create() failed", parser_str, name);
301  } else {
302  new_tsig->next = tsig;
303  tsig = new_tsig;
304  ods_log_debug("[%s] added %s tsig to list %s",
305  parser_str, name, (char*) expr);
306  }
307  }
308  free((void*)name);
309  free((void*)algo);
310  free((void*)secret);
311  }
312  }
313  xmlXPathFreeObject(xpathObj);
314  xmlXPathFreeContext(xpathCtx);
315  if (doc) {
316  xmlFreeDoc(doc);
317  }
318  return tsig;
319 }
320 
321 
326 acl_type*
327 parse_addns_request_xfr(allocator_type* allocator, const char* filename,
328  tsig_type* tsig)
329 {
330  return parse_addns_remote(allocator, filename, tsig,
331  "//Adapter/DNS/Inbound/RequestTransfer/Remote"
332  );
333 }
334 
335 
340 acl_type*
341 parse_addns_allow_notify(allocator_type* allocator, const char* filename,
342  tsig_type* tsig)
343 {
344  return parse_addns_acl(allocator, filename, tsig,
345  "//Adapter/DNS/Inbound/AllowNotify/Peer"
346  );
347 }
348 
349 
354 acl_type*
355 parse_addns_provide_xfr(allocator_type* allocator, const char* filename,
356  tsig_type* tsig)
357 {
358  return parse_addns_acl(allocator, filename, tsig,
359  "//Adapter/DNS/Outbound/ProvideTransfer/Peer"
360  );
361 }
362 
363 
368 acl_type*
369 parse_addns_do_notify(allocator_type* allocator, const char* filename,
370  tsig_type* tsig)
371 {
372  return parse_addns_remote(allocator, filename, tsig,
373  "//Adapter/DNS/Outbound/Notify/Remote"
374  );
375 }
376 
377 
382 tsig_type*
383 parse_addns_tsig(allocator_type* allocator, const char* filename)
384 {
385  return parse_addns_tsig_static(allocator, filename,
386  "//Adapter/DNS/TSIG"
387  );
388 }
389 
tsig_type * parse_addns_tsig(allocator_type *allocator, const char *filename)
Definition: addnsparser.c:383
acl_type * parse_addns_provide_xfr(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:355
void ods_log_debug(const char *format,...)
Definition: log.c:270
acl_type * parse_addns_request_xfr(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:327
void ods_log_error(const char *format,...)
Definition: log.c:334
acl_type * next
Definition: acl.h:59
tsig_type * next
Definition: tsig.h:112
acl_type * parse_addns_allow_notify(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:341
acl_type * parse_addns_do_notify(allocator_type *allocator, const char *filename, tsig_type *tsig)
Definition: addnsparser.c:369
tsig_type * tsig_create(allocator_type *allocator, char *name, char *algo, char *secret)
Definition: tsig.c:235
acl_type * acl_create(allocator_type *allocator, char *address, char *port, char *tsig_name, tsig_type *tsig)
Definition: acl.c:126
Definition: acl.h:58