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