Beispiel #1
0
static void
ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
		ldns_dnssec_name* name, ldns_rr* nsec3rr)
{
	ldns_rbnode_t* new_node;

	assert(name != NULL);
	if (! zone->_nsec3params) {
		if (! nsec3rr) {
			return;
		}
		ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);

	} else if (! nsec3rr) {
		nsec3rr = zone->_nsec3params;
	}
	name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);

	/* Also store in zone->hashed_names */
	if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {

		new_node->key  = name->hashed_name;
		new_node->data = name;

		if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {

				LDNS_FREE(new_node);
		}
	}
}
Beispiel #2
0
/* more sophisticated functions */
ldns_resolver *
ldns_resolver_new(void)
{
    ldns_resolver *r;

    r = LDNS_MALLOC(ldns_resolver);
    if (!r) {
        return NULL;
    }

    r->_searchlist = NULL;
    r->_nameservers = NULL;
    r->_rtt = NULL;

    /* defaults are filled out */
    ldns_resolver_set_searchlist_count(r, 0);
    ldns_resolver_set_nameserver_count(r, 0);
    ldns_resolver_set_usevc(r, 0);
    ldns_resolver_set_port(r, LDNS_PORT);
    ldns_resolver_set_domain(r, NULL);
    ldns_resolver_set_defnames(r, false);
    ldns_resolver_set_retry(r, 3);
    ldns_resolver_set_retrans(r, 2);
    ldns_resolver_set_fallback(r, true);
    ldns_resolver_set_fail(r, false);
    ldns_resolver_set_edns_udp_size(r, 0);
    ldns_resolver_set_dnssec(r, false);
    ldns_resolver_set_dnssec_cd(r, false);
    ldns_resolver_set_dnssec_anchors(r, NULL);
    ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
    ldns_resolver_set_igntc(r, false);
    ldns_resolver_set_recursive(r, false);
    ldns_resolver_set_dnsrch(r, true);

    /* randomize the nameserver to be queried
     * when there are multiple
     */
    ldns_resolver_set_random(r, true);

    ldns_resolver_set_debug(r, 0);

    r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
    r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;

    /* TODO: fd=0 is actually a valid socket (stdin),
           replace with -1 */
    r->_socket = 0;
    r->_axfr_soa_count = 0;
    r->_axfr_i = 0;
    r->_cur_axfr_pkt = NULL;

    r->_tsig_keyname = NULL;
    r->_tsig_keydata = NULL;
    r->_tsig_algorithm = NULL;
    return r;
}
Beispiel #3
0
ldns_dnssec_rrs *
ldns_dnssec_rrs_new(void)
{
	ldns_dnssec_rrs *new_rrs;
	new_rrs = LDNS_MALLOC(ldns_dnssec_rrs);
        if(!new_rrs) return NULL;
	new_rrs->rr = NULL;
	new_rrs->next = NULL;
	return new_rrs;
}
Beispiel #4
0
ldns_dnssec_zone *
ldns_dnssec_zone_new(void)
{
	ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone);
        if(!zone) return NULL;
	zone->soa = NULL;
	zone->names = NULL;

	return zone;
}
Beispiel #5
0
ldns_status
ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
{
	ldns_status result = LDNS_STATUS_OK;
	ldns_dnssec_name *cur_name;
	ldns_rbnode_t *cur_node;
	ldns_rr_type type_covered = 0;

	if (!zone || !rr) {
		return LDNS_STATUS_ERR;
	}

	if (!zone->names) {
		zone->names = ldns_rbtree_create(ldns_dname_compare_v);
                if(!zone->names) return LDNS_STATUS_MEM_ERR;
	}

	/* we need the original of the hashed name if this is
	   an NSEC3, or an RRSIG that covers an NSEC3 */
	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
		type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
	}
	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
	    type_covered == LDNS_RR_TYPE_NSEC3) {
		cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
		if (!cur_node) {
			return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND;
		}
	} else {
		cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
	}
	if (!cur_node) {
		/* add */
		cur_name = ldns_dnssec_name_new_frm_rr(rr);
                if(!cur_name) return LDNS_STATUS_MEM_ERR;
		cur_node = LDNS_MALLOC(ldns_rbnode_t);
                if(!cur_node) {
                        ldns_dnssec_name_free(cur_name);
                        return LDNS_STATUS_MEM_ERR;
                }
		cur_node->key = ldns_rr_owner(rr);
		cur_node->data = cur_name;
		(void)ldns_rbtree_insert(zone->names, cur_node);
		ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
	} else {
		cur_name = (ldns_dnssec_name *) cur_node->data;
		result = ldns_dnssec_name_add_rr(cur_name, rr);
	}
	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
		zone->soa = cur_name;
	}
	return result;
}
Beispiel #6
0
ldns_dnssec_rrsets *
ldns_dnssec_rrsets_new(void)
{
	ldns_dnssec_rrsets *new_rrsets;
	new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
        if(!new_rrsets) return NULL;
	new_rrsets->rrs = NULL;
	new_rrsets->type = 0;
	new_rrsets->signatures = NULL;
	new_rrsets->next = NULL;
	return new_rrsets;
}
Beispiel #7
0
ldns_zone *
ldns_zone_new(void)
{
	ldns_zone *z;

	z = LDNS_MALLOC(ldns_zone);
	if (!z) {
		return NULL;
	}

	z->_rrs = ldns_rr_list_new();
	ldns_zone_set_soa(z, NULL);
	return z;
}
Beispiel #8
0
ldns_buffer *
read_hex_buffer(char *filename)
{
	uint8_t *wire;
	size_t wiresize;
	ldns_buffer *result_buffer = NULL;
	

	wire = xmalloc(LDNS_MAX_PACKETLEN);
	
	wiresize = packetbuffromfile(filename, wire);
	
	result_buffer = LDNS_MALLOC(ldns_buffer);
	ldns_buffer_new_frm_data(result_buffer, wire, wiresize);
	ldns_buffer_set_position(result_buffer, ldns_buffer_capacity(result_buffer));
	xfree(wire);

	return result_buffer;
}
Beispiel #9
0
ldns_buffer *
ldns_buffer_new(size_t capacity)
{
	ldns_buffer *buffer = LDNS_MALLOC(ldns_buffer);

	if (!buffer) {
		return NULL;
	}
	
	buffer->_data = (uint8_t *) LDNS_XMALLOC(uint8_t, capacity);
	if (!buffer->_data) {
		LDNS_FREE(buffer);
		return NULL;
	}
	
	buffer->_position = 0;
	buffer->_limit = buffer->_capacity = capacity;
	buffer->_fixed = 0;
	buffer->_status = LDNS_STATUS_OK;
	
	ldns_buffer_invariant(buffer);
	
	return buffer;
}
Beispiel #10
0
ldns_status
ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
{
	ldns_resolver *r;
	const char *keyword[LDNS_RESOLV_KEYWORDS];
	char word[LDNS_MAX_LINELEN + 1];
	int8_t expect;
	uint8_t i;
	ldns_rdf *tmp;
#ifdef HAVE_SSL
	ldns_rr *tmp_rr;
#endif
	ssize_t gtr;
	ldns_buffer *b;

	/* do this better 
	 * expect = 
	 * 0: keyword
	 * 1: default domain dname
	 * 2: NS aaaa or a record
	 */

	/* recognized keywords */
	keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
	keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
	keyword[LDNS_RESOLV_SEARCH] = "search";
	/* these two are read but not used atm TODO */
	keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
	keyword[LDNS_RESOLV_OPTIONS] = "options";
	keyword[LDNS_RESOLV_ANCHOR] = "anchor";
	expect = LDNS_RESOLV_KEYWORD;

	r = ldns_resolver_new();
	if (!r) {
		return LDNS_STATUS_MEM_ERR;
	}

	gtr = 1;
	word[0] = 0;
	while (gtr > 0) {
		/* check comments */
		if (word[0] == '#') {
			/* read the rest of the line, should be 1 word */
			gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
			/* prepare the next string for further parsing */
			gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
			continue;
		}
		switch(expect) {
			case LDNS_RESOLV_KEYWORD:
				/* keyword */
				gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
				if (gtr != 0) {
					for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
						if (strcasecmp(keyword[i], word) == 0) {
							/* chosen the keyword and
							 * expect values carefully
							 */
							expect = i;
							break;
						}
					}
					/* no keyword recognized */
					if (expect == LDNS_RESOLV_KEYWORD) {
						/* skip line */
						/*
						ldns_resolver_deep_free(r);
						return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
						*/
					}
				}
				break;
			case LDNS_RESOLV_DEFDOMAIN:
				/* default domain dname */
				gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
				if (gtr == 0) {
					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
				}
				tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
				if (!tmp) {
					ldns_resolver_deep_free(r);
					return LDNS_STATUS_SYNTAX_DNAME_ERR;
				}

				/* DOn't free, because we copy the pointer */
				ldns_resolver_set_domain(r, tmp);
				expect = LDNS_RESOLV_KEYWORD;
				break;
			case LDNS_RESOLV_NAMESERVER:
				/* NS aaaa or a record */
				gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
				if (gtr == 0) {
					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
				}
				tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
				if (!tmp) {
					/* try ip4 */
					tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
				}
				/* could not parse it, exit */
				if (!tmp) {
					ldns_resolver_deep_free(r);
					return LDNS_STATUS_SYNTAX_ERR;
				}
				(void)ldns_resolver_push_nameserver(r, tmp);
				ldns_rdf_deep_free(tmp);
				expect = LDNS_RESOLV_KEYWORD;
				break;
			case LDNS_RESOLV_SEARCH:
				/* search list domain dname */
				gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
				b = LDNS_MALLOC(ldns_buffer);
				ldns_buffer_new_frm_data(b, word, (size_t) gtr);

				gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr);
				while (gtr > 0) {
					tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
					if (!tmp) {
						ldns_resolver_deep_free(r);
						return LDNS_STATUS_SYNTAX_DNAME_ERR;
					}

					ldns_resolver_push_searchlist(r, tmp); 

					ldns_rdf_deep_free(tmp);
					gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr);
				}
				ldns_buffer_free(b);
				gtr = 1;
				expect = LDNS_RESOLV_KEYWORD;
				break;
			case LDNS_RESOLV_SORTLIST:
				gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
				/* sortlist not implemented atm */
				expect = LDNS_RESOLV_KEYWORD;
				break;
			case LDNS_RESOLV_OPTIONS:
				gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
				/* options not implemented atm */
				expect = LDNS_RESOLV_KEYWORD;
				break;
			case LDNS_RESOLV_ANCHOR:
				/* a file containing a DNSSEC trust anchor */
				gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
				if (gtr == 0) {
					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
				}

