mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
access-control
git-svn-id: file:///svn/unbound/trunk@769 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
fc8657c421
commit
eda6528c14
@ -92,6 +92,7 @@ morechecks(struct config_file* cfg)
|
|||||||
int i;
|
int i;
|
||||||
struct sockaddr_storage a;
|
struct sockaddr_storage a;
|
||||||
socklen_t alen;
|
socklen_t alen;
|
||||||
|
struct config_acl* acl;
|
||||||
for(i=0; i<cfg->num_ifs; i++) {
|
for(i=0; i<cfg->num_ifs; i++) {
|
||||||
if(!ipstrtoaddr(cfg->ifs[i], UNBOUND_DNS_PORT, &a, &alen)) {
|
if(!ipstrtoaddr(cfg->ifs[i], UNBOUND_DNS_PORT, &a, &alen)) {
|
||||||
fatal_exit("cannot parse interface specified as '%s'",
|
fatal_exit("cannot parse interface specified as '%s'",
|
||||||
@ -105,6 +106,13 @@ morechecks(struct config_file* cfg)
|
|||||||
"specified as '%s'", cfg->out_ifs[i]);
|
"specified as '%s'", cfg->out_ifs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(acl=cfg->acls; acl; acl = acl->next) {
|
||||||
|
if(!netblockstrtoaddr(acl->address, UNBOUND_DNS_PORT,
|
||||||
|
&a, &alen, &i)) {
|
||||||
|
fatal_exit("cannot parse access control address %s %s",
|
||||||
|
acl->address, acl->control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(cfg->verbosity < 0)
|
if(cfg->verbosity < 0)
|
||||||
fatal_exit("verbosity value < 0");
|
fatal_exit("verbosity value < 0");
|
||||||
|
@ -116,7 +116,6 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
|||||||
{
|
{
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
int net;
|
int net;
|
||||||
char* s = NULL;
|
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
enum acl_access control;
|
enum acl_access control;
|
||||||
if(strcmp(s2, "allow") == 0)
|
if(strcmp(s2, "allow") == 0)
|
||||||
@ -129,33 +128,10 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
|||||||
log_err("access control type %s unknown", str);
|
log_err("access control type %s unknown", str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
net = (str_is_ip6(str)?128:32);
|
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
||||||
if((s=strchr(str, '/'))) {
|
log_err("cannot parse access control: %s %s", str, s2);
|
||||||
if(atoi(s+1) > net) {
|
|
||||||
log_err("acl netblock too large: %s", str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
net = atoi(s+1);
|
|
||||||
if(net == 0 && strcmp(s+1, "0") != 0) {
|
|
||||||
log_err("cannot parse acl netblock:"
|
|
||||||
" '%s'", str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(!(s = strdup(str))) {
|
|
||||||
log_err("out of memory");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*strchr(s, '/') = '\0';
|
|
||||||
}
|
|
||||||
if(!ipstrtoaddr(s?s:str, UNBOUND_DNS_PORT, &addr, &addrlen)) {
|
|
||||||
free(s);
|
|
||||||
log_err("cannot parse acl ip address: '%s'", str);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(s) {
|
|
||||||
free(s);
|
|
||||||
addr_mask(&addr, addrlen, net);
|
|
||||||
}
|
|
||||||
if(!acl_list_insert(acl, &addr, addrlen, net, control,
|
if(!acl_list_insert(acl, &addr, addrlen, net, control,
|
||||||
complain_duplicates)) {
|
complain_duplicates)) {
|
||||||
log_err("out of memory");
|
log_err("out of memory");
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "daemon/daemon.h"
|
#include "daemon/daemon.h"
|
||||||
#include "daemon/worker.h"
|
#include "daemon/worker.h"
|
||||||
|
#include "daemon/acl_list.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
#include "util/data/msgreply.h"
|
#include "util/data/msgreply.h"
|
||||||
@ -134,6 +135,12 @@ daemon_init()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
alloc_init(&daemon->superalloc, NULL, 0);
|
alloc_init(&daemon->superalloc, NULL, 0);
|
||||||
|
daemon->acl = acl_list_create();
|
||||||
|
if(!daemon->acl) {
|
||||||
|
free(daemon->env);
|
||||||
|
free(daemon);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return daemon;
|
return daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,6 +404,8 @@ void
|
|||||||
daemon_fork(struct daemon* daemon)
|
daemon_fork(struct daemon* daemon)
|
||||||
{
|
{
|
||||||
log_assert(daemon);
|
log_assert(daemon);
|
||||||
|
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg))
|
||||||
|
fatal_exit("Could not setup access control list");
|
||||||
|
|
||||||
/* setup modules */
|
/* setup modules */
|
||||||
daemon_setup_modules(daemon);
|
daemon_setup_modules(daemon);
|
||||||
@ -465,6 +474,7 @@ daemon_delete(struct daemon* daemon)
|
|||||||
infra_delete(daemon->env->infra_cache);
|
infra_delete(daemon->env->infra_cache);
|
||||||
}
|
}
|
||||||
alloc_clear(&daemon->superalloc);
|
alloc_clear(&daemon->superalloc);
|
||||||
|
acl_list_delete(daemon->acl);
|
||||||
free(daemon->pidfile);
|
free(daemon->pidfile);
|
||||||
free(daemon->env);
|
free(daemon->env);
|
||||||
free(daemon);
|
free(daemon);
|
||||||
|
@ -50,6 +50,7 @@ struct listen_port;
|
|||||||
struct slabhash;
|
struct slabhash;
|
||||||
struct module_env;
|
struct module_env;
|
||||||
struct rrset_cache;
|
struct rrset_cache;
|
||||||
|
struct acl_list;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure holding worker list.
|
* Structure holding worker list.
|
||||||
@ -78,6 +79,8 @@ struct daemon {
|
|||||||
int num_modules;
|
int num_modules;
|
||||||
/** the module callbacks, array of num_modules length */
|
/** the module callbacks, array of num_modules length */
|
||||||
struct module_func_block** modfunc;
|
struct module_func_block** modfunc;
|
||||||
|
/** access control, which client IPs are allowed to connect */
|
||||||
|
struct acl_list* acl;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
#include "daemon/worker.h"
|
#include "daemon/worker.h"
|
||||||
#include "daemon/daemon.h"
|
#include "daemon/daemon.h"
|
||||||
|
#include "daemon/acl_list.h"
|
||||||
#include "util/netevent.h"
|
#include "util/netevent.h"
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
#include "util/module.h"
|
#include "util/module.h"
|
||||||
@ -663,12 +664,28 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
struct lruhash_entry* e;
|
struct lruhash_entry* e;
|
||||||
struct query_info qinfo;
|
struct query_info qinfo;
|
||||||
struct edns_data edns;
|
struct edns_data edns;
|
||||||
|
enum acl_access acl;
|
||||||
|
|
||||||
if(error != NETEVENT_NOERROR) {
|
if(error != NETEVENT_NOERROR) {
|
||||||
/* some bad tcp query DNS formats give these error calls */
|
/* some bad tcp query DNS formats give these error calls */
|
||||||
verbose(VERB_ALGO, "handle request called with err=%d", error);
|
verbose(VERB_ALGO, "handle request called with err=%d", error);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr,
|
||||||
|
repinfo->addrlen);
|
||||||
|
if(acl == acl_deny) {
|
||||||
|
comm_point_drop_reply(repinfo);
|
||||||
|
return 0;
|
||||||
|
} else if(acl == acl_refuse) {
|
||||||
|
ldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
|
||||||
|
ldns_buffer_write_at(c->buffer, 4,
|
||||||
|
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
|
||||||
|
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||||
|
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
|
||||||
|
LDNS_RCODE_REFUSED);
|
||||||
|
log_buf(VERB_ALGO, "refuse", c->buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if((ret=worker_check_request(c->buffer, worker)) != 0) {
|
if((ret=worker_check_request(c->buffer, worker)) != 0) {
|
||||||
verbose(VERB_ALGO, "worker check request: bad query.");
|
verbose(VERB_ALGO, "worker check request: bad query.");
|
||||||
if(ret != -1) {
|
if(ret != -1) {
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
- README talks about gnu make.
|
- README talks about gnu make.
|
||||||
- 0.8: unit test for addr_mask and fixups for it.
|
- 0.8: unit test for addr_mask and fixups for it.
|
||||||
and unit test for addr_in_common().
|
and unit test for addr_in_common().
|
||||||
|
- 0.8: access-control config file element.
|
||||||
|
and unit test rpl replay file.
|
||||||
|
|
||||||
16 November 2007: Wouter
|
16 November 2007: Wouter
|
||||||
- privilege separation is not needed in unbound at this time.
|
- privilege separation is not needed in unbound at this time.
|
||||||
|
@ -113,6 +113,15 @@ server:
|
|||||||
# Enable TCP, "yes" or "no".
|
# Enable TCP, "yes" or "no".
|
||||||
# do-tcp: yes
|
# do-tcp: yes
|
||||||
|
|
||||||
|
# control which clients are allowed to make (recursive) queries
|
||||||
|
# to this server. Specify classless netblocks with /size and action.
|
||||||
|
# By default everything is refused, except for localhost.
|
||||||
|
# Choose deny (drop message), refuse (polite error reply), allow.
|
||||||
|
# access-control: 0.0.0.0/0 refuse
|
||||||
|
# access-control: 127.0.0.0/8 allow
|
||||||
|
# access-control: ::0/0 refuse
|
||||||
|
# access-control: ::1 allow
|
||||||
|
|
||||||
# if given, a chroot(2) is done to the given directory.
|
# if given, a chroot(2) is done to the given directory.
|
||||||
# i.e. you can chroot to the working directory, for example,
|
# i.e. you can chroot to the working directory, for example,
|
||||||
# for extra security, but make sure all files are in that directory.
|
# for extra security, but make sure all files are in that directory.
|
||||||
|
@ -48,6 +48,12 @@ server:
|
|||||||
# logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
|
# logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
|
||||||
pidfile: "/etc/unbound/unbound.pid"
|
pidfile: "/etc/unbound/unbound.pid"
|
||||||
# verbosity: 1 # uncomment and increase to get more logging.
|
# verbosity: 1 # uncomment and increase to get more logging.
|
||||||
|
|
||||||
|
# listen on all interfaces, answer queries from the local subnet.
|
||||||
|
interface: 0.0.0.0
|
||||||
|
interface: ::0
|
||||||
|
access-control: 10.0.0.0/8 allow
|
||||||
|
access-control: 2001:DB8::/64 allow
|
||||||
.fi
|
.fi
|
||||||
.Sh FILE FORMAT
|
.Sh FILE FORMAT
|
||||||
There must be whitespace between keywords. Attribute keywords end with a colon ':'. An attribute
|
There must be whitespace between keywords. Attribute keywords end with a colon ':'. An attribute
|
||||||
@ -155,6 +161,13 @@ Enable or disable whether ip6 queries are answered. Default is yes.
|
|||||||
Enable or disable whether UDP queries are answered. Default is yes.
|
Enable or disable whether UDP queries are answered. Default is yes.
|
||||||
.It \fBdo-tcp:\fR <yes or no>
|
.It \fBdo-tcp:\fR <yes or no>
|
||||||
Enable or disable whether TCP queries are answered. Default is yes.
|
Enable or disable whether TCP queries are answered. Default is yes.
|
||||||
|
.It \fBaccess-control:\fR <IP netblock> <action>
|
||||||
|
The netblock is given as an IP4 or IP6 address with /size appended for a
|
||||||
|
classless network block. The action can be deny, refuse or allow.
|
||||||
|
Deny stops queries from hosts from that netblock.
|
||||||
|
Refuse stops queries too, but sends a DNS rcode REFUSED error message back.
|
||||||
|
Allow gives access to clients from that netblock.
|
||||||
|
By default only localhost is allowed, the rest is refused.
|
||||||
.It \fBchroot:\fR <directory>
|
.It \fBchroot:\fR <directory>
|
||||||
If given a chroot is done to the given directory. The default is
|
If given a chroot is done to the given directory. The default is
|
||||||
"/etc/unbound". If you give "" no chroot is performed.
|
"/etc/unbound". If you give "" no chroot is performed.
|
||||||
|
@ -114,35 +114,11 @@ donotq_str_cfg(struct iter_donotq* dq, const char* str)
|
|||||||
{
|
{
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
int net;
|
int net;
|
||||||
char* s = NULL;
|
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
net = (str_is_ip6(str)?128:32);
|
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
||||||
if((s=strchr(str, '/'))) {
|
log_err("cannot parse donotquery netblock: %s", str);
|
||||||
if(atoi(s+1) > net) {
|
|
||||||
log_err("netblock too large: %s", str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
net = atoi(s+1);
|
|
||||||
if(net == 0 && strcmp(s+1, "0") != 0) {
|
|
||||||
log_err("cannot parse donotquery netblock:"
|
|
||||||
" '%s'", str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(!(s = strdup(str))) {
|
|
||||||
log_err("out of memory");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*strchr(s, '/') = '\0';
|
|
||||||
}
|
|
||||||
if(!ipstrtoaddr(s?s:str, UNBOUND_DNS_PORT, &addr, &addrlen)) {
|
|
||||||
free(s);
|
|
||||||
log_err("cannot parse donotquery ip address: '%s'", str);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(s) {
|
|
||||||
free(s);
|
|
||||||
addr_mask(&addr, addrlen, net);
|
|
||||||
}
|
|
||||||
if(!donotq_insert(dq, &addr, addrlen, net)) {
|
if(!donotq_insert(dq, &addr, addrlen, net)) {
|
||||||
log_err("out of memory");
|
log_err("out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -229,6 +229,11 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
|||||||
while(isspace((int)*remain))
|
while(isspace((int)*remain))
|
||||||
remain++;
|
remain++;
|
||||||
if(parse_keyword(&remain, "ADDRESS")) {
|
if(parse_keyword(&remain, "ADDRESS")) {
|
||||||
|
while(isspace((int)*remain))
|
||||||
|
remain++;
|
||||||
|
if(strlen(remain) > 0) /* remove \n */
|
||||||
|
remain[strlen(remain)-1] = 0;
|
||||||
|
printf("remain '%s'\n", remain);
|
||||||
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) {
|
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) {
|
||||||
log_err("line %d: could not parse ADDRESS: %s",
|
log_err("line %d: could not parse ADDRESS: %s",
|
||||||
*lineno, remain);
|
*lineno, remain);
|
||||||
|
52
testdata/acl.rpl
vendored
Normal file
52
testdata/acl.rpl
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
; config options
|
||||||
|
server:
|
||||||
|
hide-identity: no
|
||||||
|
hide-version: no
|
||||||
|
identity: "test-identity"
|
||||||
|
version: "test-version"
|
||||||
|
access-control: 20.0.0.0/8 allow
|
||||||
|
access-control: 20.40.0.0/16 refuse
|
||||||
|
access-control: 20.40.80.0/24 deny
|
||||||
|
|
||||||
|
CONFIG_END
|
||||||
|
SCENARIO_BEGIN Test access control list
|
||||||
|
|
||||||
|
; version.bind.
|
||||||
|
; allow
|
||||||
|
STEP 1 QUERY ADDRESS 20.1.2.3
|
||||||
|
ENTRY_BEGIN
|
||||||
|
SECTION QUESTION
|
||||||
|
version.bind. CH TXT
|
||||||
|
ENTRY_END
|
||||||
|
STEP 2 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR RA
|
||||||
|
SECTION QUESTION
|
||||||
|
version.bind. CH TXT
|
||||||
|
SECTION ANSWER
|
||||||
|
version.bind. 0 CH TXT "test-version"
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; refuse
|
||||||
|
STEP 3 QUERY ADDRESS 20.40.2.3
|
||||||
|
ENTRY_BEGIN
|
||||||
|
SECTION QUESTION
|
||||||
|
version.bind. CH TXT
|
||||||
|
ENTRY_END
|
||||||
|
STEP 4 CHECK_ANSWER
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH all
|
||||||
|
REPLY QR REFUSED
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; deny (drop)
|
||||||
|
STEP 5 QUERY ADDRESS 20.40.80.3
|
||||||
|
ENTRY_BEGIN
|
||||||
|
SECTION QUESTION
|
||||||
|
version.bind. CH TXT
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
; no answer must be pending
|
||||||
|
|
||||||
|
SCENARIO_END
|
1142
util/configlexer.c
1142
util/configlexer.c
File diff suppressed because it is too large
Load Diff
@ -144,6 +144,7 @@ forward-addr{COLON} { YDOUT; return VAR_FORWARD_ADDR;}
|
|||||||
forward-host{COLON} { YDOUT; return VAR_FORWARD_HOST;}
|
forward-host{COLON} { YDOUT; return VAR_FORWARD_HOST;}
|
||||||
do-not-query-address{COLON} { YDOUT; return VAR_DO_NOT_QUERY_ADDRESS;}
|
do-not-query-address{COLON} { YDOUT; return VAR_DO_NOT_QUERY_ADDRESS;}
|
||||||
do-not-query-localhost{COLON} { YDOUT; return VAR_DO_NOT_QUERY_LOCALHOST;}
|
do-not-query-localhost{COLON} { YDOUT; return VAR_DO_NOT_QUERY_LOCALHOST;}
|
||||||
|
access-control{COLON} { YDOUT; return VAR_ACCESS_CONTROL;}
|
||||||
hide-identity{COLON} { YDOUT; return VAR_HIDE_IDENTITY;}
|
hide-identity{COLON} { YDOUT; return VAR_HIDE_IDENTITY;}
|
||||||
hide-version{COLON} { YDOUT; return VAR_HIDE_VERSION;}
|
hide-version{COLON} { YDOUT; return VAR_HIDE_VERSION;}
|
||||||
identity{COLON} { YDOUT; return VAR_IDENTITY;}
|
identity{COLON} { YDOUT; return VAR_IDENTITY;}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -108,7 +108,8 @@
|
|||||||
VAR_ROOT_HINTS = 324,
|
VAR_ROOT_HINTS = 324,
|
||||||
VAR_DO_NOT_QUERY_LOCALHOST = 325,
|
VAR_DO_NOT_QUERY_LOCALHOST = 325,
|
||||||
VAR_CACHE_MAX_TTL = 326,
|
VAR_CACHE_MAX_TTL = 326,
|
||||||
VAR_HARDEN_DNNSEC_STRIPPED = 327
|
VAR_HARDEN_DNNSEC_STRIPPED = 327,
|
||||||
|
VAR_ACCESS_CONTROL = 328
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/* Tokens. */
|
/* Tokens. */
|
||||||
@ -182,6 +183,7 @@
|
|||||||
#define VAR_DO_NOT_QUERY_LOCALHOST 325
|
#define VAR_DO_NOT_QUERY_LOCALHOST 325
|
||||||
#define VAR_CACHE_MAX_TTL 326
|
#define VAR_CACHE_MAX_TTL 326
|
||||||
#define VAR_HARDEN_DNNSEC_STRIPPED 327
|
#define VAR_HARDEN_DNNSEC_STRIPPED 327
|
||||||
|
#define VAR_ACCESS_CONTROL 328
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -193,7 +195,7 @@ typedef union YYSTYPE
|
|||||||
char* str;
|
char* str;
|
||||||
}
|
}
|
||||||
/* Line 1489 of yacc.c. */
|
/* Line 1489 of yacc.c. */
|
||||||
#line 197 "util/configparser.h"
|
#line 199 "util/configparser.h"
|
||||||
YYSTYPE;
|
YYSTYPE;
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
|
@ -86,7 +86,7 @@ extern struct config_parser_state* cfg_parser;
|
|||||||
%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
|
%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
|
||||||
%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
|
%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
|
||||||
%token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS VAR_DO_NOT_QUERY_LOCALHOST
|
%token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS VAR_DO_NOT_QUERY_LOCALHOST
|
||||||
%token VAR_CACHE_MAX_TTL VAR_HARDEN_DNNSEC_STRIPPED
|
%token VAR_CACHE_MAX_TTL VAR_HARDEN_DNNSEC_STRIPPED VAR_ACCESS_CONTROL
|
||||||
|
|
||||||
%%
|
%%
|
||||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||||
@ -124,7 +124,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||||||
server_trusted_keys_file | server_val_nsec3_keysize_iterations |
|
server_trusted_keys_file | server_val_nsec3_keysize_iterations |
|
||||||
server_use_syslog | server_outgoing_interface | server_root_hints |
|
server_use_syslog | server_outgoing_interface | server_root_hints |
|
||||||
server_do_not_query_localhost | server_cache_max_ttl |
|
server_do_not_query_localhost | server_cache_max_ttl |
|
||||||
server_harden_dnssec_stripped
|
server_harden_dnssec_stripped | server_access_control
|
||||||
;
|
;
|
||||||
stubstart: VAR_STUB_ZONE
|
stubstart: VAR_STUB_ZONE
|
||||||
{
|
{
|
||||||
@ -574,6 +574,23 @@ server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING
|
|||||||
free($2);
|
free($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
server_access_control: VAR_ACCESS_CONTROL STRING STRING
|
||||||
|
{
|
||||||
|
OUTYY(("P(server_access_control:%s %s)\n", $2, $3));
|
||||||
|
if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 &&
|
||||||
|
strcmp($3, "allow")!=0) {
|
||||||
|
yyerror("expected deny, refuse or allow in "
|
||||||
|
"access control action");
|
||||||
|
} else {
|
||||||
|
struct config_acl* n = calloc(1, sizeof(*n));
|
||||||
|
if(!n) fatal_exit("out of memory adding acl");
|
||||||
|
n->address = $2;
|
||||||
|
n->control = $3;
|
||||||
|
n->next = cfg_parser->cfg->acls;
|
||||||
|
cfg_parser->cfg->acls = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
server_module_conf: VAR_MODULE_CONF STRING
|
server_module_conf: VAR_MODULE_CONF STRING
|
||||||
{
|
{
|
||||||
OUTYY(("P(server_module_conf:%s)\n", $2));
|
OUTYY(("P(server_module_conf:%s)\n", $2));
|
||||||
|
@ -229,6 +229,39 @@ ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
|
||||||
|
socklen_t* addrlen, int* net)
|
||||||
|
{
|
||||||
|
char* s = NULL;
|
||||||
|
*net = (str_is_ip6(str)?128:32);
|
||||||
|
if((s=strchr(str, '/'))) {
|
||||||
|
if(atoi(s+1) > *net) {
|
||||||
|
log_err("netblock too large: %s", str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*net = atoi(s+1);
|
||||||
|
if(net == 0 && strcmp(s+1, "0") != 0) {
|
||||||
|
log_err("cannot parse netblock: '%s'", str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!(s = strdup(str))) {
|
||||||
|
log_err("out of memory");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*strchr(s, '/') = '\0';
|
||||||
|
}
|
||||||
|
if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) {
|
||||||
|
free(s);
|
||||||
|
log_err("cannot parse ip address: '%s'", str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(s) {
|
||||||
|
free(s);
|
||||||
|
addr_mask(addr, *addrlen, *net);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
|
log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
|
||||||
uint16_t type, uint16_t dclass)
|
uint16_t type, uint16_t dclass)
|
||||||
|
@ -186,6 +186,19 @@ int extstrtoaddr(const char* str, struct sockaddr_storage* addr,
|
|||||||
int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
||||||
socklen_t* addrlen);
|
socklen_t* addrlen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert ip netblock (ip/netsize) string and port to sockaddr.
|
||||||
|
* *SLOW*, does a malloc internally to avoid writing over 'ip' string.
|
||||||
|
* @param ip: ip4 or ip6 address string.
|
||||||
|
* @param port: port number, host format.
|
||||||
|
* @param addr: where to store sockaddr.
|
||||||
|
* @param addrlen: length of stored sockaddr is returned.
|
||||||
|
* @param net: netblock size is returned.
|
||||||
|
* @return 0 on error.
|
||||||
|
*/
|
||||||
|
int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
||||||
|
socklen_t* addrlen, int* net);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print string with neat domain name, type and class.
|
* Print string with neat domain name, type and class.
|
||||||
* @param v: at what verbosity level to print this.
|
* @param v: at what verbosity level to print this.
|
||||||
|
Loading…
Reference in New Issue
Block a user