/** read list of rrs from the file */
static ldns_rr_list*
read_rrs(FILE* in)
{
	uint32_t my_ttl = 3600;
	ldns_rdf *my_origin = NULL;
	ldns_rdf *my_prev = NULL;
	ldns_status s;
	int line_nr = 1;
	int b;

	ldns_rr_list* list;
	ldns_rr *rr;

	list = ldns_rr_list_new();
	if(!list) fatal_exit("alloc error");

	while(!feof(in)) {
		s = ldns_rr_new_frm_fp_l(&rr, in, &my_ttl, &my_origin,
			&my_prev, &line_nr);
		if(s == LDNS_STATUS_SYNTAX_TTL || 
			s == LDNS_STATUS_SYNTAX_ORIGIN ||
			s == LDNS_STATUS_SYNTAX_EMPTY)
			continue;
		else if(s != LDNS_STATUS_OK)
			fatal_exit("parse error in line %d: %s", line_nr,
				ldns_get_errorstr_by_id(s));
		b = ldns_rr_list_push_rr(list, rr);
		log_assert(b);
	}
	printf("read %d lines\n", line_nr);

	return list;
}
示例#2
0
文件: zinfo.c 项目: benlaurie/ldns
struct zversion_t* zversion_read(struct zone_entry_t* entry, uint32_t serial)
{
	const char* fn = zinfo_ixfr_name(entry, serial);
	struct zversion_t* v;
	FILE* in = fopen(fn, "ra");
	ldns_status status;
	ldns_rr* rr = 0;
	uint32_t dttl = 3600;
	ldns_rdf* origin = 0, *prev = 0;
	int line_nr = 1;
	if(!in) {
		perror(fn);
		return NULL;
	}
	v = (struct zversion_t*)calloc(1, sizeof(*v));
	if(!v) {
		fclose(in);
		printf("out of memory\n");
		return NULL;
	}
	v->serial = serial;
	v->ixfr = ldns_rr_list_new();
	while(!feof(in)) {
		status = ldns_rr_new_frm_fp_l(&rr, in, &dttl, &origin, 
			&prev, &line_nr);
		if(status == LDNS_STATUS_SYNTAX_TTL || 
			status == LDNS_STATUS_SYNTAX_ORIGIN ||
			status == LDNS_STATUS_SYNTAX_EMPTY)
			continue;
		if(status != LDNS_STATUS_OK) {
			printf("error %s:%d: %s\n", fn, line_nr, 
				ldns_get_errorstr_by_id(status));
			fclose(in);
			ldns_rdf_deep_free(origin);
			ldns_rdf_deep_free(prev);
			ldns_rr_list_deep_free(v->ixfr);
			free(v);
			return NULL;
		}
		ldns_rr_list_push_rr(v->ixfr, rr);
	}
	ldns_rdf_deep_free(origin);
	ldns_rdf_deep_free(prev);
	fclose(in);
	if(ldns_rr_list_rr_count(v->ixfr) < 1 || 
		ldns_rr_get_type(ldns_rr_list_rr(v->ixfr, 0)) 
			!= LDNS_RR_TYPE_SOA) {
		printf("invalid IXFR format in %s\n", fn);
		ldns_rr_list_deep_free(v->ixfr);
		free(v);
		return NULL;
	}
	v->next_serial = ldns_rdf2native_int32(ldns_rr_rdf(
		ldns_rr_list_rr(v->ixfr, 0), 2));
	return v;
}
示例#3
0
文件: zonefile.c 项目: hstern/libmy
ldns_status
zonefile_read(struct zonefile *z, ldns_rr **out)
{
	ldns_rr *rr;
	ldns_status status = LDNS_STATUS_OK;

	if (!z->valid)
		return (LDNS_STATUS_ERR);

	if (z->count == 1 && z->rr_soa != NULL) {
		*out = z->rr_soa;
		z->rr_soa = NULL;
		return (LDNS_STATUS_OK);
	}
	for (;;) {
		if (feof(z->fp)) {
			*out = NULL;
			if (z->is_pipe)
				pclose(z->fp);
			else
				fclose(z->fp);
			z->fp = NULL;
			return (LDNS_STATUS_OK);
		}
		status = ldns_rr_new_frm_fp_l(&rr, z->fp, &z->ttl, &z->origin, &z->prev, NULL);
		switch (status) {
		case LDNS_STATUS_OK:
			if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
				ldns_rr_free(rr);
                		rr = 0;
				z->valid = false;
				status = LDNS_STATUS_OK;
				goto out;
			}
			z->count++;
			goto out;
		case LDNS_STATUS_SYNTAX_EMPTY:
		case LDNS_STATUS_SYNTAX_TTL:
		case LDNS_STATUS_SYNTAX_ORIGIN:
			status = LDNS_STATUS_OK;
			break;
		default:
			goto out;
		}
	}
