diff options
Diffstat (limited to 'lib/dns')
-rw-r--r-- | lib/dns/adb.c | 19 | ||||
-rw-r--r-- | lib/dns/api | 4 | ||||
-rw-r--r-- | lib/dns/dnssec.c | 100 | ||||
-rw-r--r-- | lib/dns/dst_openssl.h | 3 | ||||
-rw-r--r-- | lib/dns/dst_parse.c | 35 | ||||
-rw-r--r-- | lib/dns/dst_result.c | 4 | ||||
-rw-r--r-- | lib/dns/include/Makefile.in | 2 | ||||
-rw-r--r-- | lib/dns/include/dns/dnssec.h | 13 | ||||
-rw-r--r-- | lib/dns/include/dns/iptable.h | 4 | ||||
-rw-r--r-- | lib/dns/include/dns/log.h | 2 | ||||
-rw-r--r-- | lib/dns/include/dns/stats.h | 10 | ||||
-rw-r--r-- | lib/dns/include/dns/zone.h | 2 | ||||
-rw-r--r-- | lib/dns/include/dst/Makefile.in | 2 | ||||
-rw-r--r-- | lib/dns/include/dst/result.h | 6 | ||||
-rw-r--r-- | lib/dns/log.c | 2 | ||||
-rw-r--r-- | lib/dns/master.c | 48 | ||||
-rw-r--r-- | lib/dns/masterdump.c | 12 | ||||
-rw-r--r-- | lib/dns/openssl_link.c | 42 | ||||
-rw-r--r-- | lib/dns/openssldh_link.c | 16 | ||||
-rw-r--r-- | lib/dns/openssldsa_link.c | 34 | ||||
-rw-r--r-- | lib/dns/opensslrsa_link.c | 52 | ||||
-rw-r--r-- | lib/dns/rbtdb.c | 27 | ||||
-rw-r--r-- | lib/dns/rdata.c | 12 | ||||
-rwxr-xr-x | lib/dns/spnego_asn1.pl | 2 | ||||
-rw-r--r-- | lib/dns/zone.c | 80 |
25 files changed, 364 insertions, 169 deletions
diff --git a/lib/dns/adb.c b/lib/dns/adb.c index e021b8d9b93f..35b4caeb0be2 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -3430,8 +3430,10 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, addr->entry->srtt = new_srtt; addr->srtt = new_srtt; - isc_stdtime_get(&now); - addr->entry->expires = now + ADB_ENTRY_WINDOW; + if (addr->entry->expires == 0) { + isc_stdtime_get(&now); + addr->entry->expires = now + ADB_ENTRY_WINDOW; + } UNLOCK(&adb->entrylocks[bucket]); } @@ -3441,6 +3443,7 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits, unsigned int mask) { int bucket; + isc_stdtime_t now; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); @@ -3449,6 +3452,11 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, LOCK(&adb->entrylocks[bucket]); addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask); + if (addr->entry->expires == 0) { + isc_stdtime_get(&now); + addr->entry->expires = now + ADB_ENTRY_WINDOW; + } + /* * Note that we do not update the other bits in addr->flags with * the most recent values from addr->entry->flags. @@ -3527,15 +3535,16 @@ dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) { entry = addr->entry; REQUIRE(DNS_ADBENTRY_VALID(entry)); - isc_stdtime_get(&now); - *addrp = NULL; overmem = isc_mem_isovermem(adb->mctx); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); - entry->expires = now + ADB_ENTRY_WINDOW; + if (entry->expires == 0) { + isc_stdtime_get(&now); + entry->expires = now + ADB_ENTRY_WINDOW; + } want_check_exit = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE); diff --git a/lib/dns/api b/lib/dns/api index 974ae84d538c..02fb649d2678 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -3,6 +3,6 @@ # 9.7: 60-79 # 9.8: 80-89 # 9.9: 90-109 -LIBINTERFACE = 110 +LIBINTERFACE = 111 LIBREVISION = 2 -LIBAGE = 0 +LIBAGE = 1 diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index 6e9ab9f0d0d9..393a9c794d9d 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -35,16 +35,20 @@ #include <dns/dnssec.h> #include <dns/fixedname.h> #include <dns/keyvalues.h> +#include <dns/log.h> #include <dns/message.h> #include <dns/rdata.h> #include <dns/rdatalist.h> #include <dns/rdataset.h> #include <dns/rdatastruct.h> #include <dns/result.h> +#include <dns/stats.h> #include <dns/tsig.h> /* for DNS_TSIG_FUDGE */ #include <dst/result.h> +LIBDNS_EXTERNAL_DATA isc_stats_t *dns_dnssec_stats; + #define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR) #define RETERR(x) do { \ @@ -74,6 +78,12 @@ digest_callback(void *arg, isc_region_t *data) { return (dst_context_adddata(ctx, data)); } +static inline void +inc_stat(isc_statscounter_t counter) { + if (dns_dnssec_stats != NULL) + isc_stats_increment(dns_dnssec_stats, counter); +} + /* * Make qsort happy. */ @@ -150,7 +160,9 @@ dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx, } static isc_result_t -digest_sig(dst_context_t *ctx, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *sig) { +digest_sig(dst_context_t *ctx, isc_boolean_t downcase, dns_rdata_t *sigrdata, + dns_rdata_rrsig_t *rrsig) +{ isc_region_t r; isc_result_t ret; dns_fixedname_t fname; @@ -162,11 +174,16 @@ digest_sig(dst_context_t *ctx, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *sig) { ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) return (ret); - dns_fixedname_init(&fname); - RUNTIME_CHECK(dns_name_downcase(&sig->signer, - dns_fixedname_name(&fname), NULL) - == ISC_R_SUCCESS); - dns_name_toregion(dns_fixedname_name(&fname), &r); + if (downcase) { + dns_fixedname_init(&fname); + + RUNTIME_CHECK(dns_name_downcase(&rrsig->signer, + dns_fixedname_name(&fname), + NULL) == ISC_R_SUCCESS); + dns_name_toregion(dns_fixedname_name(&fname), &r); + } else + dns_name_toregion(&rrsig->signer, &r); + return (dst_context_adddata(ctx, &r)); } @@ -188,6 +205,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_uint32_t flags; unsigned int sigsize; dns_fixedname_t fnewname; + dns_fixedname_t fsigner; REQUIRE(name != NULL); REQUIRE(dns_name_countlabels(name) <= 255); @@ -215,8 +233,14 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, sig.common.rdtype = dns_rdatatype_rrsig; ISC_LINK_INIT(&sig.common, link); + /* + * Downcase signer. + */ dns_name_init(&sig.signer, NULL); - dns_name_clone(dst_key_name(key), &sig.signer); + dns_fixedname_init(&fsigner); + RUNTIME_CHECK(dns_name_downcase(dst_key_name(key), + dns_fixedname_name(&fsigner), NULL) == ISC_R_SUCCESS); + dns_name_clone(dns_fixedname_name(&fsigner), &sig.signer); sig.covered = set->type; sig.algorithm = dst_key_alg(key); @@ -256,7 +280,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, /* * Digest the SIG rdata. */ - ret = digest_sig(ctx, &tmpsigrdata, &sig); + ret = digest_sig(ctx, ISC_FALSE, &tmpsigrdata, &sig); if (ret != ISC_R_SUCCESS) goto cleanup_context; @@ -329,7 +353,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, memcpy(sig.signature, r.base, sig.siglen); ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass, - sig.common.rdtype, &sig, buffer); + sig.common.rdtype, &sig, buffer); cleanup_array: isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t)); @@ -360,6 +384,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, dst_context_t *ctx = NULL; int labels = 0; isc_uint32_t flags; + isc_boolean_t downcase = ISC_FALSE; REQUIRE(name != NULL); REQUIRE(set != NULL); @@ -374,8 +399,10 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, if (set->type != sig.covered) return (DNS_R_SIGINVALID); - if (isc_serial_lt(sig.timeexpire, sig.timesigned)) + if (isc_serial_lt(sig.timeexpire, sig.timesigned)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); + } if (!ignoretime) { isc_stdtime_get(&now); @@ -383,10 +410,13 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, /* * Is SIG temporally valid? */ - if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) + if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGFUTURE); - else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) + } else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGEXPIRED); + } } /* @@ -397,16 +427,22 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, case dns_rdatatype_ns: case dns_rdatatype_soa: case dns_rdatatype_dnskey: - if (!dns_name_equal(name, &sig.signer)) + if (!dns_name_equal(name, &sig.signer)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); + } break; case dns_rdatatype_ds: - if (dns_name_equal(name, &sig.signer)) + if (dns_name_equal(name, &sig.signer)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); + } /* FALLTHROUGH */ default: - if (!dns_name_issubdomain(name, &sig.signer)) + if (!dns_name_issubdomain(name, &sig.signer)) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_SIGINVALID); + } break; } @@ -414,11 +450,16 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, * Is the key allowed to sign data? */ flags = dst_key_flags(key); - if (flags & DNS_KEYTYPE_NOAUTH) + if (flags & DNS_KEYTYPE_NOAUTH) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_KEYUNAUTHORIZED); - if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) + } + if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) { + inc_stat(dns_dnssecstats_fail); return (DNS_R_KEYUNAUTHORIZED); + } + again: ret = dst_context_create(key, mctx, &ctx); if (ret != ISC_R_SUCCESS) goto cleanup_struct; @@ -426,7 +467,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, /* * Digest the SIG rdata (not including the signature). */ - ret = digest_sig(ctx, sigrdata, &sig); + ret = digest_sig(ctx, downcase, sigrdata, &sig); if (ret != ISC_R_SUCCESS) goto cleanup_context; @@ -505,21 +546,40 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, r.base = sig.signature; r.length = sig.siglen; ret = dst_context_verify(ctx, &r); - if (ret == DST_R_VERIFYFAILURE) - ret = DNS_R_SIGINVALID; + if (ret == ISC_R_SUCCESS && downcase) { + char namebuf[DNS_NAME_FORMATSIZE]; + dns_name_format(&sig.signer, namebuf, sizeof(namebuf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "sucessfully validated after lower casing " + "signer '%s'", namebuf); + inc_stat(dns_dnssecstats_downcase); + } else if (ret == ISC_R_SUCCESS) + inc_stat(dns_dnssecstats_asis); cleanup_array: isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t)); cleanup_context: dst_context_destroy(&ctx); + if (ret == DST_R_VERIFYFAILURE && !downcase) { + downcase = ISC_TRUE; + goto again; + } cleanup_struct: dns_rdata_freestruct(&sig); + if (ret == DST_R_VERIFYFAILURE) + ret = DNS_R_SIGINVALID; + + if (ret != ISC_R_SUCCESS) + inc_stat(dns_dnssecstats_fail); + if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) { if (wild != NULL) RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, dns_fixedname_name(&fnewname), wild, NULL) == ISC_R_SUCCESS); + inc_stat(dns_dnssecstats_wildcard); ret = DNS_R_FROMWILDCARD; } return (ret); diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h index 287c1a47d99a..4ecbb22ac195 100644 --- a/lib/dns/dst_openssl.h +++ b/lib/dns/dst_openssl.h @@ -39,6 +39,9 @@ ISC_LANG_BEGINDECLS isc_result_t dst__openssl_toresult(isc_result_t fallback); +isc_result_t +dst__openssl_toresult2(const char *funcname, isc_result_t fallback); + #ifdef USE_ENGINE ENGINE * dst__openssl_getengine(const char *engine); diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c index 5c2cf9333e73..e0db5fe9733e 100644 --- a/lib/dns/dst_parse.c +++ b/lib/dns/dst_parse.c @@ -248,10 +248,14 @@ check_data(const dst_private_t *priv, const unsigned int alg, switch (alg) { case DST_ALG_RSAMD5: case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + case DST_ALG_RSASHA256: + case DST_ALG_RSASHA512: return (check_rsa(priv)); case DST_ALG_DH: return (check_dh(priv)); case DST_ALG_DSA: + case DST_ALG_NSEC3DSA: return (check_dsa(priv)); case DST_ALG_HMACMD5: return (check_hmac_md5(priv, old)); @@ -289,7 +293,7 @@ int dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, isc_mem_t *mctx, dst_private_t *priv) { - int n = 0, major, minor; + int n = 0, major, minor, check; isc_buffer_t b; isc_token_t token; unsigned char *data = NULL; @@ -416,8 +420,14 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, done: priv->nelements = n; - if (check_data(priv, alg, ISC_TRUE) < 0) + check = check_data(priv, alg, ISC_TRUE); + if (check < 0) { + ret = DST_R_INVALIDPRIVATEKEY; goto fail; + } else if (check != ISC_R_SUCCESS) { + ret = check; + goto fail; + } return (ISC_R_SUCCESS); @@ -436,7 +446,7 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, { FILE *fp; int ret, i; - isc_result_t iret; + isc_result_t result; char filename[ISC_DIR_NAMEMAX]; char buffer[MAXFIELDSIZE * 2]; isc_buffer_t b; @@ -444,13 +454,16 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, REQUIRE(priv != NULL); - if (check_data(priv, dst_key_alg(key), ISC_FALSE) < 0) + ret = check_data(priv, dst_key_alg(key), ISC_FALSE); + if (ret < 0) return (DST_R_INVALIDPRIVATEKEY); + else if (ret != ISC_R_SUCCESS) + return (ret); isc_buffer_init(&b, filename, sizeof(filename)); - ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); - if (ret != ISC_R_SUCCESS) - return (ret); + result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); + if (result != ISC_R_SUCCESS) + return (result); if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); @@ -525,8 +538,8 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, r.base = priv->elements[i].data; r.length = priv->elements[i].length; isc_buffer_init(&b, buffer, sizeof(buffer)); - iret = isc_base64_totext(&r, sizeof(buffer), "", &b); - if (iret != ISC_R_SUCCESS) { + result = isc_base64_totext(&r, sizeof(buffer), "", &b); + if (result != ISC_R_SUCCESS) { fclose(fp); return (DST_R_INVALIDPRIVATEKEY); } @@ -536,9 +549,9 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, } fflush(fp); - iret = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS; + result = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS; fclose(fp); - return (iret); + return (result); } /*! \file */ diff --git a/lib/dns/dst_result.c b/lib/dns/dst_result.c index 429dbb2fc1cf..297e809cc945 100644 --- a/lib/dns/dst_result.c +++ b/lib/dns/dst_result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -30,7 +30,7 @@ static const char *text[DST_R_NRESULTS] = { "algorithm is unsupported", /*%< 0 */ - "openssl failure", /*%< 1 */ + "crypto failure", /*%< 1 */ "built with no crypto support", /*%< 2 */ "illegal operation for a null key", /*%< 3 */ "public key is invalid", /*%< 4 */ diff --git a/lib/dns/include/Makefile.in b/lib/dns/include/Makefile.in index b52cb980d550..10d798d9605f 100644 --- a/lib/dns/include/Makefile.in +++ b/lib/dns/include/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h index 6a2cbb4c19a5..22a8a41e6d48 100644 --- a/lib/dns/include/dns/dnssec.h +++ b/lib/dns/include/dns/dnssec.h @@ -24,6 +24,7 @@ #include <isc/lang.h> #include <isc/stdtime.h> +#include <isc/stats.h> #include <dns/types.h> @@ -31,6 +32,8 @@ ISC_LANG_BEGINDECLS +LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats; + /*%< Maximum number of keys supported in a zone. */ #define DNS_MAXZONEKEYS 32 @@ -60,8 +63,8 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_stdtime_t *inception, isc_stdtime_t *expire, isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata); /*%< - * Generates a SIG record covering this rdataset. This has no effect - * on existing SIG records. + * Generates a RRSIG record covering this rdataset. This has no effect + * on existing RRSIG records. * * Requires: *\li 'name' (the owner name of the record) is a valid name @@ -94,9 +97,9 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); /*%< - * Verifies the SIG record covering this rdataset signed by a specific - * key. This does not determine if the key's owner is authorized to - * sign this record, as this requires a resolver or database. + * Verifies the RRSIG record covering this rdataset signed by a specific + * key. This does not determine if the key's owner is authorized to sign + * this record, as this requires a resolver or database. * If 'ignoretime' is ISC_TRUE, temporal validity will not be checked. * * Requires: diff --git a/lib/dns/include/dns/iptable.h b/lib/dns/include/dns/iptable.h index d7eb140dc057..2ce8e18124b9 100644 --- a/lib/dns/include/dns/iptable.h +++ b/lib/dns/include/dns/iptable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,6 +23,8 @@ #include <isc/magic.h> #include <isc/radix.h> +#include <dns/types.h> + struct dns_iptable { unsigned int magic; isc_mem_t *mctx; diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h index 475d8095b637..fbcd2def8986 100644 --- a/lib/dns/include/dns/log.h +++ b/lib/dns/include/dns/log.h @@ -73,6 +73,8 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[]; #define DNS_LOGMODULE_HINTS (&dns_modules[24]) #define DNS_LOGMODULE_ACACHE (&dns_modules[25]) #define DNS_LOGMODULE_DLZ (&dns_modules[26]) +#define DNS_LOGMODULE_DNSSEC (&dns_modules[27]) +#define DNS_LOGMODULE_CRYPTO (&dns_modules[28]) ISC_LANG_BEGINDECLS diff --git a/lib/dns/include/dns/stats.h b/lib/dns/include/dns/stats.h index bc77d1e9c5a3..5364267272a0 100644 --- a/lib/dns/include/dns/stats.h +++ b/lib/dns/include/dns/stats.h @@ -64,6 +64,16 @@ enum { dns_resstatscounter_max = 30, + /* + * DNSSEC stats. + */ + dns_dnssecstats_asis = 0, + dns_dnssecstats_downcase = 1, + dns_dnssecstats_wildcard = 2, + dns_dnssecstats_fail = 3, + + dns_dnssecstats_max = 4, + /*% * Zone statistics counters. */ diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 4f8e0ba16e37..5bfe1485c0f8 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1765,7 +1765,7 @@ dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures); isc_result_t dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, - isc_uint16_t keyid, isc_boolean_t delete); + isc_uint16_t keyid, isc_boolean_t deleteit); /*%< * Initiate/resume signing of the entire zone with the zone DNSKEY(s) * that match the given algorithm and keyid. diff --git a/lib/dns/include/dst/Makefile.in b/lib/dns/include/dst/Makefile.in index 4ed4ec0430fd..cece67dd33a0 100644 --- a/lib/dns/include/dst/Makefile.in +++ b/lib/dns/include/dst/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any diff --git a/lib/dns/include/dst/result.h b/lib/dns/include/dst/result.h index d77b72e77a6e..00640a1b1c82 100644 --- a/lib/dns/include/dst/result.h +++ b/lib/dns/include/dst/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -34,7 +34,9 @@ #include <isc/result.h> /* Contractual promise. */ #define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0) -#define DST_R_OPENSSLFAILURE (ISC_RESULTCLASS_DST + 1) +#define DST_R_CRYPTOFAILURE (ISC_RESULTCLASS_DST + 1) +/* compat */ +#define DST_R_OPENSSLFAILURE DST_R_CRYPTOFAILURE #define DST_R_NOCRYPTO (ISC_RESULTCLASS_DST + 2) #define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3) #define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4) diff --git a/lib/dns/log.c b/lib/dns/log.c index 17af1d9b2d4c..3c9727df72c1 100644 --- a/lib/dns/log.c +++ b/lib/dns/log.c @@ -79,6 +79,8 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = { { "dns/hints", 0 }, { "dns/acache", 0 }, { "dns/dlz", 0 }, + { "dns/dnssec", 0 }, + { "dns/crypto", 0 }, { NULL, 0 } }; diff --git a/lib/dns/master.c b/lib/dns/master.c index 84af3b836614..d87d3987f350 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -34,6 +34,7 @@ #include <isc/util.h> #include <dns/callbacks.h> +#include <dns/compress.h> #include <dns/events.h> #include <dns/fixedname.h> #include <dns/master.h> @@ -2031,19 +2032,21 @@ load_raw(dns_loadctx_t *lctx) { unsigned int loop_cnt = 0; dns_rdatacallbacks_t *callbacks; unsigned char namebuf[DNS_NAME_MAXWIRE]; - isc_region_t r; - dns_name_t name; + dns_fixedname_t fixed; + dns_name_t *name; rdatalist_head_t head, dummy; dns_rdatalist_t rdatalist; isc_mem_t *mctx = lctx->mctx; dns_rdata_t *rdata = NULL; unsigned int rdata_size = 0; int target_size = TSIZ; - isc_buffer_t target; + isc_buffer_t target, buf; unsigned char *target_mem = NULL; + dns_decompress_t dctx; REQUIRE(DNS_LCTX_VALID(lctx)); callbacks = lctx->callbacks; + dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); if (lctx->first) { dns_masterrawheader_t header; @@ -2100,6 +2103,9 @@ load_raw(dns_loadctx_t *lctx) { } isc_buffer_init(&target, target_mem, target_size); + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + /* * In the following loop, we regard any error fatal regardless of * whether "MANYERRORS" is set in the context option. This is because @@ -2111,7 +2117,7 @@ load_raw(dns_loadctx_t *lctx) { for (loop_cnt = 0; (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt); loop_cnt++) { - unsigned int i, rdcount, consumed_name; + unsigned int i, rdcount; isc_uint16_t namelen; isc_uint32_t totallen; size_t minlen, readlen; @@ -2201,12 +2207,11 @@ load_raw(dns_loadctx_t *lctx) { lctx->f); if (result != ISC_R_SUCCESS) goto cleanup; + isc_buffer_setactive(&target, (unsigned int)namelen); - isc_buffer_activeregion(&target, &r); - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - isc_buffer_forward(&target, (unsigned int)namelen); - consumed_name = isc_buffer_consumedlength(&target); + result = dns_name_fromwire(name, &target, &dctx, 0, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; /* Rdata contents. */ if (rdcount > rdata_size) { @@ -2237,7 +2242,7 @@ load_raw(dns_loadctx_t *lctx) { /* Partial Commit. */ ISC_LIST_APPEND(head, &rdatalist, link); - result = commit(callbacks, lctx, &head, &name, + result = commit(callbacks, lctx, &head, name, NULL, 0); for (j = 0; j < i; j++) { ISC_LIST_UNLINK(rdatalist.rdata, @@ -2249,8 +2254,6 @@ load_raw(dns_loadctx_t *lctx) { /* Rewind the buffer and continue */ isc_buffer_clear(&target); - isc_buffer_add(&target, consumed_name); - isc_buffer_forward(&target, consumed_name); rdcount -= i; @@ -2270,11 +2273,20 @@ load_raw(dns_loadctx_t *lctx) { if (result != ISC_R_SUCCESS) goto cleanup; isc_buffer_setactive(&target, (unsigned int)rdlen); - isc_buffer_activeregion(&target, &r); - isc_buffer_forward(&target, (unsigned int)rdlen); - dns_rdata_fromregion(&rdata[i], rdatalist.rdclass, - rdatalist.type, &r); - + /* + * It is safe to have the source active region and + * the target available region be the same if + * decompression is disabled (see dctx above) and we + * are not downcasing names (options == 0). + */ + isc_buffer_init(&buf, isc_buffer_current(&target), + (unsigned int)rdlen); + result = dns_rdata_fromwire(&rdata[i], + rdatalist.rdclass, + rdatalist.type, &target, + &dctx, 0, &buf); + if (result != ISC_R_SUCCESS) + goto cleanup; ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link); } @@ -2291,7 +2303,7 @@ load_raw(dns_loadctx_t *lctx) { ISC_LIST_APPEND(head, &rdatalist, link); /* Commit this RRset. rdatalist will be unlinked. */ - result = commit(callbacks, lctx, &head, &name, NULL, 0); + result = commit(callbacks, lctx, &head, name, NULL, 0); for (i = 0; i < rdcount; i++) { ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link); diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index 681304f589e7..b02cc11f5219 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -1483,7 +1483,8 @@ dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, } static isc_result_t -opentmp(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) { +opentmp(isc_mem_t *mctx, dns_masterformat_t format, const char *file, + char **tempp, FILE **fp) { FILE *f = NULL; isc_result_t result; char *tempname = NULL; @@ -1498,7 +1499,10 @@ opentmp(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) { if (result != ISC_R_SUCCESS) goto cleanup; - result = isc_file_openunique(tempname, &f); + if (format == dns_masterformat_text) + result = isc_file_openunique(tempname, &f); + else + result = isc_file_bopenunique(tempname, &f); if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, @@ -1542,7 +1546,7 @@ dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, if (file == NULL) return (ISC_R_NOMEMORY); - result = opentmp(mctx, filename, &tempname, &f); + result = opentmp(mctx, format, filename, &tempname, &f); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1596,7 +1600,7 @@ dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, char *tempname; dns_dumpctx_t *dctx = NULL; - result = opentmp(mctx, filename, &tempname, &f); + result = opentmp(mctx, format, filename, &tempname, &f); if (result != ISC_R_SUCCESS) return (result); diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c index 83dd1fc666d3..dd930bdb64fe 100644 --- a/lib/dns/openssl_link.c +++ b/lib/dns/openssl_link.c @@ -45,6 +45,10 @@ #include <isc/thread.h> #include <isc/util.h> +#include <dns/log.h> + +#include <dst/result.h> + #include "dst_internal.h" #include "dst_openssl.h" @@ -166,6 +170,8 @@ dst__openssl_init() { CRYPTO_set_locking_callback(lock_callback); CRYPTO_set_id_callback(id_callback); + ERR_load_crypto_strings(); + rm = mem_alloc(sizeof(RAND_METHOD)); if (rm == NULL) { result = ISC_R_NOMEMORY; @@ -317,7 +323,7 @@ dst__openssl_destroy() { isc_result_t dst__openssl_toresult(isc_result_t fallback) { isc_result_t result = fallback; - int err = ERR_get_error(); + unsigned long err = ERR_get_error(); switch (ERR_GET_REASON(err)) { case ERR_R_MALLOC_FAILURE: @@ -330,6 +336,40 @@ dst__openssl_toresult(isc_result_t fallback) { return (result); } +isc_result_t +dst__openssl_toresult2(const char *funcname, isc_result_t fallback) { + isc_result_t result = fallback; + unsigned long err = ERR_peek_error(); + const char *file, *data; + int line, flags; + char buf[256]; + + switch (ERR_GET_REASON(err)) { + case ERR_R_MALLOC_FAILURE: + result = ISC_R_NOMEMORY; + goto done; + default: + break; + } + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, + "%s failed", funcname); + for (;;) { + err = ERR_get_error_line_data(&file, &line, &data, &flags); + if (err == 0U) + goto done; + ERR_error_string_n(err, buf, sizeof(buf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO, + "%s:%s:%d:%s", buf, file, line, + (flags & ERR_TXT_STRING) ? data : ""); + } + + done: + ERR_clear_error(); + return (result); +} + #if defined(USE_ENGINE) ENGINE * dst__openssl_getengine(const char *name) { diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c index be1d880280eb..04fb9fe5afa1 100644 --- a/lib/dns/openssldh_link.c +++ b/lib/dns/openssldh_link.c @@ -94,7 +94,8 @@ openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv, return (ISC_R_NOSPACE); ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv); if (ret == 0) - return (dst__openssl_toresult(DST_R_COMPUTESECRETFAILURE)); + return (dst__openssl_toresult2("DH_compute_key", + DST_R_COMPUTESECRETFAILURE)); isc_buffer_add(secret, len); return (ISC_R_SUCCESS); } @@ -179,14 +180,16 @@ openssldh_generate(dst_key_t *key, int generator) { #if OPENSSL_VERSION_NUMBER > 0x00908000L dh = DH_new(); if (dh == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult(ISC_R_NOMEMORY)); BN_GENCB_set_old(&cb, NULL, NULL); if (!DH_generate_parameters_ex(dh, key->key_size, generator, &cb)) { DH_free(dh); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2( + "DH_generate_parameters_ex", + DST_R_OPENSSLFAILURE)); } #else dh = DH_generate_parameters(key->key_size, generator, @@ -195,11 +198,13 @@ openssldh_generate(dst_key_t *key, int generator) { } if (dh == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DH_generate_parameters", + DST_R_OPENSSLFAILURE)); if (DH_generate_key(dh) == 0) { DH_free(dh); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DH_generate_key", + DST_R_OPENSSLFAILURE)); } dh->flags &= ~DH_FLAG_CACHE_MONT_P; @@ -430,6 +435,7 @@ openssldh_tofile(const dst_key_t *key, const char *directory) { dh = key->keydata.dh; + memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 4; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(dh->p)); if (bufs[i] == NULL) { diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c index c93c119959cd..68d19745e419 100644 --- a/lib/dns/openssldsa_link.c +++ b/lib/dns/openssldsa_link.c @@ -168,7 +168,8 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) { EVP_PKEY_free(pkey); free(sigbuf); - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_SignFinal", + ISC_R_FAILURE)); } INSIST(EVP_PKEY_size(pkey) >= (int) siglen); EVP_PKEY_free(pkey); @@ -181,23 +182,26 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { sb = sigbuf; if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) { free(sigbuf); - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("d2i_DSA_SIG", ISC_R_FAILURE)); } free(sigbuf); #elif 0 /* Only use EVP for the Digest */ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) { - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_DigestFinal_ex", + ISC_R_FAILURE)); } dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) - return (dst__openssl_toresult(DST_R_SIGNFAILURE)); + return (dst__openssl_toresult2("DSA_do_sign", + DST_R_SIGNFAILURE)); #else isc_sha1_final(sha1ctx, digest); dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa); if (dsasig == NULL) - return (dst__openssl_toresult(DST_R_SIGNFAILURE)); + return (dst__openssl_toresult2("DSA_do_sign", + DST_R_SIGNFAILURE)); #endif *r.base++ = (key->key_size - 512)/64; BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); @@ -276,10 +280,15 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa); #endif DSA_SIG_free(dsasig); - if (status != 1) + switch (status) { + case 1: + return (ISC_R_SUCCESS); + case 0: return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); - - return (ISC_R_SUCCESS); + default: + return (dst__openssl_toresult2("DSA_do_verify", + DST_R_VERIFYFAILURE)); + } } static isc_boolean_t @@ -340,19 +349,22 @@ openssldsa_generate(dst_key_t *key, int unused) { &cb)) { DSA_free(dsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DSA_generate_parameters_ex", + DST_R_OPENSSLFAILURE)); } #else dsa = DSA_generate_parameters(key->key_size, rand_array, ISC_SHA1_DIGESTLENGTH, NULL, NULL, NULL, NULL); if (dsa == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DSA_generate_parameters", + DST_R_OPENSSLFAILURE)); #endif if (DSA_generate_key(dsa) == 0) { DSA_free(dsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("DSA_generate_key", + DST_R_OPENSSLFAILURE)); } dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index 02923978fddc..fb35ce8813d9 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -155,7 +155,8 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) { EVP_MD_CTX_destroy(evp_md_ctx); - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_DigestInit_ex", + ISC_R_FAILURE)); } dctx->ctxdata.evp_md_ctx = evp_md_ctx; #else @@ -303,7 +304,8 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) { #if USE_EVP if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) { - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_DigestUpdate", + ISC_R_FAILURE)); } #else switch (dctx->key->key_alg) { @@ -373,10 +375,6 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { int status = 0; int type = 0; unsigned int digestlen = 0; - char *message; - unsigned long err; - const char* file; - int line; #if OPENSSL_VERSION_NUMBER < 0x00908000L unsigned int prefixlen = 0; const unsigned char *prefix = NULL; @@ -396,7 +394,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { return (ISC_R_NOSPACE); if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) { - return (ISC_R_FAILURE); + return (dst__openssl_toresult2("EVP_SignFinal", + ISC_R_FAILURE)); } #else if (r.length < (unsigned int) RSA_size(rsa)) @@ -488,13 +487,9 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { INSIST(type != 0); status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa); #endif - if (status == 0) { - err = ERR_peek_error_line(&file, &line); - if (err != 0U) { - message = ERR_error_string(err, NULL); - } - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); - } + if (status == 0) + return (dst__openssl_toresult2("RSA_sign", + DST_R_OPENSSLFAILURE)); #endif isc_buffer_add(sig, siglen); @@ -614,7 +609,9 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { original, rsa, RSA_PKCS1_PADDING); if (status <= 0) - return (DST_R_VERIFYFAILURE); + return (dst__openssl_toresult2( + "RSA_public_decrypt", + DST_R_VERIFYFAILURE)); if (status != (int)(prefixlen + digestlen)) return (DST_R_VERIFYFAILURE); if (memcmp(original, prefix, prefixlen)) @@ -635,7 +632,8 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { #endif #endif if (status != 1) - return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); + return (dst__openssl_toresult2("RSA_verify", + DST_R_VERIFYFAILURE)); return (ISC_R_SUCCESS); } @@ -708,6 +706,7 @@ opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) { static isc_result_t opensslrsa_generate(dst_key_t *key, int exp) { #if OPENSSL_VERSION_NUMBER > 0x00908000L + isc_result_t ret = DST_R_OPENSSLFAILURE; BN_GENCB cb; RSA *rsa = RSA_new(); BIGNUM *e = BN_new(); @@ -748,6 +747,8 @@ opensslrsa_generate(dst_key_t *key, int exp) { #endif return (ISC_R_SUCCESS); } + ret = dst__openssl_toresult2("RSA_generate_key_ex", + DST_R_OPENSSLFAILURE); err: #if USE_EVP @@ -758,7 +759,7 @@ err: BN_free(e); if (rsa != NULL) RSA_free(rsa); - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult(ret)); #else RSA *rsa; unsigned long e; @@ -778,7 +779,8 @@ err: #if USE_EVP EVP_PKEY_free(pkey); #endif - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult2("RSA_generate_key", + DST_R_OPENSSLFAILURE)); } SET_FLAGS(rsa); #if USE_EVP @@ -977,6 +979,7 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) { rsa = key->keydata.rsa; #endif + memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 8; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n)); if (bufs[i] == NULL) { @@ -1093,7 +1096,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) { /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) - return (ret); + goto err; for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { @@ -1119,10 +1122,10 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) { if (e == NULL) DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(e, label, NULL, NULL); - if (pkey == NULL) { - /* ERR_print_errors_fp(stderr); */ - DST_RET(ISC_R_NOTFOUND); - } + if (pkey == NULL) + DST_RET(dst__openssl_toresult2( + "ENGINE_load_private_key", + ISC_R_NOTFOUND)); key->engine = isc_mem_strdup(key->mctx, name); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); @@ -1243,7 +1246,8 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) - DST_RET(ISC_R_NOTFOUND); + DST_RET(dst__openssl_toresult2("ENGINE_load_private_key", + ISC_R_NOTFOUND)); key->engine = isc_mem_strdup(key->mctx, label); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 9478ef946d88..2e8245d43b8f 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -112,6 +112,8 @@ typedef isc_uint32_t rbtdb_rdatatype_t; RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname) #define RBTDB_RDATATYPE_SIGDNAME \ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname) +#define RBTDB_RDATATYPE_SIGDDS \ + RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds) #define RBTDB_RDATATYPE_NCACHEANY \ RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any) @@ -5524,13 +5526,12 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, negtype = 0; if (rbtversion == NULL && !newheader_nx) { rdtype = RBTDB_RDATATYPE_BASE(newheader->type); + covers = RBTDB_RDATATYPE_EXT(newheader->type); + sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, covers); if (NEGATIVE(newheader)) { /* * We're adding a negative cache entry. */ - covers = RBTDB_RDATATYPE_EXT(newheader->type); - sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, - covers); for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { @@ -5563,14 +5564,20 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, * We're adding something that isn't a * negative cache entry. Look for an extant * non-stale NXDOMAIN/NODATA(QTYPE=ANY) negative - * cache entry. + * cache entry. If we're adding an RRSIG, also + * check for an extant non-stale NODATA ncache + * entry which covers the same type as the RRSIG. */ for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { - if (topheader->type == - RBTDB_RDATATYPE_NCACHEANY) - break; + if ((topheader->type == + RBTDB_RDATATYPE_NCACHEANY) || + (newheader->type == sigtype && + topheader->type == + RBTDB_RDATATYPE_VALUE(0, covers))) { + break; + } } if (topheader != NULL && EXISTS(topheader) && topheader->rdh_ttl > now) { @@ -5593,7 +5600,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, } /* * The new rdataset is better. Expire the - * NXDOMAIN/NODATA(QTYPE=ANY). + * ncache entry. */ set_ttl(rbtdb, topheader, 0); topheader->attributes |= RDATASET_ATTR_STALE; @@ -5754,7 +5761,9 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, } if (IS_CACHE(rbtdb) && header->rdh_ttl > now && (header->type == dns_rdatatype_a || - header->type == dns_rdatatype_aaaa) && + header->type == dns_rdatatype_aaaa || + header->type == dns_rdatatype_ds || + header->type == RBTDB_RDATATYPE_SIGDDS) && !header_nx && !newheader_nx && header->trust >= newheader->trust && dns_rdataslab_equal((unsigned char *)header, diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 6f802623d7d1..2577e6b29be2 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -421,6 +421,8 @@ dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, REQUIRE(DNS_RDATA_INITIALIZED(rdata)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); } + REQUIRE(source != NULL); + REQUIRE(target != NULL); if (type == 0) return (DNS_R_FORMERR); @@ -521,13 +523,11 @@ rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass, dns_rdatatype_t type) { dns_decompress_t dctx; - dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); isc_buffer_setactive(src, isc_buffer_usedlength(src)); - result = dns_rdata_fromwire(&rdata, rdclass, type, src, - &dctx, 0, dest); + result = dns_rdata_fromwire(NULL, rdclass, type, src, &dctx, 0, dest); dns_decompress_invalidate(&dctx); return (result); @@ -1152,7 +1152,8 @@ txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { if (n > tregion.length) return (ISC_R_NOSPACE); - memcpy(tregion.base, sregion.base, n); + if (tregion.base != sregion.base) + memcpy(tregion.base, sregion.base, n); isc_buffer_forward(source, n); isc_buffer_add(target, n); return (ISC_R_SUCCESS); @@ -1326,7 +1327,8 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { isc_buffer_availableregion(target, &tr); if (length > tr.length) return (ISC_R_NOSPACE); - memcpy(tr.base, base, length); + if (tr.base != base) + memcpy(tr.base, base, length); isc_buffer_add(target, length); return (ISC_R_SUCCESS); } diff --git a/lib/dns/spnego_asn1.pl b/lib/dns/spnego_asn1.pl index 93dd676752df..0aaa57fa549e 100755 --- a/lib/dns/spnego_asn1.pl +++ b/lib/dns/spnego_asn1.pl @@ -1,6 +1,6 @@ #!/bin/bin/perl -w # -# Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c0f57340ab52..63e09ee1289a 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -3954,7 +3954,7 @@ zone_resigninc(dns_zone_t *zone) { result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:dns_db_newversion -> %s\n", + "zone_resigninc:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -3963,7 +3963,7 @@ zone_resigninc(dns_zone_t *zone) { zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:find_zone_keys -> %s\n", + "zone_resigninc:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } @@ -3988,7 +3988,7 @@ zone_resigninc(dns_zone_t *zone) { result = dns_db_getsigningtime(db, &rdataset, name); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:dns_db_getsigningtime -> %s\n", + "zone_resigninc:dns_db_getsigningtime -> %s", dns_result_totext(result)); } @@ -4020,7 +4020,7 @@ zone_resigninc(dns_zone_t *zone) { zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:del_sigs -> %s\n", + "zone_resigninc:del_sigs -> %s", dns_result_totext(result)); break; } @@ -4029,7 +4029,7 @@ zone_resigninc(dns_zone_t *zone) { expire, check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:add_sigs -> %s\n", + "zone_resigninc:add_sigs -> %s", dns_result_totext(result)); break; } @@ -4041,7 +4041,7 @@ zone_resigninc(dns_zone_t *zone) { } if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:dns_db_getsigningtime -> %s\n", + "zone_resigninc:dns_db_getsigningtime -> %s", dns_result_totext(result)); } @@ -4052,7 +4052,7 @@ zone_resigninc(dns_zone_t *zone) { &sig_diff, zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:del_sigs -> %s\n", + "zone_resigninc:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -4060,7 +4060,7 @@ zone_resigninc(dns_zone_t *zone) { result = increment_soa_serial(db, version, &sig_diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:increment_soa_serial -> %s\n", + "zone_resigninc:increment_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -4074,7 +4074,7 @@ zone_resigninc(dns_zone_t *zone) { soaexpire, check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:add_sigs -> %s\n", + "zone_resigninc:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -4086,7 +4086,7 @@ zone_resigninc(dns_zone_t *zone) { ISC_TRUE, &journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:dns_journal_open -> %s\n", + "zone_resigninc:dns_journal_open -> %s", dns_result_totext(result)); goto failure; } @@ -4095,7 +4095,7 @@ zone_resigninc(dns_zone_t *zone) { dns_journal_destroy(&journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:dns_journal_write_transaction -> %s\n", + "zone_resigninc:dns_journal_write_transaction -> %s", dns_result_totext(result)); goto failure; } @@ -4790,7 +4790,7 @@ zone_nsec3chain(dns_zone_t *zone) { result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:dns_db_newversion -> %s\n", + "zone_nsec3chain:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -4799,7 +4799,7 @@ zone_nsec3chain(dns_zone_t *zone) { DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:find_zone_keys -> %s\n", + "zone_nsec3chain:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } @@ -4993,7 +4993,7 @@ zone_nsec3chain(dns_zone_t *zone) { } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_dbiterator_next -> %s\n", + "dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { @@ -5155,7 +5155,7 @@ zone_nsec3chain(dns_zone_t *zone) { } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_dbiterator_next -> %s\n", + "dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { @@ -5196,7 +5196,7 @@ zone_nsec3chain(dns_zone_t *zone) { zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:del_sigs -> %s\n", + "zone_nsec3chain:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5206,7 +5206,7 @@ zone_nsec3chain(dns_zone_t *zone) { check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:add_sigs -> %s\n", + "zone_nsec3chain:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5235,7 +5235,7 @@ zone_nsec3chain(dns_zone_t *zone) { zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:del_sigs -> %s\n", + "zone_nsec3chain:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5245,7 +5245,7 @@ zone_nsec3chain(dns_zone_t *zone) { expire, check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:add_sigs -> %s\n", + "zone_nsec3chain:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5266,7 +5266,7 @@ zone_nsec3chain(dns_zone_t *zone) { zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:del_sigs -> %s\n", + "zone_nsec3chain:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5276,7 +5276,7 @@ zone_nsec3chain(dns_zone_t *zone) { expire, check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_nsec3chain:add_sigs -> %s\n", + "zone_nsec3chain:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5296,14 +5296,14 @@ zone_nsec3chain(dns_zone_t *zone) { &sig_diff, zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "del_sigs -> %s\n", dns_result_totext(result)); + "del_sigs -> %s", dns_result_totext(result)); goto failure; } result = increment_soa_serial(db, version, &sig_diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "increment_soa_serial -> %s\n", + "increment_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -5313,7 +5313,7 @@ zone_nsec3chain(dns_zone_t *zone) { soaexpire, check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "add_sigs -> %s\n", dns_result_totext(result)); + "add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5324,7 +5324,7 @@ zone_nsec3chain(dns_zone_t *zone) { ISC_TRUE, &journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_journal_open -> %s\n", + "dns_journal_open -> %s", dns_result_totext(result)); goto failure; } @@ -5333,7 +5333,7 @@ zone_nsec3chain(dns_zone_t *zone) { dns_journal_destroy(&journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "dns_journal_write_transaction -> %s\n", + "dns_journal_write_transaction -> %s", dns_result_totext(result)); goto failure; } @@ -5574,7 +5574,7 @@ zone_sign(dns_zone_t *zone) { result = dns_db_newversion(db, &version); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:dns_db_newversion -> %s\n", + "zone_sign:dns_db_newversion -> %s", dns_result_totext(result)); goto failure; } @@ -5583,7 +5583,7 @@ zone_sign(dns_zone_t *zone) { DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:find_zone_keys -> %s\n", + "zone_sign:find_zone_keys -> %s", dns_result_totext(result)); goto failure; } @@ -5761,7 +5761,7 @@ zone_sign(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "updatesecure -> %s\n", + "updatesecure -> %s", dns_result_totext(result)); goto failure; } @@ -5772,14 +5772,14 @@ zone_sign(dns_zone_t *zone) { &sig_diff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "updatesignwithkey -> %s\n", + "updatesignwithkey -> %s", dns_result_totext(result)); goto failure; } goto next_signing; } else if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:dns_dbiterator_next -> %s\n", + "zone_sign:dns_dbiterator_next -> %s", dns_result_totext(result)); goto failure; } else if (delegation) { @@ -5809,7 +5809,7 @@ zone_sign(dns_zone_t *zone) { nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:del_sigs -> %s\n", + "zone_sign:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5819,7 +5819,7 @@ zone_sign(dns_zone_t *zone) { check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:add_sigs -> %s\n", + "zone_sign:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5835,7 +5835,7 @@ zone_sign(dns_zone_t *zone) { zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:del_sigs -> %s\n", + "zone_sign:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5845,7 +5845,7 @@ zone_sign(dns_zone_t *zone) { soaexpire, check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:add_sigs -> %s\n", + "zone_sign:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5863,7 +5863,7 @@ zone_sign(dns_zone_t *zone) { &sig_diff, zone_keys, nkeys, now); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:del_sigs -> %s\n", + "zone_sign:del_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5871,7 +5871,7 @@ zone_sign(dns_zone_t *zone) { result = increment_soa_serial(db, version, &sig_diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:increment_soa_serial -> %s\n", + "zone_sign:increment_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -5885,7 +5885,7 @@ zone_sign(dns_zone_t *zone) { soaexpire, check_ksk); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:add_sigs -> %s\n", + "zone_sign:add_sigs -> %s", dns_result_totext(result)); goto failure; } @@ -5900,7 +5900,7 @@ zone_sign(dns_zone_t *zone) { ISC_TRUE, &journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:dns_journal_open -> %s\n", + "zone_sign:dns_journal_open -> %s", dns_result_totext(result)); goto failure; } @@ -5909,7 +5909,7 @@ zone_sign(dns_zone_t *zone) { dns_journal_destroy(&journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:dns_journal_write_transaction -> %s\n", + "zone_sign:dns_journal_write_transaction -> %s", dns_result_totext(result)); goto failure; } |