1 /*
2  * ldns.i: LDNS interface file
3  *
4  * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
5  *                     Karel Slany    (slany AT fit.vutbr.cz)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  *     * Redistributions of source code must retain the above copyright notice,
12  *       this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in the
15  *       documentation and/or other materials provided with the distribution.
16  *     * Neither the name of the organization nor the names of its
17  *       contributors may be used to endorse or promote products derived from this
18  *       software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 %module ldns
34 #pragma SWIG nowarn=454
35 %{
36 
37 #include "ldns.h"
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <inttypes.h>
41 
42 #include <ldns/util.h>
43 #include <ldns/buffer.h>
44 #include <ldns/common.h>
45 #include <ldns/dname.h>
46 #include <ldns/dnssec.h>
47 #include <ldns/dnssec_verify.h>
48 #include <ldns/dnssec_sign.h>
49 #include <ldns/error.h>
50 #include <ldns/higher.h>
51 #include <ldns/host2str.h>
52 #include <ldns/host2wire.h>
53 #include <ldns/net.h>
54 #include <ldns/packet.h>
55 #include <ldns/rdata.h>
56 #include <ldns/resolver.h>
57 #include <ldns/rr.h>
58 #include <ldns/str2host.h>
59 #include <ldns/tsig.h>
60 #include <ldns/update.h>
61 #include <ldns/wire2host.h>
62 #include <ldns/rr_functions.h>
63 #include <ldns/keys.h>
64 #include <ldns/parse.h>
65 #include <ldns/zone.h>
66 #include <ldns/dnssec_zone.h>
67 #include <ldns/rbtree.h>
68 %}
69 
70 //#define LDNS_DEBUG
71 //#define SWIG_FILE3_DEBUG
72 
73 %include "stdint.i" // uint_16_t is known type now
74 #ifdef PY3
75 %include "file_py3.i" // python 3 FILE *
76 #else
77 %include "file.i"     // FILE *
78 #endif
79 %include "typemaps.i"
80 
81 
82 /* ========================================================================= */
83 /* Preliminary Python code. */
84 /* ========================================================================= */
85 
86 %pythoncode
87 %{
88 	#
89 	# Use and don't ignore DeprecationWarning and
90 	# PendingDeprecationWarning.
91 	#
92 	import warnings
93 	warnings.filterwarnings("module", category=DeprecationWarning)
94 	warnings.filterwarnings("module", category=PendingDeprecationWarning)
95 %}
96 
97 
98 /* Tell SWIG how to handle ssize_t as input parameter. */
99 %typemap(in, noblock=1) (ssize_t)
100 {
101   int $1_res = 0;
102   $1_res = SWIG_AsVal_long($input, &$1);
103   if (!SWIG_IsOK($1_res)) {
104     SWIG_exception_fail(SWIG_ArgError($1_res), "in method '"
105       "$symname" "', argument " "$argnum" " of type '"
106       "$type""'");
107   }
108 }
109 
110 
111 %inline %{
ldns_make_timeval(uint32_t sec,uint32_t usec)112 struct timeval* ldns_make_timeval(uint32_t sec, uint32_t usec)
113 {
114         struct timeval* res = (struct timeval*)malloc(sizeof(*res));
115         res->tv_sec = sec;
116         res->tv_usec = usec;
117         return res;
118 }
119 uint32_t ldns_read_timeval_sec(struct timeval* t) {
120         return (uint32_t)t->tv_sec; }
121 uint32_t ldns_read_timeval_usec(struct timeval* t) {
122         return (uint32_t)t->tv_usec; }
123 %}
124 
125 %immutable ldns_struct_lookup_table::name;
126 %immutable ldns_struct_rr_descriptor::_name;
127 %immutable ldns_error_str;
128 %immutable ldns_signing_algorithms;
129 %immutable ldns_tsig_credentials_struct::algorithm;
130 %immutable ldns_tsig_credentials_struct::keyname;
131 %immutable ldns_tsig_credentials_struct::keydata;
132 
133 //*_new_frm_fp_l
134 %apply int *OUTPUT { (int *line_nr) };
135 
136 %apply uint32_t *OUTPUT { uint32_t *default_ttl};
137 
138 // wire2pkt
139 %apply (char *STRING, int LENGTH) { (const char *str, int len) };
140 
141 %include "ldns_packet.i"
142 %include "ldns_resolver.i"
143 %include "ldns_rr.i"
144 
145 %include <ldns/rr.h>
146 
147 %inline %{
148 int Python_str_Check(PyObject *o) {
149 #if PY_VERSION_HEX>=0x03000000
150   return PyUnicode_Check(o);
151 #else
152   return PyString_Check(o);
153 #endif
154 }
155 %}
156 
157 %include "ldns_rdf.i"
158 %include "ldns_zone.i"
159 %include "ldns_key.i"
160 %include "ldns_buffer.i"
161 %include "ldns_dnssec.i"
162 
163 %include <ldns/util.h>
164   %include <ldns/buffer.h>
165 %include <ldns/dnssec.h>
166 %include <ldns/dnssec_verify.h>
167   %include <ldns/dnssec_sign.h>
168 %include <ldns/error.h>
169 %include <ldns/higher.h>
170   %include <ldns/host2str.h>
171   %include <ldns/host2wire.h>
172 %include <ldns/net.h>
173   %include <ldns/packet.h>
174   %include <ldns/rdata.h>
175   %include <ldns/resolver.h>
176 %include <ldns/str2host.h>
177 %include <ldns/tsig.h>
178   %include <ldns/update.h>
179 %include <ldns/wire2host.h>
180   %include <ldns/rr_functions.h>
181   %include <ldns/keys.h>
182 %include <ldns/parse.h>
183   %include <ldns/zone.h>
184   %include <ldns/dnssec_zone.h>
185 %include <ldns/rbtree.h>
186   %include <ldns/dname.h>
187 
188 typedef struct ldns_dnssec_name { };
189 typedef struct ldns_dnssec_rrs { };
190 typedef struct ldns_dnssec_rrsets { };
191 typedef struct ldns_dnssec_zone { };
192 // ================================================================================
193 
194 %include "ldns_dname.i"
195 
196 %inline %{
197  PyObject* ldns_rr_new_frm_str_(const char *str, uint32_t default_ttl, ldns_rdf* origin, ldns_rdf* prev)
198  //returns tuple (status, ldns_rr, prev)
199  {
200    PyObject* tuple;
201 
202    /*  origin and prev have to be cloned in order to decouple the data
203     *  from the python wrapper
204     */
205    if (origin != NULL)
206        origin = ldns_rdf_clone(origin);
207    if (prev != NULL)
208        prev = ldns_rdf_clone(prev);
209 
210    ldns_rdf *p_prev = prev;
211    ldns_rdf **pp_prev = &p_prev;
212    if (p_prev == 0) pp_prev = 0;
213 
214    ldns_rr *p_rr = 0;
215    ldns_rr **pp_rr = &p_rr;
216 
217    ldns_status st = ldns_rr_new_frm_str(pp_rr, str, default_ttl, origin, pp_prev);
218 
219    tuple = PyTuple_New(3);
220    PyTuple_SetItem(tuple, 0, SWIG_From_int(st));
221    PyTuple_SetItem(tuple, 1, (st == LDNS_STATUS_OK) ?
222                              SWIG_NewPointerObj(SWIG_as_voidptr(p_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN |  0 ) :
223 		   (Py_INCREF(Py_None), Py_None));
224    PyTuple_SetItem(tuple, 2, (p_prev != prev) ?
225                              SWIG_NewPointerObj(SWIG_as_voidptr(p_prev), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN |  0 ) :
226 		   (Py_INCREF(Py_None), Py_None));
227    return tuple;
228  }
229 
230  PyObject* ldns_rr_new_frm_fp_(FILE *fp, uint32_t default_ttl,  ldns_rdf* origin,  ldns_rdf* prev)
231  //returns tuple (status, ldns_rr, ttl, origin, prev)
232  {
233    uint32_t defttl = default_ttl;
234    uint32_t *p_defttl = &defttl;
235    if (defttl == 0) p_defttl = 0;
236 
237    /*  origin and prev have to be cloned in order to decouple the data
238     *  from the python wrapper
239     */
240    if (origin != NULL)
241        origin = ldns_rdf_clone(origin);
242    if (prev != NULL)
243        prev = ldns_rdf_clone(prev);
244 
245    ldns_rdf *p_origin = origin;
246    ldns_rdf **pp_origin = &p_origin;
247    //if (p_origin == 0) pp_origin = 0;
248 
249    ldns_rdf *p_prev = prev;
250    ldns_rdf **pp_prev = &p_prev;
251    //if (p_prev == 0) pp_prev = 0;
252 
253    ldns_rr *p_rr = 0;
254    ldns_rr **pp_rr = &p_rr;
255 
256    ldns_status st = ldns_rr_new_frm_fp(pp_rr, fp, p_defttl, pp_origin, pp_prev);
257 
258    PyObject* tuple;
259    tuple = PyTuple_New(5);
260    int idx = 0;
261    PyTuple_SetItem(tuple, idx, SWIG_From_int(st));
262    idx++;
263    PyTuple_SetItem(tuple, idx, (st == LDNS_STATUS_OK) ?
264                              SWIG_NewPointerObj(SWIG_as_voidptr(p_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN |  0 ) :
265 		   (Py_INCREF(Py_None), Py_None));
266    idx++;
267    PyTuple_SetItem(tuple, idx, SWIG_From_int(defttl));
268    idx++;
269    PyTuple_SetItem(tuple, idx, SWIG_NewPointerObj(SWIG_as_voidptr(p_origin), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN |  0 ));
270    idx++;
271    PyTuple_SetItem(tuple, idx, SWIG_NewPointerObj(SWIG_as_voidptr(p_prev), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN |  0 ));
272    return tuple;
273  }
274 
275  PyObject* ldns_rr_new_frm_fp_l_(FILE *fp, uint32_t default_ttl,  ldns_rdf* origin,  ldns_rdf* prev)
276  //returns tuple (status, ldns_rr, line, ttl, origin, prev)
277  {
278    int linenr = 0;
279    int *p_linenr = &linenr;
280 
281    uint32_t defttl = default_ttl;
282    uint32_t *p_defttl = &defttl;
283    if (defttl == 0) p_defttl = 0;
284 
285    /*  origin and prev have to be cloned in order to decouple the data
286     *  from the python wrapper
287     */
288    if (origin != NULL)
289        origin = ldns_rdf_clone(origin);
290    if (prev != NULL)
291        prev = ldns_rdf_clone(prev);
292 
293    ldns_rdf *p_origin = origin;
294    ldns_rdf **pp_origin = &p_origin;
295    //if (p_origin == 0) pp_origin = 0;
296 
297    ldns_rdf *p_prev = prev;
298    ldns_rdf **pp_prev = &p_prev;
299    //if (p_prev == 0) pp_prev = 0;
300 
301    ldns_rr *p_rr = 0;
302    ldns_rr **pp_rr = &p_rr;
303 
304    ldns_status st = ldns_rr_new_frm_fp_l(pp_rr, fp, p_defttl, pp_origin, pp_prev, p_linenr);
305 
306    PyObject* tuple;
307    tuple = PyTuple_New(6);
308    int idx = 0;
309    PyTuple_SetItem(tuple, idx, SWIG_From_int(st));
310    idx++;
311    PyTuple_SetItem(tuple, idx, (st == LDNS_STATUS_OK) ?
312                              SWIG_NewPointerObj(SWIG_as_voidptr(p_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN |  0 ) :
313 		   (Py_INCREF(Py_None), Py_None));
314    idx++;
315    PyTuple_SetItem(tuple, idx, SWIG_From_int(linenr));
316    idx++;
317    PyTuple_SetItem(tuple, idx, SWIG_From_int(defttl));
318    idx++;
319    PyTuple_SetItem(tuple, idx, SWIG_NewPointerObj(SWIG_as_voidptr(p_origin), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN |  0 ));
320    idx++;
321    PyTuple_SetItem(tuple, idx, SWIG_NewPointerObj(SWIG_as_voidptr(p_prev), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN |  0 ));
322    return tuple;
323  }
324 
325 
326 PyObject* ldns_rr_new_question_frm_str_(const char *str, ldns_rdf* origin, ldns_rdf* prev)
327  //returns tuple (status, ldns_rr, prev)
328  {
329    PyObject* tuple;
330 
331    /*  origin and prev have to be cloned in order to decouple the data
332     *  from the python wrapper
333     */
334    if (origin != NULL)
335        origin = ldns_rdf_clone(origin);
336    if (prev != NULL)
337        prev = ldns_rdf_clone(prev);
338 
339    ldns_rdf *p_prev = prev;
340    ldns_rdf **pp_prev = &p_prev;
341    if (p_prev == 0) pp_prev = 0;
342 
343    ldns_rr *p_rr = 0;
344    ldns_rr **pp_rr = &p_rr;
345 
346    ldns_status st = ldns_rr_new_question_frm_str(pp_rr, str, origin, pp_prev);
347 
348    tuple = PyTuple_New(3);
349    PyTuple_SetItem(tuple, 0, SWIG_From_int(st));
350    PyTuple_SetItem(tuple, 1, (st == LDNS_STATUS_OK) ?
351                              SWIG_NewPointerObj(SWIG_as_voidptr(p_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN |  0 ) :
352 		   (Py_INCREF(Py_None), Py_None));
353    PyTuple_SetItem(tuple, 2, (p_prev != prev) ?
354                              SWIG_NewPointerObj(SWIG_as_voidptr(p_prev), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN |  0 ) :
355 		   (Py_INCREF(Py_None), Py_None));
356    return tuple;
357  }
358 
359 
360 
361 PyObject* ldns_fetch_valid_domain_keys_(const ldns_resolver * res, const ldns_rdf * domain,
362 		const ldns_rr_list * keys)
363  //returns tuple (status, result)
364  {
365    PyObject* tuple;
366 
367    ldns_rr_list *rrl = 0;
368    ldns_status st = 0;
369    rrl = ldns_fetch_valid_domain_keys(res, domain, keys, &st);
370 
371 
372    tuple = PyTuple_New(2);
373    PyTuple_SetItem(tuple, 0, SWIG_From_int(st));
374    PyTuple_SetItem(tuple, 1, (st == LDNS_STATUS_OK) ?
375                              SWIG_NewPointerObj(SWIG_as_voidptr(rrl), SWIGTYPE_p_ldns_struct_rr_list, SWIG_POINTER_OWN |  0 ) :
376 		   (Py_INCREF(Py_None), Py_None));
377    return tuple;
378  }
379 
380 PyObject* ldns_wire2pkt_(const char *str, int len)
381  //returns tuple (status, result)
382  {
383   PyObject *resultobj = 0;
384   ldns_pkt *arg1 = NULL;
385   uint8_t *arg2 = (uint8_t *) str;
386   size_t arg3 = (size_t) len;
387   ldns_status result;
388   PyObject* tuple;
389 
390   result = (ldns_status)ldns_wire2pkt(&arg1,arg2,arg3);
391   tuple = PyTuple_New(2);
392   PyTuple_SetItem(tuple, 0, SWIG_From_int(result));
393   if (result == LDNS_STATUS_OK)
394      PyTuple_SetItem(tuple, 1, SWIG_NewPointerObj(SWIG_as_voidptr(arg1), SWIGTYPE_p_ldns_struct_pkt, SWIG_POINTER_OWN |  0 ));
395   else {
396      Py_INCREF(Py_None);
397      PyTuple_SetItem(tuple, 1, Py_None);
398   }
399   return tuple;
400 }
401 
402 PyObject* ldns_pkt2wire_(const ldns_pkt *pkt)
403  //returns tuple (status, result)
404  {
405   PyObject *resultobj = 0;
406   uint8_t *arg1 = NULL;
407   size_t arg3;
408   ldns_status result;
409   PyObject* tuple;
410 
411   result = (ldns_status)ldns_pkt2wire(&arg1,pkt,&arg3);
412   tuple = PyTuple_New(2);
413   PyTuple_SetItem(tuple, 0, SWIG_From_int(result));
414   if (result == LDNS_STATUS_OK)
415      PyTuple_SetItem(tuple, 1, SWIG_FromCharPtrAndSize((char *)arg1, arg3));
416   else {
417      Py_INCREF(Py_None);
418      PyTuple_SetItem(tuple, 1, Py_None);
419   }
420   LDNS_FREE(arg1);
421   return tuple;
422 }
423 
424 %}
425 
426 %pythoncode %{
427 def ldns_fetch_valid_domain_keys(res, domain, keys):
428     return _ldns.ldns_fetch_valid_domain_keys_(res, domain, keys)
429 
430 def ldns_wire2pkt(data):
431     return _ldns.ldns_wire2pkt_(data)
432 
433 def ldns_pkt2wire(data):
434     return _ldns.ldns_pkt2wire_(data)
435 
436 def ldns_rr_iter_frm_fp_l(input_file):
437     """Creates an iterator (generator) that returns individual parsed
438     RRs from an open zone file."""
439     # variables that preserve the parsers state
440     my_ttl = 0;
441     my_origin = None
442     my_prev = None
443     # additional state variables
444     last_pos = 0
445     line_nr = 0
446 
447     while True:
448         ret = _ldns.ldns_rr_new_frm_fp_l_(input_file, my_ttl, my_origin, my_prev)
449         s, rr, line_inc, new_ttl, new_origin, new_prev = ret  # unpack the result
450         line_nr += line_inc # increase number of parsed lines
451         my_prev = new_prev  # update ref to previous owner
452 
453         if s == _ldns.LDNS_STATUS_SYNTAX_TTL:
454             my_ttl = new_ttl  # update default TTL
455         elif s == _ldns.LDNS_STATUS_SYNTAX_ORIGIN:
456             my_origin = new_origin  # update reference to origin
457         elif s == _ldns.LDNS_STATUS_SYNTAX_EMPTY:
458             if last_pos == input_file.tell():
459                 break  # no advance since last read - EOF
460             last_pos = input_file.tell()
461         elif s != _ldns.LDNS_STATUS_OK:
462             raise ValueError("Parse error in line %d" % line_nr)
463         else:
464             # we are sure to have LDNS_STATUS_OK
465             yield rr
466 
467 %}
468