out:
	if (status != LDNS_STATUS_OK)
		return (status);
	*out = rr;
	return (status);
}
示例#4
0
文件: zonefile.c 项目: hstern/libmy
static ldns_status
read_soa(struct zonefile *z)
{
	ldns_rr *rr;
	ldns_status status;

	for (;;) {
		status = ldns_rr_new_frm_fp_l(&rr, z->fp, &z->ttl, &z->origin, &z->prev, NULL);
		switch (status) {
		case LDNS_STATUS_OK:
			goto out;
		case LDNS_STATUS_SYNTAX_EMPTY:
		case LDNS_STATUS_SYNTAX_TTL:
		case LDNS_STATUS_SYNTAX_ORIGIN:
			status = LDNS_STATUS_OK;
			break;
		default:
			goto out;
		}
	}
out:
	if (status != LDNS_STATUS_OK) {
		z->valid = false;
		return (LDNS_STATUS_ERR);
	}

	if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
		ldns_rr_free(rr);
		z->valid = false;
		return (LDNS_STATUS_ERR);
	}

	z->count = 1;
	z->domain = ldns_rdf_clone(ldns_rr_owner(rr));
	z->origin = ldns_rdf_clone(ldns_rr_owner(rr));
	z->rr_soa = rr;
	return (LDNS_STATUS_OK);
}
示例#5
0
/**
 * Read a file with trust anchors
 * @param anchors: anchor storage.
 * @param buffer: parsing buffer.
 * @param fname: string.
 * @param onlyone: only one trust anchor allowed in file.
 * @return NULL on error. Else last trust-anchor point.
 */
static struct trust_anchor*
anchor_read_file(struct val_anchors* anchors, ldns_buffer* buffer,
	const char* fname, int onlyone)
{
	struct trust_anchor* ta = NULL, *tanew;
	uint32_t default_ttl = 3600;
	ldns_rdf* origin = NULL, *prev = NULL;
	int line_nr = 1;
	ldns_status status;
	ldns_rr* rr;
	int ok = 1;
	FILE* in = fopen(fname, "r");
	if(!in) {
		log_err("error opening file %s: %s", fname, strerror(errno));
		return 0;
	}
	while(!feof(in)) {
		rr = NULL;
		status = ldns_rr_new_frm_fp_l(&rr, in, &default_ttl, &origin,
			&prev, &line_nr);
		if(status == LDNS_STATUS_SYNTAX_EMPTY /* empty line */
			|| status == LDNS_STATUS_SYNTAX_TTL /* $TTL */
			|| status == LDNS_STATUS_SYNTAX_ORIGIN /* $ORIGIN */)
			continue;
		if(status != LDNS_STATUS_OK) {
			log_err("parse error in %s:%d : %s", fname, line_nr,
				ldns_get_errorstr_by_id(status));
			ldns_rr_free(rr);
			ok = 0;
			break;
		}
		if(ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS && 
			ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY) {
			ldns_rr_free(rr);
			continue;
		}
		if(!(tanew=anchor_store_new_rr(anchors, buffer, rr))) {
			log_err("error at %s line %d", fname, line_nr);
			ldns_rr_free(rr);
			ok = 0;
			break;
		}
		if(onlyone && ta && ta != tanew) {
			log_err("error at %s line %d: no multiple anchor "
				"domains allowed (you can have multiple "
				"keys, but they must have the same name).", 
				fname, line_nr);
			ldns_rr_free(rr);
			ok = 0;
			break;
		}
		ta = tanew;
		ldns_rr_free(rr);
	}
	ldns_rdf_deep_free(origin);
	ldns_rdf_deep_free(prev);
	fclose(in);
	if(!ok) return NULL;
	/* empty file is OK when multiple anchors are allowed */
	if(!onlyone && !ta) return (struct trust_anchor*)1;
	return ta;
}
示例#6
0
ldns_status
ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
	       	uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
{
	ldns_rr* cur_rr;
	size_t i;

	ldns_rdf *my_origin = NULL;
	ldns_rdf *my_prev = NULL;

	ldns_dnssec_zone *newzone = ldns_dnssec_zone_new();
	/* when reading NSEC3s, there is a chance that we encounter nsecs
	   for empty nonterminals, whose nonterminals we cannot derive yet
	   because the needed information is to be read later. in that case
	   we keep a list of those nsec3's and retry to add them later */
	ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
	ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();

	ldns_status status = LDNS_STATUS_MEM_ERR;

#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
	ldns_zone* zone = NULL;
	if (ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr)
			!= LDNS_STATUS_OK) goto error;
