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