Example #1
0
/* parses subnet mask, fills 0 mask as well */
void parse_acl_range_subnet(char* p, void* addr, int maxbits)
{
	int subnet_bits = atoi(p);
	uint8_t* addr_bytes = (uint8_t*)addr;
	if(subnet_bits == 0 && strcmp(p, "0")!=0) {
		c_error_msg("bad subnet range '%s'", p);
		return;
	}
	if(subnet_bits < 0 || subnet_bits > maxbits) {
		c_error_msg("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits);
		return;
	}
	/* fill addr with n bits of 1s (struct has been zeroed) */
	while(subnet_bits >= 8) {
		*addr_bytes++ = 0xff;
		subnet_bits -= 8;
	}
	if(subnet_bits > 0) {
		uint8_t shifts[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
		*addr_bytes = shifts[subnet_bits];
	}
}
Example #2
0
void
config_apply_pattern(const char* name)
{
	/* find the pattern */
	pattern_options_t* pat = pattern_options_find(cfg_parser->opt, name);
	pattern_options_t* a = cfg_parser->current_pattern;
	if(!pat) {
		c_error_msg("could not find pattern %s", name);
		return;
	}

	/* apply settings */
	if(pat->zonefile)
		a->zonefile = region_strdup(cfg_parser->opt->region,
			pat->zonefile);
	if(pat->zonestats)
		a->zonestats = region_strdup(cfg_parser->opt->region,
			pat->zonestats);
	if(!pat->allow_axfr_fallback_is_default) {
		a->allow_axfr_fallback = pat->allow_axfr_fallback;
		a->allow_axfr_fallback_is_default = 0;
	}
	if(!pat->notify_retry_is_default) {
		a->notify_retry = pat->notify_retry;
		a->notify_retry_is_default = 0;
	}
#ifdef RATELIMIT
	a->rrl_whitelist |= pat->rrl_whitelist;
#endif
	/* append acl items */
	append_acl(&a->allow_notify, &cfg_parser->current_allow_notify,
		pat->allow_notify);
	append_acl(&a->request_xfr, &cfg_parser->current_request_xfr,
		pat->request_xfr);
	append_acl(&a->notify, &cfg_parser->current_notify, pat->notify);
	append_acl(&a->provide_xfr, &cfg_parser->current_provide_xfr,
		pat->provide_xfr);
	append_acl(&a->outgoing_interface, &cfg_parser->
		current_outgoing_interface, pat->outgoing_interface);
}
Example #3
0
void
c_error(const char* str)
{
	c_error_msg("%s", str);
}
Example #4
0
acl_options_t*
parse_acl_info(region_type* region, char* ip, const char* key)
{
	char* p;
	acl_options_t* acl = (acl_options_t*)region_alloc(region, sizeof(acl_options_t));
	acl->next = 0;
	/* ip */
	acl->ip_address_spec = region_strdup(region, ip);
	acl->use_axfr_only = 0;
	acl->allow_udp = 0;
	acl->ixfr_disabled = 0;
	acl->bad_xfr_count = 0;
	acl->key_options = 0;
	acl->is_ipv6 = 0;
	acl->port = 0;
	memset(&acl->addr, 0, sizeof(union acl_addr_storage));
	memset(&acl->range_mask, 0, sizeof(union acl_addr_storage));
	if((p=strrchr(ip, '@'))!=0) {
		if(atoi(p+1) == 0) c_error("expected port number after '@'");
		else acl->port = atoi(p+1);
		*p=0;
	}
	acl->rangetype = parse_acl_range_type(ip, &p);
	if(parse_acl_is_ipv6(ip)) {
		acl->is_ipv6 = 1;
#ifdef INET6
		if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1)
			c_error_msg("Bad ip6 address '%s'", ip);
		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax)
			if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1)
				c_error_msg("Bad ip6 address mask '%s'", p);
		if(acl->rangetype==acl_range_subnet)
			parse_acl_range_subnet(p, &acl->range_mask.addr6, 128);
#else
		c_error_msg("encountered IPv6 address '%s'.", ip);
#endif /* INET6 */
	} else {
		acl->is_ipv6 = 0;
		if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1)
			c_error_msg("Bad ip4 address '%s'", ip);
		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax)
			if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1)
				c_error_msg("Bad ip4 address mask '%s'", p);
		if(acl->rangetype==acl_range_subnet)
			parse_acl_range_subnet(p, &acl->range_mask.addr, 32);
	}

	/* key */
	if(strcmp(key, "NOKEY")==0) {
		acl->nokey = 1;
		acl->blocked = 0;
		acl->key_name = 0;
	} else if(strcmp(key, "BLOCKED")==0) {
		acl->nokey = 0;
		acl->blocked = 1;
		acl->key_name = 0;
	} else {
		acl->nokey = 0;
		acl->blocked = 0;
		acl->key_name = region_strdup(region, key);
	}
	return acl;
}
Example #5
0
int
parse_options_file(nsd_options_t* opt, const char* file,
	void (*err)(void*,const char*), void* err_arg)
{
	FILE *in = 0;
	pattern_options_t* pat;
	acl_options_t* acl;

	if(!cfg_parser) {
		cfg_parser = (config_parser_state_t*)region_alloc(
			opt->region, sizeof(config_parser_state_t));
		cfg_parser->chroot = 0;
	}
	cfg_parser->err = err;
	cfg_parser->err_arg = err_arg;
	cfg_parser->filename = (char*)file;
	cfg_parser->line = 1;
	cfg_parser->errors = 0;
	cfg_parser->server_settings_seen = 0;
	cfg_parser->opt = opt;
	cfg_parser->current_pattern = 0;
	cfg_parser->current_zone = 0;
	cfg_parser->current_key = 0;
	cfg_parser->current_ip_address_option = opt->ip_addresses;
	while(cfg_parser->current_ip_address_option && cfg_parser->current_ip_address_option->next)
		cfg_parser->current_ip_address_option = cfg_parser->current_ip_address_option->next;
	cfg_parser->current_allow_notify = 0;
	cfg_parser->current_request_xfr = 0;
	cfg_parser->current_notify = 0;
	cfg_parser->current_provide_xfr = 0;
	
	in = fopen(cfg_parser->filename, "r");
	if(!in) {
		if(err) {
			char m[MAXSYSLOGMSGLEN];
			snprintf(m, sizeof(m), "Could not open %s: %s\n",
				file, strerror(errno));
			err(err_arg, m);
		} else {
			fprintf(stderr, "Could not open %s: %s\n",
				file, strerror(errno));
		}
		return 0;
	}
	c_in = in;
	c_parse();
	fclose(in);

	opt->configfile = region_strdup(opt->region, file);
	if(cfg_parser->current_pattern) {
		if(!cfg_parser->current_pattern->pname)
			c_error("last pattern has no name");
		else {
			if(!nsd_options_insert_pattern(cfg_parser->opt,
				cfg_parser->current_pattern))
				c_error("duplicate pattern");
		}
	}
	if(cfg_parser->current_zone) {
		if(!cfg_parser->current_zone->name)
			c_error("last zone has no name");
		else {
			if(!nsd_options_insert_zone(opt,
				cfg_parser->current_zone))
				c_error("duplicate zone");
		}
		if(!cfg_parser->current_zone->pattern)
			c_error("last zone has no pattern");
	}
	if(cfg_parser->current_key)
	{
		if(!cfg_parser->current_key->name)
			c_error("last key has no name");
		if(!cfg_parser->current_key->algorithm)
			c_error("last key has no algorithm");
		if(!cfg_parser->current_key->secret)
			c_error("last key has no secret blob");
		key_options_insert(opt, cfg_parser->current_key);
	}
	RBTREE_FOR(pat, pattern_options_t*, opt->patterns)
	{
		/* lookup keys for acls */
		for(acl=pat->allow_notify; acl; acl=acl->next)
		{
			if(acl->nokey || acl->blocked)
				continue;
			acl->key_options = key_options_find(opt, acl->key_name);
			if(!acl->key_options)
				c_error_msg("key %s in pattern %s could not be found",
					acl->key_name, pat->pname);
		}
		for(acl=pat->notify; acl; acl=acl->next)
		{
			if(acl->nokey || acl->blocked)
				continue;
			acl->key_options = key_options_find(opt, acl->key_name);
			if(!acl->key_options)
				c_error_msg("key %s in pattern %s could not be found",
					acl->key_name, pat->pname);
		}
		for(acl=pat->request_xfr; acl; acl=acl->next)
		{
			if(acl->nokey || acl->blocked)
				continue;
			acl->key_options = key_options_find(opt, acl->key_name);
			if(!acl->key_options)
				c_error_msg("key %s in pattern %s could not be found",
					acl->key_name, pat->pname);
		}
		for(acl=pat->provide_xfr; acl; acl=acl->next)
		{
			if(acl->nokey || acl->blocked)
				continue;
			acl->key_options = key_options_find(opt, acl->key_name);
			if(!acl->key_options)
				c_error_msg("key %s in pattern %s could not be found",
					acl->key_name, pat->pname);
		}
	}

	if(cfg_parser->errors > 0)
	{
		if(err) {
			char m[MAXSYSLOGMSGLEN];
			snprintf(m, sizeof(m), "read %s failed: %d errors in "
				"configuration file\n", file,
				cfg_parser->errors);
			err(err_arg, m);
		} else {
			fprintf(stderr, "read %s failed: %d errors in "
				"configuration file\n", file,
				cfg_parser->errors);
		}
		return 0;
	}
	return 1;
}
Example #6
0
int parse_options_file(nsd_options_t* opt, const char* file)
{
	FILE *in = 0;
	zone_options_t* zone;
	acl_options_t* acl;

	if(!cfg_parser)
		cfg_parser = (config_parser_state_t*)region_alloc(
			opt->region, sizeof(config_parser_state_t));
	cfg_parser->filename = file;
	cfg_parser->line = 1;
	cfg_parser->errors = 0;
	cfg_parser->opt = opt;
	cfg_parser->current_zone = 0;
	cfg_parser->current_key = opt->keys;
	while(cfg_parser->current_key && cfg_parser->current_key->next)
		cfg_parser->current_key = cfg_parser->current_key->next;
	cfg_parser->current_ip_address_option = opt->ip_addresses;
	while(cfg_parser->current_ip_address_option && cfg_parser->current_ip_address_option->next)
		cfg_parser->current_ip_address_option = cfg_parser->current_ip_address_option->next;
	cfg_parser->current_allow_notify = 0;
	cfg_parser->current_request_xfr = 0;
	cfg_parser->current_notify = 0;
	cfg_parser->current_provide_xfr = 0;

	in = fopen(cfg_parser->filename, "r");
	if(!in) {
		fprintf(stderr, "Could not open %s: %s\n", file, strerror(errno));
		return 0;
	}
	c_in = in;
	c_parse();
	fclose(in);

	if(cfg_parser->current_zone) {
		if(!cfg_parser->current_zone->name)
			c_error("last zone has no name");
		else {
			if(!nsd_options_insert_zone(opt,
				cfg_parser->current_zone))
				c_error("duplicate zone");
		}
		if(!cfg_parser->current_zone->zonefile)
			c_error("last zone has no zonefile");
	}
	if(opt->keys)
	{
		if(!opt->keys->name)
			c_error("last key has no name");
		if(!opt->keys->algorithm)
			c_error("last key has no algorithm");
		if(!opt->keys->secret)
			c_error("last key has no secret blob");
	}
	RBTREE_FOR(zone, zone_options_t*, opt->zone_options)
	{
		if(!zone->name)
			continue;
		if(!zone->zonefile)
			continue;
		/* lookup keys for acls */
		for(acl=zone->allow_notify; acl; acl=acl->next)
		{
			if(acl->nokey || acl->blocked)
				continue;
			acl->key_options = key_options_find(opt, acl->key_name);
			if(!acl->key_options)
				c_error_msg("key %s in zone %s could not be found",
					acl->key_name, zone->name);
		}
		for(acl=zone->notify; acl; acl=acl->next)
		{
			if(acl->nokey || acl->blocked)
				continue;
			acl->key_options = key_options_find(opt, acl->key_name);
			if(!acl->key_options)
				c_error_msg("key %s in zone %s could not be found",
					acl->key_name, zone->name);
		}
		for(acl=zone->request_xfr; acl; acl=acl->next)
		{
			if(acl->nokey || acl->blocked)
				continue;
			acl->key_options = key_options_find(opt, acl->key_name);
			if(!acl->key_options)
				c_error_msg("key %s in zone %s could not be found",
					acl->key_name, zone->name);
		}
		for(acl=zone->provide_xfr; acl; acl=acl->next)
		{
			if(acl->nokey || acl->blocked)
				continue;
			acl->key_options = key_options_find(opt, acl->key_name);
			if(!acl->key_options)
				c_error_msg("key %s in zone %s could not be found",
					acl->key_name, zone->name);
		}
	}

	if(cfg_parser->errors > 0)
	{
        	fprintf(stderr, "read %s failed: %d errors in configuration file\n",
			cfg_parser->filename,
			cfg_parser->errors);
		return 0;
	}
	return 1;
}