summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Henderson <sthen@cvs.openbsd.org>2013-09-22 11:58:44 +0000
committerStuart Henderson <sthen@cvs.openbsd.org>2013-09-22 11:58:44 +0000
commit10c1827d4b55aefe78d87de1d175a77ac07c3ed6 (patch)
treed69757dde70e3229e09107d86a1e37a3de206ed2
parent090f474021a3c7c46dbe024f2db2fdde018645a8 (diff)
update to ldns 1.6.16
-rw-r--r--usr.sbin/unbound/ldns/Changelog48
-rw-r--r--usr.sbin/unbound/ldns/buffer.c3
-rw-r--r--usr.sbin/unbound/ldns/dane.c742
-rw-r--r--usr.sbin/unbound/ldns/dname.c93
-rw-r--r--usr.sbin/unbound/ldns/dnssec.c41
-rw-r--r--usr.sbin/unbound/ldns/dnssec_sign.c33
-rw-r--r--usr.sbin/unbound/ldns/dnssec_verify.c61
-rw-r--r--usr.sbin/unbound/ldns/dnssec_zone.c27
-rwxr-xr-xusr.sbin/unbound/ldns/doc/doxyparse.pl19
-rw-r--r--usr.sbin/unbound/ldns/doc/function_manpages5
-rw-r--r--usr.sbin/unbound/ldns/drill/Makefile.in8
-rw-r--r--usr.sbin/unbound/ldns/drill/chasetrace.c14
-rw-r--r--usr.sbin/unbound/ldns/drill/config.h.in3
-rwxr-xr-xusr.sbin/unbound/ldns/drill/configure56
-rw-r--r--usr.sbin/unbound/ldns/drill/configure.ac26
-rw-r--r--usr.sbin/unbound/ldns/drill/dnssec.c107
-rw-r--r--usr.sbin/unbound/ldns/drill/drill.1.in242
-rw-r--r--usr.sbin/unbound/ldns/drill/drill.c30
-rw-r--r--usr.sbin/unbound/ldns/drill/drill.h1
-rw-r--r--usr.sbin/unbound/ldns/drill/drill_util.c32
-rw-r--r--usr.sbin/unbound/ldns/drill/drill_util.h7
-rw-r--r--usr.sbin/unbound/ldns/drill/securetrace.c4
-rw-r--r--usr.sbin/unbound/ldns/drill/work.c26
-rw-r--r--usr.sbin/unbound/ldns/error.c29
-rw-r--r--usr.sbin/unbound/ldns/higher.c1
-rw-r--r--usr.sbin/unbound/ldns/host2str.c112
-rw-r--r--usr.sbin/unbound/ldns/host2wire.c48
-rw-r--r--usr.sbin/unbound/ldns/keys.c50
-rw-r--r--usr.sbin/unbound/ldns/ldns/buffer.h5
-rw-r--r--usr.sbin/unbound/ldns/ldns/common.h.in5
-rw-r--r--usr.sbin/unbound/ldns/ldns/config.h.in15
-rw-r--r--usr.sbin/unbound/ldns/ldns/dane.h244
-rw-r--r--usr.sbin/unbound/ldns/ldns/dname.h9
-rw-r--r--usr.sbin/unbound/ldns/ldns/dnssec.h1
-rw-r--r--usr.sbin/unbound/ldns/ldns/dnssec_verify.h1
-rw-r--r--usr.sbin/unbound/ldns/ldns/dnssec_zone.h1
-rw-r--r--usr.sbin/unbound/ldns/ldns/error.h17
-rw-r--r--usr.sbin/unbound/ldns/ldns/host2str.h18
-rw-r--r--usr.sbin/unbound/ldns/ldns/keys.h22
-rw-r--r--usr.sbin/unbound/ldns/ldns/ldns.h1
-rw-r--r--usr.sbin/unbound/ldns/ldns/rdata.h2
-rw-r--r--usr.sbin/unbound/ldns/ldns/resolver.h4
-rw-r--r--usr.sbin/unbound/ldns/ldns/rr.h4
-rw-r--r--usr.sbin/unbound/ldns/ldns/util.h.in2
-rw-r--r--usr.sbin/unbound/ldns/libdns.doxygen189
-rw-r--r--usr.sbin/unbound/ldns/net.c17
-rw-r--r--usr.sbin/unbound/ldns/packet.c136
-rw-r--r--usr.sbin/unbound/ldns/parse.c4
-rw-r--r--usr.sbin/unbound/ldns/resolver.c59
-rw-r--r--usr.sbin/unbound/ldns/rr.c32
-rw-r--r--usr.sbin/unbound/ldns/str2host.c5
-rw-r--r--usr.sbin/unbound/ldns/tsig.c12
-rw-r--r--usr.sbin/unbound/ldns/util.c9
53 files changed, 2271 insertions, 411 deletions
diff --git a/usr.sbin/unbound/ldns/Changelog b/usr.sbin/unbound/ldns/Changelog
index 93e53931d84..845d5b8a738 100644
--- a/usr.sbin/unbound/ldns/Changelog
+++ b/usr.sbin/unbound/ldns/Changelog
@@ -1,3 +1,51 @@
+1.6.16 2012-11-13
+ * Fix Makefile to build pyldns with BSD make
+ * Fix typo in exporting b32_* symbols to make pyldns load again
+ * Allow leaving the RR owner name empty in ldns-testns datafiles.
+ * Fix fail to create NSEC3 bitmap for empty non-terminal (bug
+ introduced in 1.6.14).
+
+1.6.15 2012-10-25
+ * Remove LDNS_STATUS_EXISTS_ERR from ldns/error.h to make ldns
+ binary compatible with earlier releases again.
+
+1.6.14 2012-10-23
+ * DANE support (RFC6698), including ldns-dane example tool.
+ * Configurable default CA certificate repository for ldns-dane with
+ --with-ca-file=CAFILE and --with-ca-path=CAPATH
+ * Configurable default trust anchor with --with-trust-anchor=FILE
+ for drill, ldns-verify-zone and ldns-dane
+ * bugfix #474: Define socklen_t when undefined (like in Win32)
+ * bugfix #473: Dead code removal and resource leak fix in drill
+ * bugfix #471: Let ldns_resolver_push_dnssec_anchor accept DS RR's too.
+ * Various bugfixes from code reviews from CZ.NIC and Paul Wouters
+ * ldns-notify TSIG option argument checking
+ * Let ldns_resolver_nameservers_randomize keep nameservers and rtt's
+ in sync.
+ * Let ldns_pkt_push_rr now return false on (memory) errors.
+ * Make buffer_export comply to documentation and fix buffer2str
+ * Various improvements and fixes of pyldns from Katel Slany
+ now documented in their own Changelog.
+ * bugfix: Make ldns_resolver_pop_nameserver clear the array when
+ there was only one.
+ * bugfix #459: Remove ldns_symbols and export symbols based on regex
+ * bugfix #458: Track all newly created signatures when signing.
+ * bugfix #454: Only set -g and -O2 CFLAGS when no CFLAGS was given.
+ * bugfix #457: Memory leak fix for ldns_key_new_frm_algorithm.
+ * 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.
+ * bugfix #449: Deep free cloned rdf's in ldns_tsig_mac_new.
+ * bugfix #448: Copy nameserver value (in stead of reference) of the
+ answering nameserver to the answer packet in ldns_send_buffer, so
+ the original value may be deep freed with the ldns_resolver struct.
+ * New -0 option for ldns-read-zone to replace inception, expiration
+ and signature rdata fields with (null). Thanks Paul Wouters.
+ * New -p option for ldns-read-zone to prepend-pad SOA serial to take
+ up ten characters.
+ * Return error if printing RR fails due to unknown/null RDATA.
+
1.6.13 2012-05-21
* New -S option for ldns-verify-zone to chase signatures online.
* New -k option for ldns-verify-zone to validate using a trusted key.
diff --git a/usr.sbin/unbound/ldns/buffer.c b/usr.sbin/unbound/ldns/buffer.c
index 5a6b0ba74c8..fc6c17e7a9f 100644
--- a/usr.sbin/unbound/ldns/buffer.c
+++ b/usr.sbin/unbound/ldns/buffer.c
@@ -140,7 +140,8 @@ ldns_buffer_free(ldns_buffer *buffer)
return;
}
- LDNS_FREE(buffer->_data);
+ if (!buffer->_fixed)
+ LDNS_FREE(buffer->_data);
LDNS_FREE(buffer);
}
diff --git a/usr.sbin/unbound/ldns/dane.c b/usr.sbin/unbound/ldns/dane.c
new file mode 100644
index 00000000000..793005ddcb3
--- /dev/null
+++ b/usr.sbin/unbound/ldns/dane.c
@@ -0,0 +1,742 @@
+/*
+ * Verify or create TLS authentication with DANE (RFC6698)
+ *
+ * (c) NLnetLabs 2012
+ *
+ * See the file LICENSE for the license.
+ *
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+#include <ldns/dane.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#ifdef HAVE_SSL
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#endif
+
+ldns_status
+ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner, const ldns_rdf* name,
+ uint16_t port, ldns_dane_transport transport)
+{
+ char buf[LDNS_MAX_DOMAINLEN];
+ size_t s;
+
+ assert(tlsa_owner != NULL);
+ assert(name != NULL);
+ assert(ldns_rdf_get_type(name) == LDNS_RDF_TYPE_DNAME);
+
+ s = (size_t)snprintf(buf, LDNS_MAX_DOMAINLEN, "X_%d", (int)port);
+ buf[0] = (char)(s - 1);
+
+ switch(transport) {
+ case LDNS_DANE_TRANSPORT_TCP:
+ s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_tcp");
+ break;
+
+ case LDNS_DANE_TRANSPORT_UDP:
+ s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_udp");
+ break;
+
+ case LDNS_DANE_TRANSPORT_SCTP:
+ s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\005_sctp");
+ break;
+
+ default:
+ return LDNS_STATUS_DANE_UNKNOWN_TRANSPORT;
+ }
+ if (s + ldns_rdf_size(name) > LDNS_MAX_DOMAINLEN) {
+ return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+ }
+ memcpy(buf + s, ldns_rdf_data(name), ldns_rdf_size(name));
+ *tlsa_owner = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
+ s + ldns_rdf_size(name), buf);
+ if (*tlsa_owner == NULL) {
+ return LDNS_STATUS_MEM_ERR;
+ }
+ return LDNS_STATUS_OK;
+}
+
+
+#ifdef HAVE_SSL
+ldns_status
+ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
+ ldns_tlsa_selector selector,
+ ldns_tlsa_matching_type matching_type)
+{
+ unsigned char* buf = NULL;
+ size_t len;
+
+ X509_PUBKEY* xpubkey;
+ EVP_PKEY* epubkey;
+
+ unsigned char* digest;
+
+ assert(rdf != NULL);
+ assert(cert != NULL);
+
+ switch(selector) {
+ case LDNS_TLSA_SELECTOR_FULL_CERTIFICATE:
+
+ len = (size_t)i2d_X509(cert, &buf);
+ break;
+
+ case LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO:
+
+#ifndef S_SPLINT_S
+ xpubkey = X509_get_X509_PUBKEY(cert);
+#endif
+ if (! xpubkey) {
+ return LDNS_STATUS_SSL_ERR;
+ }
+ epubkey = X509_PUBKEY_get(xpubkey);
+ if (! epubkey) {
+ return LDNS_STATUS_SSL_ERR;
+ }
+ len = (size_t)i2d_PUBKEY(epubkey, &buf);
+ break;
+
+ default:
+ return LDNS_STATUS_DANE_UNKNOWN_SELECTOR;
+ }
+
+ switch(matching_type) {
+ case LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED:
+
+ *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, len, buf);
+
+ return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+ break;
+
+ case LDNS_TLSA_MATCHING_TYPE_SHA256:
+
+ digest = LDNS_XMALLOC(unsigned char, SHA256_DIGEST_LENGTH);
+ if (digest == NULL) {
+ LDNS_FREE(buf);
+ return LDNS_STATUS_MEM_ERR;
+ }
+ (void) ldns_sha256(buf, (unsigned int)len, digest);
+ *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA256_DIGEST_LENGTH,
+ digest);
+ LDNS_FREE(buf);
+
+ return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+ break;
+
+ case LDNS_TLSA_MATCHING_TYPE_SHA512:
+
+ digest = LDNS_XMALLOC(unsigned char, SHA512_DIGEST_LENGTH);
+ if (digest == NULL) {
+ LDNS_FREE(buf);
+ return LDNS_STATUS_MEM_ERR;
+ }
+ (void) ldns_sha512(buf, (unsigned int)len, digest);
+ *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA512_DIGEST_LENGTH,
+ digest);
+ LDNS_FREE(buf);
+
+ return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+ break;
+
+ default:
+ LDNS_FREE(buf);
+ return LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE;
+ }
+}
+
+
+/* Ordinary PKIX validation of cert (with extra_certs to help)
+ * against the CA's in store
+ */
+static ldns_status
+ldns_dane_pkix_validate(X509* cert, STACK_OF(X509)* extra_certs,
+ X509_STORE* store)
+{
+ X509_STORE_CTX* vrfy_ctx;
+ ldns_status s;
+
+ if (! store) {
+ return LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+ }
+ vrfy_ctx = X509_STORE_CTX_new();
+ if (! vrfy_ctx) {
+
+ return LDNS_STATUS_SSL_ERR;
+
+ } else if (X509_STORE_CTX_init(vrfy_ctx, store,
+ cert, extra_certs) != 1) {
+ s = LDNS_STATUS_SSL_ERR;
+
+ } else if (X509_verify_cert(vrfy_ctx) == 1) {
+
+ s = LDNS_STATUS_OK;
+
+ } else {
+ s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+ }
+ X509_STORE_CTX_free(vrfy_ctx);
+ return s;
+}
+
+
+/* Orinary PKIX validation of cert (with extra_certs to help)
+ * against the CA's in store, but also return the validation chain.
+ */
+static ldns_status
+ldns_dane_pkix_validate_and_get_chain(STACK_OF(X509)** chain, X509* cert,
+ STACK_OF(X509)* extra_certs, X509_STORE* store)
+{
+ ldns_status s;
+ X509_STORE* empty_store = NULL;
+ X509_STORE_CTX* vrfy_ctx;
+
+ assert(chain != NULL);
+
+ if (! store) {
+ store = empty_store = X509_STORE_new();
+ }
+ s = LDNS_STATUS_SSL_ERR;
+ vrfy_ctx = X509_STORE_CTX_new();
+ if (! vrfy_ctx) {
+
+ goto exit_free_empty_store;
+
+ } else if (X509_STORE_CTX_init(vrfy_ctx, store,
+ cert, extra_certs) != 1) {
+ goto exit_free_vrfy_ctx;
+
+ } else if (X509_verify_cert(vrfy_ctx) == 1) {
+
+ s = LDNS_STATUS_OK;
+
+ } else {
+ s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+ }
+ *chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
+ if (! *chain) {
+ s = LDNS_STATUS_SSL_ERR;
+ }
+
+exit_free_vrfy_ctx:
+ X509_STORE_CTX_free(vrfy_ctx);
+
+exit_free_empty_store:
+ if (empty_store) {
+ X509_STORE_free(empty_store);
+ }
+ return s;
+}
+
+
+/* Return the validation chain that can be build out of cert, with extra_certs.
+ */
+static ldns_status
+ldns_dane_pkix_get_chain(STACK_OF(X509)** chain,
+ X509* cert, STACK_OF(X509)* extra_certs)
+{
+ ldns_status s;
+ X509_STORE* empty_store = NULL;
+ X509_STORE_CTX* vrfy_ctx;
+
+ assert(chain != NULL);
+
+ empty_store = X509_STORE_new();
+ s = LDNS_STATUS_SSL_ERR;
+ vrfy_ctx = X509_STORE_CTX_new();
+ if (! vrfy_ctx) {
+
+ goto exit_free_empty_store;
+
+ } else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
+ cert, extra_certs) != 1) {
+ goto exit_free_vrfy_ctx;
+ }
+ (void) X509_verify_cert(vrfy_ctx);
+ *chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
+ if (! *chain) {
+ s = LDNS_STATUS_SSL_ERR;
+ } else {
+ s = LDNS_STATUS_OK;
+ }
+exit_free_vrfy_ctx:
+ X509_STORE_CTX_free(vrfy_ctx);
+
+exit_free_empty_store:
+ X509_STORE_free(empty_store);
+ return s;
+}
+
+
+/* Pop n+1 certs and return the last popped.
+ */
+static ldns_status
+ldns_dane_get_nth_cert_from_validation_chain(
+ X509** cert, STACK_OF(X509)* chain, int n, bool ca)
+{
+ if (n >= sk_X509_num(chain) || n < 0) {
+ return LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE;
+ }
+ *cert = sk_X509_pop(chain);
+ while (n-- > 0) {
+ X509_free(*cert);
+ *cert = sk_X509_pop(chain);
+ }
+ if (ca && ! X509_check_ca(*cert)) {
+ return LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
+ }
+ return LDNS_STATUS_OK;
+}
+
+
+/* Create validation chain with cert and extra_certs and returns the last
+ * self-signed (if present).
+ */
+static ldns_status
+ldns_dane_pkix_get_last_self_signed(X509** out_cert,
+ X509* cert, STACK_OF(X509)* extra_certs)
+{
+ ldns_status s;
+ X509_STORE* empty_store = NULL;
+ X509_STORE_CTX* vrfy_ctx;
+
+ assert(out_cert != NULL);
+
+ empty_store = X509_STORE_new();
+ s = LDNS_STATUS_SSL_ERR;
+ vrfy_ctx = X509_STORE_CTX_new();
+ if (! vrfy_ctx) {
+ goto exit_free_empty_store;
+
+ } else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
+ cert, extra_certs) != 1) {
+ goto exit_free_vrfy_ctx;
+
+ }
+ (void) X509_verify_cert(vrfy_ctx);
+ if (vrfy_ctx->error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
+ vrfy_ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT){
+
+ *out_cert = X509_STORE_CTX_get_current_cert( vrfy_ctx);
+ s = LDNS_STATUS_OK;
+ } else {
+ s = LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR;
+ }
+exit_free_vrfy_ctx:
+ X509_STORE_CTX_free(vrfy_ctx);
+
+exit_free_empty_store:
+ X509_STORE_free(empty_store);
+ return s;
+}
+
+
+ldns_status
+ldns_dane_select_certificate(X509** selected_cert,
+ X509* cert, STACK_OF(X509)* extra_certs,
+ X509_STORE* pkix_validation_store,
+ ldns_tlsa_certificate_usage cert_usage, int offset)
+{
+ ldns_status s;
+ STACK_OF(X509)* pkix_validation_chain = NULL;
+
+ assert(selected_cert != NULL);
+ assert(cert != NULL);
+
+ /* With PKIX validation explicitely turned off (pkix_validation_store
+ * == NULL), treat the "CA constraint" and "Service certificate
+ * constraint" the same as "Trust anchor assertion" and "Domain issued
+ * certificate" respectively.
+ */
+ if (pkix_validation_store == NULL) {
+ switch (cert_usage) {
+
+ case LDNS_TLSA_USAGE_CA_CONSTRAINT:
+
+ cert_usage = LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION;
+ break;
+
+ case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
+
+ cert_usage = LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Now what to do with each Certificate usage...
+ */
+ switch (cert_usage) {
+
+ case LDNS_TLSA_USAGE_CA_CONSTRAINT:
+
+ s = ldns_dane_pkix_validate_and_get_chain(
+ &pkix_validation_chain,
+ cert, extra_certs,
+ pkix_validation_store);
+ if (! pkix_validation_chain) {
+ return s;
+ }
+ if (s == LDNS_STATUS_OK) {
+ if (offset == -1) {
+ offset = 0;
+ }
+ s = ldns_dane_get_nth_cert_from_validation_chain(
+ selected_cert, pkix_validation_chain,
+ offset, true);
+ }
+ sk_X509_pop_free(pkix_validation_chain, X509_free);
+ return s;
+ break;
+
+
+ case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
+
+ *selected_cert = cert;
+ return ldns_dane_pkix_validate(cert, extra_certs,
+ pkix_validation_store);
+ break;
+
+
+ case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
+
+ if (offset == -1) {
+ s = ldns_dane_pkix_get_last_self_signed(
+ selected_cert, cert, extra_certs);
+ return s;
+ } else {
+ s = ldns_dane_pkix_get_chain(
+ &pkix_validation_chain,
+ cert, extra_certs);
+ if (s == LDNS_STATUS_OK) {
+ s =
+ ldns_dane_get_nth_cert_from_validation_chain(
+ selected_cert, pkix_validation_chain,
+ offset, false);
+ } else if (! pkix_validation_chain) {
+ return s;
+ }
+ sk_X509_pop_free(pkix_validation_chain, X509_free);
+ return s;
+ }
+ break;
+
+
+ case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
+
+ *selected_cert = cert;
+ return LDNS_STATUS_OK;
+ break;
+
+ default:
+ return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
+ break;
+ }
+}
+
+
+ldns_status
+ldns_dane_create_tlsa_rr(ldns_rr** tlsa,
+ ldns_tlsa_certificate_usage certificate_usage,
+ ldns_tlsa_selector selector,
+ ldns_tlsa_matching_type matching_type,
+ X509* cert)
+{
+ ldns_rdf* rdf;
+ ldns_status s;
+
+ assert(tlsa != NULL);
+ assert(cert != NULL);
+
+ /* create rr */
+ *tlsa = ldns_rr_new_frm_type(LDNS_RR_TYPE_TLSA);
+ if (*tlsa == NULL) {
+ return LDNS_STATUS_MEM_ERR;
+ }
+
+ rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
+ (uint8_t)certificate_usage);
+ if (rdf == NULL) {
+ goto memerror;
+ }
+ (void) ldns_rr_set_rdf(*tlsa, rdf, 0);
+
+ rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)selector);
+ if (rdf == NULL) {
+ goto memerror;
+ }
+ (void) ldns_rr_set_rdf(*tlsa, rdf, 1);
+
+ rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)matching_type);
+ if (rdf == NULL) {
+ goto memerror;
+ }
+ (void) ldns_rr_set_rdf(*tlsa, rdf, 2);
+
+ s = ldns_dane_cert2rdf(&rdf, cert, selector, matching_type);
+ if (s == LDNS_STATUS_OK) {
+ (void) ldns_rr_set_rdf(*tlsa, rdf, 3);
+ return LDNS_STATUS_OK;
+ }
+ ldns_rr_free(*tlsa);
+ *tlsa = NULL;
+ return s;
+
+memerror:
+ ldns_rr_free(*tlsa);
+ *tlsa = NULL;
+ return LDNS_STATUS_MEM_ERR;
+}
+
+
+/* Return tlsas that actually are TLSA resource records with known values
+ * for the Certificate usage, Selector and Matching type rdata fields.
+ */
+static ldns_rr_list*
+ldns_dane_filter_unusable_records(const ldns_rr_list* tlsas)
+{
+ size_t i;
+ ldns_rr_list* r = ldns_rr_list_new();
+ ldns_rr* tlsa_rr;
+
+ if (! r) {
+ return NULL;
+ }
+ for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
+ tlsa_rr = ldns_rr_list_rr(tlsas, i);
+ if (ldns_rr_get_type(tlsa_rr) == LDNS_RR_TYPE_TLSA &&
+ ldns_rr_rd_count(tlsa_rr) == 4 &&
+ ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0)) <= 3 &&
+ ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1)) <= 1 &&
+ ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2)) <= 2) {
+
+ if (! ldns_rr_list_push_rr(r, tlsa_rr)) {
+ ldns_rr_list_free(r);
+ return NULL;
+ }
+ }
+ }
+ return r;
+}
+
+
+/* Return whether cert/selector/matching_type matches data.
+ */
+static ldns_status
+ldns_dane_match_cert_with_data(X509* cert, ldns_tlsa_selector selector,
+ ldns_tlsa_matching_type matching_type, ldns_rdf* data)
+{
+ ldns_status s;
+ ldns_rdf* match_data;
+
+ s = ldns_dane_cert2rdf(&match_data, cert, selector, matching_type);
+ if (s == LDNS_STATUS_OK) {
+ if (ldns_rdf_compare(data, match_data) != 0) {
+ s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
+ }
+ ldns_rdf_free(match_data);
+ }
+ return s;
+}
+
+
+/* Return whether any certificate from the chain with selector/matching_type
+ * matches data.
+ * ca should be true if the certificate has to be a CA certificate too.
+ */
+static ldns_status
+ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain,
+ ldns_tlsa_selector selector,
+ ldns_tlsa_matching_type matching_type,
+ ldns_rdf* data, bool ca)
+{
+ ldns_status s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
+ size_t n, i;
+ X509* cert;
+
+ n = (size_t)sk_X509_num(chain);
+ for (i = 0; i < n; i++) {
+ cert = sk_X509_pop(chain);
+ if (! cert) {
+ s = LDNS_STATUS_SSL_ERR;
+ break;
+ }
+ s = ldns_dane_match_cert_with_data(cert,
+ selector, matching_type, data);
+ if (ca && s == LDNS_STATUS_OK && ! X509_check_ca(cert)) {
+ s = LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
+ }
+ X509_free(cert);
+ if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH) {
+ break;
+ }
+ /* when s == LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
+ * try to match the next certificate
+ */
+ }
+ return s;
+}
+
+
+ldns_status
+ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
+ X509* cert, STACK_OF(X509)* extra_certs,
+ X509_STORE* pkix_validation_store)
+{
+ ldns_status s;
+
+ STACK_OF(X509)* pkix_validation_chain = NULL;
+
+ ldns_tlsa_certificate_usage cert_usage;
+ ldns_tlsa_selector selector;
+ ldns_tlsa_matching_type matching_type;
+ ldns_rdf* data;
+
+ if (! tlsa_rr) {
+ /* No TLSA, so regular PKIX validation
+ */
+ return ldns_dane_pkix_validate(cert, extra_certs,
+ pkix_validation_store);
+ }
+ cert_usage = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0));
+ selector = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1));
+ matching_type = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2));
+ data = ldns_rr_rdf(tlsa_rr, 3) ;
+
+ switch (cert_usage) {
+ case LDNS_TLSA_USAGE_CA_CONSTRAINT:
+ s = ldns_dane_pkix_validate_and_get_chain(
+ &pkix_validation_chain,
+ cert, extra_certs,
+ pkix_validation_store);
+ if (! pkix_validation_chain) {
+ return s;
+ }
+ if (s == LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
+ /*
+ * NO PKIX validation. We still try to match *any*
+ * certificate from the chain, so we return
+ * TLSA errors over PKIX errors.
+ *
+ * i.e. When the TLSA matches no certificate, we return
+ * TLSA_DID_NOT_MATCH and not PKIX_DID_NOT_VALIDATE
+ */
+ s = ldns_dane_match_any_cert_with_data(
+ pkix_validation_chain,
+ selector, matching_type, data, true);
+
+ if (s == LDNS_STATUS_OK) {
+ /* A TLSA record did match a cert from the
+ * chain, thus the error is failed PKIX
+ * validation.
+ */
+ s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+ }
+
+ } else if (s == LDNS_STATUS_OK) {
+ /* PKIX validated, does the TLSA match too? */
+
+ s = ldns_dane_match_any_cert_with_data(
+ pkix_validation_chain,
+ selector, matching_type, data, true);
+ }
+ sk_X509_pop_free(pkix_validation_chain, X509_free);
+ return s;
+ break;
+
+ case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
+ s = ldns_dane_match_cert_with_data(cert,
+ selector, matching_type, data);
+
+ if (s == LDNS_STATUS_OK) {
+ return ldns_dane_pkix_validate(cert, extra_certs,
+ pkix_validation_store);
+ }
+ return s;
+ break;
+
+ case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
+ s = ldns_dane_pkix_get_chain(&pkix_validation_chain,
+ cert, extra_certs);
+
+ if (s == LDNS_STATUS_OK) {
+ s = ldns_dane_match_any_cert_with_data(
+ pkix_validation_chain,
+ selector, matching_type, data, false);
+
+ } else if (! pkix_validation_chain) {
+ return s;
+ }
+ sk_X509_pop_free(pkix_validation_chain, X509_free);
+ return s;
+ break;
+
+ case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
+ return ldns_dane_match_cert_with_data(cert,
+ selector, matching_type, data);
+ break;
+
+ default:
+ break;
+ }
+ return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
+}
+
+
+ldns_status
+ldns_dane_verify(ldns_rr_list* tlsas,
+ X509* cert, STACK_OF(X509)* extra_certs,
+ X509_STORE* pkix_validation_store)
+{
+ size_t i;
+ ldns_rr* tlsa_rr;
+ ldns_status s = LDNS_STATUS_OK, ps;
+
+ assert(cert != NULL);
+
+ if (tlsas && ldns_rr_list_rr_count(tlsas) > 0) {
+ tlsas = ldns_dane_filter_unusable_records(tlsas);
+ if (! tlsas) {
+ return LDNS_STATUS_MEM_ERR;
+ }
+ }
+ if (! tlsas || ldns_rr_list_rr_count(tlsas) == 0) {
+ /* No TLSA's, so regular PKIX validation
+ */
+ return ldns_dane_pkix_validate(cert, extra_certs,
+ pkix_validation_store);
+ } else {
+ for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
+ tlsa_rr = ldns_rr_list_rr(tlsas, i);
+ ps = s;
+ s = ldns_dane_verify_rr(tlsa_rr, cert, extra_certs,
+ pkix_validation_store);
+
+ if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH &&
+ s != LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
+
+ /* which would be LDNS_STATUS_OK (match)
+ * or some fatal error preventing use from
+ * trying the next TLSA record.
+ */
+ break;
+ }
+ s = (s > ps ? s : ps); /* prefer PKIX_DID_NOT_VALIDATE
+ * over TLSA_DID_NOT_MATCH
+ */
+ }
+ ldns_rr_list_free(tlsas);
+ }
+ return s;
+}
+#endif /* HAVE_SSL */
diff --git a/usr.sbin/unbound/ldns/dname.c b/usr.sbin/unbound/ldns/dname.c
index f3770feafb5..55aba5d65a1 100644
--- a/usr.sbin/unbound/ldns/dname.c
+++ b/usr.sbin/unbound/ldns/dname.c
@@ -30,6 +30,24 @@
#include <arpa/inet.h>
#endif
+/* Returns whether the last label in the name is a root label (a empty label).
+ * Note that it is not enough to just test the last character to be 0,
+ * because it may be part of the last label itself.
+ */
+static bool
+ldns_dname_last_label_is_root_label(const ldns_rdf* dname)
+{
+ size_t src_pos;
+ size_t len = 0;
+
+ for (src_pos = 0; src_pos < ldns_rdf_size(dname); src_pos += len + 1) {
+ len = ldns_rdf_data(dname)[src_pos];
+ }
+ assert(src_pos == ldns_rdf_size(dname));
+
+ return src_pos > 0 && len == 0;
+}
+
ldns_rdf *
ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
{
@@ -47,7 +65,7 @@ ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
* rd, by reducing the size with 1
*/
left_size = ldns_rdf_size(rd1);
- if (left_size > 0 &&ldns_rdf_data(rd1)[left_size - 1] == 0) {
+ if (ldns_dname_last_label_is_root_label(rd1)) {
left_size--;
}
@@ -84,7 +102,7 @@ ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
* rd, by reducing the size with 1
*/
left_size = ldns_rdf_size(rd1);
- if (left_size > 0 &&ldns_rdf_data(rd1)[left_size - 1] == 0) {
+ if (ldns_dname_last_label_is_root_label(rd1)) {
left_size--;
}
@@ -102,36 +120,39 @@ ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
return LDNS_STATUS_OK;
}
-ldns_rdf *
-ldns_dname_reverse(const ldns_rdf *d)
+ldns_rdf*
+ldns_dname_reverse(const ldns_rdf *dname)
{
- ldns_rdf *new;
- ldns_rdf *tmp;
- ldns_rdf *d_tmp;
- ldns_status status;
-
- d_tmp = ldns_rdf_clone(d);
-
- new = ldns_dname_new_frm_str(".");
- if(!new)
- return NULL;
-
- while(ldns_dname_label_count(d_tmp) > 0) {
- tmp = ldns_dname_label(d_tmp, 0);
- status = ldns_dname_cat(tmp, new);
- if(status != LDNS_STATUS_OK) {
- ldns_rdf_deep_free(new);
- ldns_rdf_deep_free(d_tmp);
- return NULL;
- }
- ldns_rdf_deep_free(new);
- new = tmp;
- tmp = ldns_dname_left_chop(d_tmp);
- ldns_rdf_deep_free(d_tmp);
- d_tmp = tmp;
+ size_t rd_size;
+ uint8_t* buf;
+ ldns_rdf* new;
+ size_t src_pos;
+ size_t len ;
+
+ assert(ldns_rdf_get_type(dname) == LDNS_RDF_TYPE_DNAME);
+
+ rd_size = ldns_rdf_size(dname);
+ buf = LDNS_XMALLOC(uint8_t, rd_size);
+ if (! buf) {
+ return NULL;
+ }
+ new = ldns_rdf_new(LDNS_RDF_TYPE_DNAME, rd_size, buf);
+ if (! new) {
+ LDNS_FREE(buf);
+ return NULL;
+ }
+
+ /* If dname ends in a root label, the reverse should too.
+ */
+ if (ldns_dname_last_label_is_root_label(dname)) {
+ buf[rd_size - 1] = 0;
+ rd_size -= 1;
+ }
+ for (src_pos = 0; src_pos < rd_size; src_pos += len + 1) {
+ len = ldns_rdf_data(dname)[src_pos];
+ memcpy(&buf[rd_size - src_pos - len - 1],
+ &ldns_rdf_data(dname)[src_pos], len + 1);
}
- ldns_rdf_deep_free(d_tmp);
-
return new;
}
@@ -519,6 +540,18 @@ ldns_dname_str_absolute(const char *dname_str)
return 0;
}
+bool
+ldns_dname_absolute(const ldns_rdf *rdf)
+{
+ char *str = ldns_rdf2str(rdf);
+ if (str) {
+ bool r = ldns_dname_str_absolute(str);
+ LDNS_FREE(str);
+ return r;
+ }
+ return false;
+}
+
ldns_rdf *
ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
{
diff --git a/usr.sbin/unbound/ldns/dnssec.c b/usr.sbin/unbound/ldns/dnssec.c
index c6e93211787..684d17169e2 100644
--- a/usr.sbin/unbound/ldns/dnssec.c
+++ b/usr.sbin/unbound/ldns/dnssec.c
@@ -743,7 +743,6 @@ ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
cur_data_size += cur_window_max + 3;
}
-
bitmap_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC,
cur_data_size,
data);
@@ -1154,12 +1153,15 @@ ldns_create_nsec3(ldns_rdf *cur_owner,
salt_length,
salt);
status = ldns_dname_cat(hashed_owner, cur_zone);
- if(status != LDNS_STATUS_OK)
+ if(status != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(hashed_owner);
return NULL;
-
+ }
nsec = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3);
- if(!nsec)
+ if(!nsec) {
+ ldns_rdf_deep_free(hashed_owner);
return NULL;
+ }
ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC3);
ldns_rr_set_owner(nsec, hashed_owner);
@@ -1443,8 +1445,9 @@ ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o,
sigs = s;
} else {
/* otherwise get them from the packet */
- sigs = ldns_pkt_rr_list_by_name_and_type(p, o, LDNS_RR_TYPE_RRSIG,
- LDNS_SECTION_ANY_NOQUESTION);
+ sigs = ldns_pkt_rr_list_by_name_and_type(p, o,
+ LDNS_RR_TYPE_RRSIG,
+ LDNS_SECTION_ANY_NOQUESTION);
if (!sigs) {
/* no sigs */
return LDNS_STATUS_ERR;
@@ -1457,24 +1460,26 @@ ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o,
*/
t_netorder = htons(t); /* rdf are in network order! */
/* a type identifier is a 16-bit number, so the size is 2 bytes */
- rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE,
- 2,
- &t_netorder);
- sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
+ rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, 2, &t_netorder);
- rrset = ldns_pkt_rr_list_by_name_and_type(p,
- o,
- t,
- LDNS_SECTION_ANY_NOQUESTION);
-
- if (!rrset) {
+ sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
+ ldns_rdf_free(rdf_t);
+ if (! sigs_covered) {
+ if (! s) {
+ ldns_rr_list_deep_free(sigs);
+ }
return LDNS_STATUS_ERR;
}
+ ldns_rr_list_deep_free(sigs_covered);
- if (!sigs_covered) {
+ rrset = ldns_pkt_rr_list_by_name_and_type(p, o, t,
+ LDNS_SECTION_ANY_NOQUESTION);
+ if (!rrset) {
+ if (! s) {
+ ldns_rr_list_deep_free(sigs);
+ }
return LDNS_STATUS_ERR;
}
-
return ldns_verify_time(rrset, sigs, k, check_time, good_keys);
}
diff --git a/usr.sbin/unbound/ldns/dnssec_sign.c b/usr.sbin/unbound/ldns/dnssec_sign.c
index 88878bad044..f2f9d9dda87 100644
--- a/usr.sbin/unbound/ldns/dnssec_sign.c
+++ b/usr.sbin/unbound/ldns/dnssec_sign.c
@@ -260,6 +260,8 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
ldns_buffer_free(sign_buf);
/* ERROR */
ldns_rr_list_deep_free(rrset_clone);
+ ldns_rr_free(current_sig);
+ ldns_rr_list_deep_free(signatures);
return NULL;
}
@@ -268,6 +270,8 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
!= LDNS_STATUS_OK) {
ldns_buffer_free(sign_buf);
ldns_rr_list_deep_free(rrset_clone);
+ ldns_rr_free(current_sig);
+ ldns_rr_list_deep_free(signatures);
return NULL;
}
@@ -276,6 +280,8 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
if (!b64rdf) {
/* signing went wrong */
ldns_rr_list_deep_free(rrset_clone);
+ ldns_rr_free(current_sig);
+ ldns_rr_list_deep_free(signatures);
return NULL;
}
@@ -481,10 +487,7 @@ ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
(unsigned char*)ldns_buffer_begin(b64sig),
&siglen, key);
if (result != 1) {
- return NULL;
- }
-
- if (result != 1) {
+ ldns_buffer_free(b64sig);
return NULL;
}
@@ -859,16 +862,14 @@ ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
ldns_rbtree_next(current_name_node));
}
if (result != LDNS_STATUS_OK) {
+ ldns_rr_list_free(nsec3_list);
return result;
}
ldns_rr_list_sort_nsec3(nsec3_list);
result = ldns_dnssec_chain_nsec3_list(nsec3_list);
- if (result != LDNS_STATUS_OK) {
- return result;
- }
-
ldns_rr_list_free(nsec3_list);
+
return result;
}
@@ -1023,9 +1024,9 @@ ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
}
ldns_status
-ldns_dnssec_zone_create_rrsigs_flg( ATTR_UNUSED(ldns_dnssec_zone *zone)
- , ATTR_UNUSED(ldns_rr_list *new_rrs)
- , ATTR_UNUSED(ldns_key_list *key_list)
+ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
+ , ldns_rr_list *new_rrs
+ , ldns_key_list *key_list
, int (*func)(ldns_rr *, void*)
, void *arg
, int flags
@@ -1112,9 +1113,11 @@ ldns_dnssec_zone_create_rrsigs_flg( ATTR_UNUSED(ldns_dnssec_zone *zone)
cur_rrset->signatures = ldns_dnssec_rrs_new();
cur_rrset->signatures->rr =
ldns_rr_list_rr(siglist, i);
+ }
+ if (new_rrs) {
ldns_rr_list_push_rr(new_rrs,
- ldns_rr_list_rr(siglist,
- i));
+ ldns_rr_list_rr(siglist,
+ i));
}
}
ldns_rr_list_free(siglist);
@@ -1146,8 +1149,10 @@ ldns_dnssec_zone_create_rrsigs_flg( ATTR_UNUSED(ldns_dnssec_zone *zone)
cur_name->nsec_signatures = ldns_dnssec_rrs_new();
cur_name->nsec_signatures->rr =
ldns_rr_list_rr(siglist, i);
+ }
+ if (new_rrs) {
ldns_rr_list_push_rr(new_rrs,
- ldns_rr_list_rr(siglist, i));
+ ldns_rr_list_rr(siglist, i));
}
}
diff --git a/usr.sbin/unbound/ldns/dnssec_verify.c b/usr.sbin/unbound/ldns/dnssec_verify.c
index 68c70c5e848..d435eedf6af 100644
--- a/usr.sbin/unbound/ldns/dnssec_verify.c
+++ b/usr.sbin/unbound/ldns/dnssec_verify.c
@@ -285,9 +285,11 @@ ldns_dnssec_build_data_chain(ldns_resolver *res,
ldns_rr_class c = 0;
bool other_rrset = false;
-
+
ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
+ assert(pkt != NULL);
+
if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
/* hmm. no dnssec data in the packet. go up to try and deny
* DS? */
@@ -402,15 +404,16 @@ ldns_dnssec_build_data_chain(ldns_resolver *res,
if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
}
-
if (!key_name) {
+ if (signatures) {
+ ldns_rr_list_deep_free(signatures);
+ }
return ldns_dnssec_build_data_chain_nokeyname(res,
qflags,
orig_rr,
rrset,
new_chain);
}
-
if (type != LDNS_RR_TYPE_DNSKEY) {
ldns_dnssec_build_data_chain_dnskey(res,
qflags,
@@ -419,7 +422,7 @@ ldns_dnssec_build_data_chain(ldns_resolver *res,
new_chain,
key_name,
c
- );
+ );
} else {
ldns_dnssec_build_data_chain_other(res,
qflags,
@@ -427,13 +430,11 @@ ldns_dnssec_build_data_chain(ldns_resolver *res,
key_name,
c,
dss
-
- );
+ );
}
if (signatures) {
ldns_rr_list_deep_free(signatures);
}
-
return new_chain;
}
@@ -826,10 +827,7 @@ ldns_dnssec_derive_trust_tree_normal_rrset_time(
/* might contain different names!
sort and split */
ldns_rr_list_sort(cur_rrset);
- if (tmp_rrset && tmp_rrset != cur_rrset) {
- ldns_rr_list_deep_free(tmp_rrset);
- tmp_rrset = NULL;
- }
+ assert(tmp_rrset == cur_rrset);
tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
/* with nsecs, this might be the wrong one */
@@ -849,6 +847,12 @@ ldns_dnssec_derive_trust_tree_normal_rrset_time(
cur_sig_rr,
cur_parent_rr,
check_time);
+ if (tmp_rrset && tmp_rrset != cur_rrset
+ ) {
+ ldns_rr_list_deep_free(
+ tmp_rrset);
+ tmp_rrset = NULL;
+ }
/* avoid dupes */
for (i = 0; i < new_tree->parent_count; i++) {
if (cur_parent_rr == new_tree->parents[i]->rr) {
@@ -870,9 +874,6 @@ ldns_dnssec_derive_trust_tree_normal_rrset_time(
}
}
done:
- if (tmp_rrset && tmp_rrset != cur_rrset) {
- ldns_rr_list_deep_free(tmp_rrset);
- }
ldns_rr_list_deep_free(cur_rrset);
}
@@ -1077,7 +1078,8 @@ ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
if (tree->parent_status[i] != LDNS_STATUS_OK) {
result = tree->parent_status[i];
} else {
- if (ldns_rr_get_type(tree->rr)
+ if (tree->rr &&
+ ldns_rr_get_type(tree->rr)
== LDNS_RR_TYPE_NSEC &&
parent_result == LDNS_STATUS_OK
) {
@@ -1210,8 +1212,8 @@ ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
parent_domain = ldns_dname_left_chop(domain);
- while (ldns_rdf_size(parent_domain) > 0) {
- /* Fail if we are at the root */
+ while (parent_domain && /* Fail if we are at the root*/
+ ldns_rdf_size(parent_domain) > 0) {
if ((parent_keys =
ldns_fetch_valid_domain_keys_time(res,
@@ -1247,7 +1249,9 @@ ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
ldns_rdf_deep_free(prev_parent_domain);
}
}
- ldns_rdf_deep_free(parent_domain);
+ if (parent_domain) {
+ ldns_rdf_deep_free(parent_domain);
+ }
}
}
return trusted_keys;
@@ -1519,12 +1523,11 @@ ldns_dnssec_verify_denial(ldns_rr *rr,
rr_name = ldns_rr_owner(rr);
chopped_dname = ldns_dname_left_chop(rr_name);
result = ldns_dname_cat(wildcard_name, chopped_dname);
+ ldns_rdf_deep_free(chopped_dname);
if (result != LDNS_STATUS_OK) {
return result;
}
- ldns_rdf_deep_free(chopped_dname);
-
for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
cur_nsec = ldns_rr_list_rr(nsecs, i);
if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
@@ -1576,7 +1579,6 @@ ldns_dnssec_verify_denial(ldns_rr *rr,
return LDNS_STATUS_OK;
}
-#ifdef HAVE_SSL
ldns_status
ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
, ldns_rr_list *nsecs
@@ -1612,7 +1614,7 @@ ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
ldns_rr_get_type(rr),
nsecs);
if(!closest_encloser) {
- result = LDNS_STATUS_NSEC3_ERR;
+ result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
goto done;
}
@@ -1636,16 +1638,14 @@ ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
ldns_rdf_deep_free(hashed_wildcard_name);
}
- ldns_rdf_deep_free(closest_encloser);
- ldns_rdf_deep_free(wildcard);
-
- if (!wildcard_covered) {
+ if (! wildcard_covered) {
result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
- } else if (closest_encloser && wildcard_covered) {
- result = LDNS_STATUS_OK;
} else {
- result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+ result = LDNS_STATUS_OK;
}
+ ldns_rdf_deep_free(closest_encloser);
+ ldns_rdf_deep_free(wildcard);
+
} else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
/* section 8.5 */
hashed_name = ldns_nsec3_hash_name_frm_nsec3(
@@ -1819,9 +1819,6 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
);
}
-
-#endif /* HAVE_SSL */
-
#ifdef USE_GOST
EVP_PKEY*
ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
diff --git a/usr.sbin/unbound/ldns/dnssec_zone.c b/usr.sbin/unbound/ldns/dnssec_zone.c
index 1f7274bbc96..df71a23c7ed 100644
--- a/usr.sbin/unbound/ldns/dnssec_zone.c
+++ b/usr.sbin/unbound/ldns/dnssec_zone.c
@@ -708,6 +708,7 @@ ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */
case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/
case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/
+ status = LDNS_STATUS_OK;
break;
case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
@@ -721,38 +722,42 @@ ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
if (ldns_rr_list_rr_count(todo_nsec3s) > 0) {
(void) ldns_dnssec_zone_add_empty_nonterminals(newzone);
- for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
+ for (i = 0; status == LDNS_STATUS_OK &&
+ i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
}
- for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){
+ for (i = 0; status == LDNS_STATUS_OK &&
+ i < ldns_rr_list_rr_count(todo_nsec3_rrsigs);
+ i++){
cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
}
} else if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) {
- for (i = 0; i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++){
+ for (i = 0; status == LDNS_STATUS_OK &&
+ i < ldns_rr_list_rr_count(todo_nsec3_rrsigs);
+ i++){
cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
}
}
- ldns_rr_list_free(todo_nsec3_rrsigs);
- ldns_rr_list_free(todo_nsec3s);
-
if (z) {
*z = newzone;
+ newzone = NULL;
} else {
ldns_dnssec_zone_free(newzone);
}
- return LDNS_STATUS_OK;
-
error:
#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
if (zone) {
ldns_zone_free(zone);
}
#endif
+ ldns_rr_list_free(todo_nsec3_rrsigs);
+ ldns_rr_list_free(todo_nsec3s);
+
if (my_origin) {
ldns_rdf_deep_free(my_origin);
}
@@ -822,7 +827,6 @@ ldns_dname_compare_v(const void *a, const void *b) {
return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
}
-#ifdef HAVE_SSL
ldns_rbnode_t *
ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone,
ldns_rr *rr) {
@@ -912,7 +916,6 @@ ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
return result;
}
-#endif /* HAVE_SSL */
void
ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
@@ -1009,7 +1012,9 @@ ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
if (next_node == LDNS_RBTREE_NULL) {
next_node = ldns_rbtree_first(zone->names);
}
-
+ if (! cur_node->data || ! next_node->data) {
+ return LDNS_STATUS_ERR;
+ }
cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
next_name = ((ldns_dnssec_name *)next_node->data)->name;
cur_label_count = ldns_dname_label_count(cur_name);
diff --git a/usr.sbin/unbound/ldns/doc/doxyparse.pl b/usr.sbin/unbound/ldns/doc/doxyparse.pl
index 526c617101b..96a1732f9ed 100755
--- a/usr.sbin/unbound/ldns/doc/doxyparse.pl
+++ b/usr.sbin/unbound/ldns/doc/doxyparse.pl
@@ -87,7 +87,7 @@ if (defined $options{'m'}) {
# 0 - somewhere in the file
# 1 - in a doxygen par
-# 2 - after doxygen, except funcion
+# 2 - after doxygen, expect function
# create our pwd
mkdir "doc";
@@ -126,7 +126,14 @@ while($i < $max) {
}
if ($cur_line =~ /\*\// and $state == 1) {
#print "END Comment seen!\n";
- $state = 2;
+ if ($description =~ /^\\\\file/mg) {
+ # Doxygen text for the file, do not expect
+ # a function coming.
+ #
+ $state = 0;
+ } else {
+ $state = 2;
+ }
$i++;
next;
}
@@ -184,6 +191,14 @@ while($i < $max) {
$description =~ s/\\param\[out\][ \t]*([\*\w]+)[ \t]+/.br\n\\fB$1\\fR: /g;
$description =~ s/\\return[ \t]*/.br\nReturns /g;
+ # Delete leading spaces to prevent manpages to be ascii format-
+ # ted and enable justification of text.
+ #
+ $description =~ s/^[ \t]*//mg;
+
+ # Prevent hyphening of all caps and underscore words
+ $description =~ s/\b([A-Z_]+)\b/\\%$1/g;
+
$description{$key} = $description;
$api{$key} = $api;
$return{$key} = $return;
diff --git a/usr.sbin/unbound/ldns/doc/function_manpages b/usr.sbin/unbound/ldns/doc/function_manpages
index 15706fada57..ce05899b7cf 100644
--- a/usr.sbin/unbound/ldns/doc/function_manpages
+++ b/usr.sbin/unbound/ldns/doc/function_manpages
@@ -39,6 +39,11 @@ ldns_dname_compare, ldns_dname_interval | ldns_dname_is_subdomain | ldns_dname
ldns_dname | ldns_dname_left_chop, ldns_dname_label_count, ldns_dname2canonical, ldns_dname_cat, ldns_dname_cat_clone, ldns_dname_new, ldns_dname_new_frm_str, ldns_dname_new_frm_data, ldns_dname_is_subdomain, ldns_dname_str_absolute, ldns_dname_label, ldns_dname_compare, ldns_dname_interval
### /dname.h
+### dane.h
+ldns_dane_create_tlsa_owner, ldns_dane_cert2rdf, ldns_dane_select_certificate, ldns_dane_create_tlsa_rr | ldns_dane_verify, ldns_dane_verify_rr
+ldns_dane_verify, ldns_dane_verify_rr | ldns_dane_create_tlsa_owner, ldns_dane_cert2rdf, ldns_dane_select_certificate, ldns_dane_create_tlsa_rr
+### /dane.h
+
### rdata.h
ldns_rdf, ldns_rdf_type | ldns_rdf_set_size, ldns_rdf_set_type, ldns_rdf_set_data, ldns_rdf_size, ldns_rdf_get_type, ldns_rdf_data, ldns_rdf_compare, ldns_rdf_new, ldns_rdf_clone, ldns_rdf_new_frm_data, ldns_rdf_new_frm_str, ldns_rdf_new_frm_fp, ldns_rdf_free, ldns_rdf_deep_free, ldns_rdf_print, ldns_native2rdf_int8, ldns_native2rdf_int16, ldns_native2rdf_int32, ldns_native2rdf_int16_data, ldns_rdf2native_int8, ldns_rdf2native_int16, ldns_rdf2native_int32, ldns_rdf2native_sockaddr_storage, ldns_rdf2native_time_t, ldns_native2rdf_int8, ldns_native2rdf_int16, ldns_native2rdf_int32, ldns_native2rdf_int16_data, ldns_rdf2native_int8, ldns_rdf2native_int16, ldns_rdf2native_int32, ldns_rdf2native_sockaddr_storage, ldns_rdf2native_time_t, ldns_native2rdf_int8, ldns_native2rdf_int16, ldns_native2rdf_int32, ldns_native2rdf_int16_data, ldns_rdf2native_int8, ldns_rdf2native_int16, ldns_rdf2native_int32, ldns_rdf2native_sockaddr_storage, ldns_rdf2native_time_t
ldns_rdf_set_size, ldns_rdf_set_type, ldns_rdf_set_data | ldns_rdf
diff --git a/usr.sbin/unbound/ldns/drill/Makefile.in b/usr.sbin/unbound/ldns/drill/Makefile.in
index 5730f0809c7..ac555fa1e57 100644
--- a/usr.sbin/unbound/ldns/drill/Makefile.in
+++ b/usr.sbin/unbound/ldns/drill/Makefile.in
@@ -9,6 +9,7 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
includedir = @includedir@
+datarootdir = @datarootdir@
CC = @CC@
CFLAGS = -I. @CFLAGS@
@@ -77,7 +78,6 @@ docclean:
distclean: clean docclean
rm -f config.h
- rm -f drill.h
realclean: clean docclean
rm -f tags
@@ -88,9 +88,9 @@ realclean: clean docclean
rm -rf autom4te.cache
rm -f config.h
rm -f config.h.in
- rm -f drill.h
rm -f configure
rm -f Makefile
+ rm -f drill.1
rm -f aclocal.m4
doc:
@@ -99,7 +99,7 @@ doc:
install: all
$(INSTALL) -d $(DESTDIR)$(bindir)
$(INSTALL) drill $(DESTDIR)$(bindir)/drill
- $(INSTALL) -m 644 $(srcdir)/drill.1 $(DESTDIR)$(mandir)/man1/drill.1
+ $(INSTALL) -m 644 drill.1 $(DESTDIR)$(mandir)/man1/drill.1
uninstall:
@echo
@@ -116,4 +116,4 @@ lint:
done
confclean: clean
- rm -rf config.log config.status config.h Makefile
+ rm -rf config.log config.status config.h Makefile drill.1
diff --git a/usr.sbin/unbound/ldns/drill/chasetrace.c b/usr.sbin/unbound/ldns/drill/chasetrace.c
index c2bbfd00901..0a37ff3017e 100644
--- a/usr.sbin/unbound/ldns/drill/chasetrace.c
+++ b/usr.sbin/unbound/ldns/drill/chasetrace.c
@@ -45,7 +45,15 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
p = ldns_pkt_new();
res = ldns_resolver_new();
- if (!p || !res) {
+ if (!p) {
+ if (res) {
+ ldns_resolver_free(res);
+ }
+ error("Memory allocation failed");
+ return NULL;
+ }
+ if (!res) {
+ ldns_pkt_free(p);
error("Memory allocation failed");
return NULL;
}
@@ -73,6 +81,8 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
if (status != LDNS_STATUS_OK) {
fprintf(stderr, "Error adding root servers to resolver: %s\n", ldns_get_errorstr_by_id(status));
ldns_rr_list_print(stdout, global_dns_root);
+ ldns_resolver_free(res);
+ ldns_pkt_free(p);
return NULL;
}
@@ -118,7 +128,7 @@ do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
drill_pkt_print_footer(stdout, local_res, p);
/* remove the old nameserver from the resolver */
- while((pop = ldns_resolver_pop_nameserver(res))) { /* do it */ }
+ while(ldns_resolver_pop_nameserver(res)) { /* do it */ }
/* also check for new_nss emptyness */
diff --git a/usr.sbin/unbound/ldns/drill/config.h.in b/usr.sbin/unbound/ldns/drill/config.h.in
index 9b2a282a8e9..75448a07ecc 100644
--- a/usr.sbin/unbound/ldns/drill/config.h.in
+++ b/usr.sbin/unbound/ldns/drill/config.h.in
@@ -111,6 +111,9 @@
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#undef HAVE_WS2TCPIP_H
+/* Default trust anchor file */
+#undef LDNS_TRUST_ANCHOR_FILE
+
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
diff --git a/usr.sbin/unbound/ldns/drill/configure b/usr.sbin/unbound/ldns/drill/configure
index 95bc4356072..6a4487d9a97 100755
--- a/usr.sbin/unbound/ldns/drill/configure
+++ b/usr.sbin/unbound/ldns/drill/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for ldns 1.6.13.
+# Generated by GNU Autoconf 2.68 for ldns 1.6.16.
#
# Report bugs to <libdns@nlnetlabs.nl>.
#
@@ -560,8 +560,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='ldns'
PACKAGE_TARNAME='libdns'
-PACKAGE_VERSION='1.6.13'
-PACKAGE_STRING='ldns 1.6.13'
+PACKAGE_VERSION='1.6.16'
+PACKAGE_STRING='ldns 1.6.16'
PACKAGE_BUGREPORT='libdns@nlnetlabs.nl'
PACKAGE_URL=''
@@ -604,6 +604,7 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
+LDNS_TRUST_ANCHOR_FILE
LDNSDIR
LIBS_STC
RUNTIME_PATH
@@ -664,6 +665,7 @@ enable_option_checking
enable_rpath
with_ssl
with_ldns
+with_trust_anchor
'
ac_precious_vars='build_alias
host_alias
@@ -1216,7 +1218,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures ldns 1.6.13 to adapt to many kinds of systems.
+\`configure' configures ldns 1.6.16 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1277,7 +1279,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of ldns 1.6.13:";;
+ short | recursive ) echo "Configuration of ldns 1.6.16:";;
esac
cat <<\_ACEOF
@@ -1296,6 +1298,9 @@ Optional Packages:
--with-ldns=PATH specify prefix of path of ldns library to use
+ --with-trust-anchor=KEYFILE
+ Default location of the trust anchor file.
+ [default=SYSCONFDIR/unbound/root.key]
Some influential environment variables:
CC C compiler command
@@ -1373,7 +1378,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-ldns configure 1.6.13
+ldns configure 1.6.16
generated by GNU Autoconf 2.68
Copyright (C) 2010 Free Software Foundation, Inc.
@@ -1796,7 +1801,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by ldns $as_me 1.6.13, which was
+It was created by ldns $as_me 1.6.16, which was
generated by GNU Autoconf 2.68. Invocation command line was
$ $0 $@
@@ -5379,16 +5384,46 @@ else
as_fn_error $? "Can't find ldns library" "$LINENO" 5
+fi
fi
+
+
+
+# Check whether --with-trust-anchor was given.
+if test "${with_trust_anchor+set}" = set; then :
+ withval=$with_trust_anchor;
+ LDNS_TRUST_ANCHOR_FILE="$withval"
+
+else
+
+ if test "x$LDNS_TRUST_ANCHOR_FILE" = "x"; then
+ if test "x$sysconfdir" = 'x${prefix}/etc' ; then
+ if test "x$prefix" = 'xNONE' ; then
+ LDNS_TRUST_ANCHOR_FILE="/etc/unbound/root.key"
+ else
+ LDNS_TRUST_ANCHOR_FILE="${prefix}/etc/unbound/root.key"
+ fi
+ else
+ LDNS_TRUST_ANCHOR_FILE="${sysconfdir}/unbound/root.key"
+ fi
+ fi
+
fi
+cat >>confdefs.h <<_ACEOF
+#define LDNS_TRUST_ANCHOR_FILE "$LDNS_TRUST_ANCHOR_FILE"
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Default trust anchor: $LDNS_TRUST_ANCHOR_FILE" >&5
+$as_echo "$as_me: Default trust anchor: $LDNS_TRUST_ANCHOR_FILE" >&6;}
-ac_config_files="$ac_config_files Makefile"
+ac_config_files="$ac_config_files Makefile drill.1"
ac_config_headers="$ac_config_headers config.h"
@@ -5910,7 +5945,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by ldns $as_me 1.6.13, which was
+This file was extended by ldns $as_me 1.6.16, which was
generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -5972,7 +6007,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-ldns config.status 1.6.13
+ldns config.status 1.6.16
configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
@@ -6094,6 +6129,7 @@ for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "drill.1") CONFIG_FILES="$CONFIG_FILES drill.1" ;;
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
diff --git a/usr.sbin/unbound/ldns/drill/configure.ac b/usr.sbin/unbound/ldns/drill/configure.ac
index afd5c63803b..17d7541c027 100644
--- a/usr.sbin/unbound/ldns/drill/configure.ac
+++ b/usr.sbin/unbound/ldns/drill/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.56)
-AC_INIT(ldns, 1.6.13, libdns@nlnetlabs.nl,libdns)
+AC_INIT(ldns, 1.6.16, libdns@nlnetlabs.nl,libdns)
AC_CONFIG_SRCDIR([drill.c])
sinclude(../acx_nlnetlabs.m4)
@@ -170,13 +170,33 @@ if test -f $ldns_dev_dir/ldns/util.h && \
else
AC_MSG_RESULT([no])
AC_CHECK_LIB(ldns, ldns_rr_new, , [
- AC_MSG_ERROR([Can't find ldns library])
+ AC_MSG_ERROR([Can't find ldns library])dnl '
]
)
fi
AC_SUBST(LDNSDIR)
+AC_ARG_WITH(trust-anchor, AC_HELP_STRING([--with-trust-anchor=KEYFILE],
+[Default location of the trust anchor file. [default=SYSCONFDIR/unbound/root.key]]), [
+ LDNS_TRUST_ANCHOR_FILE="$withval"
+],[
+ if test "x$LDNS_TRUST_ANCHOR_FILE" = "x"; then
+ if test "x$sysconfdir" = 'x${prefix}/etc' ; then
+ if test "x$prefix" = 'xNONE' ; then
+ LDNS_TRUST_ANCHOR_FILE="/etc/unbound/root.key"
+ else
+ LDNS_TRUST_ANCHOR_FILE="${prefix}/etc/unbound/root.key"
+ fi
+ else
+ LDNS_TRUST_ANCHOR_FILE="${sysconfdir}/unbound/root.key"
+ fi
+ fi
+])
+AC_DEFINE_UNQUOTED([LDNS_TRUST_ANCHOR_FILE], ["$LDNS_TRUST_ANCHOR_FILE"], [Default trust anchor file])
+AC_SUBST(LDNS_TRUST_ANCHOR_FILE)
+AC_MSG_NOTICE([Default trust anchor: $LDNS_TRUST_ANCHOR_FILE])
+
AH_BOTTOM([
#include <stdio.h>
@@ -254,6 +274,6 @@ extern int optind, opterr;
#endif
])
-AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([Makefile drill.1])
AC_CONFIG_HEADER([config.h])
AC_OUTPUT
diff --git a/usr.sbin/unbound/ldns/drill/dnssec.c b/usr.sbin/unbound/ldns/drill/dnssec.c
index b72ffb95dad..b8074be03cc 100644
--- a/usr.sbin/unbound/ldns/drill/dnssec.c
+++ b/usr.sbin/unbound/ldns/drill/dnssec.c
@@ -22,12 +22,10 @@ get_rr(ldns_resolver *res, ldns_rdf *zname, ldns_rr_type t, ldns_rr_class c)
p = ldns_pkt_new();
found = NULL;
- if (ldns_resolver_send(&p, res, zname, t, c, 0) != LDNS_STATUS_OK) {
- /* oops */
- return NULL;
- } else {
+ if (ldns_resolver_send(&p, res, zname, t, c, 0) == LDNS_STATUS_OK) {
found = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_ANY_NOQUESTION);
}
+ ldns_pkt_free(p);
return found;
}
@@ -36,6 +34,7 @@ drill_pkt_print(FILE *fd, ldns_resolver *r, ldns_pkt *p)
{
ldns_rr_list *new_nss;
ldns_rr_list *hostnames;
+ char *answerfrom_str;
if (verbosity < 5) {
return;
@@ -46,8 +45,7 @@ drill_pkt_print(FILE *fd, ldns_resolver *r, ldns_pkt *p)
new_nss = ldns_pkt_rr_list_by_type(p,
LDNS_RR_TYPE_NS, LDNS_SECTION_ANSWER);
ldns_rr_list_print(fd, new_nss);
-
- /* new_nss can be empty.... */
+ ldns_rr_list_deep_free(new_nss);
fprintf(fd, ";; Received %d bytes from %s#%d(",
(int) ldns_pkt_size(p),
@@ -59,7 +57,11 @@ drill_pkt_print(FILE *fd, ldns_resolver *r, ldns_pkt *p)
ldns_rr_rdf(ldns_rr_list_rr(hostnames, 0), 0));
ldns_rr_list_deep_free(hostnames);
} else {
- fprintf(fd, "%s", ldns_rdf2str(ldns_pkt_answerfrom(p)));
+ answerfrom_str = ldns_rdf2str(ldns_pkt_answerfrom(p));
+ if (answerfrom_str) {
+ fprintf(fd, "%s", answerfrom_str);
+ LDNS_FREE(answerfrom_str);
+ }
}
fprintf(fd, ") in %u ms\n\n", (unsigned int)ldns_pkt_querytime(p));
}
@@ -68,6 +70,7 @@ void
drill_pkt_print_footer(FILE *fd, ldns_resolver *r, ldns_pkt *p)
{
ldns_rr_list *hostnames;
+ char *answerfrom_str;
if (verbosity < 5) {
return;
@@ -85,7 +88,11 @@ drill_pkt_print_footer(FILE *fd, ldns_resolver *r, ldns_pkt *p)
ldns_rr_rdf(ldns_rr_list_rr(hostnames, 0), 0));
ldns_rr_list_deep_free(hostnames);
} else {
- fprintf(fd, "%s", ldns_rdf2str(ldns_pkt_answerfrom(p)));
+ answerfrom_str = ldns_rdf2str(ldns_pkt_answerfrom(p));
+ if (answerfrom_str) {
+ fprintf(fd, "%s", answerfrom_str);
+ LDNS_FREE(answerfrom_str);
+ }
}
fprintf(fd, ") in %u ms\n\n", (unsigned int)ldns_pkt_querytime(p));
}
@@ -98,7 +105,6 @@ get_dnssec_rr(ldns_pkt *p, ldns_rdf *name, ldns_rr_type t,
ldns_rr_list **rrlist, ldns_rr_list **sig)
{
ldns_pkt_type pt = LDNS_PACKET_UNKNOWN;
- ldns_rr_list *rr = NULL;
ldns_rr_list *sigs = NULL;
size_t i;
@@ -111,36 +117,52 @@ get_dnssec_rr(ldns_pkt *p, ldns_rdf *name, ldns_rr_type t,
pt = ldns_pkt_reply_type(p);
if (name) {
- rr = ldns_pkt_rr_list_by_name_and_type(p, name, t, LDNS_SECTION_ANSWER);
- if (!rr) {
- rr = ldns_pkt_rr_list_by_name_and_type(p, name, t, LDNS_SECTION_AUTHORITY);
+ if (rrlist) {
+ *rrlist = ldns_pkt_rr_list_by_name_and_type(p, name, t,
+ LDNS_SECTION_ANSWER);
+ if (!*rrlist) {
+ *rrlist = ldns_pkt_rr_list_by_name_and_type(
+ p, name, t,
+ LDNS_SECTION_AUTHORITY);
+ }
}
- sigs = ldns_pkt_rr_list_by_name_and_type(p, name, LDNS_RR_TYPE_RRSIG,
- LDNS_SECTION_ANSWER);
- if (!sigs) {
- sigs = ldns_pkt_rr_list_by_name_and_type(p, name, LDNS_RR_TYPE_RRSIG,
- LDNS_SECTION_AUTHORITY);
+ if (sig) {
+ sigs = ldns_pkt_rr_list_by_name_and_type(p, name,
+ LDNS_RR_TYPE_RRSIG,
+ LDNS_SECTION_ANSWER);
+ if (!sigs) {
+ sigs = ldns_pkt_rr_list_by_name_and_type(
+ p, name, LDNS_RR_TYPE_RRSIG,
+ LDNS_SECTION_AUTHORITY);
+ }
}
} else {
- /* A DS-referral - get the DS records if they are there */
- rr = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_AUTHORITY);
- sigs = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_RRSIG,
- LDNS_SECTION_AUTHORITY);
+ /* A DS-referral - get the DS records if they are there */
+ if (rrlist) {
+ *rrlist = ldns_pkt_rr_list_by_type(
+ p, t, LDNS_SECTION_AUTHORITY);
+ }
+ if (sig) {
+ sigs = ldns_pkt_rr_list_by_type(p,
+ LDNS_RR_TYPE_RRSIG,
+ LDNS_SECTION_AUTHORITY);
+ }
}
if (sig) {
*sig = ldns_rr_list_new();
for (i = 0; i < ldns_rr_list_rr_count(sigs); i++) {
/* only add the sigs that cover this type */
- if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(ldns_rr_list_rr(sigs, i))) ==
- t) {
- ldns_rr_list_push_rr(*sig, ldns_rr_clone(ldns_rr_list_rr(sigs, i)));
+ if (t == ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(
+ ldns_rr_list_rr(sigs, i)))) {
+
+ ldns_rr_list_push_rr(*sig,
+ ldns_rr_clone(
+ ldns_rr_list_rr(
+ sigs, i)));
}
}
}
ldns_rr_list_deep_free(sigs);
- if (rrlist) {
- *rrlist = rr;
- }
if (pt == LDNS_PACKET_NXDOMAIN || pt == LDNS_PACKET_NODATA) {
return pt;
@@ -153,6 +175,7 @@ get_dnssec_rr(ldns_pkt *p, ldns_rdf *name, ldns_rr_type t,
ldns_status
ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_list **nsec_rrs, ldns_rr_list **nsec_rr_sigs)
{
+#ifdef HAVE_SSL
uint16_t nsec_i;
ldns_rr_list *nsecs;
@@ -216,12 +239,28 @@ ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_lis
ldns_rr_list* sigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, LDNS_SECTION_ANY_NOQUESTION);
ldns_rr* q = ldns_rr_new();
ldns_rr* match = NULL;
- if(!sigs) return LDNS_STATUS_MEM_ERR;
- if(!q) return LDNS_STATUS_MEM_ERR;
+
+ if(!sigs) {
+ if (q) {
+ ldns_rr_free(q);
+ }
+ ldns_rr_list_deep_free(nsecs);
+ return LDNS_STATUS_MEM_ERR;
+ }
+ if(!q) {
+ ldns_rr_list_deep_free(nsecs);
+ ldns_rr_list_deep_free(sigs);
+ return LDNS_STATUS_MEM_ERR;
+ }
ldns_rr_set_question(q, 1);
ldns_rr_set_ttl(q, 0);
ldns_rr_set_owner(q, ldns_rdf_clone(name));
- if(!ldns_rr_owner(q)) return LDNS_STATUS_MEM_ERR;
+ if(!ldns_rr_owner(q)) {
+ ldns_rr_free(q);
+ ldns_rr_list_deep_free(sigs);
+ ldns_rr_list_deep_free(nsecs);
+ return LDNS_STATUS_MEM_ERR;
+ }
ldns_rr_set_type(q, type);
/* result = ldns_dnssec_verify_denial_nsec3(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0); */
@@ -234,6 +273,14 @@ ldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_lis
ldns_rr_list_deep_free(sigs);
}
return result;
+#else
+ (void)pkt;
+ (void)name;
+ (void)type;
+ (void)nsec_rrs;
+ (void)nsec_rr_sigs;
+ return LDNS_STATUS_ERR;
+#endif /* HAVE_SSL */
}
/* NSEC3 draft -07 */
diff --git a/usr.sbin/unbound/ldns/drill/drill.1.in b/usr.sbin/unbound/ldns/drill/drill.1.in
new file mode 100644
index 00000000000..15b15a42533
--- /dev/null
+++ b/usr.sbin/unbound/ldns/drill/drill.1.in
@@ -0,0 +1,242 @@
+.\" @(#)drill.1 1.7.0 14-Jul-2004 OF;
+.TH drill 1 "28 May 2006"
+.SH NAME
+drill \- get (debug) information out of DNS(SEC)
+.SH SYNOPSIS
+.B drill
+[
+.IR OPTIONS
+]
+.IR name
+[
+.IR @server
+]
+[
+.IR type
+]
+[
+.IR class
+]
+
+.SH DESCRIPTION
+\fBdrill\fR is a tool to designed to get all sorts of information out of the
+DNS. It is specificly designed to be used with DNSSEC.
+.PP
+The name \fBdrill\fR is a pun on \fBdig\fR. With \fBdrill\fR you should be able
+get even more information than with \fBdig\fR.
+.PP
+If no arguments are given class defaults to 'IN' and type to 'A'. The
+server(s) specified in /etc/resolv.conf are used to query against.
+
+.PP
+\fIname\fR
+Ask for this name.
+
+.PP
+\fI@server\fR
+Send to query to this server. If not specified use the nameservers from
+\fI/etc/resolv.conf\fR.
+
+.PP
+\fItype\fR
+Ask for this RR type. If type is not given on the command line it defaults
+to 'A'. Except when doing to reverse lookup when it defaults to 'PTR'.
+
+.PP
+\fIclass\fR
+Use this class when querying.
+
+.SH SAMPLE USAGE
+\fBdrill mx miek.nl\fR
+Show the MX records of the domain miek.nl
+
+.TP
+\fBdrill -S jelte.nlnetlabs.nl\fR
+Chase any signatures in the jelte.nlnetlab.nl domain. This option is
+only available when ldns has been compiled with openssl-support.
+
+.TP
+\fBdrill -TD www.example.com\fR
+Do a DNSSEC (-D) trace (-T) from the rootservers down to www.example.com.
+This option only works when ldns has been compiled with openssl support.
+
+.TP
+\fBdrill -s dnskey jelte.nlnetlabs.nl\fR
+Show the DNSKEY record(s) for jelte.nlnetlabs.nl. For each found DNSKEY
+record also print the DS record.
+
+.SH OPTIONS
+
+.TP
+\fB\-D
+Enable DNSSEC in the query. When querying for DNSSEC types (DNSKEY, RRSIG,
+DS and NSEC) this is \fInot\fR automaticly enabled.
+
+.TP
+\fB\-T
+Trace \fIname\fR from the root down. When using this option the @server and
+the type arguments are not used.
+
+.TP
+\fB\-S
+Chase the signature(s) of 'name' to a known key or as high up in
+the tree as possible.
+
+.TP
+\fB\-V \fIlevel\fR
+Be more verbose. Set level to 5 to see the actual query that is sent.
+
+.TP
+\fB\-Q
+Quiet mode, this overrules -V.
+
+.TP
+\fB\-f \fIfile\fR
+Read the query from a file. The query must be dumped with -w.
+
+.TP
+\fB\-i \fIfile\fR
+read the answer from the file instead from the network. This aids
+in debugging and can be used to check if a query on disk is valid.
+If the file contains binary data it is assumed to be a query in
+network order.
+
+.TP
+\fB\-w \fIfile\fR
+Write an answer packet to file.
+
+.TP
+\fB\-q \fIfile\fR
+Write the query packet to file.
+
+.TP
+\fB\-v
+Show drill's version.
+
+.TP
+\fB\-h
+Show a short help message.
+
+.SS QUERY OPTIONS
+
+.TP
+\fB\-4
+Stay on ip4. Only send queries to ip4 enabled nameservers.
+
+.TP
+\fB\-6
+Stay on ip6. Only send queries to ip6 enabled nameservers.
+
+.TP
+\fB\-a
+Use the resolver structure's fallback mechanism if the answer
+is truncated (TC=1). If a truncated packet is received and this
+option is set, drill will first send a new query with EDNS0
+buffer size 4096.
+
+If the EDNS0 buffer size was already set to 512+ bytes, or the
+above retry also results in a truncated answer, the resolver
+structure will fall back to TCP.
+
+.TP
+\fB\-b \fIsize\fR
+Use size as the buffer size in the EDNS0 pseudo RR.
+
+.TP
+\fB\-c \fIfile\fR
+Use file instead of /etc/resolv.conf for nameserver configuration.
+
+.TP
+\fB\-d \fIdomain\fR
+When tracing (-T), start from this domain instead of the root.
+
+.TP
+\fB\-t
+Use TCP/IP when querying a server
+
+.TP
+\fB\-k \fIkeyfile\fR
+Use this file to read a (trusted) key from. When this options is
+given \fBdrill\fR tries to validate the current answer with this
+key. No chasing is done. When \fBdrill\fR is doing a secure trace, this
+key will be used as trust anchor. Can contain a DNSKEY or a DS record.
+
+Alternatively, when DNSSEC enabled tracing (\fB-TD\fR) or signature
+chasing (\fB-S\fR), if \fB-k\fR is not specified, and a default trust anchor
+(@LDNS_TRUST_ANCHOR_FILE@) exists and contains a valid DNSKEY or DS record,
+it will be used as the trust anchor.
+
+.TP
+\fB\-o \fImnemonic\fR
+Use this option to set or unset specific header bits. A bit is
+set by using the bit mnemonic in CAPITAL letters. A bit is unset when
+the mnemonic is given in lowercase. The following mnemonics are
+understood by \fBdrill\fR:
+
+ QR, qr: set, unset QueRy (default: on)
+ AA, aa: set, unset Authoritative Answer (default: off)
+ TC, tc: set, unset TrunCated (default: off)
+ RD, rd: set, unset Recursion Desired (default: on)
+ CD, cd: set, unset Checking Disabled (default: off)
+ RA, ra: set, unset Recursion Available (default: off)
+ AD, ad: set, unset Authenticated Data (default: off)
+
+Thus: \fB-o CD\fR, will enable Checking Disabled, which instructs the
+cache to not validate the answers it gives out.
+
+.TP
+\fB\-p \fIport\fR
+Use this port instead of the default of 53.
+
+.TP
+\fB\-r \fIfile\fR
+When tracing (-T), use file as a root servers hint file.
+
+.TP
+\fB\-s
+When encountering a DNSKEY print the equivalent DS also.
+
+.TP
+\fB\-u
+Use UDP when querying a server. This is the default.
+
+.TP
+\fB\-w \fIfile\fR
+write the answer to a file. The file will contain a hexadecimal dump
+of the query. This can be used in conjunction with -f.
+
+.TP
+\fB\-x
+Do a reverse loopup. The type argument is not used, it is preset to PTR.
+
+.TP
+\fB\-y \fI<name:key[:algo]>\fR
+specify named base64 tsig key, and optional an algorithm (defaults to hmac-md5.sig-alg.reg.int)
+
+.TP
+\fB\-z \fR
+don't randomize the nameserver list before sending queries.
+
+.SH "FILES"
+.TP
+@LDNS_TRUST_ANCHOR_FILE@
+The file from which trusted keys are loaded when no \fB-k\fR option is given.
+.SH "SEE ALSO"
+.LP
+unbound-anchor(8)
+
+.SH AUTHOR
+Jelte Jansen and Miek Gieben. Both of NLnet Labs.
+
+.SH REPORTING BUGS
+Report bugs to <ldns-team@nlnetlabs.nl>.
+
+.SH BUGS
+
+.SH COPYRIGHT
+Copyright (c) 2004-2008 NLnet Labs.
+Licensed under the revised BSD license. There is NO warranty; not even for MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.
+
+.SH SEE ALSO
+\fBdig\fR(1), \fIRFC403{3,4,5}\fR.
diff --git a/usr.sbin/unbound/ldns/drill/drill.c b/usr.sbin/unbound/ldns/drill/drill.c
index 2f779634d8e..574c8b98c85 100644
--- a/usr.sbin/unbound/ldns/drill/drill.c
+++ b/usr.sbin/unbound/ldns/drill/drill.c
@@ -47,19 +47,25 @@ usage(FILE *stream, const char *progname)
fprintf(stream, "\t-6\t\tstay on ip6\n");
fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
- fprintf(stream, "\t-c <file>\t\tuse file for rescursive nameserver configuration (/etc/resolv.conf)\n");
- fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key (DNSKEY|DS) [**]\n");
- fprintf(stream, "\t\t\tused to verify any signatures in the current answer\n");
- fprintf(stream, "\t-o <mnemonic>\tset flags to: [QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
+ fprintf(stream, "\t-c <file>\tuse file for rescursive nameserver configuration"
+ "\n\t\t\t(/etc/resolv.conf)\n");
+ fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key [**]\n");
+ fprintf(stream, "\t\t\tUsed to verify any signatures in the current answer.\n");
+ fprintf(stream, "\t\t\tWhen DNSSEC enabled tracing (-TD) or signature\n"
+ "\t\t\tchasing (-S) and no key files are given, keys are read\n"
+ "\t\t\tfrom: %s\n",
+ LDNS_TRUST_ANCHOR_FILE);
+ fprintf(stream, "\t-o <mnemonic>\tset flags to:"
+ "\n\t\t\t[QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
fprintf(stream, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
fprintf(stream, "\t-p <port>\tuse <port> as remote port number\n");
fprintf(stream, "\t-s\t\tshow the DS RR for each key in a packet\n");
fprintf(stream, "\t-u\t\tsend the query with udp (the default)\n");
fprintf(stream, "\t-x\t\tdo a reverse lookup\n");
fprintf(stream, "\twhen doing a secure trace:\n");
- fprintf(stream, "\t-r <file>\t\tuse file as root servers hint file\n");
+ fprintf(stream, "\t-r <file>\tuse file as root servers hint file\n");
fprintf(stream, "\t-t\t\tsend the query with tcp (connected)\n");
- fprintf(stream, "\t-d <domain>\t\tuse domain as the start point for the trace\n");
+ fprintf(stream, "\t-d <domain>\tuse domain as the start point for the trace\n");
fprintf(stream, "\t-y <name:key[:algo]>\tspecify named base64 tsig key, and optional an\n\t\t\talgorithm (defaults to hmac-md5.sig-alg.reg.int)\n");
fprintf(stream, "\t-z\t\tdon't randomize the nameservers before use\n");
fprintf(stream, "\n [*] = enables/implies DNSSEC\n");
@@ -272,7 +278,8 @@ main(int argc, char *argv[])
qusevc = true;
break;
case 'k':
- status = read_key_file(optarg, key_list);
+ status = read_key_file(optarg,
+ key_list, false);
if (status != LDNS_STATUS_OK) {
error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
}
@@ -397,6 +404,15 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
+ if ((PURPOSE == DRILL_CHASE || (PURPOSE == DRILL_TRACE && qdnssec)) &&
+ ldns_rr_list_rr_count(key_list) == 0) {
+
+ (void) read_key_file(LDNS_TRUST_ANCHOR_FILE, key_list, true);
+ }
+ if (ldns_rr_list_rr_count(key_list) > 0) {
+ printf(";; Number of trusted keys: %d\n",
+ (int) ldns_rr_list_rr_count(key_list));
+ }
/* do a secure trace when requested */
if (PURPOSE == DRILL_TRACE && qdnssec) {
#ifdef HAVE_SSL
diff --git a/usr.sbin/unbound/ldns/drill/drill.h b/usr.sbin/unbound/ldns/drill/drill.h
index 69b0396b217..0746fe7bff2 100644
--- a/usr.sbin/unbound/ldns/drill/drill.h
+++ b/usr.sbin/unbound/ldns/drill/drill.h
@@ -85,7 +85,6 @@ ldns_status ldns_verify_denial(ldns_pkt *pkt,
ldns_rr_list **nsec_rrs,
ldns_rr_list **nsec_rr_sigs);
-ldns_status read_key_file(const char *filename, ldns_rr_list *key_list);
ldns_pkt *read_hex_pkt(char *filename);
ldns_buffer *read_hex_buffer(char *filename);
void init_root(void);
diff --git a/usr.sbin/unbound/ldns/drill/drill_util.c b/usr.sbin/unbound/ldns/drill/drill_util.c
index 98d88e7942d..db0433e77e1 100644
--- a/usr.sbin/unbound/ldns/drill/drill_util.c
+++ b/usr.sbin/unbound/ldns/drill/drill_util.c
@@ -13,14 +13,14 @@
#include <errno.h>
-static size_t
+static int
read_line(FILE *input, char *line, size_t len)
{
- size_t i;
+ int i;
char c;
- for (i = 0; i < len-1; i++) {
- c = getc(input);
+ for (i = 0; i < (int)len-1; i++) {
+ c = (char)getc(input);
if (c == EOF) {
return -1;
} else if (c != '\n') {
@@ -35,20 +35,22 @@ read_line(FILE *input, char *line, size_t len)
/* key_list must be initialized with ldns_rr_list_new() */
ldns_status
-read_key_file(const char *filename, ldns_rr_list *key_list)
+read_key_file(const char *filename, ldns_rr_list *key_list, bool silently)
{
int line_len = 0;
int line_nr = 0;
int key_count = 0;
- char line[LDNS_MAX_PACKETLEN];
+ char line[LDNS_MAX_LINELEN];
ldns_status status;
FILE *input_file;
ldns_rr *rr;
input_file = fopen(filename, "r");
if (!input_file) {
- fprintf(stderr, "Error opening %s: %s\n",
- filename, strerror(errno));
+ if (! silently) {
+ fprintf(stderr, "Error opening %s: %s\n",
+ filename, strerror(errno));
+ }
return LDNS_STATUS_ERR;
}
while (line_len >= 0) {
@@ -57,10 +59,13 @@ read_key_file(const char *filename, ldns_rr_list *key_list)
if (line_len > 0 && line[0] != ';') {
status = ldns_rr_new_frm_str(&rr, line, 0, NULL, NULL);
if (status != LDNS_STATUS_OK) {
- fprintf(stderr,
- "Error parsing DNSKEY RR in line %d: %s\n",
- line_nr,
- ldns_get_errorstr_by_id(status));
+ if (! silently) {
+ fprintf(stderr,
+ "Error parsing DNSKEY RR "
+ "in line %d: %s\n", line_nr,
+ ldns_get_errorstr_by_id(status)
+ );
+ }
} else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY ||
ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) {
ldns_rr_list_push_rr(key_list, rr);
@@ -70,7 +75,7 @@ read_key_file(const char *filename, ldns_rr_list *key_list)
}
}
}
- printf(";; Number of trusted keys: %d\n", key_count);
+ fclose(input_file);
if (key_count > 0) {
return LDNS_STATUS_OK;
} else {
@@ -132,6 +137,7 @@ print_ds_of_keys(ldns_pkt *p)
ds = ldns_key_rr2ds(ldns_rr_list_rr(keys, i), LDNS_SHA256);
local_print_ds(stdout, "; sha256: ", ds);
}
+ ldns_rr_list_deep_free(keys);
}
}
diff --git a/usr.sbin/unbound/ldns/drill/drill_util.h b/usr.sbin/unbound/ldns/drill/drill_util.h
index de7844118db..42b3f32b25d 100644
--- a/usr.sbin/unbound/ldns/drill/drill_util.h
+++ b/usr.sbin/unbound/ldns/drill/drill_util.h
@@ -12,6 +12,13 @@
#define _DRILL_UTIL_H_
#include <ldns/ldns.h>
+
+/**
+ * Read keys from filename and append to key_list.
+ */
+ldns_status read_key_file(const char *filename, ldns_rr_list *key_list,
+ bool silently);
+
/**
* return a address rdf, either A or AAAA
* NULL if anything goes wrong
diff --git a/usr.sbin/unbound/ldns/drill/securetrace.c b/usr.sbin/unbound/ldns/drill/securetrace.c
index 029ebf51d6f..c6e7e588409 100644
--- a/usr.sbin/unbound/ldns/drill/securetrace.c
+++ b/usr.sbin/unbound/ldns/drill/securetrace.c
@@ -231,7 +231,8 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
if (status != LDNS_STATUS_OK) {
printf("ERRRRR: %s\n", ldns_get_errorstr_by_id(status));
ldns_rr_list_print(stdout, global_dns_root);
- return status;
+ result = status;
+ goto done;
}
labels_count = ldns_dname_label_count(name);
if (start_name) {
@@ -392,7 +393,6 @@ do_secure_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t,
printf(";; There is an empty non-terminal here, continue\n");
continue;
}
- goto done;
}
if (ldns_resolver_nameserver_count(res) == 0) {
diff --git a/usr.sbin/unbound/ldns/drill/work.c b/usr.sbin/unbound/ldns/drill/work.c
index 3a9cb5855d7..653145fe522 100644
--- a/usr.sbin/unbound/ldns/drill/work.c
+++ b/usr.sbin/unbound/ldns/drill/work.c
@@ -122,11 +122,6 @@ packetbuffromfile(char *filename, uint8_t *wire)
hexbuf[hexbufpos] = (uint8_t) c;
hexbufpos++;
break;
- default:
- warning("unknown state while reading %s", filename);
- xfree(hexbuf);
- return 0;
- break;
}
c = fgetc(fp);
}
@@ -178,20 +173,7 @@ read_hex_buffer(char *filename)
size_t wiresize;
ldns_buffer *result_buffer = NULL;
- FILE *fp = NULL;
-
- if (strncmp(filename, "-", 2) != 0) {
- fp = fopen(filename, "r");
- } else {
- fp = stdin;
- }
-
- if (fp == NULL) {
- perror("");
- warning("Unable to open %s", filename);
- return NULL;
- }
-
+
wire = xmalloc(LDNS_MAX_PACKETLEN);
wiresize = packetbuffromfile(filename, wire);
@@ -199,8 +181,8 @@ read_hex_buffer(char *filename)
result_buffer = LDNS_MALLOC(ldns_buffer);
ldns_buffer_new_frm_data(result_buffer, wire, wiresize);
ldns_buffer_set_position(result_buffer, ldns_buffer_capacity(result_buffer));
-
xfree(wire);
+
return result_buffer;
}
@@ -236,7 +218,7 @@ read_hex_pkt(char *filename)
void
dump_hex(const ldns_pkt *pkt, const char *filename)
{
- uint8_t *wire;
+ uint8_t *wire = NULL;
size_t size, i;
FILE *fp;
ldns_status status;
@@ -252,6 +234,7 @@ dump_hex(const ldns_pkt *pkt, const char *filename)
if (status != LDNS_STATUS_OK) {
error("Unable to convert packet: error code %u", status);
+ LDNS_FREE(wire);
return;
}
@@ -273,4 +256,5 @@ dump_hex(const ldns_pkt *pkt, const char *filename)
}
fprintf(fp, "\n");
fclose(fp);
+ LDNS_FREE(wire);
}
diff --git a/usr.sbin/unbound/ldns/error.c b/usr.sbin/unbound/ldns/error.c
index cf6788ffb36..2fc63e9b099 100644
--- a/usr.sbin/unbound/ldns/error.c
+++ b/usr.sbin/unbound/ldns/error.c
@@ -95,6 +95,35 @@ ldns_lookup_table ldns_error_str[] = {
"DNSSEC signature will expire too soon" },
{ LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN,
"DNSSEC signature not incepted long enough" },
+ { LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE,
+ "Unknown TLSA Certificate Usage" },
+ { LDNS_STATUS_DANE_UNKNOWN_SELECTOR, "Unknown TLSA Selector" },
+ { LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE,
+ "Unknown TLSA Matching Type" },
+ { LDNS_STATUS_DANE_UNKNOWN_PROTOCOL,
+ "Unknown protocol. Only IPv4 and IPv6 are understood" },
+ { LDNS_STATUS_DANE_UNKNOWN_TRANSPORT,
+ "Unknown transport. Should be one of {tcp, udp, sctp}" },
+ { LDNS_STATUS_DANE_MISSING_EXTRA_CERTS, /* Trust anchor assertion */
+ "More than one certificate should be provided" },
+ { LDNS_STATUS_DANE_EXTRA_CERTS_NOT_USED, /* Trust anchor assertion */
+ "Non of the extra certificates is used to sign the first" },
+ { LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE, /* Trust anchor assertion */
+ "The offset was out of range" },
+ { LDNS_STATUS_DANE_INSECURE, /* Unused by library */
+ "The queried resource records were insecure" },
+ { LDNS_STATUS_DANE_BOGUS, /* Unused by library */
+ "The queried resource records were bogus" },
+ { LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
+ "The TLSA record(s) "
+ "did not match with the server certificate (chain)" },
+ { LDNS_STATUS_DANE_NON_CA_CERTIFICATE,
+ "The certificate was not a CA certificate" },
+ { LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE,
+ "Could not PKIX validate" },
+ { LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR,
+ "The validation path "
+ "did not end in a self-signed certificate" },
{ 0, NULL }
};
diff --git a/usr.sbin/unbound/ldns/higher.c b/usr.sbin/unbound/ldns/higher.c
index c9eb1731ae2..990fb6afb25 100644
--- a/usr.sbin/unbound/ldns/higher.c
+++ b/usr.sbin/unbound/ldns/higher.c
@@ -126,6 +126,7 @@ ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class
/* add the RD flags, because we want an answer */
pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
+ ldns_rdf_deep_free(name);
if (pkt) {
/* extract the data we need */
names = ldns_pkt_rr_list_by_type(pkt,
diff --git a/usr.sbin/unbound/ldns/host2str.c b/usr.sbin/unbound/ldns/host2str.c
index c185e0f04db..521e2468ecd 100644
--- a/usr.sbin/unbound/ldns/host2str.c
+++ b/usr.sbin/unbound/ldns/host2str.c
@@ -123,6 +123,7 @@ const ldns_output_format *ldns_output_format_onlykeyids
= &ldns_output_format_onlykeyids_record;
const ldns_output_format *ldns_output_format_default
= &ldns_output_format_onlykeyids_record;
+
const ldns_output_format ldns_output_format_bubblebabble_record = {
LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
};
@@ -195,7 +196,7 @@ ldns_pkt_opcode2str(ldns_pkt_opcode opcode)
str = NULL;
if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
- str = ldns_buffer2str(buf);
+ str = ldns_buffer_export2str(buf);
}
ldns_buffer_free(buf);
@@ -215,7 +216,7 @@ ldns_pkt_rcode2str(ldns_pkt_rcode rcode)
str = NULL;
if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
- str = ldns_buffer2str(buf);
+ str = ldns_buffer_export2str(buf);
}
ldns_buffer_free(buf);
@@ -236,7 +237,7 @@ ldns_pkt_algorithm2str(ldns_algorithm algorithm)
str = NULL;
if (ldns_algorithm2buffer_str(buf, algorithm)
== LDNS_STATUS_OK) {
- str = ldns_buffer2str(buf);
+ str = ldns_buffer_export2str(buf);
}
ldns_buffer_free(buf);
@@ -257,7 +258,7 @@ ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
str = NULL;
if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
== LDNS_STATUS_OK) {
- str = ldns_buffer2str(buf);
+ str = ldns_buffer_export2str(buf);
}
ldns_buffer_free(buf);
@@ -567,7 +568,7 @@ ldns_rr_type2str(const ldns_rr_type type)
str = NULL;
if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
- str = ldns_buffer2str(buf);
+ str = ldns_buffer_export2str(buf);
}
ldns_buffer_free(buf);
@@ -603,7 +604,7 @@ ldns_rr_class2str(const ldns_rr_class klass)
str = NULL;
if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
- str = ldns_buffer2str(buf);
+ str = ldns_buffer_export2str(buf);
}
ldns_buffer_free(buf);
return str;
@@ -1149,8 +1150,9 @@ ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
break;
}
} else {
+ /** This will write mangled RRs */
ldns_buffer_printf(buffer, "(null) ");
- res = ldns_buffer_status(buffer);
+ res = LDNS_STATUS_ERR;
}
return res;
}
@@ -1230,7 +1232,33 @@ ldns_rr2buffer_str_fmt(ldns_buffer *output,
for (i = 0; i < ldns_rr_rd_count(rr); i++) {
/* ldns_rdf2buffer_str handles NULL input fine! */
- status = ldns_rdf2buffer_str(output, ldns_rr_rdf(rr, i));
+ if ((fmt->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
+ (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
+ ((/* inception */ i == 4 &&
+ ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) ==
+ LDNS_RDF_TYPE_TIME) ||
+ (/* expiration */ i == 5 &&
+ ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
+ LDNS_RDF_TYPE_TIME) ||
+ (/* signature */ i == 8 &&
+ ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
+ LDNS_RDF_TYPE_B64))) {
+
+ ldns_buffer_printf(output, "(null)");
+ status = ldns_buffer_status(output);
+ } else if ((fmt->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
+ (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
+ /* serial */ i == 2 &&
+ ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
+ LDNS_RDF_TYPE_INT32) {
+ ldns_buffer_printf(output, "%10lu",
+ (unsigned long) ldns_read_uint32(
+ ldns_rdf_data(ldns_rr_rdf(rr, 2))));
+ status = ldns_buffer_status(output);
+ } else {
+ status = ldns_rdf2buffer_str(output,
+ ldns_rr_rdf(rr, i));
+ }
if(status != LDNS_STATUS_OK)
return status;
if (i < ldns_rr_rd_count(rr) - 1) {
@@ -1633,12 +1661,12 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
{
ldns_status status = LDNS_STATUS_OK;
unsigned char *bignum;
-#ifndef S_SPLINT_S
- uint16_t i;
-#endif
-
#ifdef HAVE_SSL
+# ifndef S_SPLINT_S
+ uint16_t i;
+# endif
/* not used when ssl is not defined */
+ /*@unused@*/
ldns_rdf *b64_bignum = NULL;
RSA *rsa;
@@ -1716,6 +1744,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1727,6 +1756,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1740,6 +1770,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1756,6 +1787,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1772,6 +1804,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1788,6 +1821,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1804,6 +1838,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1820,6 +1855,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1853,6 +1889,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1869,6 +1906,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1885,6 +1923,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1901,6 +1940,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1917,6 +1957,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1960,6 +2001,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+ ldns_rdf_deep_free(b64_bignum);
goto error;
}
ldns_rdf_deep_free(b64_bignum);
@@ -1993,9 +2035,6 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
}
#endif /* HAVE_SSL */
} else {
-#ifdef HAVE_SSL
- LDNS_FREE(b64_bignum);
-#endif
LDNS_FREE(bignum);
return ldns_buffer_status(output);
}
@@ -2012,12 +2051,11 @@ error:
}
/*
- * Zero terminate the buffer and fix it to the size of the string.
+ * Zero terminate the buffer and copy data.
*/
char *
ldns_buffer2str(ldns_buffer *buffer)
{
- char *tmp_str;
char *str;
/* check if buffer ends with \0, if not, and
@@ -2032,16 +2070,30 @@ ldns_buffer2str(ldns_buffer *buffer)
}
}
- tmp_str = ldns_buffer_export(buffer);
- str = LDNS_XMALLOC(char, strlen(tmp_str) + 1);
+ str = strdup((const char *)ldns_buffer_begin(buffer));
if(!str) {
return NULL;
}
- memcpy(str, tmp_str, strlen(tmp_str) + 1);
-
return str;
}
+/*
+ * Zero terminate the buffer and export data.
+ */
+char *
+ldns_buffer_export2str(ldns_buffer *buffer)
+{
+ /* Append '\0' as string terminator */
+ if (! ldns_buffer_reserve(buffer, 1)) {
+ return NULL;
+ }
+ ldns_buffer_write_u8(buffer, 0);
+
+ /* reallocate memory to the size of the string and export */
+ ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
+ return ldns_buffer_export(buffer);
+}
+
char *
ldns_rdf2str(const ldns_rdf *rdf)
{
@@ -2053,7 +2105,7 @@ ldns_rdf2str(const ldns_rdf *rdf)
}
if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
/* export and return string, destroy rest */
- result = ldns_buffer2str(tmp_buffer);
+ result = ldns_buffer_export2str(tmp_buffer);
}
ldns_buffer_free(tmp_buffer);
return result;
@@ -2071,7 +2123,7 @@ ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
== LDNS_STATUS_OK) {
/* export and return string, destroy rest */
- result = ldns_buffer2str(tmp_buffer);
+ result = ldns_buffer_export2str(tmp_buffer);
}
ldns_buffer_free(tmp_buffer);
return result;
@@ -2095,7 +2147,7 @@ ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
== LDNS_STATUS_OK) {
/* export and return string, destroy rest */
- result = ldns_buffer2str(tmp_buffer);
+ result = ldns_buffer_export2str(tmp_buffer);
}
ldns_buffer_free(tmp_buffer);
@@ -2119,7 +2171,7 @@ ldns_key2str(const ldns_key *k)
}
if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
/* export and return string, destroy rest */
- result = ldns_buffer2str(tmp_buffer);
+ result = ldns_buffer_export2str(tmp_buffer);
}
ldns_buffer_free(tmp_buffer);
return result;
@@ -2149,7 +2201,7 @@ ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
}
/* export and return string, destroy rest */
- result = ldns_buffer2str(tmp_buffer);
+ result = ldns_buffer_export2str(tmp_buffer);
ldns_buffer_free(tmp_buffer);
return result;
}
@@ -2167,20 +2219,20 @@ ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
if (str) {
fprintf(output, "%s", str);
} else {
- fprintf(output, "Unable to convert rdf to string\n");
+ fprintf(output, ";Unable to convert rdf to string\n");
}
LDNS_FREE(str);
}
void
-ldns_rr_print_fmt(FILE *output,
+ldns_rr_print_fmt(FILE *output,
const ldns_output_format *fmt, const ldns_rr *rr)
{
char *str = ldns_rr2str_fmt(fmt, rr);
if (str) {
fprintf(output, "%s", str);
} else {
- fprintf(output, "Unable to convert rr to string\n");
+ fprintf(output, ";Unable to convert rr to string\n");
}
LDNS_FREE(str);
}
@@ -2199,7 +2251,7 @@ ldns_pkt_print_fmt(FILE *output,
if (str) {
fprintf(output, "%s", str);
} else {
- fprintf(output, "Unable to convert packet to string\n");
+ fprintf(output, ";Unable to convert packet to string\n");
}
LDNS_FREE(str);
}
diff --git a/usr.sbin/unbound/ldns/host2wire.c b/usr.sbin/unbound/ldns/host2wire.c
index b5b0ba8ff20..de1e01e9ba3 100644
--- a/usr.sbin/unbound/ldns/host2wire.c
+++ b/usr.sbin/unbound/ldns/host2wire.c
@@ -341,7 +341,6 @@ ldns_status
ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
{
ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
- uint8_t *result = NULL;
ldns_status status;
*result_size = 0;
*dest = NULL;
@@ -350,21 +349,8 @@ ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
status = ldns_rdf2buffer_wire(buffer, rdf);
if (status == LDNS_STATUS_OK) {
*result_size = ldns_buffer_position(buffer);
- result = (uint8_t *) ldns_buffer_export(buffer);
- } else {
- ldns_buffer_free(buffer);
- return status;
- }
-
- if (result) {
- *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
- if(!*dest) {
- ldns_buffer_free(buffer);
- return LDNS_STATUS_MEM_ERR;
- }
- memcpy(*dest, result, ldns_buffer_position(buffer));
+ *dest = (uint8_t *) ldns_buffer_export(buffer);
}
-
ldns_buffer_free(buffer);
return status;
}
@@ -373,7 +359,6 @@ ldns_status
ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size)
{
ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
- uint8_t *result = NULL;
ldns_status status;
*result_size = 0;
*dest = NULL;
@@ -382,21 +367,8 @@ ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size
status = ldns_rr2buffer_wire(buffer, rr, section);
if (status == LDNS_STATUS_OK) {
*result_size = ldns_buffer_position(buffer);
- result = (uint8_t *) ldns_buffer_export(buffer);
- } else {
- ldns_buffer_free(buffer);
- return status;
+ *dest = (uint8_t *) ldns_buffer_export(buffer);
}
-
- if (result) {
- *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
- if(!*dest) {
- ldns_buffer_free(buffer);
- return LDNS_STATUS_MEM_ERR;
- }
- memcpy(*dest, result, ldns_buffer_position(buffer));
- }
-
ldns_buffer_free(buffer);
return status;
}
@@ -405,7 +377,6 @@ ldns_status
ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
{
ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
- uint8_t *result = NULL;
ldns_status status;
*result_size = 0;
*dest = NULL;
@@ -414,21 +385,8 @@ ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
status = ldns_pkt2buffer_wire(buffer, packet);
if (status == LDNS_STATUS_OK) {
*result_size = ldns_buffer_position(buffer);
- result = (uint8_t *) ldns_buffer_export(buffer);
- } else {
- ldns_buffer_free(buffer);
- return status;
+ *dest = (uint8_t *) ldns_buffer_export(buffer);
}
-
- if (result) {
- *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
- if(!*dest) {
- ldns_buffer_free(buffer);
- return LDNS_STATUS_MEM_ERR;
- }
- memcpy(*dest, result, ldns_buffer_position(buffer));
- }
-
ldns_buffer_free(buffer);
return status;
}
diff --git a/usr.sbin/unbound/ldns/keys.c b/usr.sbin/unbound/ldns/keys.c
index 54f26681494..de7c94610d8 100644
--- a/usr.sbin/unbound/ldns/keys.c
+++ b/usr.sbin/unbound/ldns/keys.c
@@ -431,8 +431,7 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
ldns_key_free(k);
return LDNS_STATUS_ERR;
}
- ldns_key_set_rsa_key(k, rsa);
- RSA_free(rsa);
+ ldns_key_assign_rsa_key(k, rsa);
#endif /* HAVE_SSL */
break;
case LDNS_SIGN_DSA:
@@ -444,8 +443,7 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
ldns_key_free(k);
return LDNS_STATUS_ERR;
}
- ldns_key_set_dsa_key(k, dsa);
- DSA_free(dsa);
+ ldns_key_assign_dsa_key(k, dsa);
#endif /* HAVE_SSL */
break;
case LDNS_SIGN_HMACMD5:
@@ -505,6 +503,7 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
*key = k;
return LDNS_STATUS_OK;
}
+ ldns_key_free(k);
return LDNS_STATUS_ERR;
}
@@ -751,28 +750,21 @@ ldns_key_new_frm_fp_hmac_l( FILE *f
, size_t *hmac_size
)
{
- size_t i;
- char *d;
- unsigned char *buf;
-
- d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
- buf = LDNS_XMALLOC(unsigned char, LDNS_MAX_LINELEN);
- if(!d || !buf) {
- goto error;
- }
+ size_t i, bufsz;
+ char d[LDNS_MAX_LINELEN];
+ unsigned char *buf = NULL;
if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
goto error;
}
- i = (size_t) ldns_b64_pton((const char*)d,
- buf,
- ldns_b64_ntop_calculate_size(strlen(d)));
+ bufsz = ldns_b64_ntop_calculate_size(strlen(d));
+ buf = LDNS_XMALLOC(unsigned char, bufsz);
+ i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz);
*hmac_size = i;
return buf;
error:
- LDNS_FREE(d);
LDNS_FREE(buf);
*hmac_size = 0;
return NULL;
@@ -850,6 +842,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 +858,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:
@@ -1005,6 +999,22 @@ ldns_key_set_dsa_key(ldns_key *k, DSA *d)
EVP_PKEY_set1_DSA(key, d);
k->_key.key = key;
}
+
+void
+ldns_key_assign_rsa_key(ldns_key *k, RSA *r)
+{
+ EVP_PKEY *key = EVP_PKEY_new();
+ EVP_PKEY_assign_RSA(key, r);
+ k->_key.key = key;
+}
+
+void
+ldns_key_assign_dsa_key(ldns_key *k, DSA *d)
+{
+ EVP_PKEY *key = EVP_PKEY_new();
+ EVP_PKEY_assign_DSA(key, d);
+ k->_key.key = key;
+}
#endif /* splint */
#endif /* HAVE_SSL */
@@ -1302,7 +1312,7 @@ ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
}
/* See RFC2536 */
- *size = (uint16_t)BN_num_bytes(k->g);
+ *size = (uint16_t)BN_num_bytes(k->p);
T = (*size - 64) / 8;
memcpy(data, &T, 1);
@@ -1365,10 +1375,10 @@ ldns_key2rr(const ldns_key *k)
#endif
int internal_data = 0;
- pubkey = ldns_rr_new();
if (!k) {
return NULL;
}
+ pubkey = ldns_rr_new();
switch (ldns_key_algorithm(k)) {
case LDNS_SIGN_HMACMD5:
@@ -1638,7 +1648,7 @@ ldns_key_get_file_base_name(ldns_key *key)
"+%03u+%05u",
ldns_key_algorithm(key),
ldns_key_keytag(key));
- file_base_name = strdup(ldns_buffer_export(buffer));
+ file_base_name = ldns_buffer_export(buffer);
ldns_buffer_free(buffer);
return file_base_name;
}
diff --git a/usr.sbin/unbound/ldns/ldns/buffer.h b/usr.sbin/unbound/ldns/ldns/buffer.h
index 03df14c9915..3b64198d8d5 100644
--- a/usr.sbin/unbound/ldns/ldns/buffer.h
+++ b/usr.sbin/unbound/ldns/ldns/buffer.h
@@ -630,8 +630,9 @@ void ldns_buffer_free(ldns_buffer *buffer);
void *ldns_buffer_export(ldns_buffer *buffer);
/**
- * Copy contents of the other buffer to this buffer. Silently truncated
- * if this buffer is too small.
+ * Copy contents of the from buffer to the result buffer and then flips
+ * the result buffer. Data will be silently truncated if the result buffer is
+ * too small.
* \param[out] *result resulting buffer which is copied to.
* \param[in] *from what to copy to result.
*/
diff --git a/usr.sbin/unbound/ldns/ldns/common.h.in b/usr.sbin/unbound/ldns/ldns/common.h.in
index 5d6254752a5..aedfc96da7f 100644
--- a/usr.sbin/unbound/ldns/ldns/common.h.in
+++ b/usr.sbin/unbound/ldns/ldns/common.h.in
@@ -23,6 +23,7 @@
#define LDNS_BUILD_CONFIG_HAVE_INTTYPES_H @ldns_build_config_have_inttypes_h@
#define LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT @ldns_build_config_have_attr_format@
#define LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED @ldns_build_config_have_attr_unused@
+#define LDNS_BUILD_CONFIG_HAVE_SOCKLEN_T @ldns_build_config_have_socklen_t@
/*
* HAVE_STDBOOL_H is not available when distributed as a library, but no build
@@ -65,4 +66,8 @@ typedef bool _Bool;
#define ATTR_UNUSED(x) x
#endif /* !LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED */
+#if !LDNS_BUILD_CONFIG_HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
#endif /* LDNS_COMMON_H */
diff --git a/usr.sbin/unbound/ldns/ldns/config.h.in b/usr.sbin/unbound/ldns/ldns/config.h.in
index 3393e99767e..98cf357074b 100644
--- a/usr.sbin/unbound/ldns/ldns/config.h.in
+++ b/usr.sbin/unbound/ldns/ldns/config.h.in
@@ -33,6 +33,12 @@
/* Define to 1 if you have the `ctime_r' function. */
#undef HAVE_CTIME_R
+/* Is a CAFILE given at configure time */
+#undef HAVE_DANE_CA_FILE
+
+/* Is a CAPATH given at configure time */
+#undef HAVE_DANE_CA_PATH
+
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
don't. */
#undef HAVE_DECL_NID_SECP384R1
@@ -250,6 +256,15 @@
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
+/* Is a CAFILE given at configure time */
+#undef LDNS_DANE_CA_FILE
+
+/* Is a CAPATH given at configure time */
+#undef LDNS_DANE_CA_PATH
+
+/* Default trust anchor file */
+#undef LDNS_TRUST_ANCHOR_FILE
+
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
diff --git a/usr.sbin/unbound/ldns/ldns/dane.h b/usr.sbin/unbound/ldns/ldns/dane.h
new file mode 100644
index 00000000000..c1c4e2d75ca
--- /dev/null
+++ b/usr.sbin/unbound/ldns/ldns/dane.h
@@ -0,0 +1,244 @@
+/*
+ * dane.h -- defines for the DNS-Based Authentication of Named Entities (DANE)
+ * Transport Layer Security (TLS) Protocol: TLSA
+ *
+ * Copyright (c) 2012, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ */
+
+/**
+ * \file
+ *
+ * This module contains base functions for creating and verifying TLSA RR's
+ * with PKIX certificates, certificate chains and validation stores.
+ * (See RFC6394 and RFC6698).
+ *
+ * Since those functions heavily rely op cryptographic operations,
+ * this module is dependent on openssl.
+ */
+
+
+#ifndef LDNS_DANE_H
+#define LDNS_DANE_H
+
+#include <ldns/common.h>
+#include <ldns/rdata.h>
+#include <ldns/rr.h>
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The different "Certificate usage" rdata field values for a TLSA RR.
+ */
+enum ldns_enum_tlsa_certificate_usage
+{
+ /** CA constraint */
+ LDNS_TLSA_USAGE_CA_CONSTRAINT = 0,
+ /** Sevice certificate constraint */
+ LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT = 1,
+ /** Trust anchor assertion */
+ LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION = 2,
+ /** Domain issued certificate */
+ LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE = 3
+};
+typedef enum ldns_enum_tlsa_certificate_usage ldns_tlsa_certificate_usage;
+
+/**
+ * The different "Selector" rdata field values for a TLSA RR.
+ */
+enum ldns_enum_tlsa_selector
+{
+ /**
+ * Full certificate: the Certificate binary structure
+ * as defined in [RFC5280]
+ */
+ LDNS_TLSA_SELECTOR_FULL_CERTIFICATE = 0,
+
+ /**
+ * SubjectPublicKeyInfo: DER-encoded binary structure
+ * as defined in [RFC5280]
+ */
+ LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO = 1
+};
+typedef enum ldns_enum_tlsa_selector ldns_tlsa_selector;
+
+/**
+ * The different "Matching type" rdata field values for a TLSA RR.
+ */
+enum ldns_enum_tlsa_matching_type
+{
+ /** Exact match on selected content */
+ LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED = 0,
+ /** SHA-256 hash of selected content [RFC6234] */
+ LDNS_TLSA_MATCHING_TYPE_SHA256 = 1,
+ /** SHA-512 hash of selected content [RFC6234] */
+ LDNS_TLSA_MATCHING_TYPE_SHA512 = 2
+};
+typedef enum ldns_enum_tlsa_matching_type ldns_tlsa_matching_type;
+
+/**
+ * Known transports to use with TLSA owner names.
+ */
+enum ldns_enum_dane_transport
+{
+ /** TCP */
+ LDNS_DANE_TRANSPORT_TCP = 0,
+ /** UDP */
+ LDNS_DANE_TRANSPORT_UDP = 1,
+ /** SCTP */
+ LDNS_DANE_TRANSPORT_SCTP = 2
+};
+typedef enum ldns_enum_dane_transport ldns_dane_transport;
+
+
+/**
+ * Creates a dname consisting of the given name, prefixed by the service port
+ * and type of transport: _<EM>port</EM>._<EM>transport</EM>.<EM>name</EM>.
+ *
+ * \param[out] tlsa_owner The created dname.
+ * \param[in] name The dname that should be prefixed.
+ * \param[in] port The service port number for wich the name should be created.
+ * \param[in] transport The transport for wich the name should be created.
+ * \return LDNS_STATUS_OK on success or an error code otherwise.
+ */
+ldns_status ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner,
+ const ldns_rdf* name, uint16_t port,
+ ldns_dane_transport transport);
+
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * Creates a LDNS_RDF_TYPE_HEX type rdf based on the binary data choosen by
+ * the selector and encoded using matching_type.
+ *
+ * \param[out] rdf The created created rdf of type LDNS_RDF_TYPE_HEX.
+ * \param[in] cert The certificate from which the data is selected
+ * \param[in] selector The full certificate or the public key
+ * \param[in] matching_type The full data or the SHA256 or SHA512 hash
+ * of the selected data
+ * \return LDNS_STATUS_OK on success or an error code otherwise.
+ */
+ldns_status ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
+ ldns_tlsa_selector selector,
+ ldns_tlsa_matching_type matching_type);
+
+
+/**
+ * Selects the certificate from cert, extra_certs or the pkix_validation_store
+ * based on the value of cert_usage and index.
+ *
+ * \param[out] selected_cert The selected cert.
+ * \param[in] cert The certificate to validate (or not)
+ * \param[in] extra_certs Intermediate certificates that might be necessary
+ * during validation. May be NULL, except when the certificate
+ * usage is "Trust Anchor Assertion" because the trust anchor has
+ * to be provided.(otherwise choose a "Domain issued certificate!"
+ * \param[in] pkix_validation_store Used when the certificate usage is
+ * "CA constraint" or "Service Certificate Constraint" to
+ * validate the certificate and, in case of "CA constraint",
+ * select the CA.
+ * When pkix_validation_store is NULL, validation is explicitely
+ * turned off and the behaviour is then the same as for "Trust
+ * anchor assertion" and "Domain issued certificate" respectively.
+ * \param[in] cert_usage Which certificate to use and how to validate.
+ * \param[in] index Used to select the trust anchor when certificate usage
+ * is "Trust Anchor Assertion". 0 is the last certificate in the
+ * validation chain. 1 the one but last, etc. When index is -1,
+ * the last certificate is used that MUST be self-signed.
+ * This can help to make sure that the intended (self signed)
+ * trust anchor is actually present in extra_certs (which is a
+ * DANE requirement).
+ *
+ * \return LDNS_STATUS_OK on success or an error code otherwise.
+ */
+ldns_status ldns_dane_select_certificate(X509** selected_cert,
+ X509* cert, STACK_OF(X509)* extra_certs,
+ X509_STORE* pkix_validation_store,
+ ldns_tlsa_certificate_usage cert_usage, int index);
+
+/**
+ * Creates a TLSA resource record from the certificate.
+ * No PKIX validation is performed! The given certificate is used as data
+ * regardless the value of certificate_usage.
+ *
+ * \param[out] tlsa The created TLSA resource record.
+ * \param[in] certificate_usage The value for the Certificate Usage field
+ * \param[in] selector The value for the Selector field
+ * \param[in] matching_type The value for the Matching Type field
+ * \param[in] cert The certificate which data will be represented
+ *
+ * \return LDNS_STATUS_OK on success or an error code otherwise.
+ */
+ldns_status ldns_dane_create_tlsa_rr(ldns_rr** tlsa,
+ ldns_tlsa_certificate_usage certificate_usage,
+ ldns_tlsa_selector selector,
+ ldns_tlsa_matching_type matching_type,
+ X509* cert);
+
+/**
+ * Verify if the given TLSA resource record matches the given certificate.
+ * Reporting on a TLSA rr mismatch (LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH)
+ * is preferred over PKIX failure (LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE).
+ * So when PKIX validation is required by the TLSA Certificate usage,
+ * but the TLSA data does not match, LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH
+ * is returned whether the PKIX validated or not.
+ *
+ * \param[in] tlsa_rr The resource record that specifies what and how to
+ * match the certificate. With tlsa_rr == NULL, regular PKIX
+ * validation is performed.
+ * \param[in] cert The certificate to match (and validate)
+ * \param[in] extra_certs Intermediate certificates that might be necessary
+ * creating the validation chain.
+ * \param[in] pkix_validation_store Used when the certificate usage is
+ * "CA constraint" or "Service Certificate Constraint" to
+ * validate the certificate.
+ *
+ * \return LDNS_STATUS_OK on success,
+ * LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH on TLSA data mismatch,
+ * LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE when TLSA matched,
+ * but the PKIX validation failed, or other ldns_status errors.
+ */
+ldns_status ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
+ X509* cert, STACK_OF(X509)* extra_certs,
+ X509_STORE* pkix_validation_store);
+
+/**
+ * Verify if any of the given TLSA resource records matches the given
+ * certificate.
+ *
+ * \param[in] tlsas The resource records that specify what and how to
+ * match the certificate. One must match for this function
+ * to succeed. With tlsas == NULL or the number of TLSA records
+ * in tlsas == 0, regular PKIX validation is performed.
+ * \param[in] cert The certificate to match (and validate)
+ * \param[in] extra_certs Intermediate certificates that might be necessary
+ * creating the validation chain.
+ * \param[in] pkix_validation_store Used when the certificate usage is
+ * "CA constraint" or "Service Certificate Constraint" to
+ * validate the certificate.
+ *
+ * \return LDNS_STATUS_OK on success,
+ * LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE when one of the TLSA's
+ * matched but the PKIX validation failed,
+ * LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH when none of the TLSA's matched,
+ * or other ldns_status errors.
+ */
+ldns_status ldns_dane_verify(ldns_rr_list* tlsas,
+ X509* cert, STACK_OF(X509)* extra_certs,
+ X509_STORE* pkix_validation_store);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_DANE_H */
+
diff --git a/usr.sbin/unbound/ldns/ldns/dname.h b/usr.sbin/unbound/ldns/ldns/dname.h
index a91f075257c..16b45429fb2 100644
--- a/usr.sbin/unbound/ldns/ldns/dname.h
+++ b/usr.sbin/unbound/ldns/ldns/dname.h
@@ -111,6 +111,7 @@ ldns_rdf *ldns_dname_new_frm_str(const char *str);
* Create a new dname rdf from a string
* \param[in] s the size of the new dname
* \param[in] *data pointer to the actual data
+ *
* \return ldns_rdf*
*/
ldns_rdf *ldns_dname_new(uint16_t s, void *data);
@@ -119,6 +120,7 @@ ldns_rdf *ldns_dname_new(uint16_t s, void *data);
* Create a new dname rdf from data (the data is copied)
* \param[in] size the size of the data
* \param[in] *data pointer to the actual data
+ *
* \return ldns_rdf*
*/
ldns_rdf *ldns_dname_new_frm_data(uint16_t size, const void *data);
@@ -178,6 +180,13 @@ int ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle, const ldns
bool ldns_dname_str_absolute(const char *dname_str);
/**
+ * Checks whether the given dname is absolute (i.e. ends with a '.')
+ * \param[in] *dname a rdf representing the dname
+ * \return true or false
+ */
+bool ldns_dname_absolute(const ldns_rdf *dname);
+
+/**
* look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME
* try and retrieve a specific label. The labels are numbered
* starting from 0 (left most).
diff --git a/usr.sbin/unbound/ldns/ldns/dnssec.h b/usr.sbin/unbound/ldns/ldns/dnssec.h
index 9e602b5bc1d..34f63714c34 100644
--- a/usr.sbin/unbound/ldns/ldns/dnssec.h
+++ b/usr.sbin/unbound/ldns/ldns/dnssec.h
@@ -198,6 +198,7 @@ RSA *ldns_key_buf2rsa_raw(unsigned char* key, size_t len);
*
* \param[in] *key the key to convert
* \param[in] h the hash to use LDNS_SHA1/LDNS_SHA256
+ *
* \return ldns_rr* a new rr pointer to a DS
*/
ldns_rr *ldns_key_rr2ds(const ldns_rr *key, ldns_hash h);
diff --git a/usr.sbin/unbound/ldns/ldns/dnssec_verify.h b/usr.sbin/unbound/ldns/ldns/dnssec_verify.h
index 32036a8c0b0..b6bdeca539b 100644
--- a/usr.sbin/unbound/ldns/ldns/dnssec_verify.h
+++ b/usr.sbin/unbound/ldns/ldns/dnssec_verify.h
@@ -367,6 +367,7 @@ void ldns_dnssec_derive_trust_tree_no_sig_time(
*
* \param *tree The trust tree so search
* \param *keys A ldns_rr_list of DNSKEY and DS rrs to look for
+ *
* \return LDNS_STATUS_OK if there is a trusted path to one of
* the keys, or the *first* error encountered
* if there were no paths
diff --git a/usr.sbin/unbound/ldns/ldns/dnssec_zone.h b/usr.sbin/unbound/ldns/ldns/dnssec_zone.h
index 4d2642fd1b4..70c81b04793 100644
--- a/usr.sbin/unbound/ldns/ldns/dnssec_zone.h
+++ b/usr.sbin/unbound/ldns/ldns/dnssec_zone.h
@@ -8,7 +8,6 @@
#ifndef LDNS_DNSSEC_ZONE_H
#define LDNS_DNSSEC_ZONE_H
-#include <ldns/ldns.h>
#include <ldns/rbtree.h>
#include <ldns/host2str.h>
diff --git a/usr.sbin/unbound/ldns/ldns/error.h b/usr.sbin/unbound/ldns/ldns/error.h
index 6396a934664..bac38ff8714 100644
--- a/usr.sbin/unbound/ldns/ldns/error.h
+++ b/usr.sbin/unbound/ldns/ldns/error.h
@@ -102,7 +102,22 @@ enum ldns_enum_status {
LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG,
LDNS_STATUS_MISSING_RDATA_FIELDS_KEY,
LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN,
- LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN
+ LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN,
+ LDNS_STATUS_DANE_STATUS_MESSAGES,
+ LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE,
+ LDNS_STATUS_DANE_UNKNOWN_SELECTOR,
+ LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE,
+ LDNS_STATUS_DANE_UNKNOWN_PROTOCOL,
+ LDNS_STATUS_DANE_UNKNOWN_TRANSPORT,
+ LDNS_STATUS_DANE_MISSING_EXTRA_CERTS,
+ LDNS_STATUS_DANE_EXTRA_CERTS_NOT_USED,
+ LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE,
+ LDNS_STATUS_DANE_INSECURE,
+ LDNS_STATUS_DANE_BOGUS,
+ LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
+ LDNS_STATUS_DANE_NON_CA_CERTIFICATE,
+ LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE,
+ LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR
};
typedef enum ldns_enum_status ldns_status;
diff --git a/usr.sbin/unbound/ldns/ldns/host2str.h b/usr.sbin/unbound/ldns/ldns/host2str.h
index f0a14a4304a..bbf932767b3 100644
--- a/usr.sbin/unbound/ldns/ldns/host2str.h
+++ b/usr.sbin/unbound/ldns/ldns/host2str.h
@@ -64,6 +64,8 @@ extern "C" {
#define LDNS_COMMENT_LAYOUT 0x0080
/** Also comment KEY_ID with RRSIGS **/
#define LDNS_COMMENT_RRSIGS 0x0100
+#define LDNS_FMT_ZEROIZE_RRSIGS 0x0200
+#define LDNS_FMT_PAD_SOA_SERIAL 0x0400
/**
* Output format specifier
@@ -601,8 +603,9 @@ char *ldns_rr_list2str_fmt(
const ldns_output_format *fmt, const ldns_rr_list *rr_list);
/**
- * Returns the data in the buffer as a null terminated char * string
- * Buffer data must be char * type, and must be freed by the caller
+ * Returns a copy of the data in the buffer as a null terminated
+ * char * string. The returned string must be freed by the caller.
+ * The buffer must be in write modus and may thus not have been flipped.
*
* \param[in] buffer buffer containing char * data
* \return null terminated char * data, or NULL on error
@@ -610,6 +613,17 @@ char *ldns_rr_list2str_fmt(
char *ldns_buffer2str(ldns_buffer *buffer);
/**
+ * Exports and returns the data in the buffer as a null terminated
+ * char * string. The returned string must be freed by the caller.
+ * The buffer must be in write modus and may thus not have been flipped.
+ * The buffer is fixed after this function returns.
+ *
+ * \param[in] buffer buffer containing char * data
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_buffer_export2str(ldns_buffer *buffer);
+
+/**
* Prints the data in the rdata field to the given file stream
* (in presentation format)
*
diff --git a/usr.sbin/unbound/ldns/ldns/keys.h b/usr.sbin/unbound/ldns/ldns/keys.h
index c4bf536911f..3e156233ba2 100644
--- a/usr.sbin/unbound/ldns/ldns/keys.h
+++ b/usr.sbin/unbound/ldns/ldns/keys.h
@@ -25,7 +25,6 @@
#if LDNS_BUILD_CONFIG_HAVE_SSL
#include <openssl/ssl.h>
#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-#include <ldns/dnssec.h>
#include <ldns/util.h>
#include <errno.h>
@@ -299,18 +298,37 @@ void ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l);
void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e);
/**
- * Set the key's rsa data
+ * Set the key's rsa data.
+ * The rsa data should be freed by the user.
* \param[in] k the key
* \param[in] r the rsa data
*/
void ldns_key_set_rsa_key(ldns_key *k, RSA *r);
+
/**
* Set the key's dsa data
+ * The dsa data should be freed by the user.
* \param[in] k the key
* \param[in] d the dsa data
*/
void ldns_key_set_dsa_key(ldns_key *k, DSA *d);
+/**
+ * Assign the key's rsa data
+ * The rsa data will be freed automatically when the key is freed.
+ * \param[in] k the key
+ * \param[in] r the rsa data
+ */
+void ldns_key_assign_rsa_key(ldns_key *k, RSA *r);
+
+/**
+ * Assign the key's dsa data
+ * The dsa data will be freed automatically when the key is freed.
+ * \param[in] k the key
+ * \param[in] d the dsa data
+ */
+void ldns_key_assign_dsa_key(ldns_key *k, DSA *d);
+
/**
* Get the PKEY id for GOST, loads GOST into openssl as a side effect.
* Only available if GOST is compiled into the library and openssl.
diff --git a/usr.sbin/unbound/ldns/ldns/ldns.h b/usr.sbin/unbound/ldns/ldns/ldns.h
index 79152543348..a41e0325d67 100644
--- a/usr.sbin/unbound/ldns/ldns/ldns.h
+++ b/usr.sbin/unbound/ldns/ldns/ldns.h
@@ -95,6 +95,7 @@ Or you can just use the menu above to browse through the API docs.
#include <ldns/util.h>
#include <ldns/buffer.h>
#include <ldns/common.h>
+#include <ldns/dane.h>
#include <ldns/dname.h>
#include <ldns/dnssec.h>
#include <ldns/dnssec_verify.h>
diff --git a/usr.sbin/unbound/ldns/ldns/rdata.h b/usr.sbin/unbound/ldns/ldns/rdata.h
index 90dcbf13818..229a4d4c5b5 100644
--- a/usr.sbin/unbound/ldns/ldns/rdata.h
+++ b/usr.sbin/unbound/ldns/ldns/rdata.h
@@ -194,6 +194,7 @@ ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd);
/**
* returns the data of the rdf.
* \param[in] *rd the rdf to read from
+ *
* \return uint8_t* pointer to the rdf's data
*/
uint8_t *ldns_rdf_data(const ldns_rdf *rd);
@@ -303,6 +304,7 @@ ldns_rdf *ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value);
* The memory is copied, and an LDNS_RDF_TYPE_INT16DATA is returned
* \param[in] size the size of the data
* \param[in] *data pointer to the actual data
+ *
* \return ldns_rd* the rdf with the data
*/
ldns_rdf *ldns_native2rdf_int16_data(size_t size, uint8_t *data);
diff --git a/usr.sbin/unbound/ldns/ldns/resolver.h b/usr.sbin/unbound/ldns/ldns/resolver.h
index f887aaf676e..7af5d401e65 100644
--- a/usr.sbin/unbound/ldns/ldns/resolver.h
+++ b/usr.sbin/unbound/ldns/ldns/resolver.h
@@ -578,6 +578,7 @@ ldns_status ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list
* \param[in] t query for this type (may be 0, defaults to A)
* \param[in] c query for this class (may be 0, default to IN)
* \param[in] flags the query flags
+ *
* \return ldns_pkt* a packet with the reply from the nameserver
*/
ldns_pkt* ldns_resolver_search(const ldns_resolver *r, const ldns_rdf *rdf, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
@@ -590,6 +591,7 @@ ldns_pkt* ldns_resolver_search(const ldns_resolver *r, const ldns_rdf *rdf, ldns
* \param[in] t query for this type (may be 0, defaults to A)
* \param[in] c query for this class (may be 0, default to IN)
* \param[in] f the query flags
+ *
* \return ldns_pkt* a packet with the reply from the nameserver
*/
ldns_status ldns_resolver_prepare_query_pkt(ldns_pkt **q, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t f);
@@ -602,6 +604,7 @@ ldns_status ldns_resolver_prepare_query_pkt(ldns_pkt **q, ldns_resolver *r, cons
* \param[in] t query for this type (may be 0, defaults to A)
* \param[in] c query for this class (may be 0, default to IN)
* \param[in] flags the query flags
+ *
* \return ldns_pkt* a packet with the reply from the nameserver
*/
ldns_status ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
@@ -621,6 +624,7 @@ ldns_status ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, ldns_pkt
* \param[in] *t query for this type (may be 0, defaults to A)
* \param[in] *c query for this class (may be 0, default to IN)
* \param[in] flags the query flags
+ *
* \return ldns_pkt* a packet with the reply from the nameserver
* if _defnames is true the default domain will be added
*/
diff --git a/usr.sbin/unbound/ldns/ldns/rr.h b/usr.sbin/unbound/ldns/ldns/rr.h
index 9882931b488..0520dcfe102 100644
--- a/usr.sbin/unbound/ldns/ldns/rr.h
+++ b/usr.sbin/unbound/ldns/ldns/rr.h
@@ -37,7 +37,7 @@ extern "C" {
#define LDNS_RR_OVERHEAD 10
/* The first fields are 'common' and can be referenced instantly */
-#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 52
+#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 53
@@ -179,6 +179,8 @@ enum ldns_enum_rr_type
LDNS_RR_TYPE_NSEC3 = 50, /* RFC 5155 */
LDNS_RR_TYPE_NSEC3PARAM = 51, /* RFC 5155 */
LDNS_RR_TYPE_NSEC3PARAMS = 51,
+ /** draft-ietf-dane-protocol */
+ LDNS_RR_TYPE_TLSA = 52,
/** draft-ietf-dnsop-trust-history */
LDNS_RR_TYPE_TALINK = 58,
diff --git a/usr.sbin/unbound/ldns/ldns/util.h.in b/usr.sbin/unbound/ldns/ldns/util.h.in
index f9fb10420cc..fe4ff3720b0 100644
--- a/usr.sbin/unbound/ldns/ldns/util.h.in
+++ b/usr.sbin/unbound/ldns/ldns/util.h.in
@@ -268,6 +268,8 @@ const char * ldns_version(void);
* \param[in] tm a struct tm* with the date
* \return the seconds since epoch
*/
+time_t ldns_mktime_from_utc(const struct tm *tm);
+
time_t mktime_from_utc(const struct tm *tm);
/**
diff --git a/usr.sbin/unbound/ldns/libdns.doxygen b/usr.sbin/unbound/ldns/libdns.doxygen
index 3325db94af4..0f84b73435e 100644
--- a/usr.sbin/unbound/ldns/libdns.doxygen
+++ b/usr.sbin/unbound/ldns/libdns.doxygen
@@ -1,4 +1,4 @@
-# Doxyfile 1.7.3
+# Doxyfile 1.7.6.1
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -22,8 +22,9 @@
DOXYFILE_ENCODING = UTF-8
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
PROJECT_NAME = ldns
@@ -33,7 +34,9 @@ PROJECT_NAME = ldns
PROJECT_NUMBER = 1.6.7
-# Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short.
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF =
@@ -192,6 +195,13 @@ TAB_SIZE = 8
ALIASES =
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
# For instance, some of the names that are used will be different. The list
@@ -274,6 +284,22 @@ DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
# is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
@@ -296,10 +322,21 @@ TYPEDEF_HIDES_STRUCT = NO
# a logarithmic scale so increasing the size by one will roughly double the
# memory usage. The cache size is given by this formula:
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols
+# corresponding to a cache size of 2^16 = 65536 symbols.
SYMBOL_CACHE_SIZE = 0
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 0
+
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@@ -449,8 +486,11 @@ SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a
-# match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
# will still accept a match between prototype and implementation in such cases.
STRICT_PROTO_MATCHING = NO
@@ -538,6 +578,16 @@ FILE_VERSION_FILTER =
LAYOUT_FILE =
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES =
+
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
@@ -629,13 +679,15 @@ FILE_PATTERNS =
RECURSIVE = NO
-# The EXCLUDE tag can be used to specify files and/or directories that should
+# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
EXCLUDE =
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
# from the input.
@@ -821,7 +873,14 @@ HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
HTML_HEADER = doc/header.html
@@ -836,12 +895,21 @@ HTML_FOOTER =
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet. Note that doxygen will try to copy
# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
+# style sheet in the HTML output directory as well, or it will be erased!
HTML_STYLESHEET =
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
-# Doxygen will adjust the colors in the stylesheet and background images
+# Doxygen will adjust the colors in the style sheet and background images
# according to this color. Hue is specified as an angle on a colorwheel,
# see http://en.wikipedia.org/wiki/Hue for more information.
# For instance the value 0 represents red, 60 is yellow, 120 is green,
@@ -871,12 +939,6 @@ HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded. For this to work a browser that supports
@@ -1036,18 +1098,14 @@ GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
DISABLE_INDEX = NO
-# This tag can be used to set the number of enum values (range [0,1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-# Note that a value of 0 will completely suppress the enum values from appearing in the overview section.
-
-ENUM_VALUES_PER_LINE = 4
-
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information.
# If the tag value is set to YES, a side panel will be generated
@@ -1055,13 +1113,17 @@ ENUM_VALUES_PER_LINE = 4
# is generated for HTML Help). For this to work a browser that supports
# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
GENERATE_TREEVIEW = NO
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
-# and Class Hierarchy pages using a tree view instead of an ordered list.
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
-USE_INLINE_TREES = NO
+ENUM_VALUES_PER_LINE = 4
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
@@ -1103,12 +1165,18 @@ USE_MATHJAX = NO
# HTML output directory using the MATHJAX_RELPATH option. The destination
# directory should contain the MathJax.js script. For instance, if the mathjax
# directory is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the
+# mathjax.org site, so you can quickly see the result without installing
# MathJax, but it is strongly recommended to install a local copy of MathJax
# before deployment.
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
# When the SEARCHENGINE tag is enabled doxygen will generate a search box
# for the HTML output. The underlying search engine uses javascript
# and DHTML and should work on any modern browser. Note that when using
@@ -1182,6 +1250,13 @@ EXTRA_PACKAGES =
LATEX_HEADER =
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
@@ -1215,6 +1290,12 @@ LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
@@ -1246,7 +1327,7 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# Load style sheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
@@ -1391,7 +1472,7 @@ MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
SEARCH_INCLUDES = YES
@@ -1399,7 +1480,7 @@ SEARCH_INCLUDES = YES
# contain include files that are not input files but should be processed by
# the preprocessor.
-INCLUDE_PATH =
+INCLUDE_PATH = .
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1421,7 +1502,8 @@ PREDEFINED = HAVE_SSL
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
EXPAND_AS_DEFINED =
@@ -1519,13 +1601,12 @@ HAVE_DOT = NO
DOT_NUM_THREADS = 0
-# By default doxygen will write a font called Helvetica to the output
-# directory and reference it in all dot files that doxygen generates.
-# When you want a differently looking font you can specify the font name
-# using DOT_FONTNAME. You need to make sure dot is able to find the font,
-# which can be done by putting it in a standard location or by setting the
-# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
-# containing the font.
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
DOT_FONTNAME = Helvetica
@@ -1534,17 +1615,16 @@ DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
-# By default doxygen will tell dot to use the output directory to look for the
-# FreeSans.ttf font (which doxygen will put there itself). If you specify a
-# different font using DOT_FONTNAME you can set the path where dot
-# can find it using this tag.
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
DOT_FONTPATH =
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
+# CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
@@ -1614,11 +1694,22 @@ GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, svg, gif or svg.
-# If left blank png will be used.
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
DOT_IMAGE_FORMAT = png
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
diff --git a/usr.sbin/unbound/ldns/net.c b/usr.sbin/unbound/ldns/net.c
index 870511a75b2..6b444da677b 100644
--- a/usr.sbin/unbound/ldns/net.c
+++ b/usr.sbin/unbound/ldns/net.c
@@ -110,12 +110,14 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
if ((ns->ss_family == AF_INET) &&
(ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
/* not reachable */
+ LDNS_FREE(ns);
continue;
}
if ((ns->ss_family == AF_INET6) &&
(ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
/* not reachable */
+ LDNS_FREE(ns);
continue;
}
#endif
@@ -182,7 +184,8 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
ldns_pkt_set_querytime(reply, (uint32_t)
((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
(tv_e.tv_usec - tv_s.tv_usec) / 1000);
- ldns_pkt_set_answerfrom(reply, ns_array[i]);
+ ldns_pkt_set_answerfrom(reply,
+ ldns_rdf_clone(ns_array[i]));
ldns_pkt_set_timestamp(reply, tv_s);
ldns_pkt_set_size(reply, reply_size);
break;
@@ -203,7 +206,7 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
return LDNS_STATUS_RES_NO_NS;
}
#ifdef HAVE_SSL
- if (tsig_mac && reply_bytes) {
+ if (tsig_mac && reply && reply_bytes) {
if (!ldns_pkt_tsig_verify(reply,
reply_bytes,
reply_size,
@@ -470,7 +473,7 @@ ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
if(!sendbuf) return 0;
ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
- memcpy(sendbuf + 2, ldns_buffer_export(qbin), ldns_buffer_position(qbin));
+ memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
bytes = sendto(sockfd, (void*)sendbuf,
ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
@@ -669,7 +672,7 @@ ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storag
}
/* resize accordingly */
- *result = (uint8_t*)LDNS_XREALLOC(answer, uint8_t *, (size_t)*answer_size);
+ *result = LDNS_XREALLOC(answer, uint8_t, (size_t)*answer_size);
if(!*result) {
LDNS_FREE(answer);
return LDNS_STATUS_MEM_ERR;
@@ -807,6 +810,9 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
ns_i < ldns_resolver_nameserver_count(resolver) &&
resolver->_socket == 0;
ns_i++) {
+ if (ns != NULL) {
+ LDNS_FREE(ns);
+ }
ns = ldns_rdf2native_sockaddr_storage(
resolver->_nameservers[ns_i],
ldns_resolver_port(resolver), &ns_len);
@@ -837,6 +843,9 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
#endif
resolver->_socket = 0;
+ ldns_pkt_free(query);
+ LDNS_FREE(ns);
+
return LDNS_STATUS_CRYPTO_TSIG_ERR;
}
}
diff --git a/usr.sbin/unbound/ldns/packet.c b/usr.sbin/unbound/ldns/packet.c
index 0ac5ca8ba31..b44c0add645 100644
--- a/usr.sbin/unbound/ldns/packet.c
+++ b/usr.sbin/unbound/ldns/packet.c
@@ -255,7 +255,6 @@ ldns_pkt_rr_list_by_name(ldns_pkt *packet,
ldns_pkt_section sec)
{
ldns_rr_list *rrs;
- ldns_rr_list *new;
ldns_rr_list *ret;
uint16_t i;
@@ -264,7 +263,6 @@ ldns_pkt_rr_list_by_name(ldns_pkt *packet,
}
rrs = ldns_pkt_get_section_clone(packet, sec);
- new = ldns_rr_list_new();
ret = NULL;
for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
@@ -272,8 +270,10 @@ ldns_pkt_rr_list_by_name(ldns_pkt *packet,
ldns_rr_list_rr(rrs, i)),
ownername) == 0) {
/* owner names match */
- ldns_rr_list_push_rr(new, ldns_rr_list_rr(rrs, i));
- ret = new;
+ if (ret == NULL) {
+ ret = ldns_rr_list_new();
+ }
+ ldns_rr_list_push_rr(ret, ldns_rr_list_rr(rrs, i));
}
}
return ret;
@@ -649,19 +649,27 @@ ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr)
{
switch(section) {
case LDNS_SECTION_QUESTION:
- ldns_rr_list_push_rr(ldns_pkt_question(packet), rr);
+ if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
+ return false;
+ }
ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1);
break;
case LDNS_SECTION_ANSWER:
- ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr);
+ if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
+ return false;
+ }
ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1);
break;
case LDNS_SECTION_AUTHORITY:
- ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr);
+ if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
+ return false;
+ }
ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1);
break;
case LDNS_SECTION_ADDITIONAL:
- ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr);
+ if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
+ return false;
+ }
ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1);
break;
case LDNS_SECTION_ANY:
@@ -783,6 +791,7 @@ ldns_pkt_free(ldns_pkt *packet)
ldns_rr_list_deep_free(packet->_additional);
ldns_rr_free(packet->_tsig_rr);
ldns_rdf_deep_free(packet->_edns_data);
+ ldns_rdf_deep_free(packet->_answerfrom);
LDNS_FREE(packet);
}
}
@@ -817,6 +826,86 @@ ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags)
return true;
}
+
+static ldns_status
+ldns_pkt_add_authsoa(ldns_pkt* packet, ldns_rdf* rr_name, ldns_rr_class rr_class)
+{
+ ldns_rr* soa_rr = ldns_rr_new();
+ ldns_rdf *owner_rdf;
+ ldns_rdf *mname_rdf;
+ ldns_rdf *rname_rdf;
+ ldns_rdf *serial_rdf;
+ ldns_rdf *refresh_rdf;
+ ldns_rdf *retry_rdf;
+ ldns_rdf *expire_rdf;
+ ldns_rdf *minimum_rdf;
+
+ if (!soa_rr) {
+ return LDNS_STATUS_MEM_ERR;
+ }
+ owner_rdf = ldns_rdf_clone(rr_name);
+ if (!owner_rdf) {
+ ldns_rr_free(soa_rr);
+ return LDNS_STATUS_MEM_ERR;
+ }
+
+ ldns_rr_set_owner(soa_rr, owner_rdf);
+ ldns_rr_set_type(soa_rr, LDNS_RR_TYPE_SOA);
+ ldns_rr_set_class(soa_rr, rr_class);
+ ldns_rr_set_question(soa_rr, false);
+
+ if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
+ ldns_rr_free(soa_rr);
+ return LDNS_STATUS_MEM_ERR;
+ } else {
+ ldns_rr_push_rdf(soa_rr, mname_rdf);
+ }
+ if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
+ ldns_rr_free(soa_rr);
+ return LDNS_STATUS_MEM_ERR;
+ } else {
+ ldns_rr_push_rdf(soa_rr, rname_rdf);
+ }
+ serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+ if (!serial_rdf) {
+ ldns_rr_free(soa_rr);
+ return LDNS_STATUS_MEM_ERR;
+ } else {
+ ldns_rr_push_rdf(soa_rr, serial_rdf);
+ }
+ refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+ if (!refresh_rdf) {
+ ldns_rr_free(soa_rr);
+ return LDNS_STATUS_MEM_ERR;
+ } else {
+ ldns_rr_push_rdf(soa_rr, refresh_rdf);
+ }
+ retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+ if (!retry_rdf) {
+ ldns_rr_free(soa_rr);
+ return LDNS_STATUS_MEM_ERR;
+ } else {
+ ldns_rr_push_rdf(soa_rr, retry_rdf);
+ }
+ expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+ if (!expire_rdf) {
+ ldns_rr_free(soa_rr);
+ return LDNS_STATUS_MEM_ERR;
+ } else {
+ ldns_rr_push_rdf(soa_rr, expire_rdf);
+ }
+ minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+ if (!minimum_rdf) {
+ ldns_rr_free(soa_rr);
+ return LDNS_STATUS_MEM_ERR;
+ } else {
+ ldns_rr_push_rdf(soa_rr, minimum_rdf);
+ }
+ ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, soa_rr);
+ return LDNS_STATUS_OK;
+}
+
+
ldns_status
ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name, ldns_rr_type rr_type,
ldns_rr_class rr_class, uint16_t flags)
@@ -851,21 +940,29 @@ ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name, ldns_rr_type rr_type,
ldns_rr_set_type(question_rr, rr_type);
ldns_rr_set_class(question_rr, rr_class);
ldns_rr_set_question(question_rr, true);
-
+
ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
} else {
ldns_rr_free(question_rr);
ldns_pkt_free(packet);
return LDNS_STATUS_ERR;
}
-
+
+ /** IXFR? */
+ if (rr_type == LDNS_RR_TYPE_IXFR) {
+ if (ldns_pkt_add_authsoa(packet, name_rdf, rr_class) != LDNS_STATUS_OK) {
+ ldns_pkt_free(packet);
+ return LDNS_STATUS_ERR;
+ }
+ }
+
packet->_tsig_rr = NULL;
-
ldns_pkt_set_answerfrom(packet, NULL);
if (p) {
*p = packet;
return LDNS_STATUS_OK;
} else {
+ ldns_pkt_free(packet);
return LDNS_STATUS_NULL;
}
}
@@ -888,6 +985,7 @@ ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_cla
question_rr = ldns_rr_new();
if (!question_rr) {
+ ldns_pkt_free(packet);
return NULL;
}
@@ -902,11 +1000,17 @@ ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_cla
ldns_rr_set_type(question_rr, rr_type);
ldns_rr_set_class(question_rr, rr_class);
ldns_rr_set_question(question_rr, true);
-
- packet->_tsig_rr = NULL;
-
ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
+ /** IXFR? */
+ if (rr_type == LDNS_RR_TYPE_IXFR) {
+ if (ldns_pkt_add_authsoa(packet, rr_name, rr_class) != LDNS_STATUS_OK) {
+ ldns_pkt_free(packet);
+ return NULL;
+ }
+ }
+
+ packet->_tsig_rr = NULL;
return packet;
}
@@ -980,7 +1084,9 @@ ldns_pkt_clone(ldns_pkt *pkt)
ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt));
ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt));
ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt));
- ldns_pkt_set_answerfrom(new_pkt, ldns_pkt_answerfrom(pkt));
+ if (ldns_pkt_answerfrom(pkt))
+ ldns_pkt_set_answerfrom(new_pkt,
+ ldns_rdf_clone(ldns_pkt_answerfrom(pkt)));
ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt)));
diff --git a/usr.sbin/unbound/ldns/parse.c b/usr.sbin/unbound/ldns/parse.c
index ac9bdbdd556..ea5ffad026f 100644
--- a/usr.sbin/unbound/ldns/parse.c
+++ b/usr.sbin/unbound/ldns/parse.c
@@ -161,7 +161,7 @@ ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *li
return (ssize_t)i;
tokenread:
- ldns_fskipcs_l(f, delim, line_nr);
+ ldns_fskipcs_l(f, del, line_nr);
*t = '\0';
if (p != 0) {
return -1;
@@ -331,7 +331,7 @@ ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
return (ssize_t)i;
tokenread:
- ldns_bskipcs(b, delim);
+ ldns_bskipcs(b, del);
*t = '\0';
if (p != 0) {
diff --git a/usr.sbin/unbound/ldns/resolver.c b/usr.sbin/unbound/ldns/resolver.c
index 1a788a363fe..2cee9fff194 100644
--- a/usr.sbin/unbound/ldns/resolver.c
+++ b/usr.sbin/unbound/ldns/resolver.c
@@ -253,13 +253,20 @@ ldns_resolver_pop_nameserver(ldns_resolver *r)
pop = nameservers[ns_count - 1];
- nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count - 1));
- rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
+ if (ns_count == 1) {
+ LDNS_FREE(nameservers);
+ LDNS_FREE(rtt);
+
+ ldns_resolver_set_nameservers(r, NULL);
+ ldns_resolver_set_rtt(r, NULL);
+ } else {
+ nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *,
+ (ns_count - 1));
+ rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
- if(nameservers)
ldns_resolver_set_nameservers(r, nameservers);
- if(rtt)
ldns_resolver_set_rtt(r, rtt);
+ }
/* decr the count */
ldns_resolver_dec_nameserver_count(r);
return pop;
@@ -385,7 +392,9 @@ ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
{
ldns_rr_list * trust_anchors;
- if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY)) {
+ if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
+ ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS)) {
+
return LDNS_STATUS_ERR;
}
@@ -800,8 +809,7 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
gtr -= bgtr;
if(word[0] == '#') {
expect = LDNS_RESOLV_KEYWORD;
- ldns_buffer_free(b);
- continue;
+ break;
}
tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
if (!tmp) {
@@ -817,8 +825,10 @@ ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
(size_t) gtr + 1);
}
ldns_buffer_free(b);
- gtr = 1;
- expect = LDNS_RESOLV_KEYWORD;
+ if (expect != LDNS_RESOLV_KEYWORD) {
+ gtr = 1;
+ expect = LDNS_RESOLV_KEYWORD;
+ }
break;
case LDNS_RESOLV_SORTLIST:
gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
@@ -885,6 +895,7 @@ ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
*res = r;
return LDNS_STATUS_OK;
} else {
+ ldns_resolver_free(r);
return LDNS_STATUS_NULL;
}
}
@@ -947,15 +958,12 @@ ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name,
ldns_rr_type t, ldns_rr_class c, uint16_t flags)
{
- char *str_dname;
ldns_rdf *new_name;
ldns_rdf **search_list;
size_t i;
ldns_pkt *p;
- str_dname = ldns_rdf2str(name);
-
- if (ldns_dname_str_absolute(str_dname)) {
+ if (ldns_dname_absolute(name)) {
/* query as-is */
return ldns_resolver_query(r, name, t, c, flags);
} else if (ldns_resolver_dnsrch(r)) {
@@ -1017,9 +1025,6 @@ ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
newname = ldns_dname_cat_clone((const ldns_rdf*)name, ldns_resolver_domain(r));
if (!newname) {
- if (pkt) {
- ldns_pkt_free(pkt);
- }
return NULL;
}
@@ -1212,9 +1217,11 @@ ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
ldns_resolver_tsig_keydata(r),
300, ldns_resolver_tsig_algorithm(r), NULL);
if (status != LDNS_STATUS_OK) {
+ ldns_pkt_free(query_pkt);
return LDNS_STATUS_CRYPTO_TSIG_ERR;
}
#else
+ ldns_pkt_free(query_pkt);
return LDNS_STATUS_CRYPTO_TSIG_ERR;
#endif /* HAVE_SSL */
}
@@ -1294,7 +1301,14 @@ ldns_axfr_next(ldns_resolver *resolver)
return NULL;
} else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt));
- fprintf(stderr, "Error in AXFR: %s\n", rcode->name);
+ if (rcode) {
+ fprintf(stderr, "Error in AXFR: %s\n",
+ rcode->name);
+ } else {
+ fprintf(stderr, "Error in AXFR: %d\n",
+ (int) ldns_pkt_get_rcode(
+ resolver->_cur_axfr_pkt));
+ }
/* RoRi: we must now also close the socket, otherwise subsequent uses of the
same resolver structure will fail because the link is still open or
@@ -1333,17 +1347,22 @@ void
ldns_resolver_nameservers_randomize(ldns_resolver *r)
{
uint16_t i, j;
- ldns_rdf **ns, *tmp;
+ ldns_rdf **ns, *tmpns;
+ size_t *rtt, tmprtt;
/* should I check for ldns_resolver_random?? */
assert(r != NULL);
ns = ldns_resolver_nameservers(r);
+ rtt = ldns_resolver_rtt(r);
for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
j = ldns_get_random() % ldns_resolver_nameserver_count(r);
- tmp = ns[i];
+ tmpns = ns[i];
ns[i] = ns[j];
- ns[j] = tmp;
+ ns[j] = tmpns;
+ tmprtt = rtt[i];
+ rtt[i] = rtt[j];
+ rtt[j] = tmprtt;
}
ldns_resolver_set_nameservers(r, ns);
}
diff --git a/usr.sbin/unbound/ldns/rr.c b/usr.sbin/unbound/ldns/rr.c
index 8f4ce85c7eb..72076d40c58 100644
--- a/usr.sbin/unbound/ldns/rr.c
+++ b/usr.sbin/unbound/ldns/rr.c
@@ -119,7 +119,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
char *type = NULL;
char *rdata = NULL;
char *rd = NULL;
- char *b64 = NULL;
+ char * b64 = NULL;
size_t rd_strlen;
const char *delimiters;
ssize_t c;
@@ -477,6 +477,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
ldns_buffer_free(rr_buf);
LDNS_FREE(rdata);
ldns_rr_free(new);
+ LDNS_FREE(hex_data);
return s;
}
LDNS_FREE(hex_data);
@@ -600,6 +601,9 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
if (newrr) {
*newrr = new;
+ } else {
+ /* Maybe the caller just wanted to see if it would parse? */
+ ldns_rr_free(new);
}
return LDNS_STATUS_OK;
@@ -724,8 +728,13 @@ ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf
}
}
LDNS_FREE(line);
- if (newrr && s == LDNS_STATUS_OK) {
- *newrr = rr;
+ if (s == LDNS_STATUS_OK) {
+ if (newrr) {
+ *newrr = rr;
+ } else {
+ /* Just testing if it would parse? */
+ ldns_rr_free(rr);
+ }
}
return s;
}
@@ -1156,7 +1165,8 @@ ldns_rr_list_pop_rr_list(ldns_rr_list *rr_list, size_t howmany)
i--;
}
- if (i == howmany) {
+ if (i == howmany) { /* so i <= 0 */
+ ldns_rr_list_free(popped);
return NULL;
} else {
return popped;
@@ -1480,6 +1490,7 @@ ldns_rr_list_sort(ldns_rr_list *unsorted)
LDNS_FREE(sortables[i]);
}
/* no way to return error */
+ LDNS_FREE(sortables);
return;
}
sortables[i]->original_object = ldns_rr_list_rr(unsorted, i);
@@ -1941,6 +1952,12 @@ static const ldns_rdf_type type_tsig_wireformat[] = {
LDNS_RDF_TYPE_INT16,
LDNS_RDF_TYPE_INT16_DATA
};
+static const ldns_rdf_type type_tlsa_wireformat[] = {
+ LDNS_RDF_TYPE_INT8,
+ LDNS_RDF_TYPE_INT8,
+ LDNS_RDF_TYPE_INT8,
+ LDNS_RDF_TYPE_HEX
+};
/** \endcond */
/** \cond */
@@ -2048,13 +2065,14 @@ static ldns_rr_descriptor rdata_field_descriptors[] = {
/* 48 */
{LDNS_RR_TYPE_DNSKEY, "DNSKEY", 4, 4, type_dnskey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 49 */
-{LDNS_RR_TYPE_DHCID, "DHCID", 1, 1, type_dhcid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+ {LDNS_RR_TYPE_DHCID, "DHCID", 1, 1, type_dhcid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 50 */
{LDNS_RR_TYPE_NSEC3, "NSEC3", 5, 6, type_nsec3_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 51 */
-{LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+ {LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 52 */
-{LDNS_RR_TYPE_NULL, "TYPE52", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+ {LDNS_RR_TYPE_TLSA, "TLSA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
{LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_NULL, "TYPE55", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
diff --git a/usr.sbin/unbound/ldns/str2host.c b/usr.sbin/unbound/ldns/str2host.c
index 2783f0805a4..51357cc3176 100644
--- a/usr.sbin/unbound/ldns/str2host.c
+++ b/usr.sbin/unbound/ldns/str2host.c
@@ -96,7 +96,7 @@ ldns_str2rdf_time(ldns_rdf **rd, const char *time)
goto bad_format;
}
- l = htonl(mktime_from_utc(&tm));
+ l = htonl(ldns_mktime_from_utc(&tm));
memcpy(r, &l, sizeof(uint32_t));
*rd = ldns_rdf_new_frm_data(
LDNS_RDF_TYPE_TIME, sizeof(uint32_t), r);
@@ -534,6 +534,7 @@ ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
if(!data) {
+ LDNS_FREE(afdpart);
LDNS_FREE(my_ip_str);
return LDNS_STATUS_INVALID_STR;
}
@@ -1104,8 +1105,6 @@ ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
data[0] = (uint8_t) proto->p_proto;
} else if (proto_str) {
data[0] = (uint8_t) atoi(proto_str);
- } else {
- data[0] = 0;
}
memcpy(data + 1, bitmap, (size_t) bm_len);
diff --git a/usr.sbin/unbound/ldns/tsig.c b/usr.sbin/unbound/ldns/tsig.c
index 90c20a03ea0..41693463df3 100644
--- a/usr.sbin/unbound/ldns/tsig.c
+++ b/usr.sbin/unbound/ldns/tsig.c
@@ -179,10 +179,12 @@ ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
return LDNS_STATUS_NULL;
}
canonical_key_name_rdf = ldns_rdf_clone(key_name_rdf);
+ if (canonical_key_name_rdf == NULL) {
+ return LDNS_STATUS_MEM_ERR;
+ }
canonical_algorithm_rdf = ldns_rdf_clone(algorithm_rdf);
-
- if (canonical_key_name_rdf == NULL
- || canonical_algorithm_rdf == NULL) {
+ if (canonical_algorithm_rdf == NULL) {
+ ldns_rdf_deep_free(canonical_key_name_rdf);
return LDNS_STATUS_MEM_ERR;
}
/*
@@ -266,8 +268,8 @@ ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
LDNS_FREE(key_bytes);
LDNS_FREE(algorithm_name);
ldns_buffer_free(data_buffer);
- ldns_rdf_free(canonical_algorithm_rdf);
- ldns_rdf_free(canonical_key_name_rdf);
+ ldns_rdf_deep_free(canonical_algorithm_rdf);
+ ldns_rdf_deep_free(canonical_key_name_rdf);
return status;
}
#endif /* HAVE_SSL */
diff --git a/usr.sbin/unbound/ldns/util.c b/usr.sbin/unbound/ldns/util.c
index a7ab96080ce..f5462c4b08f 100644
--- a/usr.sbin/unbound/ldns/util.c
+++ b/usr.sbin/unbound/ldns/util.c
@@ -227,7 +227,7 @@ leap_days(int y1, int y2)
* Code adapted from Python 2.4.1 sources (Lib/calendar.py).
*/
time_t
-mktime_from_utc(const struct tm *tm)
+ldns_mktime_from_utc(const struct tm *tm)
{
int year = 1900 + tm->tm_year;
time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year);
@@ -251,6 +251,12 @@ mktime_from_utc(const struct tm *tm)
return seconds;
}
+time_t
+mktime_from_utc(const struct tm *tm)
+{
+ return ldns_mktime_from_utc(tm);
+}
+
#if SIZEOF_TIME_T <= 4
static void
@@ -398,6 +404,7 @@ ldns_init_random(FILE *fd, unsigned int size)
if (read < size) {
LDNS_FREE(seed);
+ if (!fd) fclose(rand_f);
return 1;
} else {
#ifdef HAVE_SSL