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