]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2982. [bug] Reference count dst keys. dst_key_attach() can be used
authorMark Andrews <marka@isc.org>
Thu, 9 Dec 2010 01:12:55 +0000 (01:12 +0000)
committerMark Andrews <marka@isc.org>
Thu, 9 Dec 2010 01:12:55 +0000 (01:12 +0000)
                        increment the reference count.

                        Note: dns_tsigkey_createfromkey() callers should now
                        always call dst_key_free() rather than setting it
                        to NULL on success. [RT #22672]

CHANGES
bin/dig/dighost.c
bin/nsupdate/nsupdate.c
bin/tests/system/tkey/keydelete.c
lib/dns/dst_api.c
lib/dns/dst_internal.h
lib/dns/include/dns/tsig.h
lib/dns/include/dst/dst.h
lib/dns/tkey.c
lib/dns/tsig.c

diff --git a/CHANGES b/CHANGES
index c64ca2c36ecbea766be5ca964cfc1842369733e7..0d128598e5e878dd6ca99157b144947364d1f647 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+2982.  [bug]           Reference count dst keys.  dst_key_attach() can be used
+                       increment the reference count.
+
+                       Note: dns_tsigkey_createfromkey() callers should now
+                       always call dst_key_free() rather than setting it
+                       to NULL on success. [RT #22672]
+
 2979.  [bug]           named could deadlock during shutdown if two
                        "rndc stop" commands were issued at the same
                        time. [RT #22108]
index bfb7a6b6e0cc80a67ab52550abfd01583b59e0ce..e0e2b17c027953dc505b35616d129c6b640f9641 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dighost.c,v 1.311.70.16 2010/12/02 23:40:27 marka Exp $ */
+/* $Id: dighost.c,v 1.311.70.17 2010/12/09 01:12:54 marka Exp $ */
 
 /*! \file
  *  \note
@@ -963,7 +963,7 @@ setup_file_key(void) {
                goto failure;
        }
        result = dns_tsigkey_createfromkey(dst_key_name(dstkey), hmacname,
-                                          &dstkey, ISC_FALSE, NULL, 0, 0,
+                                          dstkey, ISC_FALSE, NULL, 0, 0,
                                           mctx, NULL, &key);
        if (result != ISC_R_SUCCESS) {
                printf(";; Couldn't create key %s: %s\n",
index 54218cc810fe5c895e7e7edbdebd05b55e7593c8..37e749814549ae70950631620b3dbbcd501addf2 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: nsupdate.c,v 1.163.48.13 2010/12/02 23:40:27 marka Exp $ */
+/* $Id: nsupdate.c,v 1.163.48.14 2010/12/09 01:12:55 marka Exp $ */
 
 /*! \file */
 
@@ -574,6 +574,9 @@ setup_keyfile(void) {
 
        debug("Creating key...");
 
+       if (sig0key != NULL)
+               dst_key_free(&sig0key);
+
        result = dst_key_fromnamedfile(keyfile,
                                       DST_TYPE_PRIVATE | DST_TYPE_KEY, mctx,
                                       &dstkey);
@@ -605,17 +608,17 @@ setup_keyfile(void) {
        }
        if (hmacname != NULL) {
                result = dns_tsigkey_createfromkey(dst_key_name(dstkey),
-                                                  hmacname, &dstkey, ISC_FALSE,
+                                                  hmacname, dstkey, ISC_FALSE,
                                                   NULL, 0, 0, mctx, NULL,
                                                   &tsigkey);
+               dst_key_free(&dstkey);
                if (result != ISC_R_SUCCESS) {
                        fprintf(stderr, "could not create key from %s: %s\n",
                                keyfile, isc_result_totext(result));
-                       dst_key_free(&dstkey);
                        return;
                }
-       } else
-               sig0key = dstkey;
+       } else 
+               dst_key_attach(dstkey, &sig0key);
 }
 
 static void
index e7ea99c92bbbe9f23ad237b40be66a56fd95a465..bbc63a1e19adef9cec28cf1e00f3e0bdf56e83b4 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: keydelete.c,v 1.11.332.2 2010/12/03 23:45:47 tbox Exp $ */
+/* $Id: keydelete.c,v 1.11.332.3 2010/12/09 01:12:55 marka Exp $ */
 
 #include <config.h>
 
@@ -230,8 +230,9 @@ main(int argc, char **argv) {
        CHECK("dst_key_fromnamedfile", result);
        result = dns_tsigkey_createfromkey(dst_key_name(dstkey),
                                           DNS_TSIG_HMACMD5_NAME,
-                                          &dstkey, ISC_TRUE, NULL, 0, 0,
+                                          dstkey, ISC_TRUE, NULL, 0, 0,
                                           mctx, ring, &tsigkey);
+       dst_key_free(&dstkey);
        CHECK("dns_tsigkey_createfromkey", result);
 
        (void)isc_app_run();
index a499777c588351725e284700a0a6d35cb8a4863f..0493ae79765cd1ad02d98607207a01738b5278f4 100644 (file)
@@ -31,7 +31,7 @@
 
 /*
  * Principal Author: Brian Wellington
- * $Id: dst_api.c,v 1.16.12.11 2010/12/02 23:40:28 marka Exp $
+ * $Id: dst_api.c,v 1.16.12.12 2010/12/09 01:12:55 marka Exp $
  */
 
 /*! \file */
@@ -49,6 +49,7 @@
 #include <isc/mem.h>
 #include <isc/once.h>
 #include <isc/print.h>
+#include <isc/refcount.h>
 #include <isc/random.h>
 #include <isc/string.h>
 #include <isc/time.h>
@@ -800,10 +801,22 @@ dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
                return (ISC_FALSE);
 }
 
+void
+dst_key_attach(dst_key_t *source, dst_key_t **target) {
+
+       REQUIRE(dst_initialized == ISC_TRUE);
+       REQUIRE(target != NULL && *target == NULL);
+       REQUIRE(VALID_KEY(source));
+
+       isc_refcount_increment(&source->refs, NULL);
+       *target = source;
+}
+
 void
 dst_key_free(dst_key_t **keyp) {
        isc_mem_t *mctx;
        dst_key_t *key;
+       unsigned int refs;
 
        REQUIRE(dst_initialized == ISC_TRUE);
        REQUIRE(keyp != NULL && VALID_KEY(*keyp));
@@ -811,6 +824,11 @@ dst_key_free(dst_key_t **keyp) {
        key = *keyp;
        mctx = key->mctx;
 
+       isc_refcount_decrement(&key->refs, &refs);
+       if (refs != 0)
+               return;
+
+       isc_refcount_destroy(&key->refs);
        if (key->keydata.generic != NULL) {
                INSIST(key->func->destroy != NULL);
                key->func->destroy(key);
@@ -928,14 +946,22 @@ get_key_struct(dns_name_t *name, unsigned int alg,
        memset(key, 0, sizeof(dst_key_t));
        key->magic = KEY_MAGIC;
 
+       result = isc_refcount_init(&key->refs, 1);
+       if (result != ISC_R_SUCCESS) {
+               isc_mem_put(mctx, key, sizeof(dst_key_t));
+               return (NULL);
+       }
+
        key->key_name = isc_mem_get(mctx, sizeof(dns_name_t));
        if (key->key_name == NULL) {
+               isc_refcount_destroy(&key->refs);
                isc_mem_put(mctx, key, sizeof(dst_key_t));
                return (NULL);
        }
        dns_name_init(key->key_name, NULL);
        result = dns_name_dup(name, mctx, key->key_name);
        if (result != ISC_R_SUCCESS) {
+               isc_refcount_destroy(&key->refs);
                isc_mem_put(mctx, key->key_name, sizeof(dns_name_t));
                isc_mem_put(mctx, key, sizeof(dst_key_t));
                return (NULL);
index 16696487bc47de817991ff034ef157e192d8c26b..6e416312762b4e3c690f03c2e1ddf12eb70329b9 100644 (file)
@@ -29,7 +29,7 @@
  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dst_internal.h,v 1.11.120.2 2010/01/15 23:47:33 tbox Exp $ */
+/* $Id: dst_internal.h,v 1.11.120.3 2010/12/09 01:12:55 marka Exp $ */
 
 #ifndef DST_DST_INTERNAL_H
 #define DST_DST_INTERNAL_H 1
@@ -41,6 +41,7 @@
 #include <isc/region.h>
 #include <isc/types.h>
 #include <isc/md5.h>
+#include <isc/refcount.h>
 #include <isc/sha1.h>
 #include <isc/sha2.h>
 #include <isc/hmacmd5.h>
@@ -83,6 +84,7 @@ typedef struct dst_hmacsha512_key dst_hmacsha512_key_t;
 /*% DST Key Structure */
 struct dst_key {
        unsigned int    magic;
+       isc_refcount_t  refs;
        dns_name_t *    key_name;       /*%< name of the key */
        unsigned int    key_size;       /*%< size of the key in bits */
        unsigned int    key_proto;      /*%< protocols this key is used for */
index 3e8882ef53877ad8ba1afe505b8c200f4e5195be..44fb9353805246a9ea7577f5e6a09e7a9767496f 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: tsig.h,v 1.51.332.3 2010/12/02 23:40:28 marka Exp $ */
+/* $Id: tsig.h,v 1.51.332.4 2010/12/09 01:12:55 marka Exp $ */
 
 #ifndef DNS_TSIG_H
 #define DNS_TSIG_H 1
@@ -103,7 +103,7 @@ dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
 
 isc_result_t
 dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
-                         dst_key_t **dstkeyp, isc_boolean_t generated,
+                         dst_key_t *dstkey, isc_boolean_t generated,
                          dns_name_t *creator, isc_stdtime_t inception,
                          isc_stdtime_t expire, isc_mem_t *mctx,
                          dns_tsig_keyring_t *ring, dns_tsigkey_t **key);
@@ -117,12 +117,15 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
  *     allows a transient key with an invalid algorithm to exist long enough
  *     to generate a BADKEY response.
  *
+ *     If dns_tsigkey_createfromkey is successful a new reference to 'dstkey'
+ *     will have been made.
+ *
  *     Requires:
  *\li          'name' is a valid dns_name_t
  *\li          'algorithm' is a valid dns_name_t
  *\li          'secret' is a valid pointer
  *\li          'length' is an integer >= 0
- *\li          'key' is a valid dst key or NULL
+ *\li          'dstkey' is a valid dst key or NULL
  *\li          'creator' points to a valid dns_name_t or is NULL
  *\li          'mctx' is a valid memory context
  *\li          'ring' is a valid TSIG keyring or NULL
index de262bdafb1a2e83091c47dee4ea4cac2f918cf2..05eedbc10f8caa0dc0d9af2c8b71d758dca3e1bc 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dst.h,v 1.12.50.2 2010/01/15 23:47:34 tbox Exp $ */
+/* $Id: dst.h,v 1.12.50.3 2010/12/09 01:12:55 marka Exp $ */
 
 #ifndef DST_DST_H
 #define DST_DST_H 1
@@ -508,6 +508,16 @@ dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2);
  * \li ISC_FALSE
  */
 
+void
+dst_key_attach(dst_key_t *source, dst_key_t **target);
+/*
+ * Attach to a existing key increasing the reference count.
+ *
+ * Requires:
+ *\li 'source' to be a valid key.
+ *\li 'target' to be non-NULL and '*target' to be NULL.
+ */
+
 void
 dst_key_free(dst_key_t **keyp);
 /*%<
index 9ce8de77a72e23aad884f307876ab7ba1d1ca3e8..163292606ec1d72432c3a293d67974c030ffc3c7 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 /*
- * $Id: tkey.c,v 1.90.118.3 2010/12/02 23:40:28 marka Exp $
+ * $Id: tkey.c,v 1.90.118.4 2010/12/09 01:12:55 marka Exp $
  */
 /*! \file */
 #include <config.h>
@@ -491,10 +491,11 @@ process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin,
                        expire = now + lifetime;
 #endif
                RETERR(dns_tsigkey_createfromkey(name, &tkeyin->algorithm,
-                                                &dstkey, ISC_TRUE,
+                                                dstkey, ISC_TRUE,
                                                 dns_fixedname_name(&principal),
                                                 now, expire, ring->mctx, ring,
                                                 NULL));
+               dst_key_free(&dstkey);
                tkeyout->inception = now;
                tkeyout->expire = expire;
        } else {
@@ -1273,9 +1274,10 @@ dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
                                  &dstkey));
 
        RETERR(dns_tsigkey_createfromkey(tkeyname, DNS_TSIG_GSSAPI_NAME,
-                                        &dstkey, ISC_FALSE, NULL,
+                                        dstkey, ISC_FALSE, NULL,
                                         rtkey.inception, rtkey.expire,
                                         ring->mctx, ring, outkey));
+       dst_key_free(&dstkey);
        dns_rdata_freestruct(&rtkey);
        return (result);
 
@@ -1408,9 +1410,10 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
                                         (win2k
                                          ? DNS_TSIG_GSSAPIMS_NAME
                                          : DNS_TSIG_GSSAPI_NAME),
-                                        &dstkey, ISC_TRUE, NULL,
+                                        dstkey, ISC_TRUE, NULL,
                                         rtkey.inception, rtkey.expire,
                                         ring->mctx, ring, outkey));
+       dst_key_free(&dstkey);
        dns_rdata_freestruct(&rtkey);
        return (result);
 
index b5c13d46dd23afe89d4d806e1797ce5db396f91b..6c4e81dc9b96da3f552b5bcd1ca42af551c74a9e 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 /*
- * $Id: tsig.c,v 1.136.18.4 2010/12/02 23:40:28 marka Exp $
+ * $Id: tsig.c,v 1.136.18.5 2010/12/09 01:12:55 marka Exp $
  */
 /*! \file */
 #include <config.h>
@@ -247,7 +247,7 @@ tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
 
 isc_result_t
 dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
-                         dst_key_t **dstkeyp, isc_boolean_t generated,
+                         dst_key_t *dstkey, isc_boolean_t generated,
                          dns_name_t *creator, isc_stdtime_t inception,
                          isc_stdtime_t expire, isc_mem_t *mctx,
                          dns_tsig_keyring_t *ring, dns_tsigkey_t **key)
@@ -255,7 +255,6 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
        dns_tsigkey_t *tkey;
        isc_result_t ret;
        unsigned int refs = 0;
-       dst_key_t *dstkey;
 
        REQUIRE(key == NULL || *key == NULL);
        REQUIRE(name != NULL);
@@ -263,10 +262,6 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
        REQUIRE(mctx != NULL);
        REQUIRE(key != NULL || ring != NULL);
 
-       if (dstkeyp != NULL)
-               dstkey = *dstkeyp;
-       else
-               dstkey = NULL;
        tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t));
        if (tkey == NULL)
                return (ISC_R_NOMEMORY);