#ifdef HAVE_SSL
				tmp_rr = ldns_read_anchor_file(word);
				(void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
				ldns_rr_free(tmp_rr);
#endif
				expect = LDNS_RESOLV_KEYWORD;
				break;
		}
	}
	
	if (res) {
		*res = r;
		return LDNS_STATUS_OK;
	} else {
		return LDNS_STATUS_NULL;
	}
}
Beispiel #11
0
ldns_status
ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
{
	ldns_dnssec_name *new_name;
	ldns_rdf *cur_name;
	ldns_rdf *next_name;
	ldns_rbnode_t *cur_node, *next_node, *new_node;

	/* for the detection */
	uint16_t i, cur_label_count, next_label_count;
	uint16_t soa_label_count = 0;
	ldns_rdf *l1, *l2;
	int lpos;

	if (!zone) {
		return LDNS_STATUS_ERR;
	}
	if (zone->soa && zone->soa->name) {
		soa_label_count = ldns_dname_label_count(zone->soa->name);
	}
	
	cur_node = ldns_rbtree_first(zone->names);
	while (cur_node != LDNS_RBTREE_NULL) {
		next_node = ldns_rbtree_next(cur_node);
		
		/* skip glue */
		while (next_node != LDNS_RBTREE_NULL && 
		       next_node->data &&
		       ((ldns_dnssec_name *)next_node->data)->is_glue
		) {
			next_node = ldns_rbtree_next(next_node);
		}

		if (next_node == LDNS_RBTREE_NULL) {
			next_node = ldns_rbtree_first(zone->names);
		}
		if (! cur_node->data || ! next_node->data) {
			return LDNS_STATUS_ERR;
		}
		cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
		next_name = ((ldns_dnssec_name *)next_node->data)->name;
		cur_label_count = ldns_dname_label_count(cur_name);
		next_label_count = ldns_dname_label_count(next_name);

		/* Since the names are in canonical order, we can
		 * recognize empty non-terminals by their labels;
		 * every label after the first one on the next owner
		 * name is a non-terminal if it either does not exist
		 * in the current name or is different from the same
		 * label in the current name (counting from the end)
		 */
		for (i = 1; i < next_label_count - soa_label_count; i++) {
			lpos = (int)cur_label_count - (int)next_label_count + (int)i;
			if (lpos >= 0) {
				l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
			} else {
				l1 = NULL;
			}
			l2 = ldns_dname_clone_from(next_name, i);

			if (!l1 || ldns_dname_compare(l1, l2) != 0) {
				/* We have an empty nonterminal, add it to the
				 * tree
				 */
				new_name = ldns_dnssec_name_new();
				if (!new_name) {
					return LDNS_STATUS_MEM_ERR;
				}
				new_name->name = ldns_dname_clone_from(next_name,
				                                       i);
				if (!new_name->name) {
					ldns_dnssec_name_free(new_name);
					return LDNS_STATUS_MEM_ERR;
				}
				new_name->name_alloced = true;
				new_node = LDNS_MALLOC(ldns_rbnode_t);
				if (!new_node) {
					ldns_dnssec_name_free(new_name);
					return LDNS_STATUS_MEM_ERR;
				}
				new_node->key = new_name->name;
				new_node->data = new_name;
				(void)ldns_rbtree_insert(zone->names, new_node);
				ldns_dnssec_name_make_hashed_name(
						zone, new_name, NULL);
			}
			ldns_rdf_deep_free(l1);
			ldns_rdf_deep_free(l2);
		}
		
		/* we might have inserted a new node after
		 * the current one so we can't just use next()
		 */
		if (next_node != ldns_rbtree_first(zone->names)) {
			cur_node = next_node;
		} else {
			cur_node = LDNS_RBTREE_NULL;
		}
	}
	return LDNS_STATUS_OK;
}
Beispiel #12
0
ldns_status
ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
{
    ldns_resolver *r;
    const char *keyword[LDNS_RESOLV_KEYWORDS];
    char word[LDNS_MAX_LINELEN + 1];
    int8_t expect;
    uint8_t i;
    ldns_rdf *tmp;
#ifdef HAVE_SSL
    ldns_rr *tmp_rr;
#endif
    ssize_t gtr, bgtr;
    ldns_buffer *b;
    int lnr = 0, oldline;
    if(!line_nr) line_nr = &lnr;

    /* do this better
     * expect =
     * 0: keyword
     * 1: default domain dname
     * 2: NS aaaa or a record
     */

    /* recognized keywords */
    keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
    keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
    keyword[LDNS_RESOLV_SEARCH] = "search";
    /* these two are read but not used atm TODO */
    keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
    keyword[LDNS_RESOLV_OPTIONS] = "options";
    keyword[LDNS_RESOLV_ANCHOR] = "anchor";
    expect = LDNS_RESOLV_KEYWORD;

    r = ldns_resolver_new();
    if (!r) {
        return LDNS_STATUS_MEM_ERR;
    }

    gtr = 1;
    word[0] = 0;
    oldline = *line_nr;
    expect = LDNS_RESOLV_KEYWORD;
    while (gtr > 0) {
        /* check comments */
        if (word[0] == '#') {
            word[0]='x';
            if(oldline == *line_nr) {
                /* skip until end of line */
                int c;
                do {
                    c = fgetc(fp);
                } while(c != EOF && c != '\n');
                if(c=='\n' && line_nr) (*line_nr)++;
            }
            /* and read next to prepare for further parsing */
            oldline = *line_nr;
            continue;
        }
        oldline = *line_nr;
        switch(expect) {
        case LDNS_RESOLV_KEYWORD:
            /* keyword */
            gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
            if (gtr != 0) {
                if(word[0] == '#') continue;
                for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
                    if (strcasecmp(keyword[i], word) == 0) {
                        /* chosen the keyword and
                         * expect values carefully
                        	 */
                        expect = i;
                        break;
                    }
                }
                /* no keyword recognized */
                if (expect == LDNS_RESOLV_KEYWORD) {
                    /* skip line */
                    /*
                    ldns_resolver_deep_free(r);
                    return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
                    */
                }
            }
            break;
        case LDNS_RESOLV_DEFDOMAIN:
            /* default domain dname */
            gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
            if (gtr == 0) {
                return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
            }
            if(word[0] == '#') {
                expect = LDNS_RESOLV_KEYWORD;
                continue;
            }
            tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
            if (!tmp) {
                ldns_resolver_deep_free(r);
                return LDNS_STATUS_SYNTAX_DNAME_ERR;
            }

            /* DOn't free, because we copy the pointer */
            ldns_resolver_set_domain(r, tmp);
            expect = LDNS_RESOLV_KEYWORD;
            break;
        case LDNS_RESOLV_NAMESERVER:
            /* NS aaaa or a record */
            gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
            if (gtr == 0) {
                return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
            }
            if(word[0] == '#') {
                expect = LDNS_RESOLV_KEYWORD;
                continue;
            }
            if(strchr(word, '%')) {
                /* snip off interface labels,
                 * fe80::222:19ff:fe31:4222%eth0 */
                strchr(word, '%')[0]=0;
            }
            tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
            if (!tmp) {
                /* try ip4 */
                tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
            }
            /* could not parse it, exit */
            if (!tmp) {
                ldns_resolver_deep_free(r);
                return LDNS_STATUS_SYNTAX_ERR;
            }
            (void)ldns_resolver_push_nameserver(r, tmp);
            ldns_rdf_deep_free(tmp);
            expect = LDNS_RESOLV_KEYWORD;
            break;
        case LDNS_RESOLV_SEARCH:
            /* search list domain dname */
            gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
            b = LDNS_MALLOC(ldns_buffer);
            if(!b) {
                ldns_resolver_deep_free(r);
                return LDNS_STATUS_MEM_ERR;
            }

            ldns_buffer_new_frm_data(b, word, (size_t) gtr);
            if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
                LDNS_FREE(b);
                ldns_resolver_deep_free(r);
                return LDNS_STATUS_MEM_ERR;
            }
            bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
            while (bgtr > 0) {
                gtr -= bgtr;
                if(word[0] == '#') {
                    expect = LDNS_RESOLV_KEYWORD;
                    ldns_buffer_free(b);
                    continue;
                }
                tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
                if (!tmp) {
                    ldns_resolver_deep_free(r);
                    ldns_buffer_free(b);
                    return LDNS_STATUS_SYNTAX_DNAME_ERR;
                }

                ldns_resolver_push_searchlist(r, tmp);

                ldns_rdf_deep_free(tmp);
                bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
                                       (size_t) gtr + 1);
            }
            ldns_buffer_free(b);
            gtr = 1;
            expect = LDNS_RESOLV_KEYWORD;
            break;
        case LDNS_RESOLV_SORTLIST:
            gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
            /* sortlist not implemented atm */
            expect = LDNS_RESOLV_KEYWORD;
            break;
        case LDNS_RESOLV_OPTIONS:
            gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
            /* options not implemented atm */
            expect = LDNS_RESOLV_KEYWORD;
            break;
        case LDNS_RESOLV_ANCHOR:
            /* a file containing a DNSSEC trust anchor */
            gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
            if (gtr == 0) {
                ldns_resolver_deep_free(r);
                return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
            }
            if(word[0] == '#') {
                expect = LDNS_RESOLV_KEYWORD;
                continue;
            }

