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