1238104Sdes/* 2238104Sdes * dnssec.c 3238104Sdes * Some DNSSEC helper function are defined here 4238104Sdes * and tracing is done 5238104Sdes * (c) 2005 NLnet Labs 6238104Sdes * 7238104Sdes * See the file LICENSE for the license 8238104Sdes * 9238104Sdes */ 10238104Sdes 11238104Sdes#include "drill.h" 12238104Sdes#include <ldns/ldns.h> 13238104Sdes 14238104Sdes/* get rr_type from a server from a server */ 15238104Sdesldns_rr_list * 16238104Sdesget_rr(ldns_resolver *res, ldns_rdf *zname, ldns_rr_type t, ldns_rr_class c) 17238104Sdes{ 18238104Sdes /* query, retrieve, extract and return */ 19238104Sdes ldns_pkt *p; 20238104Sdes ldns_rr_list *found; 21238104Sdes 22238104Sdes p = ldns_pkt_new(); 23238104Sdes found = NULL; 24238104Sdes 25246854Sdes if (ldns_resolver_send(&p, res, zname, t, c, 0) == LDNS_STATUS_OK) { 26238104Sdes found = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_ANY_NOQUESTION); 27238104Sdes } 28246854Sdes ldns_pkt_free(p); 29238104Sdes return found; 30238104Sdes} 31238104Sdes 32238104Sdesvoid 33238104Sdesdrill_pkt_print(FILE *fd, ldns_resolver *r, ldns_pkt *p) 34238104Sdes{ 35238104Sdes ldns_rr_list *new_nss; 36238104Sdes ldns_rr_list *hostnames; 37246854Sdes char *answerfrom_str; 38238104Sdes 39238104Sdes if (verbosity < 5) { 40238104Sdes return; 41238104Sdes } 42238104Sdes 43238104Sdes hostnames = ldns_get_rr_list_name_by_addr(r, ldns_pkt_answerfrom(p), 0, 0); 44238104Sdes 45238104Sdes new_nss = ldns_pkt_rr_list_by_type(p, 46238104Sdes LDNS_RR_TYPE_NS, LDNS_SECTION_ANSWER); 47238104Sdes ldns_rr_list_print(fd, new_nss); 48246854Sdes ldns_rr_list_deep_free(new_nss); 49238104Sdes 50238104Sdes fprintf(fd, ";; Received %d bytes from %s#%d(", 51238104Sdes (int) ldns_pkt_size(p), 52238104Sdes ldns_rdf2str(ldns_pkt_answerfrom(p)), 53238104Sdes (int) ldns_resolver_port(r)); 54238104Sdes /* if we can resolve this print it, other print the ip again */ 55238104Sdes if (hostnames) { 56238104Sdes ldns_rdf_print(fd, 57238104Sdes ldns_rr_rdf(ldns_rr_list_rr(hostnames, 0), 0)); 58238104Sdes ldns_rr_list_deep_free(hostnames); 59238104Sdes } else { 60246854Sdes answerfrom_str = ldns_rdf2str(ldns_pkt_answerfrom(p)); 61246854Sdes if (answerfrom_str) { 62246854Sdes fprintf(fd, "%s", answerfrom_str); 63246854Sdes LDNS_FREE(answerfrom_str); 64246854Sdes } 65238104Sdes } 66238104Sdes fprintf(fd, ") in %u ms\n\n", (unsigned int)ldns_pkt_querytime(p)); 67238104Sdes} 68238104Sdes 69238104Sdesvoid 70238104Sdesdrill_pkt_print_footer(FILE *fd, ldns_resolver *r, ldns_pkt *p) 71238104Sdes{ 72238104Sdes ldns_rr_list *hostnames; 73246854Sdes char *answerfrom_str; 74238104Sdes 75238104Sdes if (verbosity < 5) { 76238104Sdes return; 77238104Sdes } 78238104Sdes 79238104Sdes hostnames = ldns_get_rr_list_name_by_addr(r, ldns_pkt_answerfrom(p), 0, 0); 80238104Sdes 81238104Sdes fprintf(fd, ";; Received %d bytes from %s#%d(", 82238104Sdes (int) ldns_pkt_size(p), 83238104Sdes ldns_rdf2str(ldns_pkt_answerfrom(p)), 84238104Sdes (int) ldns_resolver_port(r)); 85238104Sdes /* if we can resolve this print it, other print the ip again */ 86238104Sdes if (hostnames) { 87238104Sdes ldns_rdf_print(fd, 88238104Sdes ldns_rr_rdf(ldns_rr_list_rr(hostnames, 0), 0)); 89238104Sdes ldns_rr_list_deep_free(hostnames); 90238104Sdes } else { 91246854Sdes answerfrom_str = ldns_rdf2str(ldns_pkt_answerfrom(p)); 92246854Sdes if (answerfrom_str) { 93246854Sdes fprintf(fd, "%s", answerfrom_str); 94246854Sdes LDNS_FREE(answerfrom_str); 95246854Sdes } 96238104Sdes } 97238104Sdes fprintf(fd, ") in %u ms\n\n", (unsigned int)ldns_pkt_querytime(p)); 98238104Sdes} 99238104Sdes/* 100238104Sdes * generic function to get some RRset from a nameserver 101238104Sdes * and possible some signatures too (that would be the day...) 102238104Sdes */ 103238104Sdesldns_pkt_type 104238104Sdesget_dnssec_rr(ldns_pkt *p, ldns_rdf *name, ldns_rr_type t, 105238104Sdes ldns_rr_list **rrlist, ldns_rr_list **sig) 106238104Sdes{ 107238104Sdes ldns_pkt_type pt = LDNS_PACKET_UNKNOWN; 108238104Sdes ldns_rr_list *sigs = NULL; 109238104Sdes size_t i; 110238104Sdes 111238104Sdes if (!p) { 112238104Sdes if (rrlist) { 113238104Sdes *rrlist = NULL; 114238104Sdes } 115238104Sdes return LDNS_PACKET_UNKNOWN; 116238104Sdes } 117238104Sdes 118238104Sdes pt = ldns_pkt_reply_type(p); 119238104Sdes if (name) { 120246854Sdes if (rrlist) { 121246854Sdes *rrlist = ldns_pkt_rr_list_by_name_and_type(p, name, t, 122246854Sdes LDNS_SECTION_ANSWER); 123246854Sdes if (!*rrlist) { 124246854Sdes *rrlist = ldns_pkt_rr_list_by_name_and_type( 125246854Sdes p, name, t, 126246854Sdes LDNS_SECTION_AUTHORITY); 127246854Sdes } 128238104Sdes } 129246854Sdes if (sig) { 130246854Sdes sigs = ldns_pkt_rr_list_by_name_and_type(p, name, 131246854Sdes LDNS_RR_TYPE_RRSIG, 132246854Sdes LDNS_SECTION_ANSWER); 133246854Sdes if (!sigs) { 134246854Sdes sigs = ldns_pkt_rr_list_by_name_and_type( 135246854Sdes p, name, LDNS_RR_TYPE_RRSIG, 136246854Sdes LDNS_SECTION_AUTHORITY); 137246854Sdes } 138238104Sdes } 139238104Sdes } else { 140246854Sdes /* A DS-referral - get the DS records if they are there */ 141246854Sdes if (rrlist) { 142246854Sdes *rrlist = ldns_pkt_rr_list_by_type( 143246854Sdes p, t, LDNS_SECTION_AUTHORITY); 144246854Sdes } 145246854Sdes if (sig) { 146246854Sdes sigs = ldns_pkt_rr_list_by_type(p, 147246854Sdes LDNS_RR_TYPE_RRSIG, 148246854Sdes LDNS_SECTION_AUTHORITY); 149246854Sdes } 150238104Sdes } 151238104Sdes if (sig) { 152238104Sdes *sig = ldns_rr_list_new(); 153238104Sdes for (i = 0; i < ldns_rr_list_rr_count(sigs); i++) { 154238104Sdes /* only add the sigs that cover this type */ 155246854Sdes if (t == ldns_rdf2rr_type(ldns_rr_rrsig_typecovered( 156246854Sdes ldns_rr_list_rr(sigs, i)))) { 157246854Sdes 158246854Sdes ldns_rr_list_push_rr(*sig, 159246854Sdes ldns_rr_clone( 160246854Sdes ldns_rr_list_rr( 161246854Sdes sigs, i))); 162238104Sdes } 163238104Sdes } 164238104Sdes } 165238104Sdes ldns_rr_list_deep_free(sigs); 166238104Sdes 167238104Sdes if (pt == LDNS_PACKET_NXDOMAIN || pt == LDNS_PACKET_NODATA) { 168238104Sdes return pt; 169238104Sdes } else { 170238104Sdes return LDNS_PACKET_ANSWER; 171238104Sdes } 172238104Sdes} 173238104Sdes 174238104Sdes 175238104Sdesldns_status 176238104Sdesldns_verify_denial(ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type, ldns_rr_list **nsec_rrs, ldns_rr_list **nsec_rr_sigs) 177238104Sdes{ 178246854Sdes#ifdef HAVE_SSL 179238104Sdes uint16_t nsec_i; 180238104Sdes 181238104Sdes ldns_rr_list *nsecs; 182238104Sdes ldns_status result; 183238104Sdes 184238104Sdes if (verbosity >= 5) { 185238104Sdes printf("VERIFY DENIAL FROM:\n"); 186238104Sdes ldns_pkt_print(stdout, pkt); 187238104Sdes } 188238104Sdes 189238104Sdes result = LDNS_STATUS_CRYPTO_NO_RRSIG; 190238104Sdes /* Try to see if there are NSECS in the packet */ 191238104Sdes nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC, LDNS_SECTION_ANY_NOQUESTION); 192238104Sdes if (nsecs) { 193238104Sdes for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsecs); nsec_i++) { 194238104Sdes /* there are four options: 195238104Sdes * - name equals ownername and is covered by the type bitmap 196238104Sdes * - name equals ownername but is not covered by the type bitmap 197238104Sdes * - name falls within nsec coverage but is not equal to the owner name 198238104Sdes * - name falls outside of nsec coverage 199238104Sdes */ 200238104Sdes if (ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), name) == 0) { 201238104Sdes /* 202238104Sdes printf("CHECKING NSEC:\n"); 203238104Sdes ldns_rr_print(stdout, ldns_rr_list_rr(nsecs, nsec_i)); 204238104Sdes printf("DAWASEM\n"); 205238104Sdes */ 206238104Sdes if (ldns_nsec_bitmap_covers_type( 207238104Sdes ldns_nsec_get_bitmap(ldns_rr_list_rr(nsecs, 208238104Sdes nsec_i)), 209238104Sdes type)) { 210238104Sdes /* Error, according to the nsec this rrset is signed */ 211238104Sdes result = LDNS_STATUS_CRYPTO_NO_RRSIG; 212238104Sdes } else { 213238104Sdes /* ok nsec denies existence */ 214238104Sdes if (verbosity >= 3) { 215238104Sdes printf(";; Existence of data set with this type denied by NSEC\n"); 216238104Sdes } 217238104Sdes /*printf(";; Verifiably insecure.\n");*/ 218238104Sdes if (nsec_rrs && nsec_rr_sigs) { 219238104Sdes (void) get_dnssec_rr(pkt, ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), LDNS_RR_TYPE_NSEC, nsec_rrs, nsec_rr_sigs); 220238104Sdes } 221238104Sdes ldns_rr_list_deep_free(nsecs); 222238104Sdes return LDNS_STATUS_OK; 223238104Sdes } 224238104Sdes } else if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, nsec_i), name)) { 225238104Sdes if (verbosity >= 3) { 226238104Sdes printf(";; Existence of data set with this name denied by NSEC\n"); 227238104Sdes } 228238104Sdes if (nsec_rrs && nsec_rr_sigs) { 229238104Sdes (void) get_dnssec_rr(pkt, ldns_rr_owner(ldns_rr_list_rr(nsecs, nsec_i)), LDNS_RR_TYPE_NSEC, nsec_rrs, nsec_rr_sigs); 230238104Sdes } 231238104Sdes ldns_rr_list_deep_free(nsecs); 232238104Sdes return LDNS_STATUS_OK; 233238104Sdes } else { 234238104Sdes /* nsec has nothing to do with this data */ 235238104Sdes } 236238104Sdes } 237238104Sdes ldns_rr_list_deep_free(nsecs); 238238104Sdes } else if( (nsecs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_NSEC3, LDNS_SECTION_ANY_NOQUESTION)) ) { 239238104Sdes ldns_rr_list* sigs = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_RRSIG, LDNS_SECTION_ANY_NOQUESTION); 240238104Sdes ldns_rr* q = ldns_rr_new(); 241238104Sdes ldns_rr* match = NULL; 242246854Sdes 243246854Sdes if(!sigs) { 244246854Sdes if (q) { 245246854Sdes ldns_rr_free(q); 246246854Sdes } 247246854Sdes ldns_rr_list_deep_free(nsecs); 248246854Sdes return LDNS_STATUS_MEM_ERR; 249246854Sdes } 250246854Sdes if(!q) { 251246854Sdes ldns_rr_list_deep_free(nsecs); 252246854Sdes ldns_rr_list_deep_free(sigs); 253246854Sdes return LDNS_STATUS_MEM_ERR; 254246854Sdes } 255238104Sdes ldns_rr_set_question(q, 1); 256238104Sdes ldns_rr_set_ttl(q, 0); 257238104Sdes ldns_rr_set_owner(q, ldns_rdf_clone(name)); 258246854Sdes if(!ldns_rr_owner(q)) { 259246854Sdes ldns_rr_free(q); 260246854Sdes ldns_rr_list_deep_free(sigs); 261246854Sdes ldns_rr_list_deep_free(nsecs); 262246854Sdes return LDNS_STATUS_MEM_ERR; 263246854Sdes } 264238104Sdes ldns_rr_set_type(q, type); 265238104Sdes 266238104Sdes /* result = ldns_dnssec_verify_denial_nsec3(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0); */ 267238104Sdes result = ldns_dnssec_verify_denial_nsec3_match(q, nsecs, sigs, ldns_pkt_get_rcode(pkt), type, ldns_pkt_ancount(pkt) == 0, &match); 268238104Sdes if (result == LDNS_STATUS_OK && match && nsec_rrs && nsec_rr_sigs) { 269238104Sdes (void) get_dnssec_rr(pkt, ldns_rr_owner(match), LDNS_RR_TYPE_NSEC3, nsec_rrs, nsec_rr_sigs); 270238104Sdes } 271238104Sdes ldns_rr_free(q); 272238104Sdes ldns_rr_list_deep_free(nsecs); 273238104Sdes ldns_rr_list_deep_free(sigs); 274238104Sdes } 275238104Sdes return result; 276246854Sdes#else 277246854Sdes (void)pkt; 278246854Sdes (void)name; 279246854Sdes (void)type; 280246854Sdes (void)nsec_rrs; 281246854Sdes (void)nsec_rr_sigs; 282246854Sdes return LDNS_STATUS_ERR; 283246854Sdes#endif /* HAVE_SSL */ 284238104Sdes} 285238104Sdes 286238104Sdes/* NSEC3 draft -07 */ 287238104Sdes/*return hash name match*/ 288238104Sdesldns_rr * 289238104Sdesldns_nsec3_exact_match(ldns_rdf *qname, ldns_rr_type qtype, ldns_rr_list *nsec3s) { 290238104Sdes uint8_t algorithm; 291238104Sdes uint32_t iterations; 292238104Sdes uint8_t salt_length; 293238104Sdes uint8_t *salt; 294238104Sdes 295238104Sdes ldns_rdf *sname = NULL, *hashed_sname = NULL; 296238104Sdes 297238104Sdes size_t nsec_i; 298238104Sdes ldns_rr *nsec; 299238104Sdes ldns_rr *result = NULL; 300238104Sdes 301238104Sdes const ldns_rr_descriptor *descriptor; 302238104Sdes 303238104Sdes ldns_rdf *zone_name = NULL; 304238104Sdes 305238104Sdes if (verbosity >= 4) { 306238104Sdes printf(";; finding exact match for "); 307238104Sdes descriptor = ldns_rr_descript(qtype); 308238104Sdes if (descriptor && descriptor->_name) { 309238104Sdes printf("%s ", descriptor->_name); 310238104Sdes } else { 311238104Sdes printf("TYPE%d ", qtype); 312238104Sdes } 313238104Sdes ldns_rdf_print(stdout, qname); 314238104Sdes printf("\n"); 315238104Sdes } 316238104Sdes 317238104Sdes if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) { 318238104Sdes if (verbosity >= 4) { 319238104Sdes printf("no qname, nsec3s or list empty\n"); 320238104Sdes } 321238104Sdes return NULL; 322238104Sdes } 323238104Sdes 324238104Sdes nsec = ldns_rr_list_rr(nsec3s, 0); 325238104Sdes algorithm = ldns_nsec3_algorithm(nsec); 326238104Sdes salt_length = ldns_nsec3_salt_length(nsec); 327238104Sdes salt = ldns_nsec3_salt_data(nsec); 328238104Sdes iterations = ldns_nsec3_iterations(nsec); 329238104Sdes if (salt == NULL) { 330238104Sdes goto done; 331238104Sdes } 332238104Sdes 333238104Sdes sname = ldns_rdf_clone(qname); 334238104Sdes if (sname == NULL) { 335238104Sdes goto done; 336238104Sdes } 337238104Sdes if (verbosity >= 4) { 338238104Sdes printf(";; owner name hashes to: "); 339238104Sdes } 340238104Sdes hashed_sname = ldns_nsec3_hash_name(sname, algorithm, iterations, salt_length, salt); 341238104Sdes if (hashed_sname == NULL) { 342238104Sdes goto done; 343238104Sdes } 344238104Sdes zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec)); 345238104Sdes if (zone_name == NULL) { 346238104Sdes goto done; 347238104Sdes } 348238104Sdes if (ldns_dname_cat(hashed_sname, zone_name) != LDNS_STATUS_OK) { 349238104Sdes goto done; 350238104Sdes }; 351238104Sdes 352238104Sdes if (verbosity >= 4) { 353238104Sdes ldns_rdf_print(stdout, hashed_sname); 354238104Sdes printf("\n"); 355238104Sdes } 356238104Sdes 357238104Sdes for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) { 358238104Sdes nsec = ldns_rr_list_rr(nsec3s, nsec_i); 359238104Sdes 360238104Sdes /* check values of iterations etc! */ 361238104Sdes 362238104Sdes /* exact match? */ 363238104Sdes if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) { 364238104Sdes result = nsec; 365238104Sdes goto done; 366238104Sdes } 367238104Sdes 368238104Sdes } 369238104Sdes 370238104Sdesdone: 371238104Sdes ldns_rdf_deep_free(zone_name); 372238104Sdes ldns_rdf_deep_free(sname); 373238104Sdes ldns_rdf_deep_free(hashed_sname); 374238104Sdes LDNS_FREE(salt); 375238104Sdes 376238104Sdes if (verbosity >= 4) { 377238104Sdes if (result) { 378238104Sdes printf(";; Found.\n"); 379238104Sdes } else { 380238104Sdes printf(";; Not foud.\n"); 381238104Sdes } 382238104Sdes } 383238104Sdes return result; 384238104Sdes} 385238104Sdes 386238104Sdes/*return the owner name of the closest encloser for name from the list of rrs */ 387238104Sdes/* this is NOT the hash, but the original name! */ 388238104Sdesldns_rdf * 389238104Sdesldns_nsec3_closest_encloser(ldns_rdf *qname, ldns_rr_type qtype, ldns_rr_list *nsec3s) 390238104Sdes{ 391238104Sdes /* remember parameters, they must match */ 392238104Sdes uint8_t algorithm; 393238104Sdes uint32_t iterations; 394238104Sdes uint8_t salt_length; 395238104Sdes uint8_t *salt; 396238104Sdes 397238104Sdes ldns_rdf *sname = NULL, *hashed_sname = NULL, *tmp; 398238104Sdes bool flag; 399238104Sdes 400238104Sdes bool exact_match_found; 401238104Sdes bool in_range_found; 402238104Sdes 403238104Sdes ldns_rdf *zone_name = NULL; 404238104Sdes 405238104Sdes size_t nsec_i; 406238104Sdes ldns_rr *nsec; 407238104Sdes ldns_rdf *result = NULL; 408238104Sdes 409238104Sdes if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) { 410238104Sdes return NULL; 411238104Sdes } 412238104Sdes 413238104Sdes if (verbosity >= 4) { 414238104Sdes printf(";; finding closest encloser for type %d ", qtype); 415238104Sdes ldns_rdf_print(stdout, qname); 416238104Sdes printf("\n"); 417238104Sdes } 418238104Sdes 419238104Sdes nsec = ldns_rr_list_rr(nsec3s, 0); 420238104Sdes algorithm = ldns_nsec3_algorithm(nsec); 421238104Sdes salt_length = ldns_nsec3_salt_length(nsec); 422238104Sdes salt = ldns_nsec3_salt_data(nsec); 423238104Sdes iterations = ldns_nsec3_iterations(nsec); 424238104Sdes if (salt == NULL) { 425238104Sdes goto done; 426238104Sdes } 427238104Sdes 428238104Sdes sname = ldns_rdf_clone(qname); 429238104Sdes if (sname == NULL) { 430238104Sdes goto done; 431238104Sdes } 432238104Sdes 433238104Sdes flag = false; 434238104Sdes 435238104Sdes zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec)); 436238104Sdes if (zone_name == NULL) { 437238104Sdes goto done; 438238104Sdes } 439238104Sdes 440238104Sdes /* algorithm from nsec3-07 8.3 */ 441238104Sdes while (ldns_dname_label_count(sname) > 0) { 442238104Sdes exact_match_found = false; 443238104Sdes in_range_found = false; 444238104Sdes 445238104Sdes if (verbosity >= 3) { 446238104Sdes printf(";; "); 447238104Sdes ldns_rdf_print(stdout, sname); 448238104Sdes printf(" hashes to: "); 449238104Sdes } 450238104Sdes hashed_sname = ldns_nsec3_hash_name(sname, algorithm, iterations, salt_length, salt); 451238104Sdes if (hashed_sname == NULL) { 452238104Sdes goto done; 453238104Sdes } 454238104Sdes 455238104Sdes if (ldns_dname_cat(hashed_sname, zone_name) != LDNS_STATUS_OK){ 456238104Sdes goto done; 457238104Sdes } 458238104Sdes 459238104Sdes if (verbosity >= 3) { 460238104Sdes ldns_rdf_print(stdout, hashed_sname); 461238104Sdes printf("\n"); 462238104Sdes } 463238104Sdes 464238104Sdes for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) { 465238104Sdes nsec = ldns_rr_list_rr(nsec3s, nsec_i); 466238104Sdes 467238104Sdes /* check values of iterations etc! */ 468238104Sdes 469238104Sdes /* exact match? */ 470238104Sdes if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) { 471238104Sdes if (verbosity >= 4) { 472238104Sdes printf(";; exact match found\n"); 473238104Sdes } 474238104Sdes exact_match_found = true; 475238104Sdes } else if (ldns_nsec_covers_name(nsec, hashed_sname)) { 476238104Sdes if (verbosity >= 4) { 477238104Sdes printf(";; in range of an nsec\n"); 478238104Sdes } 479238104Sdes in_range_found = true; 480238104Sdes } 481238104Sdes 482238104Sdes } 483238104Sdes if (!exact_match_found && in_range_found) { 484238104Sdes flag = true; 485238104Sdes } else if (exact_match_found && flag) { 486238104Sdes result = ldns_rdf_clone(sname); 487238104Sdes } else if (exact_match_found && !flag) { 488238104Sdes // error! 489238104Sdes if (verbosity >= 4) { 490238104Sdes printf(";; the closest encloser is the same name (ie. this is an exact match, ie there is no closest encloser)\n"); 491238104Sdes } 492238104Sdes ldns_rdf_deep_free(hashed_sname); 493238104Sdes goto done; 494238104Sdes } else { 495238104Sdes flag = false; 496238104Sdes } 497238104Sdes 498238104Sdes ldns_rdf_deep_free(hashed_sname); 499238104Sdes tmp = sname; 500238104Sdes sname = ldns_dname_left_chop(sname); 501238104Sdes ldns_rdf_deep_free(tmp); 502238104Sdes if (sname == NULL) { 503238104Sdes goto done; 504238104Sdes } 505238104Sdes } 506238104Sdes 507238104Sdesdone: 508238104Sdes LDNS_FREE(salt); 509238104Sdes ldns_rdf_deep_free(zone_name); 510238104Sdes ldns_rdf_deep_free(sname); 511238104Sdes 512238104Sdes if (!result) { 513238104Sdes if (verbosity >= 4) { 514238104Sdes printf(";; no closest encloser found\n"); 515238104Sdes } 516238104Sdes } 517238104Sdes 518238104Sdes /* todo checks from end of 6.2. here or in caller? */ 519238104Sdes return result; 520238104Sdes} 521