chasetrace.c revision 246827
1/* 2 * chasetrace.c 3 * Where all the hard work concerning chasing 4 * and tracing is done 5 * (c) 2005, 2006 NLnet Labs 6 * 7 * See the file LICENSE for the license 8 * 9 */ 10 11#include "drill.h" 12#include <ldns/ldns.h> 13 14/** 15 * trace down from the root to name 16 */ 17 18/* same naive method as in drill0.9 19 * We resolver _ALL_ the names, which is ofcourse not needed 20 * We _do_ use the local resolver to do that, so it still is 21 * fast, but it can be made to run much faster 22 */ 23ldns_pkt * 24do_trace(ldns_resolver *local_res, ldns_rdf *name, ldns_rr_type t, 25 ldns_rr_class c) 26{ 27 ldns_resolver *res; 28 ldns_pkt *p; 29 ldns_rr_list *new_nss_a; 30 ldns_rr_list *new_nss_aaaa; 31 ldns_rr_list *final_answer; 32 ldns_rr_list *new_nss; 33 ldns_rr_list *ns_addr; 34 uint16_t loop_count; 35 ldns_rdf *pop; 36 ldns_status status; 37 size_t i; 38 39 loop_count = 0; 40 new_nss_a = NULL; 41 new_nss_aaaa = NULL; 42 new_nss = NULL; 43 ns_addr = NULL; 44 final_answer = NULL; 45 p = ldns_pkt_new(); 46 res = ldns_resolver_new(); 47 48 if (!p || !res) { 49 error("Memory allocation failed"); 50 return NULL; 51 } 52 53 /* transfer some properties of local_res to res, 54 * because they were given on the commandline */ 55 ldns_resolver_set_ip6(res, 56 ldns_resolver_ip6(local_res)); 57 ldns_resolver_set_port(res, 58 ldns_resolver_port(local_res)); 59 ldns_resolver_set_debug(res, 60 ldns_resolver_debug(local_res)); 61 ldns_resolver_set_dnssec(res, 62 ldns_resolver_dnssec(local_res)); 63 ldns_resolver_set_fail(res, 64 ldns_resolver_fail(local_res)); 65 ldns_resolver_set_usevc(res, 66 ldns_resolver_usevc(local_res)); 67 ldns_resolver_set_random(res, 68 ldns_resolver_random(local_res)); 69 ldns_resolver_set_recursive(res, false); 70 71 /* setup the root nameserver in the new resolver */ 72 status = ldns_resolver_push_nameserver_rr_list(res, global_dns_root); 73 if (status != LDNS_STATUS_OK) { 74 fprintf(stderr, "Error adding root servers to resolver: %s\n", ldns_get_errorstr_by_id(status)); 75 ldns_rr_list_print(stdout, global_dns_root); 76 return NULL; 77 } 78 79 /* this must be a real query to local_res */ 80 status = ldns_resolver_send(&p, res, ldns_dname_new_frm_str("."), LDNS_RR_TYPE_NS, c, 0); 81 /* p can still be NULL */ 82 83 84 if (ldns_pkt_empty(p)) { 85 warning("No root server information received"); 86 } 87 88 if (status == LDNS_STATUS_OK) { 89 if (!ldns_pkt_empty(p)) { 90 drill_pkt_print(stdout, local_res, p); 91 } 92 } else { 93 error("cannot use local resolver"); 94 return NULL; 95 } 96 97 status = ldns_resolver_send(&p, res, name, t, c, 0); 98 99 while(status == LDNS_STATUS_OK && 100 ldns_pkt_reply_type(p) == LDNS_PACKET_REFERRAL) { 101 102 if (!p) { 103 /* some error occurred, bail out */ 104 return NULL; 105 } 106 107 new_nss_a = ldns_pkt_rr_list_by_type(p, 108 LDNS_RR_TYPE_A, LDNS_SECTION_ADDITIONAL); 109 new_nss_aaaa = ldns_pkt_rr_list_by_type(p, 110 LDNS_RR_TYPE_AAAA, LDNS_SECTION_ADDITIONAL); 111 new_nss = ldns_pkt_rr_list_by_type(p, 112 LDNS_RR_TYPE_NS, LDNS_SECTION_AUTHORITY); 113 114 if (verbosity != -1) { 115 ldns_rr_list_print(stdout, new_nss); 116 } 117 /* checks itself for verbosity */ 118 drill_pkt_print_footer(stdout, local_res, p); 119 120 /* remove the old nameserver from the resolver */ 121 while((pop = ldns_resolver_pop_nameserver(res))) { /* do it */ } 122 123 /* also check for new_nss emptyness */ 124 125 if (!new_nss_aaaa && !new_nss_a) { 126 /* 127 * no nameserver found!!! 128 * try to resolve the names we do got 129 */ 130 for(i = 0; i < ldns_rr_list_rr_count(new_nss); i++) { 131 /* get the name of the nameserver */ 132 pop = ldns_rr_rdf(ldns_rr_list_rr(new_nss, i), 0); 133 if (!pop) { 134 break; 135 } 136 137 ldns_rr_list_print(stdout, new_nss); 138 ldns_rdf_print(stdout, pop); 139 /* retrieve it's addresses */ 140 ns_addr = ldns_rr_list_cat_clone(ns_addr, 141 ldns_get_rr_list_addr_by_name(local_res, pop, c, 0)); 142 } 143 144 if (ns_addr) { 145 if (ldns_resolver_push_nameserver_rr_list(res, ns_addr) != 146 LDNS_STATUS_OK) { 147 error("Error adding new nameservers"); 148 ldns_pkt_free(p); 149 return NULL; 150 } 151 ldns_rr_list_free(ns_addr); 152 } else { 153 ldns_rr_list_print(stdout, ns_addr); 154 error("Could not find the nameserver ip addr; abort"); 155 ldns_pkt_free(p); 156 return NULL; 157 } 158 } 159 160 /* add the new ones */ 161 if (new_nss_aaaa) { 162 if (ldns_resolver_push_nameserver_rr_list(res, new_nss_aaaa) != 163 LDNS_STATUS_OK) { 164 error("adding new nameservers"); 165 ldns_pkt_free(p); 166 return NULL; 167 } 168 } 169 if (new_nss_a) { 170 if (ldns_resolver_push_nameserver_rr_list(res, new_nss_a) != 171 LDNS_STATUS_OK) { 172 error("adding new nameservers"); 173 ldns_pkt_free(p); 174 return NULL; 175 } 176 } 177 178 if (loop_count++ > 20) { 179 /* unlikely that we are doing something usefull */ 180 error("Looks like we are looping"); 181 ldns_pkt_free(p); 182 return NULL; 183 } 184 185 status = ldns_resolver_send(&p, res, name, t, c, 0); 186 new_nss_aaaa = NULL; 187 new_nss_a = NULL; 188 ns_addr = NULL; 189 } 190 191 status = ldns_resolver_send(&p, res, name, t, c, 0); 192 193 if (!p) { 194 return NULL; 195 } 196 197 new_nss = ldns_pkt_authority(p); 198 final_answer = ldns_pkt_answer(p); 199 200 if (verbosity != -1) { 201 ldns_rr_list_print(stdout, final_answer); 202 ldns_rr_list_print(stdout, new_nss); 203 204 } 205 drill_pkt_print_footer(stdout, local_res, p); 206 ldns_pkt_free(p); 207 return NULL; 208} 209 210 211/** 212 * Chase the given rr to a known and trusted key 213 * 214 * Based on drill 0.9 215 * 216 * the last argument prev_key_list, if not null, and type == DS, then the ds 217 * rr list we have must all be a ds for the keys in this list 218 */ 219#ifdef HAVE_SSL 220ldns_status 221do_chase(ldns_resolver *res, 222 ldns_rdf *name, 223 ldns_rr_type type, 224 ldns_rr_class c, 225 ldns_rr_list *trusted_keys, 226 ldns_pkt *pkt_o, 227 uint16_t qflags, 228 ldns_rr_list * ATTR_UNUSED(prev_key_list), 229 int verbosity) 230{ 231 ldns_rr_list *rrset = NULL; 232 ldns_status result; 233 ldns_rr *orig_rr = NULL; 234 235/* 236 ldns_rr_list *sigs; 237 ldns_rr *cur_sig; 238 uint16_t sig_i; 239 ldns_rr_list *keys; 240*/ 241 ldns_pkt *pkt; 242 ldns_status tree_result; 243 ldns_dnssec_data_chain *chain; 244 ldns_dnssec_trust_tree *tree; 245 246 const ldns_rr_descriptor *descriptor; 247 descriptor = ldns_rr_descript(type); 248 249 ldns_dname2canonical(name); 250 251 pkt = ldns_pkt_clone(pkt_o); 252 if (!name) { 253 mesg("No name to chase"); 254 ldns_pkt_free(pkt); 255 return LDNS_STATUS_EMPTY_LABEL; 256 } 257 if (verbosity != -1) { 258 printf(";; Chasing: "); 259 ldns_rdf_print(stdout, name); 260 if (descriptor && descriptor->_name) { 261 printf(" %s\n", descriptor->_name); 262 } else { 263 printf(" type %d\n", type); 264 } 265 } 266 267 if (!trusted_keys || ldns_rr_list_rr_count(trusted_keys) < 1) { 268 warning("No trusted keys specified"); 269 } 270 271 if (pkt) { 272 rrset = ldns_pkt_rr_list_by_name_and_type(pkt, 273 name, 274 type, 275 LDNS_SECTION_ANSWER 276 ); 277 if (!rrset) { 278 /* nothing in answer, try authority */ 279 rrset = ldns_pkt_rr_list_by_name_and_type(pkt, 280 name, 281 type, 282 LDNS_SECTION_AUTHORITY 283 ); 284 } 285 /* answer might be a cname, chase that first, then chase 286 cname target? (TODO) */ 287 if (!rrset) { 288 rrset = ldns_pkt_rr_list_by_name_and_type(pkt, 289 name, 290 LDNS_RR_TYPE_CNAME, 291 LDNS_SECTION_ANSWER 292 ); 293 if (!rrset) { 294 /* nothing in answer, try authority */ 295 rrset = ldns_pkt_rr_list_by_name_and_type(pkt, 296 name, 297 LDNS_RR_TYPE_CNAME, 298 LDNS_SECTION_AUTHORITY 299 ); 300 } 301 } 302 } else { 303 /* no packet? */ 304 if (verbosity >= 0) { 305 fprintf(stderr, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR)); 306 fprintf(stderr, "\n"); 307 } 308 return LDNS_STATUS_MEM_ERR; 309 } 310 311 if (!rrset) { 312 /* not found in original packet, try again */ 313 ldns_pkt_free(pkt); 314 pkt = NULL; 315 pkt = ldns_resolver_query(res, name, type, c, qflags); 316 317 if (!pkt) { 318 if (verbosity >= 0) { 319 fprintf(stderr, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_NETWORK_ERR)); 320 fprintf(stderr, "\n"); 321 } 322 return LDNS_STATUS_NETWORK_ERR; 323 } 324 if (verbosity >= 5) { 325 ldns_pkt_print(stdout, pkt); 326 } 327 328 rrset = ldns_pkt_rr_list_by_name_and_type(pkt, 329 name, 330 type, 331 LDNS_SECTION_ANSWER 332 ); 333 } 334 335 orig_rr = ldns_rr_new(); 336 337/* if the answer had no answer section, we need to construct our own rr (for instance if 338 * the rr qe asked for doesn't exist. This rr will be destroyed when the chain is freed */ 339 if (ldns_pkt_ancount(pkt) < 1) { 340 ldns_rr_set_type(orig_rr, type); 341 ldns_rr_set_owner(orig_rr, ldns_rdf_clone(name)); 342 343 chain = ldns_dnssec_build_data_chain(res, qflags, rrset, pkt, ldns_rr_clone(orig_rr)); 344 } else { 345 /* chase the first answer */ 346 chain = ldns_dnssec_build_data_chain(res, qflags, rrset, pkt, NULL); 347 } 348 349 if (verbosity >= 4) { 350 printf("\n\nDNSSEC Data Chain:\n"); 351 ldns_dnssec_data_chain_print(stdout, chain); 352 } 353 354 result = LDNS_STATUS_OK; 355 356 tree = ldns_dnssec_derive_trust_tree(chain, NULL); 357 358 if (verbosity >= 2) { 359 printf("\n\nDNSSEC Trust tree:\n"); 360 ldns_dnssec_trust_tree_print(stdout, tree, 0, true); 361 } 362 363 if (ldns_rr_list_rr_count(trusted_keys) > 0) { 364 tree_result = ldns_dnssec_trust_tree_contains_keys(tree, trusted_keys); 365 366 if (tree_result == LDNS_STATUS_DNSSEC_EXISTENCE_DENIED) { 367 if (verbosity >= 1) { 368 printf("Existence denied or verifiably insecure\n"); 369 } 370 result = LDNS_STATUS_OK; 371 } else if (tree_result != LDNS_STATUS_OK) { 372 if (verbosity >= 1) { 373 printf("No trusted keys found in tree: first error was: %s\n", ldns_get_errorstr_by_id(tree_result)); 374 } 375 result = tree_result; 376 } 377 378 } else { 379 if (verbosity >= 0) { 380 printf("You have not provided any trusted keys.\n"); 381 } 382 } 383 384 ldns_rr_free(orig_rr); 385 ldns_dnssec_trust_tree_free(tree); 386 ldns_dnssec_data_chain_deep_free(chain); 387 388 ldns_rr_list_deep_free(rrset); 389 ldns_pkt_free(pkt); 390 /* ldns_rr_free(orig_rr);*/ 391 392 return result; 393} 394#endif /* HAVE_SSL */ 395 396