From: Willem Toorop Date: Thu, 12 Jul 2012 14:31:56 +0000 (+0000) Subject: * memory handling fixes and the python3/ldns-signzone.py examples script contribution... X-Git-Tag: release-1.6.14rc1~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0265cde5c3d76ae06e09bfbcb21bbe1f927bd818;p=thirdparty%2Fldns.git * memory handling fixes and the python3/ldns-signzone.py examples script contribution from Karel Slany. * Memroy leak fix for ldns_key_new_frm_algorithm from Michael Sheldon. --- diff --git a/Changelog b/Changelog index 6aa7d358..76e9c925 100644 --- a/Changelog +++ b/Changelog @@ -1,4 +1,7 @@ 1.6.14 + * Memroy leak fix for ldns_key_new_frm_algorithm from Michael Sheldon. + * pyldns memory handling fixes and the python3/ldns-signzone.py + examples script contribution from Karel Slany. * bugfix #450: Base # bytes for P, G and Y (T) on the guaranteed to be bigger (or equal) P in ldns_key_dsa2bin. Thanks Peter Koch and Patrick Fedick. diff --git a/contrib/python/Makefile b/contrib/python/Makefile index c4397050..867433da 100644 --- a/contrib/python/Makefile +++ b/contrib/python/Makefile @@ -45,16 +45,16 @@ _ldns.so: ../../Makefile $(MAKE) -C ../.. clean: - rm -rdf examples/ldns + rm -rf examples/ldns rm -f _ldns.so ldns_wrapper.o $(MAKE) -C ../.. clean testenv: ../../.libs/libldns.so.1 _ldns.so - rm -rdf examples/ldns - cd examples && mkdir ldns && ln -s ../../ldns.py ldns/__init__.py && ln -s ../../_ldns.so ldns/_ldns.so && ln -s ../../../../.libs/libldns.so.1 ldns/libldns.so.1 && ls -la + rm -rf examples/ldns + cd examples && mkdir ldns && ln -s ../../ldns.py ldns/__init__.py && ln -s ../../../../.libs/_ldns.so ldns/_ldns.so && ln -s ../../../../.libs/libldns.so.1 ldns/libldns.so.1 && ls -la @echo "Run a script by typing ./script_name.py" cd examples && LD_LIBRARY_PATH=ldns bash - rm -rdf examples/ldns + rm -rf examples/ldns doc: ../../.libs/ldns.so.1 _ldns.so $(MAKE) -C docs html @@ -63,5 +63,4 @@ doc: ../../.libs/ldns.so.1 _ldns.so swig: ldns.i swig -python -py3 -o ldns_wrapper.c -I../.. ldns.i gcc -c ldns_wrapper.c -O9 -fPIC -I../.. -I../../ldns -I/usr/include/python3.1 -I. -o ldns_wrapper.o - ld -shared ldns_wrapper.o -L../../.libs -lldns -o _ldns.so - + ld -shared ldns_wrapper.o -L../../.libs -lldns -o _ldns.so diff --git a/contrib/python/examples/ldns-keygen.py b/contrib/python/examples/ldns-keygen.py index 3ddf41a9..71375fce 100755 --- a/contrib/python/examples/ldns-keygen.py +++ b/contrib/python/examples/ldns-keygen.py @@ -7,7 +7,7 @@ import ldns algorithm = ldns.LDNS_SIGN_DSA bits = 512 -ldns.ldns_init_random(open("/dev/random","rb"), (bits+7)//8) +ldns.ldns_init_random(open("/dev/urandom","rb"), (bits+7)//8) domain = ldns.ldns_dname("example.") diff --git a/contrib/python/examples/python3/ldns-signzone.py b/contrib/python/examples/python3/ldns-signzone.py new file mode 100755 index 00000000..cac5d321 --- /dev/null +++ b/contrib/python/examples/python3/ldns-signzone.py @@ -0,0 +1,65 @@ +#!/usr/bin/python +# This example shows how to sign a given zone file with private key + +import ldns +import sys, os, time + +#private key TAG which identifies the private key +#use ldns-keygen.py in order to obtain private key +keytag = 30761 + +# Read zone file +#------------------------------------------------------------- + +zone = ldns.ldns_zone.new_frm_fp(open("zone.txt","r"), None, 0, ldns.LDNS_RR_CLASS_IN) +soa = zone.soa() +origin = soa.owner() + +# Prepare keys +#------------------------------------------------------------- + +#Read private key from file +keyfile = open("key-%s-%d.private" % (origin, keytag), "r"); +key = ldns.ldns_key.new_frm_fp(keyfile) + +#Read public key from file +pubfname = "key-%s-%d.key" % (origin, keytag) +pubkey = None +if os.path.isfile(pubfname): + pubkeyfile = open(pubfname, "r"); + pubkey,_,_,_ = ldns.ldns_rr.new_frm_fp(pubkeyfile) + +if not pubkey: + #Create new public key + pubkey = key.key_to_rr() + +#Set key expiration +key.set_expiration(int(time.time()) + 365*60*60*24) #365 days + +#Set key owner (important step) +key.set_pubkey_owner(origin) + +#Insert DNSKEY RR +zone.push_rr(pubkey) + +# Sign zone +#------------------------------------------------------------- + +#Create keylist and push private key +keys = ldns.ldns_key_list() +keys.push_key(key) + +#Add SOA +signed_zone = ldns.ldns_dnssec_zone() +signed_zone.add_rr(soa) + +#Add RRs +for rr in zone.rrs().rrs(): + print("RR:", str(rr), end=" ") + signed_zone.add_rr(rr) + +added_rrs = ldns.ldns_rr_list() +status = signed_zone.sign(added_rrs, keys) +if (status == ldns.LDNS_STATUS_OK): + signed_zone.print_to_file(open("zone_signed.txt","w")) + diff --git a/contrib/python/ldns.i b/contrib/python/ldns.i index 122ebe18..d90fc280 100644 --- a/contrib/python/ldns.i +++ b/contrib/python/ldns.i @@ -192,8 +192,53 @@ typedef struct ldns_dnssec_zone { }; return tuple; } + PyObject* ldns_rr_new_frm_fp_(FILE *fp, uint32_t default_ttl, ldns_rdf* origin, ldns_rdf* prev) + //returns tuple (status, ldns_rr, ttl, origin, prev) + { + uint32_t defttl = default_ttl; + uint32_t *p_defttl = &defttl; + if (defttl == 0) p_defttl = 0; + + /* origin and prev have to be cloned in order to decouple the data + * from the python wrapper + */ + if (origin != NULL) + origin = ldns_rdf_clone(origin); + if (prev != NULL) + prev = ldns_rdf_clone(prev); + + ldns_rdf *p_origin = origin; + ldns_rdf **pp_origin = &p_origin; + //if (p_origin == 0) pp_origin = 0; + + ldns_rdf *p_prev = prev; + ldns_rdf **pp_prev = &p_prev; + //if (p_prev == 0) pp_prev = 0; + + ldns_rr *p_rr = 0; + ldns_rr **pp_rr = &p_rr; + + ldns_status st = ldns_rr_new_frm_fp(pp_rr, fp, p_defttl, pp_origin, pp_prev); + + PyObject* tuple; + tuple = PyTuple_New(5); + int idx = 0; + PyTuple_SetItem(tuple, idx, SWIG_From_int(st)); + idx++; + PyTuple_SetItem(tuple, idx, (st == LDNS_STATUS_OK) ? + SWIG_NewPointerObj(SWIG_as_voidptr(p_rr), SWIGTYPE_p_ldns_struct_rr, SWIG_POINTER_OWN | 0 ) : + (Py_INCREF(Py_None), Py_None)); + idx++; + PyTuple_SetItem(tuple, idx, SWIG_From_int(defttl)); + idx++; + PyTuple_SetItem(tuple, idx, SWIG_NewPointerObj(SWIG_as_voidptr(p_origin), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN | 0 )); + idx++; + PyTuple_SetItem(tuple, idx, SWIG_NewPointerObj(SWIG_as_voidptr(p_prev), SWIGTYPE_p_ldns_struct_rdf, SWIG_POINTER_OWN | 0 )); + return tuple; + } + PyObject* ldns_rr_new_frm_fp_l_(FILE *fp, uint32_t default_ttl, ldns_rdf* origin, ldns_rdf* prev) - //returns tuple (status, ldns_rr, [line if ret_linenr], ttl, origin, prev) + //returns tuple (status, ldns_rr, line, ttl, origin, prev) { int linenr = 0; int *p_linenr = &linenr; diff --git a/contrib/python/ldns_dnssec.i b/contrib/python/ldns_dnssec.i index 6c065648..3c29bb44 100644 --- a/contrib/python/ldns_dnssec.i +++ b/contrib/python/ldns_dnssec.i @@ -247,6 +247,29 @@ ldns_status ldns_dnssec_zone_sign_defcb(ldns_dnssec_zone *zone, ldns_rr_list *ne return ldns_dnssec_zone_sign(zone, new_rrs, key_list, ldns_dnssec_default_replace_signatures, NULL); } + +ldns_status ldns_dnssec_zone_add_rr_(ldns_dnssec_zone *zone, ldns_rr *rr) +{ + ldns_rr *new_rr; + ldns_status status; + + new_rr = ldns_rr_clone(rr); + + /* + * A clone of the RR is created to be stored in the DNSSEC zone. + * The Python engine frees a RR object as soon it's reference count + * reaches zero. The code must avoid double freeing or accessing of freed + * memory. + */ + + status = ldns_dnssec_zone_add_rr(zone, new_rr); + + if (status != LDNS_STATUS_OK) { + ldns_rr_free(new_rr); + } + + return status; +} %} %extend ldns_dnssec_zone { @@ -413,7 +436,7 @@ ldns_status ldns_dnssec_zone_sign_defcb(ldns_dnssec_zone *zone, ldns_rr_list *ne The RR to add :returns: (ldns_status) LDNS_STATUS_OK on success, an error code otherwise """ - return _ldns.ldns_dnssec_zone_add_rr(self,rr) + return _ldns.ldns_dnssec_zone_add_rr_(self,rr) #parameters: ldns_dnssec_zone *,ldns_rr *, #retvals: ldns_status diff --git a/contrib/python/ldns_rr.i b/contrib/python/ldns_rr.i index 1a9f3f1c..b5e1ee90 100644 --- a/contrib/python/ldns_rr.i +++ b/contrib/python/ldns_rr.i @@ -467,7 +467,7 @@ The RR is the basic DNS element that contains actual data. This class allows to * prev - (ldns_rdf) None or updated value of prev parameter """ - res = _ldns.ldns_rr_new_frm_fp_l_(file, default_ttl, origin, prev, 0) + res = _ldns.ldns_rr_new_frm_fp_(file, default_ttl, origin, prev) if res[0] != LDNS_STATUS_OK: if (raiseException): raise Exception("Can't create RR, error: %d" % res[0]) return None @@ -493,7 +493,7 @@ The RR is the basic DNS element that contains actual data. This class allows to * prev - (ldns_rdf) None or updated value of prev parameter """ - res = _ldns.ldns_rr_new_frm_fp_l_(file, default_ttl, origin, prev, 1) + res = _ldns.ldns_rr_new_frm_fp_l_(file, default_ttl, origin, prev) if res[0] != LDNS_STATUS_OK: if (raiseException): raise Exception("Can't create RR, error: %d" % res[0]) return None diff --git a/keys.c b/keys.c index 38c38a31..ed7f5e90 100644 --- a/keys.c +++ b/keys.c @@ -850,6 +850,7 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) return NULL; } ldns_key_set_rsa_key(k, r); + RSA_free(r); #endif /* HAVE_SSL */ break; case LDNS_SIGN_DSA: @@ -865,6 +866,7 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) return NULL; } ldns_key_set_dsa_key(k, d); + DSA_free(d); #endif /* HAVE_SSL */ break; case LDNS_SIGN_HMACMD5: