]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
A new function tha
authorWillem Toorop <willem@NLnetLabs.nl>
Tue, 17 May 2011 14:19:00 +0000 (14:19 +0000)
committerWillem Toorop <willem@NLnetLabs.nl>
Tue, 17 May 2011 14:19:00 +0000 (14:19 +0000)
dnssec.c
dnssec_sign.c
examples/ldns-verify-zone.c
ldns/dnssec.h
ldns/dnssec_sign.h
ldns_symbols.def

index ae50996cc4a0b7e28a78b7ea67b089ce2dec58ea..6550a910d0c16bbcb585d3eddde640370a6a69b0 100644 (file)
--- a/dnssec.c
+++ b/dnssec.c
@@ -764,21 +764,6 @@ ldns_dnssec_rrsets_contains_type(ldns_dnssec_rrsets *rrsets,
        return 0;
 }
 
-/* returns true if the current dnssec_rrset from the given list of rrsets
- * is glue */
-static int
-is_glue(ldns_dnssec_rrsets *cur_rrsets, ldns_dnssec_rrsets *orig_rrsets)
-{
-       /* only glue if a or aaaa with names that have an NS rrset and are not the 
-          apex (do not have a soa rrset) */
-       return (cur_rrsets->type == LDNS_RR_TYPE_A ||
-               cur_rrsets->type ==  LDNS_RR_TYPE_AAAA) &&
-               (ldns_dnssec_rrsets_contains_type(orig_rrsets,
-                     LDNS_RR_TYPE_NS) &&
-               !ldns_dnssec_rrsets_contains_type(orig_rrsets,
-                     LDNS_RR_TYPE_SOA));
-}
-
 ldns_rr *
 ldns_dnssec_create_nsec(ldns_dnssec_name *from,
                         ldns_dnssec_name *to,
@@ -788,6 +773,7 @@ ldns_dnssec_create_nsec(ldns_dnssec_name *from,
        ldns_rr_type types[65536];
        size_t type_count = 0;
        ldns_dnssec_rrsets *cur_rrsets;
+       int on_delegation_point;
 
        if (!from || !to || (nsec_type != LDNS_RR_TYPE_NSEC &&
                                         nsec_type != LDNS_RR_TYPE_NSEC3)) {
@@ -799,14 +785,22 @@ ldns_dnssec_create_nsec(ldns_dnssec_name *from,
        ldns_rr_set_owner(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(from)));
        ldns_rr_push_rdf(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(to)));
 
+       on_delegation_point = ldns_dnssec_rrsets_contains_type(
+                       from->rrsets, LDNS_RR_TYPE_NS)
+               && !ldns_dnssec_rrsets_contains_type(
+                       from->rrsets, LDNS_RR_TYPE_SOA);
+
        cur_rrsets = from->rrsets;
        while (cur_rrsets) {
-               if (is_glue(cur_rrsets, from->rrsets)) {
-                       cur_rrsets = cur_rrsets->next;
-                       continue;
-               }
-               if (cur_rrsets->type != LDNS_RR_TYPE_RRSIG &&
-                   cur_rrsets->type != LDNS_RR_TYPE_NSEC) {
+               /* Do not include obscured rrsets on the delegation point
+                * in the type bitmap */
+               if (       ( on_delegation_point && (
+                               cur_rrsets->type == LDNS_RR_TYPE_NS 
+                            || cur_rrsets->type == LDNS_RR_TYPE_DS))
+                       || (!on_delegation_point &&
+                               cur_rrsets->type != LDNS_RR_TYPE_RRSIG
+                            && cur_rrsets->type != LDNS_RR_TYPE_NSEC)) {
+
                        types[type_count] = cur_rrsets->type;
                        type_count++;
                }
@@ -840,6 +834,7 @@ ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
        size_t type_count = 0;
        ldns_dnssec_rrsets *cur_rrsets;
        ldns_status status;
+       int on_delegation_point;
 
        flags = flags;
 
@@ -866,13 +861,23 @@ ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
                                  salt_length,
                                  salt);
 
+       on_delegation_point = ldns_dnssec_rrsets_contains_type(
+                       from->rrsets, LDNS_RR_TYPE_NS)
+               && !ldns_dnssec_rrsets_contains_type(
+                       from->rrsets, LDNS_RR_TYPE_SOA);
        cur_rrsets = from->rrsets;
        while (cur_rrsets) {
-               if (is_glue(cur_rrsets, from->rrsets)) {
-                       cur_rrsets = cur_rrsets->next;
-                       continue;
-               }
-               if (cur_rrsets->type != LDNS_RR_TYPE_RRSIG) {
+               /* Do not include obscured rrsets on the delegation point
+                * in the type bitmap. Potentionally not skipping insecure
+                * delegation should have been done earlier, in
+                * 
+                */
+               if (       ( on_delegation_point && (
+                               cur_rrsets->type == LDNS_RR_TYPE_NS
+                            || cur_rrsets->type == LDNS_RR_TYPE_DS))
+                       || (!on_delegation_point &&
+                               cur_rrsets->type != LDNS_RR_TYPE_RRSIG)) {
+
                        types[type_count] = cur_rrsets->type;
                        type_count++;
                }
index d28f87a49f5a79ce8e1c703c492e8ea9b1e750d0..126f8e7068a6542bd5edc56eb37adc268eab62d8 100644 (file)
@@ -522,72 +522,149 @@ ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
 }
 #endif /* HAVE_SSL */
 
-static int
-ldns_dnssec_name_has_only_a(ldns_dnssec_name *cur_name)
+/**
+ * Pushes all rrs from the rrsets of type A and AAAA on gluelist.
+ */
+static ldns_status
+ldns_dnssec_addresses_on_glue_list(
+               ldns_dnssec_rrsets *cur_rrset,
+               ldns_rr_list *glue_list)
 {
-       ldns_dnssec_rrsets *cur_rrset;
-       cur_rrset = cur_name->rrsets;
+       ldns_dnssec_rrs *cur_rrs;
        while (cur_rrset) {
-               if (cur_rrset->type != LDNS_RR_TYPE_A &&
-                       cur_rrset->type != LDNS_RR_TYPE_AAAA) {
-                       return 0;
-               } else {
-                       cur_rrset = cur_rrset->next;
+               if (cur_rrset->type == LDNS_RR_TYPE_A 
+                               || cur_rrset->type == LDNS_RR_TYPE_AAAA) {
+                       for (cur_rrs = cur_rrset->rrs; 
+                                       cur_rrs; 
+                                       cur_rrs = cur_rrs->next) {
+                               if (cur_rrs->rr) {
+                                       if (!ldns_rr_list_push_rr(glue_list, 
+                                                       cur_rrs->rr)) {
+                                               return LDNS_STATUS_MEM_ERR; 
+                                               /* ldns_rr_list_push_rr()
+                                                * returns false when unable
+                                                * to increase the capacity
+                                                * of the ldsn_rr_list
+                                                */
+                                       }
+                               }
+                       }
                }
+               cur_rrset = cur_rrset->next;
        }
-       return 1;
+       return LDNS_STATUS_OK;
 }
 
-/*
- * Regardless of its name, this function does not mark the glue rrsets as glue,
- * but only names that have ONLY glue rrsets.
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially obscured (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account seperatly.
  *
- * TODO
- * Names with glue on the delegation are NOT marked! They are handled seperatly
- * and specially within the is_glue() function in dnssec.c to exclude them 
- * from the NSEC and NSEC3 bitmaps; and in ldns_dnssec_zone_create_rrsigs_flg()
- * in dnssec_sign.c to make sure those rrsets are not signed.
- * 
- * Also, names that have other obscured rrsets besides A and AAAA types will NOT
- * be marked. This is probably a mistake.
+ * When glue_list is given (not NULL), in the process of marking the names, all
+ * glue resource records will be pushed to that list. Even glue in partially
+ * obscured names.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \param[in] glue_list the list to which to push the glue rrs
+ * \return LDNS_STATUS_OK on success, an error code otherwise
  */
 ldns_status
-ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
+ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 
+       ldns_rr_list *glue_list)
 {
-       ldns_rbnode_t *cur_node;
-       ldns_dnssec_name *cur_name;
-       ldns_rdf *cur_owner, *cur_parent;
+       ldns_rbnode_t    *node;
+       ldns_dnssec_name *name;
+       ldns_rdf         *owner;
+       ldns_rdf         *cut = NULL; /* keeps track of zone cuts */
+       /* When the cut is caused by a delegation, below_delegation will be 1.
+        * When caused by a DNAME, below_delegation will be 0.
+        */
+       int below_delegation = -1; /* init suppresses comiler warning */
+       ldns_status s;
 
-       cur_node = ldns_rbtree_first(zone->names);
-       while (cur_node != LDNS_RBTREE_NULL) {
-               cur_name = (ldns_dnssec_name *) cur_node->data;
-               cur_node = ldns_rbtree_next(cur_node);
-               if (ldns_dnssec_name_has_only_a(cur_name)) {
-                       /* assume glue XXX check for zone cut */
-                       cur_owner = ldns_rdf_clone(ldns_rr_owner(
-                                             cur_name->rrsets->rrs->rr));
-                       while (ldns_dname_label_count(cur_owner) >
-                                 ldns_dname_label_count(zone->soa->name)) {
-                               if (ldns_dnssec_zone_find_rrset(zone,
-                                                                                 cur_owner,
-                                                                                 LDNS_RR_TYPE_NS)) {
-                                       /*
-                                       fprintf(stderr, "[XX] Marking as glue: ");
-                                       ldns_rdf_print(stderr, cur_name->name);
-                                       fprintf(stderr, "\n");
-                                       */
-                                       cur_name->is_glue = true;
+       if (!zone || !zone->names) {
+               return LDNS_STATUS_NULL;
+       }
+       for (node = ldns_rbtree_first(zone->names); 
+                       node != LDNS_RBTREE_NULL; 
+                       node = ldns_rbtree_next(node)) {
+               name = (ldns_dnssec_name *) node->data;
+               owner = ldns_dnssec_name_name(name);
+
+               if (cut) { 
+                       /* The previous node was a zone cut, or a subdomain
+                        * below a zone cut. Is this node (still) a subdomain
+                        * below the cut? Then the name is occluded. Unless
+                        * the name contains a SOA, after which we are 
+                        * authoritative again.
+                        *
+                        * FIXME! If there are labels in between the SOA and
+                        * the cut, going from the authoritative space (below
+                        * the SOA) up into occluded space again, will not be
+                        * detected with the contruct below!
+                        */
+                       if (ldns_dname_is_subdomain(owner, cut) &&
+                                       !ldns_dnssec_rrsets_contains_type(
+                                       name->rrsets, LDNS_RR_TYPE_SOA)) {
+
+                               if (below_delegation && glue_list) {
+                                       s = ldns_dnssec_addresses_on_glue_list(
+                                               name->rrsets, glue_list);
+                                       if (s != LDNS_STATUS_OK) {
+                                               return s;
+                                       }
                                }
-                               cur_parent = ldns_dname_left_chop(cur_owner);
-                               ldns_rdf_deep_free(cur_owner);
-                               cur_owner = cur_parent;
+                               name->is_glue = true; /* Mark occluded name! */
+                               continue;
+                       } else {
+                               cut = NULL;
                        }
-                       ldns_rdf_deep_free(cur_owner);
+               }
+
+               /* The node is not below a zone cut. Is it a zone cut itself?
+                * Everything below a SOA is authoritative of course; Except
+                * when the name also contains a DNAME :).
+                */
+               if (ldns_dnssec_rrsets_contains_type(
+                               name->rrsets, LDNS_RR_TYPE_NS)
+                           && !ldns_dnssec_rrsets_contains_type(
+                               name->rrsets, LDNS_RR_TYPE_SOA)) {
+                       cut = owner;
+                       below_delegation = 1;
+                       if (glue_list) { /* record glue on the zone cut */
+                               s = ldns_dnssec_addresses_on_glue_list(
+                                       name->rrsets, glue_list);
+                               if (s != LDNS_STATUS_OK) {
+                                       return s;
+                               }
+                       }
+               } else if (ldns_dnssec_rrsets_contains_type(
+                               name->rrsets, LDNS_RR_TYPE_DNAME)) {
+                       cut = owner;
+                       below_delegation = 0;
                }
        }
        return LDNS_STATUS_OK;
 }
 
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially obscured (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account seperatly.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status
+ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
+{
+       return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
+}
+
 ldns_rbnode_t *
 ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
 {
@@ -928,6 +1005,8 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
 
        size_t i;
 
+       int on_delegation_point = 0; /* handle partially obscured names */
+
        ldns_rr_list *pubkey_list = ldns_rr_list_new();
        zone = zone;
        new_rrs = new_rrs;
@@ -943,6 +1022,10 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                cur_name = (ldns_dnssec_name *) cur_node->data;
 
                if (!cur_name->is_glue) {
+                       on_delegation_point = ldns_dnssec_rrsets_contains_type(
+                                       cur_name->rrsets, LDNS_RR_TYPE_NS)
+                               && !ldns_dnssec_rrsets_contains_type(
+                                       cur_name->rrsets, LDNS_RR_TYPE_SOA);
                        cur_rrset = cur_name->rrsets;
                        while (cur_rrset) {
                                /* reset keys to use */
@@ -972,20 +1055,15 @@ ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
                                }
 
                                /* only sign non-delegation RRsets */
-                               /* (glue should have been marked earlier) */
-                               if ((ldns_rr_list_type(rr_list) != LDNS_RR_TYPE_NS ||
-                                       ldns_dname_compare(ldns_rr_list_owner(rr_list),
-                                       zone->soa->name) == 0) &&
-                                       /* OK, there is also the possibility that the record
-                                        * is glue, but at the same owner name as other records that
-                                        * are not NS nor A/AAAA. Bleh, our current data structure
-                                        * doesn't really support that... */
-                                       !((ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_A ||
-                                        ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_AAAA) &&
-                                        !ldns_dname_compare(ldns_rr_list_owner(rr_list), zone->soa->name) == 0 &&
-                                        ldns_dnssec_zone_find_rrset(zone, ldns_rr_list_owner(rr_list), LDNS_RR_TYPE_NS)
-                                        )) {
-
+                               /* (glue should have been marked earlier, 
+                                *  except on the delegation points itself) */
+                               if (!on_delegation_point ||
+                                               ldns_rr_list_type(rr_list) 
+                                                       == LDNS_RR_TYPE_DS ||
+                                               ldns_rr_list_type(rr_list) 
+                                                       == LDNS_RR_TYPE_NSEC ||
+                                               ldns_rr_list_type(rr_list) 
+                                                       == LDNS_RR_TYPE_NSEC3) {
                                        siglist = ldns_sign_public(rr_list, key_list);
                                        for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
                                                if (cur_rrset->signatures) {
@@ -1280,3 +1358,4 @@ ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm
 }
 #endif /* HAVE_SSL */
 
+
index e840c89bf5ba1fd87388fd0929fd76ad1477fbf4..88e79d2c1fc74a733f94a45bb236dcdd23cc09c8 100644 (file)
@@ -59,26 +59,6 @@ ldns_rr_list_contains_name(const ldns_rr_list *rr_list,
        return false;
 }
 
-/* returns 1 if the list is empty, or if there are only ns or glue rrs in the
- * list, 0 otherwise */
-static int
-only_ns_and_glues_in_rrsets(ldns_dnssec_name *name,
-                            ldns_rr_list *glue_rrs
-)
-{
-       ldns_dnssec_rrsets *cur_rrset = name->rrsets;
-
-       while (cur_rrset) {
-               if (cur_rrset->type != LDNS_RR_TYPE_NS &&
-                    !ldns_rr_list_contains_name(glue_rrs, name->name)
-               ) {
-                       return 0;
-               }
-               cur_rrset = cur_rrset->next;
-       }
-       return 1;
-}
-
 static void
 print_type(ldns_rr_type type)
 {
@@ -149,8 +129,7 @@ static ldns_status
 verify_dnssec_rrset(ldns_rdf *zone_name,
                                        ldns_rdf *name,
                     ldns_dnssec_rrsets *rrset,
-                    ldns_rr_list *keys,
-                    ldns_rr_list *glue_rrs)
+                    ldns_rr_list *keys)
 {
        ldns_rr_list *rrset_rrs;
        ldns_dnssec_rrs *cur_rr, *cur_sig;
@@ -362,29 +341,10 @@ verify_next_hashed_name(ldns_rbtree_t *zone_nodes,
        }
 }
 
-static ldns_rbnode_t *
-next_nonglue_node(ldns_rbnode_t *node, ldns_rr_list *glue_rrs)
-{
-       ldns_rbnode_t *cur_node = ldns_rbtree_next(node);
-       ldns_dnssec_name *cur_name;
-       while (cur_node != LDNS_RBTREE_NULL) {
-               cur_name = (ldns_dnssec_name *) cur_node->data;
-               if (cur_name && cur_name->name) {
-                       if (!ldns_rr_list_contains_name(glue_rrs, cur_name->name)) {
-                               return cur_node;
-                       }
-               }
-               cur_node = ldns_rbtree_next(cur_node);
-       }
-       return LDNS_RBTREE_NULL;
-}
-
 static ldns_status
 verify_nsec(ldns_rbtree_t *zone_nodes,
             ldns_rbnode_t *cur_node,
-            ldns_rr_list *keys,
-            ldns_rr_list *glue_rrs
-)
+            ldns_rr_list *keys)
 {
        ldns_rbnode_t *next_node;
        ldns_dnssec_name *name, *next_name;
@@ -414,10 +374,11 @@ verify_nsec(ldns_rbtree_t *zone_nodes,
                switch (ldns_rr_get_type(name->nsec)) {
                        case LDNS_RR_TYPE_NSEC:
                                /* simply try next name */
-                               next_node = next_nonglue_node(cur_node, glue_rrs);
+                               next_node = ldns_rbtree_next(cur_node);
                                if (next_node == LDNS_RBTREE_NULL) {
                                        next_node = ldns_rbtree_first(zone_nodes);
                                }
+                               next_node = ldns_dnssec_name_node_next_nonglue(next_node);
                                next_name = (ldns_dnssec_name *)next_node->data;
                                if (ldns_dname_compare(next_name->name,
                                                                           ldns_rr_rdf(name->nsec, 0))
@@ -425,6 +386,11 @@ verify_nsec(ldns_rbtree_t *zone_nodes,
                                        printf("Error: the NSEC record for ");
                                        ldns_rdf_print(stdout, name->name);
                                        printf(" points to the wrong next owner name\n");
+                                       printf("     : ");
+                                       ldns_rdf_print(stdout, ldns_rr_rdf(name->nsec, 0));
+                                       printf(" i.s.o. ");
+                                       ldns_rdf_print(stdout, next_name->name);
+                                       printf(".\n");
                                        if (result == LDNS_STATUS_OK) {
                                                result = LDNS_STATUS_ERR;
                                        }
@@ -447,7 +413,14 @@ verify_nsec(ldns_rbtree_t *zone_nodes,
        } else {
                /* todo; do this once and cache result? */
                if (zone_is_nsec3_optout(zone_nodes) &&
-                   only_ns_and_glues_in_rrsets(name, glue_rrs)) {
+                               (   ldns_dnssec_name_is_glue(name)
+                                || (
+                                        ldns_dnssec_rrsets_contains_type(
+                                               name->rrsets, LDNS_RR_TYPE_NS)
+                                    && !ldns_dnssec_rrsets_contains_type(
+                                               name->rrsets, LDNS_RR_TYPE_DS)
+                                   )
+                               )) {
                        /* ok, no problem, but we need to remember to check
                         * whether the chain does not actually point to this
                         * name later */
@@ -465,34 +438,18 @@ verify_nsec(ldns_rbtree_t *zone_nodes,
        return result;
 }
 
-static int
-ldns_dnssec_name_has_only_a(ldns_dnssec_name *cur_name)
-{
-       ldns_dnssec_rrsets *cur_rrset;
-       cur_rrset = cur_name->rrsets;
-       while (cur_rrset) {
-               if (cur_rrset->type != LDNS_RR_TYPE_A &&
-                       cur_rrset->type != LDNS_RR_TYPE_AAAA) {
-                       return 0;
-               } else {
-                       cur_rrset = cur_rrset->next;
-               }
-       }
-       return 1;
-}
-
 static ldns_status
 verify_dnssec_name(ldns_rdf *zone_name,
                 ldns_dnssec_zone *zone,
                 ldns_rbtree_t *zone_nodes,
                 ldns_rbnode_t *cur_node,
-                           ldns_rr_list *keys,
-                           ldns_rr_list *glue_rrs)
+                           ldns_rr_list *keys)
 {
        ldns_status result = LDNS_STATUS_OK;
        ldns_status status;
        ldns_dnssec_rrsets *cur_rrset;
        ldns_dnssec_name *name;
+       int on_delegation_point;
        /* for NSEC chain checks */
 
        name = (ldns_dnssec_name *) cur_node->data;
@@ -502,9 +459,7 @@ verify_dnssec_name(ldns_rdf *zone_name,
                printf("\n");
        }
 
-       if (ldns_dnssec_name_has_only_a(name) &&
-               ldns_rr_list_contains_name(glue_rrs, name->name)
-       ) {
+       if (ldns_dnssec_name_is_glue(name)) {
                /* glue */
                cur_rrset = name->rrsets;
                while (cur_rrset) {
@@ -530,11 +485,26 @@ verify_dnssec_name(ldns_rdf *zone_name,
                }
        } else {
                /* not glue, do real verify */
+
+               on_delegation_point = ldns_dnssec_rrsets_contains_type(
+                               name->rrsets, LDNS_RR_TYPE_NS)
+                       && !ldns_dnssec_rrsets_contains_type(
+                               name->rrsets, LDNS_RR_TYPE_SOA);
+
                cur_rrset = name->rrsets;
                while(cur_rrset) {
-                       if ((cur_rrset->type != LDNS_RR_TYPE_A && cur_rrset->type != LDNS_RR_TYPE_AAAA) ||
-                           !ldns_dnssec_zone_find_rrset(zone, name->name, LDNS_RR_TYPE_NS)) {
-                               status = verify_dnssec_rrset(zone_name, name->name, cur_rrset, keys, glue_rrs);
+
+                       /* Do not check obscured rrsets 
+                        * on the delegation point
+                        */
+                       if (       ( on_delegation_point && (
+                                       cur_rrset->type == LDNS_RR_TYPE_NS
+                                    || cur_rrset->type == LDNS_RR_TYPE_DS))
+                               || (!on_delegation_point &&
+                                       cur_rrset->type != LDNS_RR_TYPE_RRSIG
+                                    && cur_rrset->type != LDNS_RR_TYPE_NSEC)) {
+
+                               status = verify_dnssec_rrset(zone_name, name->name, cur_rrset, keys);
                                if (status != LDNS_STATUS_OK && result == LDNS_STATUS_OK) {
                                        result = status;
                                }
@@ -542,7 +512,7 @@ verify_dnssec_name(ldns_rdf *zone_name,
                        cur_rrset = cur_rrset->next;
                }
 
-               status = verify_nsec(zone_nodes, cur_node, keys, glue_rrs);
+               status = verify_nsec(zone_nodes, cur_node, keys);
                if (result == LDNS_STATUS_OK) {
                        result = status;
                }
@@ -552,9 +522,7 @@ verify_dnssec_name(ldns_rdf *zone_name,
 
 static ldns_status
 verify_dnssec_zone(ldns_dnssec_zone *dnssec_zone,
-                           ldns_rdf *zone_name,
-                           ldns_rr_list *glue_rrs)
-{
+                           ldns_rdf *zone_name) {
        ldns_rr_list *keys;
        ldns_rbnode_t *cur_node;
        ldns_dnssec_rrsets *cur_key_rrset;
@@ -596,8 +564,7 @@ verify_dnssec_zone(ldns_dnssec_zone *dnssec_zone,
                                                    dnssec_zone,
                                                    dnssec_zone->names,
                                                    cur_node,
-                                                   keys,
-                                                   glue_rrs);
+                                                   keys);
                        if (status != LDNS_STATUS_OK && result == LDNS_STATUS_OK) {
                                result = status;
                        }
@@ -620,7 +587,6 @@ main(int argc, char **argv)
        ldns_status s;
        ldns_dnssec_zone *dnssec_zone;
        ldns_status result = LDNS_STATUS_ERR;
-       ldns_rr_list *glue_rrs;
 
        while ((c = getopt(argc, argv, "hvV:")) != -1) {
                switch(c) {
@@ -674,16 +640,20 @@ main(int argc, char **argv)
                        exit(1);
                }
 
-               glue_rrs = ldns_zone_glue_rr_list(z);
                dnssec_zone = create_dnssec_zone(z);
+               result = ldns_dnssec_zone_mark_glue(dnssec_zone);
+               if (result != LDNS_STATUS_OK) {
+                       if (verbosity >= 1) {
+                               printf("There were errors identifying the glue in the zone\n");
+                       }
+               }
 
                if (verbosity >= 5) {
                        ldns_dnssec_zone_print(stdout, dnssec_zone);
                }
 
                result = verify_dnssec_zone(dnssec_zone,
-                                                          ldns_rr_owner(ldns_zone_soa(z)),
-                                                          glue_rrs);
+                                                          ldns_rr_owner(ldns_zone_soa(z)));
 
 
                if (result == LDNS_STATUS_OK) {
index 7bfc70b710f1678023b6dc6a730a2a030e00e9ca..c68ce36e8aba7deba0feab98e66b746bd351f7bc 100644 (file)
@@ -210,6 +210,16 @@ ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
                                                 size_t size,
                                                 ldns_rr_type nsec_type);
 
+/**
+ * returns whether a rrset of the given type is found in the rrsets.
+ *
+ * \param[in] *rsets the rrsets to be tested
+ * \param[in] type the type to test for
+ * \return int 1 if the type was found, 0 otherwise.
+ */
+int
+ldns_dnssec_rrsets_contains_type (ldns_dnssec_rrsets *rrsets, ldns_rr_type type);
+
 /**
  * Creates NSEC
  */
index 66856d52ee7cbf3f65cb8c49eca010049c63d821..bca7d511bc7a7b4a8a17d5ed5487e5d1a9c15ed3 100644 (file)
@@ -83,10 +83,30 @@ ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key);
 #endif /* HAVE_SSL */
 
 /**
- * Marks the names in the zone that contain only glue, by setting the
- * is_glue attribute of the ldns_dnssec_name structure to true.
- * Names with glue on the delegation point and occluded names with other 
- * rrsets than only A and AAAA are not marked!
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially obscured (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account seperatly.
+ *
+ * When glue_list is given (not NULL), in the process of marking the names, all
+ * glue resource records will be pushed to that list. Even glue in partially
+ * obscured names.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \param[in] glue_list the list to which to push the glue rrs
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status
+ldns_dnssec_zone_mark_and_get_glue(
+               ldns_dnssec_zone *zone, ldns_rr_list *glue_list);
+
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially obscured (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account seperatly.
  *
  * \param[in] zone the zone in which to mark the names
  * \return LDNS_STATUS_OK on succesful completion
@@ -95,8 +115,8 @@ ldns_status
 ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone);
 
 /**
- * Finds the first dnssec_name node in the rbtree that has not been marked
- * as glue, starting at the given node
+ * Finds the first dnssec_name node in the rbtree that is not occluded.
+ * It *does* return names that are partially obscured.
  *
  * \param[in] node the first node to check
  * \return the first node that has not been marked as glue, or NULL
index 9158fe5adeaba634382510a307c7f1739b1eb4a6..551f2b0ca90c320c3ef97d7762ac8e2c47f8d747 100644 (file)
@@ -136,6 +136,7 @@ ldns_dnssec_zone_deep_free
 ldns_dnssec_zone_find_nsec3_original
 ldns_dnssec_zone_find_rrset
 ldns_dnssec_zone_free
+ldns_dnssec_zone_mark_and_get_glue
 ldns_dnssec_zone_mark_glue
 ldns_dnssec_zone_names_print
 ldns_dnssec_zone_new