#else
	uint32_t  my_ttl = ttl;
#endif

	if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) goto error;

	if (origin) {
		if (!(my_origin = ldns_rdf_clone(origin))) goto error;
		if (!(my_prev   = ldns_rdf_clone(origin))) goto error;
	}

#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
	if (ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone))
			!= LDNS_STATUS_OK) goto error;

	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
		cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
		status = LDNS_STATUS_OK;
#else
	while (!feof(fp)) {
		status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
				&my_prev, line_nr);

#endif
		switch (status) {
		case LDNS_STATUS_OK:

			status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
			if (status ==
				LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) {

				if (rr_is_rrsig_covering(cur_rr,
							LDNS_RR_TYPE_NSEC3)){
					ldns_rr_list_push_rr(todo_nsec3_rrsigs,
							cur_rr);
				} else {
					ldns_rr_list_push_rr(todo_nsec3s,
						       	cur_rr);
				}
				status = LDNS_STATUS_OK;

			} else if (status != LDNS_STATUS_OK)
				goto error;

			break;


		case LDNS_STATUS_SYNTAX_EMPTY:	/* empty line was seen */
		case LDNS_STATUS_SYNTAX_TTL:	/* the ttl was set*/
		case LDNS_STATUS_SYNTAX_ORIGIN:	/* the origin was set*/
			status = LDNS_STATUS_OK;
			break;

		case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
			status =  LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
			break;

		default:
			goto error;
		}
	}

	if (ldns_rr_list_rr_count(todo_nsec3s) > 0) {
		(void) ldns_dnssec_zone_add_empty_nonterminals(newzone);
		for (i = 0; status == LDNS_STATUS_OK &&
				i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
			cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
			status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
		}
	} 
	if (ldns_rr_list_rr_count(todo_nsec3_rrsigs) > 0) {
		for (i = 0; status == LDNS_STATUS_OK &&
				i < ldns_rr_list_rr_count(todo_nsec3_rrsigs);
				i++){
			cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
			status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
		}
	}

	if (z) {
		*z = newzone;
		newzone = NULL;
	} else {
		ldns_dnssec_zone_free(newzone);
	}

error:
#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
	if (zone) {
		ldns_zone_free(zone);
	}
#endif
	ldns_rr_list_free(todo_nsec3_rrsigs);
	ldns_rr_list_free(todo_nsec3s);

	if (my_origin) {
		ldns_rdf_deep_free(my_origin);
	}
	if (my_prev) {
		ldns_rdf_deep_free(my_prev);
	}
	if (newzone) {
		ldns_dnssec_zone_free(newzone);
	}
	return status;
}

ldns_status
ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
		uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
{
	return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
}

