Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #include <memory>
16 : : #include <string>
17 : : #include <vector>
18 : :
19 : : #include <boost/shared_ptr.hpp>
20 : :
21 : : #include <exceptions/exceptions.h>
22 : :
23 : : #include <dns/name.h>
24 : : #include <dns/tsigrecord.h>
25 : :
26 : : #include <cc/data.h>
27 : :
28 : : #include <acl/dns.h>
29 : : #include <acl/ip_check.h>
30 : : #include <acl/dnsname_check.h>
31 : : #include <acl/loader.h>
32 : : #include <acl/logic_check.h>
33 : :
34 : : using namespace std;
35 : : using namespace isc::dns;
36 : : using namespace isc::data;
37 : :
38 : : namespace isc {
39 : : namespace acl {
40 : :
41 : : /// The specialization of \c IPCheck for access control with \c RequestContext.
42 : : ///
43 : : /// It returns \c true if the remote (source) IP address of the request
44 : : /// matches the expression encapsulated in the \c IPCheck, and returns
45 : : /// \c false if not.
46 : : template <>
47 : : bool
48 : 94 : IPCheck<dns::RequestContext>::matches(
49 : : const dns::RequestContext& request) const
50 : : {
51 : : return (compare(request.remote_address.getData(),
52 : 94 : request.remote_address.getFamily()));
53 : : }
54 : :
55 : : namespace dns {
56 : :
57 : : /// The specialization of \c NameCheck for access control with
58 : : /// \c RequestContext.
59 : : ///
60 : : /// It returns \c true if the request contains a TSIG record and its key
61 : : /// (owner) name is equal to the name stored in the check; otherwise
62 : : /// it returns \c false.
63 : : template<>
64 : : bool
65 : 35 : NameCheck<RequestContext>::matches(const RequestContext& request) const {
66 [ + + + + ]: 55 : return (request.tsig != NULL && request.tsig->getName() == name_);
67 : : }
68 : :
69 : : vector<string>
70 : 5 : internal::RequestCheckCreator::names() const {
71 : : // Probably we should eventually build this vector in a more
72 : : // sophisticated way. For now, it's simple enough to hardcode
73 : : // everything.
74 : 0 : vector<string> supported_names;
75 [ + - ][ + - ]: 5 : supported_names.push_back("from");
76 [ + - ][ + - ]: 5 : supported_names.push_back("key");
77 : 5 : return (supported_names);
78 : : }
79 : :
80 : : boost::shared_ptr<RequestCheck>
81 : 159 : internal::RequestCheckCreator::create(const string& name,
82 : : ConstElementPtr definition,
83 : : // unused:
84 : : const acl::Loader<RequestContext>&)
85 : : {
86 [ + + ]: 159 : if (!definition) {
87 [ + - ][ + - ]: 3 : isc_throw(LoaderError,
88 : : "NULL pointer is passed to RequestCheckCreator");
89 : : }
90 : :
91 [ + + ]: 158 : if (name == "from") {
92 : : return (boost::shared_ptr<internal::RequestIPCheck>(
93 [ + - ][ + + ]: 209 : new internal::RequestIPCheck(definition->stringValue())));
94 [ + + ]: 37 : } else if (name == "key") {
95 : : return (boost::shared_ptr<internal::RequestKeyCheck>(
96 : : new internal::RequestKeyCheck(
97 [ + + ][ + - ]: 63 : Name(definition->stringValue()))));
98 : : } else {
99 : : // This case shouldn't happen (normally) as it should have been
100 : : // rejected at the loader level. But we explicitly catch the case
101 : : // and throw an exception for that.
102 [ + - ][ + - ]: 118 : isc_throw(LoaderError, "Invalid check name for RequestCheck: " <<
[ + - ]
103 : : name);
104 : : }
105 : : }
106 : :
107 : : RequestLoader&
108 : 93 : getRequestLoader() {
109 : : static RequestLoader* loader(NULL);
110 [ + + ]: 93 : if (loader == NULL) {
111 : : // Creator registration may throw, so we first store the new loader
112 : : // in an auto pointer in order to provide the strong exception
113 : : // guarantee.
114 : : auto_ptr<RequestLoader> loader_ptr =
115 [ + - ][ + - ]: 12 : auto_ptr<RequestLoader>(new RequestLoader(REJECT));
[ + - ]
116 : :
117 : : // Register default check creator(s)
118 : : loader_ptr->registerCreator(
119 : : boost::shared_ptr<internal::RequestCheckCreator>(
120 [ + - ][ + - ]: 8 : new internal::RequestCheckCreator()));
121 : : loader_ptr->registerCreator(
122 : : boost::shared_ptr<NotCreator<RequestContext> >(
123 [ + - ][ + - ]: 12 : new NotCreator<RequestContext>("NOT")));
[ + - ]
124 : : loader_ptr->registerCreator(
125 : : boost::shared_ptr<LogicCreator<AnyOfSpec, RequestContext> >(
126 [ + - ][ + - ]: 12 : new LogicCreator<AnyOfSpec, RequestContext>("ANY")));
[ + - ]
127 : : loader_ptr->registerCreator(
128 : : boost::shared_ptr<LogicCreator<AllOfSpec, RequestContext> >(
129 [ + - ][ + - ]: 12 : new LogicCreator<AllOfSpec, RequestContext>("ALL")));
[ + - ]
130 : :
131 : : // From this point there shouldn't be any exception thrown
132 : 4 : loader = loader_ptr.release();
133 : : }
134 : :
135 : 93 : return (*loader);
136 : : }
137 : :
138 : : }
139 : : }
140 : 4 : }
|