• 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 #include "src/core/lib/security/authorization/matchers.h"
16 
17 #include <grpc/grpc_security_constants.h>
18 #include <grpc/support/port_platform.h>
19 #include <string.h>
20 
21 #include <string>
22 
23 #include "absl/log/log.h"
24 #include "absl/status/status.h"
25 #include "absl/status/statusor.h"
26 #include "absl/strings/string_view.h"
27 #include "src/core/lib/address_utils/parse_address.h"
28 #include "src/core/lib/address_utils/sockaddr_utils.h"
29 
30 namespace grpc_core {
31 
Create(Rbac::Permission permission)32 std::unique_ptr<AuthorizationMatcher> AuthorizationMatcher::Create(
33     Rbac::Permission permission) {
34   switch (permission.type) {
35     case Rbac::Permission::RuleType::kAnd: {
36       std::vector<std::unique_ptr<AuthorizationMatcher>> matchers;
37       matchers.reserve(permission.permissions.size());
38       for (const auto& rule : permission.permissions) {
39         matchers.push_back(AuthorizationMatcher::Create(std::move(*rule)));
40       }
41       return std::make_unique<AndAuthorizationMatcher>(std::move(matchers));
42     }
43     case Rbac::Permission::RuleType::kOr: {
44       std::vector<std::unique_ptr<AuthorizationMatcher>> matchers;
45       matchers.reserve(permission.permissions.size());
46       for (const auto& rule : permission.permissions) {
47         matchers.push_back(AuthorizationMatcher::Create(std::move(*rule)));
48       }
49       return std::make_unique<OrAuthorizationMatcher>(std::move(matchers));
50     }
51     case Rbac::Permission::RuleType::kNot:
52       return std::make_unique<NotAuthorizationMatcher>(
53           AuthorizationMatcher::Create(std::move(*permission.permissions[0])));
54     case Rbac::Permission::RuleType::kAny:
55       return std::make_unique<AlwaysAuthorizationMatcher>();
56     case Rbac::Permission::RuleType::kHeader:
57       return std::make_unique<HeaderAuthorizationMatcher>(
58           std::move(permission.header_matcher));
59     case Rbac::Permission::RuleType::kPath:
60       return std::make_unique<PathAuthorizationMatcher>(
61           std::move(permission.string_matcher));
62     case Rbac::Permission::RuleType::kDestIp:
63       return std::make_unique<IpAuthorizationMatcher>(
64           IpAuthorizationMatcher::Type::kDestIp, std::move(permission.ip));
65     case Rbac::Permission::RuleType::kDestPort:
66       return std::make_unique<PortAuthorizationMatcher>(permission.port);
67     case Rbac::Permission::RuleType::kMetadata:
68       return std::make_unique<MetadataAuthorizationMatcher>(permission.invert);
69     case Rbac::Permission::RuleType::kReqServerName:
70       return std::make_unique<ReqServerNameAuthorizationMatcher>(
71           std::move(permission.string_matcher));
72   }
73   return nullptr;
74 }
75 
Create(Rbac::Principal principal)76 std::unique_ptr<AuthorizationMatcher> AuthorizationMatcher::Create(
77     Rbac::Principal principal) {
78   switch (principal.type) {
79     case Rbac::Principal::RuleType::kAnd: {
80       std::vector<std::unique_ptr<AuthorizationMatcher>> matchers;
81       matchers.reserve(principal.principals.size());
82       for (const auto& id : principal.principals) {
83         matchers.push_back(AuthorizationMatcher::Create(std::move(*id)));
84       }
85       return std::make_unique<AndAuthorizationMatcher>(std::move(matchers));
86     }
87     case Rbac::Principal::RuleType::kOr: {
88       std::vector<std::unique_ptr<AuthorizationMatcher>> matchers;
89       matchers.reserve(principal.principals.size());
90       for (const auto& id : principal.principals) {
91         matchers.push_back(AuthorizationMatcher::Create(std::move(*id)));
92       }
93       return std::make_unique<OrAuthorizationMatcher>(std::move(matchers));
94     }
95     case Rbac::Principal::RuleType::kNot:
96       return std::make_unique<NotAuthorizationMatcher>(
97           AuthorizationMatcher::Create(std::move(*principal.principals[0])));
98     case Rbac::Principal::RuleType::kAny:
99       return std::make_unique<AlwaysAuthorizationMatcher>();
100     case Rbac::Principal::RuleType::kPrincipalName:
101       return std::make_unique<AuthenticatedAuthorizationMatcher>(
102           std::move(principal.string_matcher));
103     case Rbac::Principal::RuleType::kSourceIp:
104       return std::make_unique<IpAuthorizationMatcher>(
105           IpAuthorizationMatcher::Type::kSourceIp, std::move(principal.ip));
106     case Rbac::Principal::RuleType::kDirectRemoteIp:
107       return std::make_unique<IpAuthorizationMatcher>(
108           IpAuthorizationMatcher::Type::kDirectRemoteIp,
109           std::move(principal.ip));
110     case Rbac::Principal::RuleType::kRemoteIp:
111       return std::make_unique<IpAuthorizationMatcher>(
112           IpAuthorizationMatcher::Type::kRemoteIp, std::move(principal.ip));
113     case Rbac::Principal::RuleType::kHeader:
114       return std::make_unique<HeaderAuthorizationMatcher>(
115           std::move(principal.header_matcher));
116     case Rbac::Principal::RuleType::kPath:
117       return std::make_unique<PathAuthorizationMatcher>(
118           std::move(principal.string_matcher.value()));
119     case Rbac::Principal::RuleType::kMetadata:
120       return std::make_unique<MetadataAuthorizationMatcher>(principal.invert);
121   }
122   return nullptr;
123 }
124 
Matches(const EvaluateArgs & args) const125 bool AndAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
126   for (const auto& matcher : matchers_) {
127     if (!matcher->Matches(args)) {
128       return false;
129     }
130   }
131   return true;
132 }
133 
Matches(const EvaluateArgs & args) const134 bool OrAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
135   for (const auto& matcher : matchers_) {
136     if (matcher->Matches(args)) {
137       return true;
138     }
139   }
140   return false;
141 }
142 
Matches(const EvaluateArgs & args) const143 bool NotAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
144   return !matcher_->Matches(args);
145 }
146 
Matches(const EvaluateArgs & args) const147 bool HeaderAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
148   std::string concatenated_value;
149   return matcher_.Match(
150       args.GetHeaderValue(matcher_.name(), &concatenated_value));
151 }
152 
IpAuthorizationMatcher(Type type,Rbac::CidrRange range)153 IpAuthorizationMatcher::IpAuthorizationMatcher(Type type, Rbac::CidrRange range)
154     : type_(type), prefix_len_(range.prefix_len) {
155   auto address =
156       StringToSockaddr(range.address_prefix, 0);  // Port does not matter here.
157   if (!address.ok()) {
158     VLOG(2) << "CidrRange address \"" << range.address_prefix
159             << "\" is not IPv4/IPv6. Error: " << address.status();
160     memset(&subnet_address_, 0, sizeof(subnet_address_));
161     return;
162   }
163   subnet_address_ = *address;
164   grpc_sockaddr_mask_bits(&subnet_address_, prefix_len_);
165 }
166 
Matches(const EvaluateArgs & args) const167 bool IpAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
168   grpc_resolved_address address;
169   switch (type_) {
170     case Type::kDestIp: {
171       address = args.GetLocalAddress();
172       break;
173     }
174     case Type::kSourceIp:
175     case Type::kDirectRemoteIp:
176     case Type::kRemoteIp: {
177       address = args.GetPeerAddress();
178       break;
179     }
180     default:
181       return false;
182   }
183   return grpc_sockaddr_match_subnet(&address, &subnet_address_, prefix_len_);
184 }
185 
Matches(const EvaluateArgs & args) const186 bool PortAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
187   return port_ == args.GetLocalPort();
188 }
189 
Matches(const EvaluateArgs & args) const190 bool AuthenticatedAuthorizationMatcher::Matches(
191     const EvaluateArgs& args) const {
192   if (args.GetTransportSecurityType() != GRPC_SSL_TRANSPORT_SECURITY_TYPE &&
193       args.GetTransportSecurityType() != GRPC_TLS_TRANSPORT_SECURITY_TYPE) {
194     // Connection is not authenticated.
195     return false;
196   }
197   if (!matcher_.has_value()) {
198     // Allows any authenticated user.
199     return true;
200   }
201   std::vector<absl::string_view> uri_sans = args.GetUriSans();
202   if (!uri_sans.empty()) {
203     for (const auto& uri : uri_sans) {
204       if (matcher_->Match(uri)) {
205         return true;
206       }
207     }
208   }
209   std::vector<absl::string_view> dns_sans = args.GetDnsSans();
210   if (!dns_sans.empty()) {
211     for (const auto& dns : dns_sans) {
212       if (matcher_->Match(dns)) {
213         return true;
214       }
215     }
216   }
217   return matcher_->Match(args.GetSubject());
218 }
219 
Matches(const EvaluateArgs &) const220 bool ReqServerNameAuthorizationMatcher::Matches(const EvaluateArgs&) const {
221   // Currently we only support matching against an empty string.
222   return matcher_.Match("");
223 }
224 
Matches(const EvaluateArgs & args) const225 bool PathAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
226   absl::string_view path = args.GetPath();
227   if (!path.empty()) {
228     return matcher_.Match(path);
229   }
230   return false;
231 }
232 
Matches(const EvaluateArgs & args) const233 bool PolicyAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
234   return permissions_->Matches(args) && principals_->Matches(args);
235 }
236 
237 }  // namespace grpc_core
238