#ifdef HAVE_SSL
            tmp_rr = ldns_read_anchor_file(word);
            (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
            ldns_rr_free(tmp_rr);
#endif
            expect = LDNS_RESOLV_KEYWORD;
            break;
        }
    }

    /* finally, add the root domain to the search list */
    ldns_resolver_push_searchlist(r, ldns_dname_new_frm_str("."));

    if (res) {
        *res = r;
        return LDNS_STATUS_OK;
    } else {
        ldns_resolver_deep_free(r);
        return LDNS_STATUS_NULL;
    }
}
Beispiel #13
0
static ldns_status
ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
		ldns_rr_list *new_rrs,
		uint8_t algorithm,
		uint8_t flags,
		uint16_t iterations,
		uint8_t salt_length,
		uint8_t *salt,
		ldns_rbtree_t **map)
{
	ldns_rbnode_t *first_name_node;
	ldns_rbnode_t *current_name_node;
	ldns_dnssec_name *current_name;
	ldns_status result = LDNS_STATUS_OK;
	ldns_rr *nsec_rr;
	ldns_rr_list *nsec3_list;
	uint32_t nsec_ttl;
	ldns_dnssec_rrsets *soa;
	ldns_rbnode_t *hashmap_node;

	if (!zone || !new_rrs || !zone->names) {
		return LDNS_STATUS_ERR;
	}

	/* the TTL of NSEC rrs should be set to the minimum TTL of
	 * the zone SOA (RFC4035 Section 2.3)
	 */
	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);

	/* did the caller actually set it? if not,
	 * fall back to default ttl
	 */
	if (soa && soa->rrs && soa->rrs->rr
			&& ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
	} else {
		nsec_ttl = LDNS_DEFAULT_TTL;
	}

	if (zone->hashed_names) {
		ldns_traverse_postorder(zone->hashed_names,
				ldns_hashed_names_node_free, NULL);
		LDNS_FREE(zone->hashed_names);
	}
	zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
	if (zone->hashed_names && map) {
		*map = zone->hashed_names;
	}

	first_name_node = ldns_dnssec_name_node_next_nonglue(
					  ldns_rbtree_first(zone->names));

	current_name_node = first_name_node;

	while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
			result == LDNS_STATUS_OK) {

		current_name = (ldns_dnssec_name *) current_name_node->data;
		nsec_rr = ldns_dnssec_create_nsec3(current_name,
		                                   NULL,
		                                   zone->soa->name,
		                                   algorithm,
		                                   flags,
		                                   iterations,
		                                   salt_length,
		                                   salt);
		/* by default, our nsec based generator adds rrsigs
		 * remove the bitmap for empty nonterminals */
		if (!current_name->rrsets) {
			ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
		}
		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
		result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
		ldns_rr_list_push_rr(new_rrs, nsec_rr);
		if (ldns_rr_owner(nsec_rr)) {
			hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
			if (hashmap_node == NULL) {
				return LDNS_STATUS_MEM_ERR;
			}
			current_name->hashed_name = 
				ldns_dname_label(ldns_rr_owner(nsec_rr), 0);

			if (current_name->hashed_name == NULL) {
				LDNS_FREE(hashmap_node);
				return LDNS_STATUS_MEM_ERR;
			}
			hashmap_node->key  = current_name->hashed_name;
			hashmap_node->data = current_name;

			if (! ldns_rbtree_insert(zone->hashed_names
						, hashmap_node)) {
				LDNS_FREE(hashmap_node);
			}
		}
		current_name_node = ldns_dnssec_name_node_next_nonglue(
		                   ldns_rbtree_next(current_name_node));
	}
	if (result != LDNS_STATUS_OK) {
		return result;
	}

	/* Make sorted list of nsec3s (via zone->hashed_names)
	 */
	nsec3_list = ldns_rr_list_new();
	if (nsec3_list == NULL) {
		return LDNS_STATUS_MEM_ERR;
	}
	for ( hashmap_node  = ldns_rbtree_first(zone->hashed_names)
	    ; hashmap_node != LDNS_RBTREE_NULL
	    ; hashmap_node  = ldns_rbtree_next(hashmap_node)
	    ) {
		current_name = (ldns_dnssec_name *) hashmap_node->data;
		nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
		if (nsec_rr) {
			ldns_rr_list_push_rr(nsec3_list, nsec_rr);
		}
	}
	result = ldns_dnssec_chain_nsec3_list(nsec3_list);
	ldns_rr_list_free(nsec3_list);

	return result;
}