• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H
16 #define GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <memory>
21 
22 #include "src/core/lib/matchers/matchers.h"
23 #include "src/core/lib/security/authorization/evaluate_args.h"
24 #include "src/core/lib/security/authorization/rbac_policy.h"
25 
26 namespace grpc_core {
27 
28 // Describes the rules for matching permission or principal.
29 class AuthorizationMatcher {
30  public:
31   virtual ~AuthorizationMatcher() = default;
32 
33   // Returns whether or not the permission/principal matches the rules of the
34   // matcher.
35   virtual bool Matches(const EvaluateArgs& args) const = 0;
36 
37   // Creates an instance of a matcher based off the rules defined in Permission
38   // config.
39   static std::unique_ptr<AuthorizationMatcher> Create(
40       Rbac::Permission permission);
41 
42   // Creates an instance of a matcher based off the rules defined in Principal
43   // config.
44   static std::unique_ptr<AuthorizationMatcher> Create(
45       Rbac::Principal principal);
46 };
47 
48 class AlwaysAuthorizationMatcher : public AuthorizationMatcher {
49  public:
50   explicit AlwaysAuthorizationMatcher(bool not_rule = false)
not_rule_(not_rule)51       : not_rule_(not_rule) {}
52 
Matches(const EvaluateArgs &)53   bool Matches(const EvaluateArgs&) const override { return !not_rule_; }
54 
55  private:
56   // Negates matching the provided permission/principal.
57   const bool not_rule_;
58 };
59 
60 class AndAuthorizationMatcher : public AuthorizationMatcher {
61  public:
62   explicit AndAuthorizationMatcher(
63       std::vector<std::unique_ptr<Rbac::Permission>> rules,
64       bool not_rule = false);
65   explicit AndAuthorizationMatcher(
66       std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule = false);
67 
68   bool Matches(const EvaluateArgs& args) const override;
69 
70  private:
71   std::vector<std::unique_ptr<AuthorizationMatcher>> matchers_;
72   // Negates matching the provided permission/principal.
73   const bool not_rule_;
74 };
75 
76 class OrAuthorizationMatcher : public AuthorizationMatcher {
77  public:
78   explicit OrAuthorizationMatcher(
79       std::vector<std::unique_ptr<Rbac::Permission>> rules,
80       bool not_rule = false);
81   explicit OrAuthorizationMatcher(
82       std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule = false);
83 
84   bool Matches(const EvaluateArgs& args) const override;
85 
86  private:
87   std::vector<std::unique_ptr<AuthorizationMatcher>> matchers_;
88   // Negates matching the provided permission/principal.
89   const bool not_rule_;
90 };
91 
92 // TODO(ashithasantosh): Add matcher implementation for metadata field.
93 
94 // Perform a match against HTTP headers.
95 class HeaderAuthorizationMatcher : public AuthorizationMatcher {
96  public:
97   explicit HeaderAuthorizationMatcher(HeaderMatcher matcher,
98                                       bool not_rule = false)
matcher_(std::move (matcher))99       : matcher_(std::move(matcher)), not_rule_(not_rule) {}
100 
101   bool Matches(const EvaluateArgs& args) const override;
102 
103  private:
104   const HeaderMatcher matcher_;
105   // Negates matching the provided permission/principal.
106   const bool not_rule_;
107 };
108 
109 // Perform a match against IP Cidr Range.
110 // TODO(ashithasantosh): Handle type of Ip or use seperate matchers for each
111 // type. Implement Match functionality, this would require updating EvaluateArgs
112 // getters, to return format of IP as well.
113 class IpAuthorizationMatcher : public AuthorizationMatcher {
114  public:
115   explicit IpAuthorizationMatcher(Rbac::CidrRange range, bool not_rule = false)
range_(std::move (range))116       : range_(std::move(range)), not_rule_(not_rule) {}
117 
118   bool Matches(const EvaluateArgs&) const override;
119 
120  private:
121   const Rbac::CidrRange range_;
122   // Negates matching the provided permission/principal.
123   const bool not_rule_;
124 };
125 
126 // Perform a match against port number of the destination (local) address.
127 class PortAuthorizationMatcher : public AuthorizationMatcher {
128  public:
129   explicit PortAuthorizationMatcher(int port, bool not_rule = false)
port_(port)130       : port_(port), not_rule_(not_rule) {}
131 
132   bool Matches(const EvaluateArgs& args) const override;
133 
134  private:
135   const int port_;
136   // Negates matching the provided permission/principal.
137   const bool not_rule_;
138 };
139 
140 // Matches the principal name as described in the peer certificate. Uses URI SAN
141 // or DNS SAN in that order, otherwise uses subject field.
142 class AuthenticatedAuthorizationMatcher : public AuthorizationMatcher {
143  public:
144   explicit AuthenticatedAuthorizationMatcher(StringMatcher auth,
145                                              bool not_rule = false)
matcher_(std::move (auth))146       : matcher_(std::move(auth)), not_rule_(not_rule) {}
147 
148   bool Matches(const EvaluateArgs& args) const override;
149 
150  private:
151   const StringMatcher matcher_;
152   // Negates matching the provided permission/principal.
153   const bool not_rule_;
154 };
155 
156 // Perform a match against the request server from the client's connection
157 // request. This is typically TLS SNI. Currently unsupported.
158 class ReqServerNameAuthorizationMatcher : public AuthorizationMatcher {
159  public:
160   explicit ReqServerNameAuthorizationMatcher(
161       StringMatcher requested_server_name, bool not_rule = false)
matcher_(std::move (requested_server_name))162       : matcher_(std::move(requested_server_name)), not_rule_(not_rule) {}
163 
164   bool Matches(const EvaluateArgs&) const override;
165 
166  private:
167   const StringMatcher matcher_;
168   // Negates matching the provided permission/principal.
169   const bool not_rule_;
170 };
171 
172 // Perform a match against the path header of HTTP request.
173 class PathAuthorizationMatcher : public AuthorizationMatcher {
174  public:
175   explicit PathAuthorizationMatcher(StringMatcher path, bool not_rule = false)
matcher_(std::move (path))176       : matcher_(std::move(path)), not_rule_(not_rule) {}
177 
178   bool Matches(const EvaluateArgs& args) const override;
179 
180  private:
181   const StringMatcher matcher_;
182   // Negates matching the provided permission/principal.
183   const bool not_rule_;
184 };
185 
186 // Performs a match for policy field in RBAC, which is a collection of
187 // permission and principal matchers. Policy matches iff, we find a match in one
188 // of its permissions and a match in one of its principals.
189 class PolicyAuthorizationMatcher : public AuthorizationMatcher {
190  public:
PolicyAuthorizationMatcher(Rbac::Policy policy)191   explicit PolicyAuthorizationMatcher(Rbac::Policy policy)
192       : permissions_(
193             AuthorizationMatcher::Create(std::move(policy.permissions))),
194         principals_(
195             AuthorizationMatcher::Create(std::move(policy.principals))) {}
196 
197   bool Matches(const EvaluateArgs& args) const override;
198 
199  private:
200   std::unique_ptr<AuthorizationMatcher> permissions_;
201   std::unique_ptr<AuthorizationMatcher> principals_;
202 };
203 
204 }  // namespace grpc_core
205 
206 #endif  // GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H
207