static void
ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
	(void) arg;
	ldns_dnssec_name_free((ldns_dnssec_name *)node->data);
	LDNS_FREE(node);
}
示例#7
0
文件: zone.c 项目: LANJr4D/iEnum
ldns_status
ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c, 
		int *line_nr)
{
	ldns_zone *newzone;
	ldns_rr *rr;
	uint32_t my_ttl = ttl;
	ldns_rr_class my_class = c;
	ldns_rr *last_rr = NULL;
	ldns_rdf *my_origin;
	ldns_rdf *my_prev;
	bool soa_seen = false; 	/* 2 soa are an error */
	ldns_status s;

	newzone = ldns_zone_new();
	my_origin = origin;
	my_ttl    = ttl;
	my_class  = c;
	
	if (origin) {
		my_origin = ldns_rdf_clone(origin);
		/* also set the prev */
		my_prev   = ldns_rdf_clone(origin);
	} else {
		my_origin = NULL;
		my_prev = NULL;
	}

	while(!feof(fp)) {
		s = ldns_rr_new_frm_fp_l(&rr, fp, &my_ttl, &my_origin, &my_prev, line_nr);
		switch (s) {
		case LDNS_STATUS_OK:
			if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
				if (soa_seen) {
					/* second SOA 
					 * just skip, maybe we want to say
					 * something??? */
					ldns_rr_free(rr);
					continue;
				}
				soa_seen = true;
				ldns_zone_set_soa(newzone, rr);
				/* set origin to soa if not specified */
				if (!my_origin) {
					my_origin = ldns_rdf_clone(ldns_rr_owner(rr));
				}
				continue;
			}
			
			/* a normal RR - as sofar the DNS is normal */
			last_rr = rr;
			if (!ldns_zone_push_rr(newzone, rr)) {
				if (my_origin) {
					ldns_rdf_deep_free(my_origin);
				}
				ldns_zone_free(newzone);
				return LDNS_STATUS_MEM_ERR;
			}

			/*my_origin = ldns_rr_owner(rr);*/
			my_ttl    = ldns_rr_ttl(rr);
			my_class  = ldns_rr_get_class(rr);
		case LDNS_STATUS_SYNTAX_EMPTY:
			/* empty line was seen */
		case LDNS_STATUS_SYNTAX_TTL:
			/* the function set the ttl */
			break;
		case LDNS_STATUS_SYNTAX_ORIGIN:
			/* the function set the origin */
			break;
		default:
			ldns_zone_free(newzone);
			return s;
		}
	}

	if (my_origin) {
		ldns_rdf_deep_free(my_origin);
	}
	if (my_prev) {
		ldns_rdf_deep_free(my_prev);
	}
	if (z) {
		*z = newzone;
	}

	return LDNS_STATUS_OK;
}
示例#8
0
/** read root hints from file */
static int 
read_root_hints(struct iter_hints* hints, char* fname)
{
	int lineno = 0;
	uint32_t default_ttl = 0;
	ldns_rdf* origin = NULL;
	ldns_rdf* prev_rr = NULL;
	struct delegpt* dp;
	ldns_rr* rr = NULL;
	ldns_status status;
	uint16_t c = LDNS_RR_CLASS_IN;
	FILE* f = fopen(fname, "r");
	if(!f) {
		log_err("could not read root hints %s: %s",
			fname, strerror(errno));
		return 0;
	}
	dp = delegpt_create_mlc(NULL);
	if(!dp) {
		log_err("out of memory reading root hints");
		fclose(f);
		return 0;
	}
	verbose(VERB_QUERY, "Reading root hints from %s", fname);
	dp->has_parent_side_NS = 1;
	while(!feof(f)) {
		status = ldns_rr_new_frm_fp_l(&rr, f, 
			&default_ttl, &origin, &prev_rr, &lineno);
		if(status == LDNS_STATUS_SYNTAX_EMPTY ||
			status == LDNS_STATUS_SYNTAX_TTL ||
			status == LDNS_STATUS_SYNTAX_ORIGIN)
			continue;
		if(status != LDNS_STATUS_OK) {
			log_err("reading root hints %s %d: %s", fname,
				lineno, ldns_get_errorstr_by_id(status));
			goto stop_read;
		}
		if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
			if(!delegpt_add_ns_mlc(dp,
				ldns_rdf_data(ldns_rr_rdf(rr, 0)), 0)) {
				log_err("out of memory reading root hints");
				goto stop_read;
			}
			c = ldns_rr_get_class(rr);
			if(!dp->name) {
				if(!delegpt_set_name_mlc(dp,
					ldns_rdf_data(ldns_rr_owner(rr)))){
					log_err("out of memory.");
					goto stop_read;
				}
			}
		} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A) {
			struct sockaddr_in sa;
			socklen_t len = (socklen_t)sizeof(sa);
			memset(&sa, 0, len);
			sa.sin_family = AF_INET;
			sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
			memmove(&sa.sin_addr, 
				ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET_SIZE);
			if(!delegpt_add_target_mlc(dp,
					ldns_rdf_data(ldns_rr_owner(rr)),
					ldns_rdf_size(ldns_rr_owner(rr)),
					(struct sockaddr_storage*)&sa, len, 
					0, 0)) {
				log_err("out of memory reading root hints");
				goto stop_read;
			}
		} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
			struct sockaddr_in6 sa;
			socklen_t len = (socklen_t)sizeof(sa);
			memset(&sa, 0, len);
			sa.sin6_family = AF_INET6;
			sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
			memmove(&sa.sin6_addr, 
				ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET6_SIZE);
			if(!delegpt_add_target_mlc(dp,
					ldns_rdf_data(ldns_rr_owner(rr)),
					ldns_rdf_size(ldns_rr_owner(rr)),
					(struct sockaddr_storage*)&sa, len,
					0, 0)) {
				log_err("out of memory reading root hints");
				goto stop_read;
			}
		} else {
			log_warn("root hints %s:%d skipping type %d",
				fname, lineno, ldns_rr_get_type(rr));
		}

		ldns_rr_free(rr);
	}

	if (origin)
		ldns_rdf_deep_free(origin);
	if (prev_rr)
		ldns_rdf_deep_free(prev_rr);
	fclose(f);
	if(!dp->name) {
		log_warn("root hints %s: no NS content", fname);
		delegpt_free_mlc(dp);
		return 1;
	}
	if(!hints_insert(hints, c, dp, 0)) {
		return 0;
	}
	delegpt_log(VERB_QUERY, dp);
	return 1;

stop_read:
	if (origin)
		ldns_rdf_deep_free(origin);
	if (prev_rr)
		ldns_rdf_deep_free(prev_rr);
	delegpt_free_mlc(dp);
	fclose(f);
	return 0;
}