mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-06-09 08:34:02 -04:00
- access-control-tag config directive.
git-svn-id: file:///svn/unbound/trunk@3754 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
17302c0e23
commit
415fc52b08
13 changed files with 1602 additions and 1453 deletions
|
|
@ -71,7 +71,7 @@ acl_list_delete(struct acl_list* acl)
|
|||
}
|
||||
|
||||
/** insert new address into acl_list structure */
|
||||
static int
|
||||
static struct acl_addr*
|
||||
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, enum acl_access control,
|
||||
int complain_duplicates)
|
||||
|
|
@ -79,13 +79,15 @@ acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
|
|||
struct acl_addr* node = regional_alloc(acl->region,
|
||||
sizeof(struct acl_addr));
|
||||
if(!node)
|
||||
return 0;
|
||||
return NULL;
|
||||
node->control = control;
|
||||
node->taglist = NULL;
|
||||
node->taglen = 0;
|
||||
if(!addr_tree_insert(&acl->tree, &node->node, addr, addrlen, net)) {
|
||||
if(complain_duplicates)
|
||||
verbose(VERB_QUERY, "duplicate acl address ignored.");
|
||||
}
|
||||
return 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
/** apply acl_list string */
|
||||
|
|
@ -125,6 +127,40 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** apply acl_tag string */
|
||||
static int
|
||||
acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
|
||||
size_t bitmaplen)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
int net;
|
||||
socklen_t addrlen;
|
||||
struct acl_addr* node;
|
||||
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
||||
log_err("cannot parse netblock in access-control-tag: %s", str);
|
||||
return 0;
|
||||
}
|
||||
/* find or create node */
|
||||
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr,
|
||||
addrlen, net))) {
|
||||
/* create node, type 'allow' since otherwise tags are
|
||||
* pointless, can override with specific access-control: cfg */
|
||||
if(!(node=(struct acl_addr*)acl_list_insert(acl, &addr,
|
||||
addrlen, net, acl_allow, 1))) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
log_assert(node);
|
||||
node->taglen = bitmaplen;
|
||||
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
|
||||
if(!node->taglist) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl_list config */
|
||||
static int
|
||||
read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
||||
|
|
@ -138,6 +174,19 @@ read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tags config */
|
||||
static int
|
||||
read_acl_tags(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_strbytelist* p;
|
||||
for(p = cfg->acl_tags; p; p = p->next) {
|
||||
log_assert(p->str && p->str2);
|
||||
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
|
|
@ -145,6 +194,8 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
|||
addr_tree_init(&acl->tree);
|
||||
if(!read_acl_list(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_tags(acl, cfg))
|
||||
return 0;
|
||||
/* insert defaults, with '0' to ignore them if they are duplicates */
|
||||
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,10 @@ struct acl_addr {
|
|||
struct addr_tree_node node;
|
||||
/** access control on this netblock */
|
||||
enum acl_access control;
|
||||
/** tag bitlist */
|
||||
uint8_t* taglist;
|
||||
/** length of the taglist (in bytes) */
|
||||
size_t taglen;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
6 June 2016: Wouter
|
||||
- Better help text from -h (from Ray Griffith).
|
||||
- access-control-tag config directive.
|
||||
|
||||
3 June 2016: Wouter
|
||||
- Fix to not ignore return value of chown() in daemon startup.
|
||||
|
|
|
|||
|
|
@ -203,6 +203,11 @@ server:
|
|||
# access-control: ::1 allow
|
||||
# access-control: ::ffff:127.0.0.1 allow
|
||||
|
||||
# tag access-control with list of tags (in "" with spaces between)
|
||||
# Clients using this access control element use localzones that
|
||||
# are tagged with one of these tags.
|
||||
# access-control-tag: "192.0.2.0/24" "tag2 tag3"
|
||||
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
|
|
|
|||
|
|
@ -784,6 +784,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
|||
else O_YNO(opt, "qname-minimisation", qname_minimisation)
|
||||
else O_IFC(opt, "define-tag", num_tags, tagname)
|
||||
else O_LTG(opt, "local-zone-tag", local_zone_tags)
|
||||
else O_LTG(opt, "access-control-tag", acl_tags)
|
||||
/* not here:
|
||||
* outgoing-permit, outgoing-avoid - have list of ports
|
||||
* local-zone - zones and nodefault variables
|
||||
|
|
@ -1022,6 +1023,7 @@ config_delete(struct config_file* cfg)
|
|||
config_delstrlist(cfg->local_data);
|
||||
config_del_strarray(cfg->tagname, cfg->num_tags);
|
||||
config_del_strbytelist(cfg->local_zone_tags);
|
||||
config_del_strbytelist(cfg->acl_tags);
|
||||
config_delstrlist(cfg->control_ifs);
|
||||
free(cfg->server_key_file);
|
||||
free(cfg->server_cert_file);
|
||||
|
|
|
|||
|
|
@ -298,6 +298,8 @@ struct config_file {
|
|||
int insecure_lan_zones;
|
||||
/** list of zonename, tagbitlist */
|
||||
struct config_strbytelist* local_zone_tags;
|
||||
/** list of aclname, tagbitlist */
|
||||
struct config_strbytelist* acl_tags;
|
||||
/** tag list, array with tagname[i] is malloced string */
|
||||
char** tagname;
|
||||
/** number of items in the taglist */
|
||||
|
|
|
|||
1512
util/configlexer.c
1512
util/configlexer.c
File diff suppressed because it is too large
Load diff
|
|
@ -345,6 +345,7 @@ dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) }
|
|||
dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) }
|
||||
define-tag{COLON} { YDVAR(1, VAR_DEFINE_TAG) }
|
||||
local-zone-tag{COLON} { YDVAR(2, VAR_LOCAL_ZONE_TAG) }
|
||||
access-control-tag{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_TAG) }
|
||||
dnstap{COLON} { YDVAR(0, VAR_DNSTAP) }
|
||||
dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) }
|
||||
dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) }
|
||||
|
|
|
|||
1418
util/configparser.c
1418
util/configparser.c
File diff suppressed because it is too large
Load diff
|
|
@ -211,7 +211,8 @@ extern int yydebug;
|
|||
VAR_QNAME_MINIMISATION = 421,
|
||||
VAR_IP_FREEBIND = 422,
|
||||
VAR_DEFINE_TAG = 423,
|
||||
VAR_LOCAL_ZONE_TAG = 424
|
||||
VAR_LOCAL_ZONE_TAG = 424,
|
||||
VAR_ACCESS_CONTROL_TAG = 425
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
|
|
@ -382,6 +383,7 @@ extern int yydebug;
|
|||
#define VAR_IP_FREEBIND 422
|
||||
#define VAR_DEFINE_TAG 423
|
||||
#define VAR_LOCAL_ZONE_TAG 424
|
||||
#define VAR_ACCESS_CONTROL_TAG 425
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
|
@ -392,7 +394,7 @@ union YYSTYPE
|
|||
|
||||
char* str;
|
||||
|
||||
#line 396 "util/configparser.h" /* yacc.c:1909 */
|
||||
#line 398 "util/configparser.h" /* yacc.c:1909 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR
|
||||
%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
|
||||
%token VAR_QNAME_MINIMISATION VAR_IP_FREEBIND VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG
|
||||
%token VAR_ACCESS_CONTROL_TAG
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
|
|
@ -194,7 +195,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_caps_whitelist | server_cache_max_negative_ttl |
|
||||
server_permit_small_holddown | server_qname_minimisation |
|
||||
server_ip_freebind | server_define_tag | server_local_zone_tag |
|
||||
server_disable_dnssec_lame_check
|
||||
server_disable_dnssec_lame_check | access_control_tag
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
|
|
@ -1332,6 +1333,25 @@ server_local_zone_tag: VAR_LOCAL_ZONE_TAG STRING_ARG STRING_ARG
|
|||
}
|
||||
}
|
||||
;
|
||||
access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG
|
||||
{
|
||||
size_t len = 0;
|
||||
uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3,
|
||||
&len);
|
||||
free($3);
|
||||
OUTYY(("P(server_access_control_tag:%s)\n", $2));
|
||||
if(!bitlist)
|
||||
yyerror("could not parse tags, (define-tag them first)");
|
||||
if(bitlist) {
|
||||
if(!cfg_strbytelist_insert(
|
||||
&cfg_parser->cfg->acl_tags,
|
||||
$2, bitlist, len)) {
|
||||
yyerror("out of memory");
|
||||
free($2);
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
server_ratelimit: VAR_RATELIMIT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ratelimit:%s)\n", $2));
|
||||
|
|
|
|||
|
|
@ -231,6 +231,19 @@ struct addr_tree_node* addr_tree_lookup(rbtree_t* tree,
|
|||
return result;
|
||||
}
|
||||
|
||||
struct addr_tree_node* addr_tree_find(rbtree_t* tree,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int net)
|
||||
{
|
||||
rbnode_t* res = NULL;
|
||||
struct addr_tree_node key;
|
||||
key.node.key = &key;
|
||||
memcpy(&key.addr, addr, addrlen);
|
||||
key.addrlen = addrlen;
|
||||
key.net = net;
|
||||
res = rbtree_search(tree, &key);
|
||||
return (struct addr_tree_node*)res;
|
||||
}
|
||||
|
||||
int
|
||||
name_tree_next_root(rbtree_t* tree, uint16_t* dclass)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -183,6 +183,18 @@ void addr_tree_init_parents(rbtree_t* tree);
|
|||
struct addr_tree_node* addr_tree_lookup(rbtree_t* tree,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Find element in addr tree. (search a netblock, not a match for an address)
|
||||
* @param tree: addr tree
|
||||
* @param addr: netblock to lookup.
|
||||
* @param addrlen: length of addr
|
||||
* @param net: size of subnet
|
||||
* @return addr tree element, or NULL if not found.
|
||||
*/
|
||||
struct addr_tree_node* addr_tree_find(rbtree_t* tree,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int net);
|
||||
|
||||
|
||||
/** compare name tree nodes */
|
||||
int name_tree_compare(const void* k1, const void* k2);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue