Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Adam Osuchowski
Kea
Commits
4c0d2595
Commit
4c0d2595
authored
Jul 05, 2011
by
JINMEI Tatuya
Browse files
[master] Merge branch 'trac1069'
with fixing conflicts in src/bin/resolver/Makefile.am
parents
baf3d878
803a215c
Changes
16
Hide whitespace changes
Inline
Side-by-side
src/bin/resolver/Makefile.am
View file @
4c0d2595
...
...
@@ -60,6 +60,7 @@ b10_resolver_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/config/libcfgclient.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/cc/libcc.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/util/libutil.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/acl/libdnsacl.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/exceptions/libexceptions.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/asiodns/libasiodns.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/asiolink/libasiolink.la
...
...
@@ -68,7 +69,6 @@ b10_resolver_LDADD += $(top_builddir)/src/lib/log/liblog.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/server_common/libserver_common.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/cache/libcache.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/nsas/libnsas.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/acl/libacl.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/lib/resolve/libresolve.la
b10_resolver_LDADD
+=
$(top_builddir)
/src/bin/auth/change_user.o
b10_resolver_LDFLAGS
=
-pthread
...
...
src/bin/resolver/resolver.cc
View file @
4c0d2595
...
...
@@ -26,7 +26,7 @@
#include
<exceptions/exceptions.h>
#include
<acl/
acl
.h>
#include
<acl/
dns
.h>
#include
<acl/loader.h>
#include
<asiodns/asiodns.h>
...
...
@@ -62,6 +62,7 @@ using boost::shared_ptr;
using
namespace
isc
;
using
namespace
isc
::
util
;
using
namespace
isc
::
acl
;
using
isc
::
acl
::
dns
::
RequestACL
;
using
namespace
isc
::
dns
;
using
namespace
isc
::
data
;
using
namespace
isc
::
config
;
...
...
@@ -82,7 +83,9 @@ public:
client_timeout_
(
4000
),
lookup_timeout_
(
30000
),
retries_
(
3
),
query_acl_
(
new
Resolver
::
ClientACL
(
REJECT
)),
// we apply "reject all" (implicit default of the loader) ACL by
// default:
query_acl_
(
acl
::
dns
::
getRequestLoader
().
load
(
Element
::
fromJSON
(
"[]"
))),
rec_query_
(
NULL
)
{}
...
...
@@ -160,11 +163,11 @@ public:
OutputBufferPtr
buffer
,
DNSServer
*
server
);
const
Re
solver
::
Clien
tACL
&
getQueryACL
()
const
{
const
Re
ques
tACL
&
getQueryACL
()
const
{
return
(
*
query_acl_
);
}
void
setQueryACL
(
shared_ptr
<
const
Re
solver
::
Clien
tACL
>
new_acl
)
{
void
setQueryACL
(
shared_ptr
<
const
Re
ques
tACL
>
new_acl
)
{
query_acl_
=
new_acl
;
}
...
...
@@ -192,7 +195,7 @@ public:
private:
/// ACL on incoming queries
shared_ptr
<
const
Re
solver
::
Clien
tACL
>
query_acl_
;
shared_ptr
<
const
Re
ques
tACL
>
query_acl_
;
/// Object to handle upstream queries
RecursiveQuery
*
rec_query_
;
...
...
@@ -514,8 +517,10 @@ ResolverImpl::processNormalQuery(const IOMessage& io_message,
const
RRClass
qclass
=
question
->
getClass
();
// Apply query ACL
Client
client
(
io_message
);
const
BasicAction
query_action
(
getQueryACL
().
execute
(
client
));
const
Client
client
(
io_message
);
const
BasicAction
query_action
(
getQueryACL
().
execute
(
acl
::
dns
::
RequestContext
(
client
.
getRequestSourceIPAddress
())));
if
(
query_action
==
isc
::
acl
::
REJECT
)
{
LOG_INFO
(
resolver_logger
,
RESOLVER_QUERY_REJECTED
)
.
arg
(
question
->
getName
()).
arg
(
qtype
).
arg
(
qclass
).
arg
(
client
);
...
...
@@ -574,32 +579,6 @@ ResolverImpl::processNormalQuery(const IOMessage& io_message,
return
(
RECURSION
);
}
namespace
{
// This is a simplified ACL parser for the initial implementation with minimal
// external dependency. For a longer term we'll switch to a more generic
// loader with allowing more complicated ACL syntax.
shared_ptr
<
const
Resolver
::
ClientACL
>
createQueryACL
(
isc
::
data
::
ConstElementPtr
acl_config
)
{
if
(
!
acl_config
)
{
return
(
shared_ptr
<
const
Resolver
::
ClientACL
>
());
}
shared_ptr
<
Resolver
::
ClientACL
>
new_acl
(
new
Resolver
::
ClientACL
(
REJECT
));
BOOST_FOREACH
(
ConstElementPtr
rule
,
acl_config
->
listValue
())
{
ConstElementPtr
action
=
rule
->
get
(
"action"
);
ConstElementPtr
from
=
rule
->
get
(
"from"
);
if
(
!
action
||
!
from
)
{
isc_throw
(
BadValue
,
"query ACL misses mandatory parameter"
);
}
new_acl
->
append
(
shared_ptr
<
IPCheck
<
Client
>
>
(
new
IPCheck
<
Client
>
(
from
->
stringValue
())),
defaultActionLoader
(
action
));
}
return
(
new_acl
);
}
}
ConstElementPtr
Resolver
::
updateConfig
(
ConstElementPtr
config
)
{
LOG_DEBUG
(
resolver_logger
,
RESOLVER_DBG_CONFIG
,
RESOLVER_CONFIG_UPDATED
)
...
...
@@ -616,8 +595,10 @@ Resolver::updateConfig(ConstElementPtr config) {
ConstElementPtr
listenAddressesE
(
config
->
get
(
"listen_on"
));
AddressList
listenAddresses
(
parseAddresses
(
listenAddressesE
,
"listen_on"
));
shared_ptr
<
const
ClientACL
>
query_acl
(
createQueryACL
(
config
->
get
(
"query_acl"
)));
const
ConstElementPtr
query_acl_cfg
(
config
->
get
(
"query_acl"
));
const
shared_ptr
<
const
RequestACL
>
query_acl
=
query_acl_cfg
?
acl
::
dns
::
getRequestLoader
().
load
(
query_acl_cfg
)
:
shared_ptr
<
const
RequestACL
>
();
bool
set_timeouts
(
false
);
int
qtimeout
=
impl_
->
query_timeout_
;
int
ctimeout
=
impl_
->
client_timeout_
;
...
...
@@ -777,13 +758,13 @@ Resolver::getListenAddresses() const {
return
(
impl_
->
listen_
);
}
const
Re
solver
::
Clien
tACL
&
const
Re
ques
tACL
&
Resolver
::
getQueryACL
()
const
{
return
(
impl_
->
getQueryACL
());
}
void
Resolver
::
setQueryACL
(
shared_ptr
<
const
Clien
tACL
>
new_acl
)
{
Resolver
::
setQueryACL
(
shared_ptr
<
const
Reques
tACL
>
new_acl
)
{
if
(
!
new_acl
)
{
isc_throw
(
InvalidParameter
,
"NULL pointer is passed to setQueryACL"
);
}
...
...
src/bin/resolver/resolver.h
View file @
4c0d2595
...
...
@@ -21,10 +21,9 @@
#include
<boost/shared_ptr.hpp>
#include
<acl/acl.h>
#include
<cc/data.h>
#include
<config/ccsession.h>
#include
<acl/dns.h>
#include
<dns/message.h>
#include
<util/buffer.h>
...
...
@@ -41,12 +40,6 @@
#include
<resolve/resolver_interface.h>
namespace
isc
{
namespace
server_common
{
class
Client
;
}
}
class
ResolverImpl
;
/**
...
...
@@ -246,13 +239,10 @@ public:
*/
int
getRetries
()
const
;
// Shortcut typedef used for query ACL.
typedef
isc
::
acl
::
ACL
<
isc
::
server_common
::
Client
>
ClientACL
;
/// Get the query ACL.
///
/// \exception None
const
Clien
tACL
&
getQueryACL
()
const
;
const
isc
::
acl
::
dns
::
Reques
tACL
&
getQueryACL
()
const
;
/// Set the new query ACL.
///
...
...
@@ -265,7 +255,8 @@ public:
/// \exception InvalidParameter The given pointer is NULL
///
/// \param new_acl The new ACL to replace the existing one.
void
setQueryACL
(
boost
::
shared_ptr
<
const
ClientACL
>
new_acl
);
void
setQueryACL
(
boost
::
shared_ptr
<
const
isc
::
acl
::
dns
::
RequestACL
>
new_acl
);
private:
ResolverImpl
*
impl_
;
...
...
src/bin/resolver/tests/Makefile.am
View file @
4c0d2595
...
...
@@ -39,6 +39,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/asiodns/libasiodns.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/asiolink/libasiolink.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/config/libcfgclient.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/acl/libdnsacl.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/cc/libcc.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/exceptions/libexceptions.la
run_unittests_LDADD
+=
$(top_builddir)
/src/lib/xfr/libxfr.la
...
...
src/bin/resolver/tests/resolver_config_unittest.cc
View file @
4c0d2595
...
...
@@ -43,6 +43,7 @@
using
namespace
std
;
using
boost
::
scoped_ptr
;
using
namespace
isc
::
acl
;
using
isc
::
acl
::
dns
::
RequestContext
;
using
namespace
isc
::
data
;
using
namespace
isc
::
testutils
;
using
namespace
isc
::
asiodns
;
...
...
@@ -57,19 +58,22 @@ protected:
DNSService
dnss
;
Resolver
server
;
scoped_ptr
<
const
IOEndpoint
>
endpoint
;
scoped_ptr
<
const
IOMessage
>
re
que
st
;
scoped_ptr
<
const
IOMessage
>
que
ry_message
;
scoped_ptr
<
const
Client
>
client
;
scoped_ptr
<
const
RequestContext
>
request
;
ResolverConfig
()
:
dnss
(
ios
,
NULL
,
NULL
,
NULL
)
{
server
.
setDNSService
(
dnss
);
server
.
setConfigured
();
}
const
Clien
t
&
create
Clien
t
(
const
string
&
source_addr
)
{
const
RequestContex
t
&
create
Reques
t
(
const
string
&
source_addr
)
{
endpoint
.
reset
(
IOEndpoint
::
create
(
IPPROTO_UDP
,
IOAddress
(
source_addr
),
53210
));
request
.
reset
(
new
IOMessage
(
NULL
,
0
,
IOSocket
::
getDummyUDPSocket
(),
*
endpoint
));
client
.
reset
(
new
Client
(
*
request
));
return
(
*
client
);
query_message
.
reset
(
new
IOMessage
(
NULL
,
0
,
IOSocket
::
getDummyUDPSocket
(),
*
endpoint
));
client
.
reset
(
new
Client
(
*
query_message
));
request
.
reset
(
new
RequestContext
(
client
->
getRequestSourceIPAddress
()));
return
(
*
request
);
}
void
invalidTest
(
const
string
&
JSON
,
const
string
&
name
);
};
...
...
@@ -100,14 +104,14 @@ TEST_F(ResolverConfig, forwardAddresses) {
TEST_F
(
ResolverConfig
,
forwardAddressConfig
)
{
// Try putting there some address
ElementPtr
config
(
Element
::
fromJSON
(
"{"
"
\"
forward_addresses
\"
: ["
"
{"
"
\"
address
\"
:
\"
192.0.2.1
\"
,"
"
\"
port
\"
: 53"
"
}"
"]"
"}"
));
Const
ElementPtr
config
(
Element
::
fromJSON
(
"{"
"
\"
forward_addresses
\"
: ["
"
{"
"
\"
address
\"
:
\"
192.0.2.1
\"
,"
"
\"
port
\"
: 53"
"
}"
"]"
"}"
));
ConstElementPtr
result
(
server
.
updateConfig
(
config
));
EXPECT_EQ
(
result
->
toWire
(),
isc
::
config
::
createAnswer
()
->
toWire
());
EXPECT_TRUE
(
server
.
isForwarding
());
...
...
@@ -127,14 +131,14 @@ TEST_F(ResolverConfig, forwardAddressConfig) {
TEST_F
(
ResolverConfig
,
rootAddressConfig
)
{
// Try putting there some address
ElementPtr
config
(
Element
::
fromJSON
(
"{"
"
\"
root_addresses
\"
: ["
"
{"
"
\"
address
\"
:
\"
192.0.2.1
\"
,"
"
\"
port
\"
: 53"
"
}"
"]"
"}"
));
Const
ElementPtr
config
(
Element
::
fromJSON
(
"{"
"
\"
root_addresses
\"
: ["
"
{"
"
\"
address
\"
:
\"
192.0.2.1
\"
,"
"
\"
port
\"
: 53"
"
}"
"]"
"}"
));
ConstElementPtr
result
(
server
.
updateConfig
(
config
));
EXPECT_EQ
(
result
->
toWire
(),
isc
::
config
::
createAnswer
()
->
toWire
());
ASSERT_EQ
(
1
,
server
.
getRootAddresses
().
size
());
...
...
@@ -210,12 +214,12 @@ TEST_F(ResolverConfig, timeouts) {
}
TEST_F
(
ResolverConfig
,
timeoutsConfig
)
{
ElementPtr
config
=
Element
::
fromJSON
(
"{"
"
\"
timeout_query
\"
: 1000,"
"
\"
timeout_client
\"
: 2000,"
"
\"
timeout_lookup
\"
: 3000,"
"
\"
retries
\"
: 4"
"}"
);
Const
ElementPtr
config
=
Element
::
fromJSON
(
"{"
"
\"
timeout_query
\"
: 1000,"
"
\"
timeout_client
\"
: 2000,"
"
\"
timeout_lookup
\"
: 3000,"
"
\"
retries
\"
: 4"
"}"
);
ConstElementPtr
result
(
server
.
updateConfig
(
config
));
EXPECT_EQ
(
result
->
toWire
(),
isc
::
config
::
createAnswer
()
->
toWire
());
EXPECT_EQ
(
1000
,
server
.
getQueryTimeout
());
...
...
@@ -253,51 +257,51 @@ TEST_F(ResolverConfig, invalidTimeoutsConfig) {
TEST_F
(
ResolverConfig
,
defaultQueryACL
)
{
// If no configuration is loaded, the default ACL should reject everything.
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Reques
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"2001:db8::1"
)));
create
Reques
t
(
"2001:db8::1"
)));
// The following would be allowed if the server had loaded the default
// configuration from the spec file. In this context it should not have
// happened, and they should be rejected just like the above cases.
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"127.0.0.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"::1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Reques
t
(
"127.0.0.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Reques
t
(
"::1"
)));
}
TEST_F
(
ResolverConfig
,
emptyQueryACL
)
{
// Explicitly configured empty ACL should have the same effect.
ElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: [] }"
));
Const
ElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: [] }"
));
ConstElementPtr
result
(
server
.
updateConfig
(
config
));
EXPECT_EQ
(
result
->
toWire
(),
isc
::
config
::
createAnswer
()
->
toWire
());
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Reques
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"2001:db8::1"
)));
create
Reques
t
(
"2001:db8::1"
)));
}
TEST_F
(
ResolverConfig
,
queryACLIPv4
)
{
// A simple "accept" query for a specific IPv4 address
ElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: "
" [ {
\"
action
\"
:
\"
ACCEPT
\"
,"
"
\"
from
\"
:
\"
192.0.2.1
\"
} ] }"
));
Const
ElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: "
" [ {
\"
action
\"
:
\"
ACCEPT
\"
,"
"
\"
from
\"
:
\"
192.0.2.1
\"
} ] }"
));
ConstElementPtr
result
(
server
.
updateConfig
(
config
));
EXPECT_EQ
(
result
->
toWire
(),
isc
::
config
::
createAnswer
()
->
toWire
());
EXPECT_EQ
(
ACCEPT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
ACCEPT
,
server
.
getQueryACL
().
execute
(
create
Reques
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"2001:db8::1"
)));
create
Reques
t
(
"2001:db8::1"
)));
}
TEST_F
(
ResolverConfig
,
queryACLIPv6
)
{
// same for IPv6
ElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: "
" [ {
\"
action
\"
:
\"
ACCEPT
\"
,"
"
\"
from
\"
:
\"
2001:db8::1
\"
} ] }"
));
Const
ElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: "
" [ {
\"
action
\"
:
\"
ACCEPT
\"
,"
"
\"
from
\"
:
\"
2001:db8::1
\"
} ] }"
));
ConstElementPtr
result
(
server
.
updateConfig
(
config
));
EXPECT_EQ
(
result
->
toWire
(),
isc
::
config
::
createAnswer
()
->
toWire
());
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Reques
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
ACCEPT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"2001:db8::1"
)));
create
Reques
t
(
"2001:db8::1"
)));
}
TEST_F
(
ResolverConfig
,
multiEntryACL
)
{
...
...
@@ -306,25 +310,26 @@ TEST_F(ResolverConfig, multiEntryACL) {
// as it should have been tested in the underlying ACL module. All we
// have to do to check is a reasonably complicated ACL configuration is
// loaded as expected.
ElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: "
" [ {
\"
action
\"
:
\"
ACCEPT
\"
,"
"
\"
from
\"
:
\"
192.0.2.1
\"
},"
" {
\"
action
\"
:
\"
REJECT
\"
,"
"
\"
from
\"
:
\"
192.0.2.0/24
\"
},"
" {
\"
action
\"
:
\"
DROP
\"
,"
"
\"
from
\"
:
\"
2001:db8::1
\"
},"
"] }"
));
Const
ElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: "
" [ {
\"
action
\"
:
\"
ACCEPT
\"
,"
"
\"
from
\"
:
\"
192.0.2.1
\"
},"
" {
\"
action
\"
:
\"
REJECT
\"
,"
"
\"
from
\"
:
\"
192.0.2.0/24
\"
},"
" {
\"
action
\"
:
\"
DROP
\"
,"
"
\"
from
\"
:
\"
2001:db8::1
\"
},"
"] }"
));
ConstElementPtr
result
(
server
.
updateConfig
(
config
));
EXPECT_EQ
(
result
->
toWire
(),
isc
::
config
::
createAnswer
()
->
toWire
());
EXPECT_EQ
(
ACCEPT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"192.0.2.2"
)));
EXPECT_EQ
(
ACCEPT
,
server
.
getQueryACL
().
execute
(
create
Reques
t
(
"192.0.2.1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Reques
t
(
"192.0.2.2"
)));
EXPECT_EQ
(
DROP
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"2001:db8::1"
)));
create
Reques
t
(
"2001:db8::1"
)));
EXPECT_EQ
(
REJECT
,
server
.
getQueryACL
().
execute
(
create
Clien
t
(
"2001:db8::2"
)));
// match the default rule
create
Reques
t
(
"2001:db8::2"
)));
// match the default rule
}
int
getResultCode
(
ConstElementPtr
result
)
{
int
rcode
;
...
...
@@ -332,6 +337,22 @@ getResultCode(ConstElementPtr result) {
return
(
rcode
);
}
TEST_F
(
ResolverConfig
,
queryACLActionOnly
)
{
// "action only" rule will be accepted by the loader, which can
// effectively change the default action.
ConstElementPtr
config
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
: "
" [ {
\"
action
\"
:
\"
ACCEPT
\"
,"
"
\"
from
\"
:
\"
192.0.2.1
\"
},"
" {
\"
action
\"
:
\"
DROP
\"
} ] }"
));
EXPECT_EQ
(
0
,
getResultCode
(
server
.
updateConfig
(
config
)));
EXPECT_EQ
(
ACCEPT
,
server
.
getQueryACL
().
execute
(
createRequest
(
"192.0.2.1"
)));
// We reject non matching queries by default, but the last resort
// rule should have changed the action in that case to "DROP".
EXPECT_EQ
(
DROP
,
server
.
getQueryACL
().
execute
(
createRequest
(
"192.0.2.2"
)));
}
TEST_F
(
ResolverConfig
,
badQueryACL
)
{
// Most of these cases shouldn't happen in practice because the syntax
// check should be performed before updateConfig(). But we check at
...
...
@@ -346,10 +367,6 @@ TEST_F(ResolverConfig, badQueryACL) {
server
.
updateConfig
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
:"
" [ {
\"
from
\"
:
\"
192.0.2.1
\"
} ] }"
))));
EXPECT_EQ
(
1
,
getResultCode
(
server
.
updateConfig
(
Element
::
fromJSON
(
"{
\"
query_acl
\"
:"
" [ {
\"
action
\"
:
\"
DROP
\"
} ] }"
))));
// invalid "action"
EXPECT_EQ
(
1
,
getResultCode
(
server
.
updateConfig
(
...
...
@@ -361,7 +378,6 @@ TEST_F(ResolverConfig, badQueryACL) {
Element
::
fromJSON
(
"{
\"
query_acl
\"
:"
" [ {
\"
action
\"
:
\"
BADACTION
\"
,"
"
\"
from
\"
:
\"
192.0.2.1
\"
}]}"
))));
// invalid "from"
EXPECT_EQ
(
1
,
getResultCode
(
server
.
updateConfig
(
...
...
src/bin/resolver/tests/resolver_unittest.cc
View file @
4c0d2595
...
...
@@ -27,6 +27,7 @@
using
namespace
std
;
using
namespace
isc
::
dns
;
using
namespace
isc
::
data
;
using
isc
::
acl
::
dns
::
RequestACL
;
using
namespace
isc
::
testutils
;
using
isc
::
UnitTestUtil
;
...
...
@@ -156,8 +157,7 @@ TEST_F(ResolverTest, notifyFail) {
TEST_F
(
ResolverTest
,
setQueryACL
)
{
// valid cases are tested through other tests. We only explicitly check
// an invalid case: passing a NULL shared pointer.
EXPECT_THROW
(
server
.
setQueryACL
(
boost
::
shared_ptr
<
const
Resolver
::
ClientACL
>
()),
EXPECT_THROW
(
server
.
setQueryACL
(
boost
::
shared_ptr
<
const
RequestACL
>
()),
isc
::
InvalidParameter
);
}
...
...
src/lib/acl/dns.cc
View file @
4c0d2595
...
...
@@ -12,20 +12,97 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include
"dns.h"
#include
<memory>
#include
<string>
#include
<vector>
#include
<boost/shared_ptr.hpp>
#include
<exceptions/exceptions.h>
#include
<cc/data.h>
#include
<acl/dns.h>
#include
<acl/ip_check.h>
#include
<acl/loader.h>
using
namespace
std
;
using
boost
::
shared_ptr
;
using
namespace
isc
::
data
;
namespace
isc
{
namespace
acl
{
/// The specialization of \c IPCheck for access control with \c RequestContext.
///
/// It returns \c true if the remote (source) IP address of the request
/// matches the expression encapsulated in the \c IPCheck, and returns
/// \c false if not.
///
/// \note The match logic is expected to be extended as we add
/// more match parameters (at least there's a plan for TSIG key).
template
<
>
bool
IPCheck
<
dns
::
RequestContext
>::
matches
(
const
dns
::
RequestContext
&
request
)
const
{
return
(
compare
(
request
.
remote_address
.
getData
(),
request
.
remote_address
.
getFamily
()));
}
namespace
dns
{
Loader
&
getLoader
()
{
static
Loader
*
loader
(
NULL
);
vector
<
string
>
internal
::
RequestCheckCreator
::
names
()
const
{
// Probably we should eventually build this vector in a more
// sophisticated way. For now, it's simple enough to hardcode
// everything.
vector
<
string
>
supported_names
;
supported_names
.
push_back
(
"from"
);
return
(
supported_names
);
}
shared_ptr
<
RequestCheck
>
internal
::
RequestCheckCreator
::
create
(
const
string
&
name
,
ConstElementPtr
definition
,
// unused:
const
acl
::
Loader
<
RequestContext
>&
)
{
if
(
!
definition
)
{
isc_throw
(
LoaderError
,
"NULL pointer is passed to RequestCheckCreator"
);
}
if
(
name
==
"from"
)
{
return
(
shared_ptr
<
internal
::
RequestIPCheck
>
(
new
internal
::
RequestIPCheck
(
definition
->
stringValue
())));
}
else
{
// This case shouldn't happen (normally) as it should have been
// rejected at the loader level. But we explicitly catch the case
// and throw an exception for that.
isc_throw
(
LoaderError
,
"Invalid check name for RequestCheck: "
<<
name
);
}
}
RequestLoader
&
getRequestLoader
()
{
static
RequestLoader
*
loader
(
NULL
);
if
(
loader
==
NULL
)
{
loader
=
new
Loader
(
REJECT
);
// TODO: This is the place where we register default check creators
// like IP check, etc, once we have them.
// Creator registration may throw, so we first store the new loader
// in an auto pointer in order to provide the strong exception
// guarantee.
auto_ptr
<
RequestLoader
>
loader_ptr
=
auto_ptr
<
RequestLoader
>
(
new
RequestLoader
(
REJECT
));
// Register default check creator(s)
loader_ptr
->
registerCreator
(
shared_ptr
<
internal
::
RequestCheckCreator
>
(
new
internal
::
RequestCheckCreator
()));
// From this point there shouldn't be any exception thrown
loader
=
loader_ptr
.
release
();
}
return
(
*
loader
);
}
...
...
src/lib/acl/dns.h
View file @
4c0d2595
...
...
@@ -13,12 +13,17 @@
// PERFORMANCE OF THIS SOFTWARE.
#ifndef ACL_DNS_H
#define ACL_DNS_H
#define ACL_DNS_H
1
#include
"loader.h"
#include
<string>
#include
<vector>
#include
<asiolink/io_address.h>
#include
<dns/message.h>
#include
<boost/shared_ptr.hpp>
#include
<cc/data.h>
#include
<acl/ip_check.h>
#include
<acl/loader.h>
namespace
isc
{
namespace
acl
{
...
...
@@ -30,47 +35,65 @@ namespace dns {
* This plays the role of Context of the generic template ACLs (in namespace
* isc::acl).
*
* It is simple structure holding just the bunch of information. Therefore
* the names don't end up with a slash, there are no methods so they can't be
* confused with local variables.
* It is a simple structure holding just the bunch of information. Therefore
* the names don't end up with an underscore; there are no methods so they
* can't be confused with local variables.
*
* This structure is generally expected to be ephemeral and read-only: It
* would be constructed immediately before a particular ACL is checked