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