@@ -362,11 +357,11 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
        } else
                tkey->creator = NULL;
 
-       tkey->key = dstkey;
+       tkey->key = NULL;
+       if (dstkey != NULL)
+               dst_key_attach(dstkey, &tkey->key);
        tkey->ring = ring;
 
-       if (dstkeyp != NULL)
-               *dstkeyp = NULL;
        if (key != NULL)
                refs++;
        if (ring != NULL)
@@ -440,6 +435,8 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
                isc_refcount_decrement(&tkey->refs, NULL);
        isc_refcount_destroy(&tkey->refs);
  cleanup_creator:
+       if (tkey->key != NULL)
+               dst_key_free(&tkey->key);
        if (tkey->creator != NULL) {
                dns_name_free(tkey->creator, mctx);
                isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t));
@@ -616,10 +613,10 @@ dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
        } else if (length > 0)
                return (DNS_R_BADALG);
 
-       result = dns_tsigkey_createfromkey(name, algorithm, &dstkey,
+       result = dns_tsigkey_createfromkey(name, algorithm, dstkey,
                                           generated, creator,
                                           inception, expire, mctx, ring, key);
-       if (result != ISC_R_SUCCESS && dstkey != NULL)
+       if (dstkey != NULL)
                dst_key_free(&dstkey);
        return (result);
 }