iter_scrub.c (356345) | iter_scrub.c (361435) |
---|---|
1/* 2 * iterator/iter_scrub.c - scrubbing, normalization, sanitization of DNS msgs. 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 171 unchanged lines hidden (view full) --- 180 } 181 } 182 } 183} 184 185/** Get target name of a CNAME */ 186static int 187parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, | 1/* 2 * iterator/iter_scrub.c - scrubbing, normalization, sanitization of DNS msgs. 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 171 unchanged lines hidden (view full) --- 180 } 181 } 182 } 183} 184 185/** Get target name of a CNAME */ 186static int 187parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname, |
188 size_t* snamelen) | 188 size_t* snamelen, sldns_buffer* pkt) |
189{ | 189{ |
190 size_t oldpos, dlen; |
|
190 if(rrset->rr_count != 1) { 191 struct rr_parse* sig; 192 verbose(VERB_ALGO, "Found CNAME rrset with " 193 "size > 1: %u", (unsigned)rrset->rr_count); 194 /* use the first CNAME! */ 195 rrset->rr_count = 1; 196 rrset->size = rrset->rr_first->size; 197 for(sig=rrset->rrsig_first; sig; sig=sig->next) 198 rrset->size += sig->size; 199 rrset->rr_last = rrset->rr_first; 200 rrset->rr_first->next = NULL; 201 } 202 if(rrset->rr_first->size < sizeof(uint16_t)+1) 203 return 0; /* CNAME rdata too small */ 204 *sname = rrset->rr_first->ttl_data + sizeof(uint32_t) 205 + sizeof(uint16_t); /* skip ttl, rdatalen */ 206 *snamelen = rrset->rr_first->size - sizeof(uint16_t); | 191 if(rrset->rr_count != 1) { 192 struct rr_parse* sig; 193 verbose(VERB_ALGO, "Found CNAME rrset with " 194 "size > 1: %u", (unsigned)rrset->rr_count); 195 /* use the first CNAME! */ 196 rrset->rr_count = 1; 197 rrset->size = rrset->rr_first->size; 198 for(sig=rrset->rrsig_first; sig; sig=sig->next) 199 rrset->size += sig->size; 200 rrset->rr_last = rrset->rr_first; 201 rrset->rr_first->next = NULL; 202 } 203 if(rrset->rr_first->size < sizeof(uint16_t)+1) 204 return 0; /* CNAME rdata too small */ 205 *sname = rrset->rr_first->ttl_data + sizeof(uint32_t) 206 + sizeof(uint16_t); /* skip ttl, rdatalen */ 207 *snamelen = rrset->rr_first->size - sizeof(uint16_t); |
208 209 if(rrset->rr_first->outside_packet) { 210 if(!dname_valid(*sname, *snamelen)) 211 return 0; 212 return 1; 213 } 214 oldpos = sldns_buffer_position(pkt); 215 sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt))); 216 dlen = pkt_dname_len(pkt); 217 sldns_buffer_set_position(pkt, oldpos); 218 if(dlen == 0) 219 return 0; /* parse fail on the rdata name */ 220 *snamelen = dlen; |
|
207 return 1; 208} 209 210/** Synthesize CNAME from DNAME, false if too long */ 211static int 212synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset, 213 uint8_t* alias, size_t* aliaslen, sldns_buffer* pkt) 214{ 215 /* we already know that sname is a strict subdomain of DNAME owner */ 216 uint8_t* dtarg = NULL; 217 size_t dtarglen; | 221 return 1; 222} 223 224/** Synthesize CNAME from DNAME, false if too long */ 225static int 226synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset, 227 uint8_t* alias, size_t* aliaslen, sldns_buffer* pkt) 228{ 229 /* we already know that sname is a strict subdomain of DNAME owner */ 230 uint8_t* dtarg = NULL; 231 size_t dtarglen; |
218 if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen)) | 232 if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt)) |
219 return 0; 220 if(qnamelen <= dname_rrset->dname_len) 221 return 0; 222 if(qnamelen == 0) 223 return 0; 224 log_assert(qnamelen > dname_rrset->dname_len); 225 /* DNAME from com. to net. with qname example.com. -> example.net. */ 226 /* so: \3com\0 to \3net\0 and qname \7example\3com\0 */ --- 156 unchanged lines hidden (view full) --- 383 "too long"); 384 return 0; 385 } 386 if(nx && nx->type == LDNS_RR_TYPE_CNAME && 387 dname_pkt_compare(pkt, sname, nx->dname) == 0) { 388 /* check next cname */ 389 uint8_t* t = NULL; 390 size_t tlen = 0; | 233 return 0; 234 if(qnamelen <= dname_rrset->dname_len) 235 return 0; 236 if(qnamelen == 0) 237 return 0; 238 log_assert(qnamelen > dname_rrset->dname_len); 239 /* DNAME from com. to net. with qname example.com. -> example.net. */ 240 /* so: \3com\0 to \3net\0 and qname \7example\3com\0 */ --- 156 unchanged lines hidden (view full) --- 397 "too long"); 398 return 0; 399 } 400 if(nx && nx->type == LDNS_RR_TYPE_CNAME && 401 dname_pkt_compare(pkt, sname, nx->dname) == 0) { 402 /* check next cname */ 403 uint8_t* t = NULL; 404 size_t tlen = 0; |
391 if(!parse_get_cname_target(nx, &t, &tlen)) | 405 if(!parse_get_cname_target(nx, &t, &tlen, pkt)) |
392 return 0; 393 if(dname_pkt_compare(pkt, alias, t) == 0) { 394 /* it's OK and better capitalized */ 395 prev = rrset; 396 rrset = nx; 397 continue; 398 } 399 /* synth ourselves */ --- 34 unchanged lines hidden (view full) --- 434 /* check if the alias of the DNAME equals 435 * this CNAME */ 436 uint8_t alias[LDNS_MAX_DOMAINLEN+1]; 437 size_t aliaslen = 0; 438 uint8_t* t = NULL; 439 size_t tlen = 0; 440 if(synth_cname(sname, snamelen, nx, alias, 441 &aliaslen, pkt) && | 406 return 0; 407 if(dname_pkt_compare(pkt, alias, t) == 0) { 408 /* it's OK and better capitalized */ 409 prev = rrset; 410 rrset = nx; 411 continue; 412 } 413 /* synth ourselves */ --- 34 unchanged lines hidden (view full) --- 448 /* check if the alias of the DNAME equals 449 * this CNAME */ 450 uint8_t alias[LDNS_MAX_DOMAINLEN+1]; 451 size_t aliaslen = 0; 452 uint8_t* t = NULL; 453 size_t tlen = 0; 454 if(synth_cname(sname, snamelen, nx, alias, 455 &aliaslen, pkt) && |
442 parse_get_cname_target(rrset, &t, &tlen) && | 456 parse_get_cname_target(rrset, &t, &tlen, pkt) && |
443 dname_pkt_compare(pkt, alias, t) == 0) { 444 /* the synthesized CNAME equals the 445 * current CNAME. This CNAME is the 446 * one that the DNAME creates, and this 447 * CNAME is better capitalised */ 448 verbose(VERB_ALGO, "normalize: re-order of DNAME and its CNAME"); 449 if(prev) prev->rrset_all_next = nx; 450 else msg->rrset_first = nx; --- 4 unchanged lines hidden (view full) --- 455 nx->rrset_all_next = rrset; 456 /* prev = nx; unused, enable if there 457 * is other rrset removal code after 458 * this */ 459 } 460 } 461 462 /* move to next name in CNAME chain */ | 457 dname_pkt_compare(pkt, alias, t) == 0) { 458 /* the synthesized CNAME equals the 459 * current CNAME. This CNAME is the 460 * one that the DNAME creates, and this 461 * CNAME is better capitalised */ 462 verbose(VERB_ALGO, "normalize: re-order of DNAME and its CNAME"); 463 if(prev) prev->rrset_all_next = nx; 464 else msg->rrset_first = nx; --- 4 unchanged lines hidden (view full) --- 469 nx->rrset_all_next = rrset; 470 /* prev = nx; unused, enable if there 471 * is other rrset removal code after 472 * this */ 473 } 474 } 475 476 /* move to next name in CNAME chain */ |
463 if(!parse_get_cname_target(rrset, &sname, &snamelen)) | 477 if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt)) |
464 return 0; 465 prev = rrset; 466 rrset = rrset->rrset_all_next; 467 /* in CNAME ANY response, can have data after CNAME */ 468 if(qinfo->qtype == LDNS_RR_TYPE_ANY) { 469 while(rrset && rrset->section == 470 LDNS_SECTION_ANSWER && 471 dname_pkt_compare(pkt, oldsname, --- 358 unchanged lines hidden --- | 478 return 0; 479 prev = rrset; 480 rrset = rrset->rrset_all_next; 481 /* in CNAME ANY response, can have data after CNAME */ 482 if(qinfo->qtype == LDNS_RR_TYPE_ANY) { 483 while(rrset && rrset->section == 484 LDNS_SECTION_ANSWER && 485 dname_pkt_compare(pkt, oldsname, --- 358 unchanged lines hidden --- |