Branch data Line data Source code
1 : : // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #include <Python.h>
16 : :
17 : : #include <stdexcept>
18 : :
19 : : #include <util/python/pycppwrapper_util.h>
20 : :
21 : : #include <dns/name.h>
22 : : #include <dns/tsigkey.h>
23 : : #include <dns/rdata.h>
24 : :
25 : : #include "pydnspp_common.h"
26 : : #include "name_python.h"
27 : : #include "tsigkey_python.h"
28 : :
29 : : using namespace std;
30 : : using namespace isc::util::python;
31 : : using namespace isc::dns;
32 : : using namespace isc::dns::python;
33 : :
34 : : // For each class, we need a struct, a helper functions (init, destroy,
35 : : // and static wrappers around the methods we export), a list of methods,
36 : : // and a type description
37 : :
38 : : //
39 : : // TSIGKey
40 : : //
41 : :
42 : : namespace {
43 : : // The s_* Class simply covers one instantiation of the object
44 : : class s_TSIGKey : public PyObject {
45 : : public:
46 : : s_TSIGKey() : cppobj(NULL) {};
47 : : TSIGKey* cppobj;
48 : : };
49 : :
50 : : //
51 : : // We declare the functions here, the definitions are below
52 : : // the type definition of the object, since both can use the other
53 : : //
54 : :
55 : : // General creation and destruction
56 : : int TSIGKey_init(s_TSIGKey* self, PyObject* args);
57 : : void TSIGKey_destroy(s_TSIGKey* self);
58 : :
59 : : // These are the functions we export
60 : : // This is a second version of toText, we need one where the argument
61 : : // is a PyObject*, for the str() function in python.
62 : : PyObject* TSIGKey_getKeyName(const s_TSIGKey* self);
63 : : PyObject* TSIGKey_getAlgorithmName(const s_TSIGKey* self);
64 : : PyObject* TSIGKey_getSecret(const s_TSIGKey* self);
65 : : PyObject* TSIGKey_toText(const s_TSIGKey* self);
66 : :
67 : : // This list contains the actual set of functions we have in
68 : : // python. Each entry has
69 : : // 1. Python method name
70 : : // 2. Our static function here
71 : : // 3. Argument type
72 : : // 4. Documentation
73 : : PyMethodDef TSIGKey_methods[] = {
74 : : { "get_key_name",
75 : : reinterpret_cast<PyCFunction>(TSIGKey_getKeyName), METH_NOARGS,
76 : : "Return the key name." },
77 : : { "get_algorithm_name",
78 : : reinterpret_cast<PyCFunction>(TSIGKey_getAlgorithmName), METH_NOARGS,
79 : : "Return the algorithm name." },
80 : : { "get_secret",
81 : : reinterpret_cast<PyCFunction>(TSIGKey_getSecret), METH_NOARGS,
82 : : "Return the value of the TSIG secret." },
83 : : { "to_text", reinterpret_cast<PyCFunction>(TSIGKey_toText), METH_NOARGS,
84 : : "Returns the string representation (name:secret:algorithm)" },
85 : : { NULL, NULL, 0, NULL }
86 : : };
87 : :
88 : : int
89 : 129 : TSIGKey_init(s_TSIGKey* self, PyObject* args) {
90 : : try {
91 : : const char* str;
92 [ + - ][ + + ]: 129 : if (PyArg_ParseTuple(args, "s", &str)) {
93 [ + - ][ + - ]: 78 : self->cppobj = new TSIGKey(str);
[ + + ]
94 : : return (0);
95 : : }
96 : :
97 [ + - ]: 51 : PyErr_Clear();
98 : : const PyObject* key_name;
99 : : const PyObject* algorithm_name;
100 : : PyObject* bytes_obj;
101 : : const char* secret;
102 : : Py_ssize_t secret_len;
103 [ + - ][ + + ]: 102 : if (PyArg_ParseTuple(args, "O!O!O", &name_type, &key_name,
[ + + ]
104 [ + - ]: 51 : &name_type, &algorithm_name, &bytes_obj) &&
105 [ + - ]: 51 : PyObject_AsCharBuffer(bytes_obj, &secret, &secret_len) == 0) {
106 [ + + ]: 50 : if (secret_len == 0) {
107 : 1 : secret = NULL;
108 : : }
109 : 50 : self->cppobj = new TSIGKey(PyName_ToName(key_name),
110 : 50 : PyName_ToName(algorithm_name),
111 [ + - ][ + - ]: 50 : secret, secret_len);
[ + - ][ + + ]
112 : 49 : return (0);
113 : : }
114 : 24 : } catch (const isc::InvalidParameter& ex) {
115 [ - + ]: 12 : PyErr_SetString(po_InvalidParameter, ex.what());
116 : : return (-1);
117 [ + - ]: 12 : } catch (...) {
118 [ # # ]: 0 : PyErr_SetString(po_IscException, "Unexpected exception");
119 : : return (-1);
120 : : }
121 : :
122 : 1 : PyErr_Clear();
123 : : PyErr_SetString(PyExc_TypeError,
124 : 1 : "Invalid arguments to TSIGKey constructor");
125 : :
126 : 129 : return (-1);
127 : : }
128 : :
129 : : void
130 : 137 : TSIGKey_destroy(s_TSIGKey* const self) {
131 [ + + ]: 137 : delete self->cppobj;
132 : 137 : self->cppobj = NULL;
133 : 137 : Py_TYPE(self)->tp_free(self);
134 : 137 : }
135 : :
136 : : PyObject*
137 : 14 : TSIGKey_getKeyName(const s_TSIGKey* const self) {
138 : : try {
139 [ + - ][ + - ]: 14 : return (createNameObject(self->cppobj->getKeyName()));
140 : 0 : } catch (const exception& ex) {
141 : : const string ex_what =
142 [ # # ][ # # ]: 0 : "Failed to get key name of TSIGKey: " + string(ex.what());
143 [ # # ]: 0 : PyErr_SetString(po_IscException, ex_what.c_str());
144 [ # # ]: 0 : } catch (...) {
145 : : PyErr_SetString(PyExc_SystemError, "Unexpected failure in "
146 [ # # ]: 0 : "getting key name of TSIGKey");
147 : : }
148 : : return (NULL);
149 : : }
150 : :
151 : : PyObject*
152 : 5 : TSIGKey_getAlgorithmName(const s_TSIGKey* const self) {
153 : : try {
154 [ + - ][ + - ]: 5 : return (createNameObject(self->cppobj->getAlgorithmName()));
155 : 0 : } catch (const exception& ex) {
156 : : const string ex_what =
157 [ # # ][ # # ]: 0 : "Failed to get algorithm name of TSIGKey: " + string(ex.what());
158 [ # # ]: 0 : PyErr_SetString(po_IscException, ex_what.c_str());
159 [ # # ]: 0 : } catch (...) {
160 : : PyErr_SetString(PyExc_SystemError, "Unexpected failure in "
161 [ # # ]: 0 : "getting algorithm name of TSIGKey");
162 : : }
163 : : return (NULL);
164 : : }
165 : :
166 : : PyObject*
167 : 3 : TSIGKey_getSecret(const s_TSIGKey* const self) {
168 : : return (Py_BuildValue("y#", self->cppobj->getSecret(),
169 : 3 : self->cppobj->getSecretLength()));
170 : : }
171 : :
172 : : PyObject*
173 : 21 : TSIGKey_toText(const s_TSIGKey* self) {
174 [ + - ]: 21 : return (Py_BuildValue("s", self->cppobj->toText().c_str()));
175 : : }
176 : : } // end of unnamed namespace
177 : :
178 : : namespace isc {
179 : : namespace dns {
180 : : namespace python {
181 : : // This defines the complete type for reflection in python and
182 : : // parsing of PyObject* to s_EDNS
183 : : // Most of the functions are not actually implemented and NULL here.
184 : : PyTypeObject tsigkey_type = {
185 : : PyVarObject_HEAD_INIT(NULL, 0)
186 : : "pydnspp.TSIGKey",
187 : : sizeof(s_TSIGKey), // tp_basicsize
188 : : 0, // tp_itemsize
189 : : (destructor)TSIGKey_destroy, // tp_dealloc
190 : : NULL, // tp_print
191 : : NULL, // tp_getattr
192 : : NULL, // tp_setattr
193 : : NULL, // tp_reserved
194 : : NULL, // tp_repr
195 : : NULL, // tp_as_number
196 : : NULL, // tp_as_sequence
197 : : NULL, // tp_as_mapping
198 : : NULL, // tp_hash
199 : : NULL, // tp_call
200 : : NULL, // tp_str
201 : : NULL, // tp_getattro
202 : : NULL, // tp_setattro
203 : : NULL, // tp_as_buffer
204 : : Py_TPFLAGS_DEFAULT, // tp_flags
205 : : "The TSIGKey class holds a TSIG key along with some related attributes as "
206 : : "defined in RFC2845.",
207 : : NULL, // tp_traverse
208 : : NULL, // tp_clear
209 : : NULL, // tp_richcompare
210 : : 0, // tp_weaklistoffset
211 : : NULL, // tp_iter
212 : : NULL, // tp_iternext
213 : : TSIGKey_methods, // tp_methods
214 : : NULL, // tp_members
215 : : NULL, // tp_getset
216 : : NULL, // tp_base
217 : : NULL, // tp_dict
218 : : NULL, // tp_descr_get
219 : : NULL, // tp_descr_set
220 : : 0, // tp_dictoffset
221 : : (initproc)TSIGKey_init, // tp_init
222 : : NULL, // tp_alloc
223 : : PyType_GenericNew, // tp_new
224 : : NULL, // tp_free
225 : : NULL, // tp_is_gc
226 : : NULL, // tp_bases
227 : : NULL, // tp_mro
228 : : NULL, // tp_cache
229 : : NULL, // tp_subclasses
230 : : NULL, // tp_weaklist
231 : : NULL, // tp_del
232 : : 0 // tp_version_tag
233 : : };
234 : :
235 : : bool
236 : 0 : PyTSIGKey_Check(PyObject* obj) {
237 [ # # ]: 0 : if (obj == NULL) {
238 [ # # ][ # # ]: 0 : isc_throw(PyCPPWrapperException, "obj argument NULL in typecheck");
239 : : }
240 [ # # ][ # # ]: 0 : return (PyObject_TypeCheck(obj, &tsigkey_type));
241 : : }
242 : :
243 : : const TSIGKey&
244 : 154 : PyTSIGKey_ToTSIGKey(const PyObject* tsigkey_obj) {
245 : 154 : const s_TSIGKey* tsigkey = static_cast<const s_TSIGKey*>(tsigkey_obj);
246 : 154 : return (*tsigkey->cppobj);
247 : : }
248 : :
249 : : } // namespace python
250 : : } // namespace dns
251 : : } // namespace isc
252 : : //
253 : : // End of TSIGKey
254 : : //
255 : :
256 : : //
257 : : // TSIGKeyRing
258 : : //
259 : :
260 : : namespace {
261 : : // The s_* Class simply covers one instantiation of the object
262 : : class s_TSIGKeyRing : public PyObject {
263 : : public:
264 : : s_TSIGKeyRing() : cppobj(NULL) {};
265 : : TSIGKeyRing* cppobj;
266 : : };
267 : :
268 : : //
269 : : // We declare the functions here, the definitions are below
270 : : // the type definition of the object, since both can use the other
271 : : //
272 : :
273 : : int TSIGKeyRing_init(s_TSIGKeyRing* self, PyObject* args);
274 : : void TSIGKeyRing_destroy(s_TSIGKeyRing* self);
275 : :
276 : : PyObject* TSIGKeyRing_size(const s_TSIGKeyRing* self);
277 : : PyObject* TSIGKeyRing_add(const s_TSIGKeyRing* self, PyObject* args);
278 : : PyObject* TSIGKeyRing_remove(const s_TSIGKeyRing* self, PyObject* args);
279 : : PyObject* TSIGKeyRing_find(const s_TSIGKeyRing* self, PyObject* args);
280 : :
281 : : PyMethodDef TSIGKeyRing_methods[] = {
282 : : { "size", reinterpret_cast<PyCFunction>(TSIGKeyRing_size), METH_NOARGS,
283 : : "Return the number of keys stored in the TSIGKeyRing." },
284 : : { "add", reinterpret_cast<PyCFunction>(TSIGKeyRing_add), METH_VARARGS,
285 : : "Add a TSIGKey to the TSIGKeyRing." },
286 : : { "remove", reinterpret_cast<PyCFunction>(TSIGKeyRing_remove),
287 : : METH_VARARGS,
288 : : "Remove a TSIGKey for the given name from the TSIGKeyRing." },
289 : : { "find", reinterpret_cast<PyCFunction>(TSIGKeyRing_find), METH_VARARGS,
290 : : "Find a TSIGKey for the given name in the TSIGKeyRing. "
291 : : "It returns a tuple of (result_code, key)." },
292 : : { NULL, NULL, 0, NULL }
293 : : };
294 : :
295 : : int
296 : 96 : TSIGKeyRing_init(s_TSIGKeyRing* self, PyObject* args) {
297 [ + + ]: 96 : if (!PyArg_ParseTuple(args, "")) {
298 : 2 : PyErr_Clear();
299 : : PyErr_SetString(PyExc_TypeError,
300 : 2 : "Invalid arguments to TSIGKeyRing constructor");
301 : 2 : return (-1);
302 : : }
303 : :
304 [ + - ][ + - ]: 94 : self->cppobj = new(nothrow) TSIGKeyRing();
305 [ - + ]: 94 : if (self->cppobj == NULL) {
306 : 0 : PyErr_SetString(po_IscException, "Allocating TSIGKeyRing failed");
307 : 96 : return (-1);
308 : : }
309 : :
310 : : return (0);
311 : : }
312 : :
313 : : void
314 : 96 : TSIGKeyRing_destroy(s_TSIGKeyRing* self) {
315 [ + + ]: 96 : delete self->cppobj;
316 : 96 : self->cppobj = NULL;
317 : 96 : Py_TYPE(self)->tp_free(self);
318 : 96 : }
319 : :
320 : : PyObject*
321 : 11 : TSIGKeyRing_size(const s_TSIGKeyRing* const self) {
322 : 11 : return (Py_BuildValue("I", self->cppobj->size()));
323 : : }
324 : :
325 : : PyObject*
326 : 36 : TSIGKeyRing_add(const s_TSIGKeyRing* const self, PyObject* args) {
327 : : s_TSIGKey* tsigkey;
328 : :
329 [ + + ]: 36 : if (PyArg_ParseTuple(args, "O!", &tsigkey_type, &tsigkey)) {
330 : : try {
331 : : const TSIGKeyRing::Result result =
332 [ + - ]: 31 : self->cppobj->add(*tsigkey->cppobj);
333 [ + - ]: 31 : return (Py_BuildValue("I", result));
334 : 0 : } catch (...) {
335 [ # # ]: 0 : PyErr_SetString(po_IscException, "Unexpected exception");
336 : : return (NULL);
337 : : }
338 : : }
339 : :
340 : 5 : PyErr_Clear();
341 : 5 : PyErr_SetString(PyExc_TypeError, "Invalid arguments to TSIGKeyRing.add");
342 : :
343 : 36 : return (NULL);
344 : : }
345 : :
346 : : PyObject*
347 : 4 : TSIGKeyRing_remove(const s_TSIGKeyRing* self, PyObject* args) {
348 : : PyObject* key_name;
349 : :
350 [ + - ]: 4 : if (PyArg_ParseTuple(args, "O!", &name_type, &key_name)) {
351 : : const TSIGKeyRing::Result result =
352 : 4 : self->cppobj->remove(PyName_ToName(key_name));
353 : 4 : return (Py_BuildValue("I", result));
354 : : }
355 : :
356 : 0 : PyErr_Clear();
357 : 0 : PyErr_SetString(PyExc_TypeError, "Invalid arguments to TSIGKeyRing.add");
358 : :
359 : 4 : return (NULL);
360 : : }
361 : :
362 : : PyObject*
363 : 17 : TSIGKeyRing_find(const s_TSIGKeyRing* self, PyObject* args) {
364 : : PyObject* key_name;
365 : : PyObject* algorithm_name;
366 : :
367 [ + + ]: 17 : if (PyArg_ParseTuple(args, "O!O!", &name_type, &key_name,
368 : 17 : &name_type, &algorithm_name)) {
369 : : const TSIGKeyRing::FindResult result =
370 : 14 : self->cppobj->find(PyName_ToName(key_name),
371 : 28 : PyName_ToName(algorithm_name));
372 [ + + ]: 14 : if (result.key != NULL) {
373 : 8 : s_TSIGKey* key = PyObject_New(s_TSIGKey, &tsigkey_type);
374 [ + - ]: 8 : if (key == NULL) {
375 : : return (NULL);
376 : : }
377 [ + - ][ + - ]: 8 : key->cppobj = new(nothrow) TSIGKey(*result.key);
378 [ - + ]: 8 : if (key->cppobj == NULL) {
379 [ # # ]: 0 : Py_DECREF(key);
380 : : PyErr_SetString(po_IscException,
381 : 0 : "Allocating TSIGKey object failed");
382 : 0 : return (NULL);
383 : : }
384 : 8 : return (Py_BuildValue("IN", result.code, key));
385 : : } else {
386 : 17 : return (Py_BuildValue("Is", result.code, NULL));
387 : : }
388 : : }
389 : :
390 : : return (NULL);
391 : : }
392 : : } // end of unnamed namespace
393 : :
394 : : namespace isc {
395 : : namespace dns {
396 : : namespace python {
397 : : PyTypeObject tsigkeyring_type = {
398 : : PyVarObject_HEAD_INIT(NULL, 0)
399 : : "pydnspp.TSIGKeyRing",
400 : : sizeof(s_TSIGKeyRing), // tp_basicsize
401 : : 0, // tp_itemsize
402 : : (destructor)TSIGKeyRing_destroy, // tp_dealloc
403 : : NULL, // tp_print
404 : : NULL, // tp_getattr
405 : : NULL, // tp_setattr
406 : : NULL, // tp_reserved
407 : : NULL, // tp_repr
408 : : NULL, // tp_as_number
409 : : NULL, // tp_as_sequence
410 : : NULL, // tp_as_mapping
411 : : NULL, // tp_hash
412 : : NULL, // tp_call
413 : : NULL, // tp_str
414 : : NULL, // tp_getattro
415 : : NULL, // tp_setattro
416 : : NULL, // tp_as_buffer
417 : : Py_TPFLAGS_DEFAULT, // tp_flags
418 : : "A simple repository of a set of TSIGKey objects.",
419 : : NULL, // tp_traverse
420 : : NULL, // tp_clear
421 : : NULL, // tp_richcompare
422 : : 0, // tp_weaklistoffset
423 : : NULL, // tp_iter
424 : : NULL, // tp_iternext
425 : : TSIGKeyRing_methods, // tp_methods
426 : : NULL, // tp_members
427 : : NULL, // tp_getset
428 : : NULL, // tp_base
429 : : NULL, // tp_dict
430 : : NULL, // tp_descr_get
431 : : NULL, // tp_descr_set
432 : : 0, // tp_dictoffset
433 : : (initproc)TSIGKeyRing_init, // tp_init
434 : : NULL, // tp_alloc
435 : : PyType_GenericNew, // tp_new
436 : : NULL, // tp_free
437 : : NULL, // tp_is_gc
438 : : NULL, // tp_bases
439 : : NULL, // tp_mro
440 : : NULL, // tp_cache
441 : : NULL, // tp_subclasses
442 : : NULL, // tp_weaklist
443 : : NULL, // tp_del
444 : : 0 // tp_version_tag
445 : : };
446 : :
447 : : bool
448 : 0 : PyTSIGKeyRing_Check(PyObject* obj) {
449 [ # # ]: 0 : if (obj == NULL) {
450 [ # # ][ # # ]: 0 : isc_throw(PyCPPWrapperException, "obj argument NULL in typecheck");
451 : : }
452 [ # # ][ # # ]: 0 : return (PyObject_TypeCheck(obj, &tsigkeyring_type));
453 : : }
454 : :
455 : : const TSIGKeyRing&
456 : 23 : PyTSIGKeyRing_ToTSIGKeyRing(const PyObject* tsigkeyring_obj) {
457 [ - + ]: 23 : if (tsigkeyring_obj == NULL) {
458 [ # # ][ # # ]: 0 : isc_throw(PyCPPWrapperException,
459 : : "obj argument NULL in TSIGKeyRing PyObject conversion");
460 : : }
461 : : const s_TSIGKeyRing* tsigkeyring =
462 : 23 : static_cast<const s_TSIGKeyRing*>(tsigkeyring_obj);
463 : 23 : return (*tsigkeyring->cppobj);
464 : : }
465 : :
466 : : } // namespace python
467 : : } // namespace dns
468 : 0 : } // namespace isc
|