• 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 <grpc/support/port_platform.h>
16 
17 #include "src/core/lib/security/authorization/evaluate_args.h"
18 
19 #include "src/core/lib/address_utils/parse_address.h"
20 #include "src/core/lib/gprpp/host_port.h"
21 #include "src/core/lib/slice/slice_utils.h"
22 
23 namespace grpc_core {
24 
25 namespace {
26 
GetAuthPropertyValue(grpc_auth_context * context,const char * property_name)27 absl::string_view GetAuthPropertyValue(grpc_auth_context* context,
28                                        const char* property_name) {
29   grpc_auth_property_iterator it =
30       grpc_auth_context_find_properties_by_name(context, property_name);
31   const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it);
32   if (prop == nullptr) {
33     gpr_log(GPR_DEBUG, "No value found for %s property.", property_name);
34     return "";
35   }
36   if (grpc_auth_property_iterator_next(&it) != nullptr) {
37     gpr_log(GPR_DEBUG, "Multiple values found for %s property.", property_name);
38     return "";
39   }
40   return absl::string_view(prop->value, prop->value_length);
41 }
42 
ParseEndpointUri(absl::string_view uri_text,std::string * address,int * port)43 void ParseEndpointUri(absl::string_view uri_text, std::string* address,
44                       int* port) {
45   absl::StatusOr<URI> uri = URI::Parse(uri_text);
46   if (!uri.ok()) {
47     gpr_log(GPR_DEBUG, "Failed to parse uri.");
48     return;
49   }
50   absl::string_view host_view;
51   absl::string_view port_view;
52   if (!SplitHostPort(uri->path(), &host_view, &port_view)) {
53     gpr_log(GPR_DEBUG, "Failed to split %s into host and port.",
54             uri->path().c_str());
55     return;
56   }
57   *address = std::string(host_view);
58   if (!absl::SimpleAtoi(port_view, port)) {
59     gpr_log(GPR_DEBUG, "Port %s is out of range or null.",
60             std::string(port_view).c_str());
61   }
62 }
63 
64 }  // namespace
65 
PerChannelArgs(grpc_auth_context * auth_context,grpc_endpoint * endpoint)66 EvaluateArgs::PerChannelArgs::PerChannelArgs(grpc_auth_context* auth_context,
67                                              grpc_endpoint* endpoint) {
68   if (auth_context != nullptr) {
69     transport_security_type = GetAuthPropertyValue(
70         auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
71     spiffe_id =
72         GetAuthPropertyValue(auth_context, GRPC_PEER_SPIFFE_ID_PROPERTY_NAME);
73     common_name =
74         GetAuthPropertyValue(auth_context, GRPC_X509_CN_PROPERTY_NAME);
75   }
76   if (endpoint != nullptr) {
77     ParseEndpointUri(grpc_endpoint_get_local_address(endpoint), &local_address,
78                      &local_port);
79     ParseEndpointUri(grpc_endpoint_get_peer(endpoint), &peer_address,
80                      &peer_port);
81   }
82 }
83 
GetPath() const84 absl::string_view EvaluateArgs::GetPath() const {
85   absl::string_view path;
86   if (metadata_ != nullptr && metadata_->idx.named.path != nullptr) {
87     grpc_linked_mdelem* elem = metadata_->idx.named.path;
88     const grpc_slice& val = GRPC_MDVALUE(elem->md);
89     path = StringViewFromSlice(val);
90   }
91   return path;
92 }
93 
GetHost() const94 absl::string_view EvaluateArgs::GetHost() const {
95   absl::string_view host;
96   if (metadata_ != nullptr && metadata_->idx.named.host != nullptr) {
97     grpc_linked_mdelem* elem = metadata_->idx.named.host;
98     const grpc_slice& val = GRPC_MDVALUE(elem->md);
99     host = StringViewFromSlice(val);
100   }
101   return host;
102 }
103 
GetMethod() const104 absl::string_view EvaluateArgs::GetMethod() const {
105   absl::string_view method;
106   if (metadata_ != nullptr && metadata_->idx.named.method != nullptr) {
107     grpc_linked_mdelem* elem = metadata_->idx.named.method;
108     const grpc_slice& val = GRPC_MDVALUE(elem->md);
109     method = StringViewFromSlice(val);
110   }
111   return method;
112 }
113 
GetHeaders() const114 std::multimap<absl::string_view, absl::string_view> EvaluateArgs::GetHeaders()
115     const {
116   std::multimap<absl::string_view, absl::string_view> headers;
117   if (metadata_ == nullptr) {
118     return headers;
119   }
120   for (grpc_linked_mdelem* elem = metadata_->list.head; elem != nullptr;
121        elem = elem->next) {
122     const grpc_slice& key = GRPC_MDKEY(elem->md);
123     const grpc_slice& val = GRPC_MDVALUE(elem->md);
124     headers.emplace(StringViewFromSlice(key), StringViewFromSlice(val));
125   }
126   return headers;
127 }
128 
GetHeaderValue(absl::string_view key,std::string * concatenated_value) const129 absl::optional<absl::string_view> EvaluateArgs::GetHeaderValue(
130     absl::string_view key, std::string* concatenated_value) const {
131   if (metadata_ == nullptr) {
132     return absl::nullopt;
133   }
134   return grpc_metadata_batch_get_value(metadata_, key, concatenated_value);
135 }
136 
GetLocalAddress() const137 absl::string_view EvaluateArgs::GetLocalAddress() const {
138   if (channel_args_ == nullptr) {
139     return "";
140   }
141   return channel_args_->local_address;
142 }
143 
GetLocalPort() const144 int EvaluateArgs::GetLocalPort() const {
145   if (channel_args_ == nullptr) {
146     return 0;
147   }
148   return channel_args_->local_port;
149 }
150 
GetPeerAddress() const151 absl::string_view EvaluateArgs::GetPeerAddress() const {
152   if (channel_args_ == nullptr) {
153     return "";
154   }
155   return channel_args_->peer_address;
156 }
157 
GetPeerPort() const158 int EvaluateArgs::GetPeerPort() const {
159   if (channel_args_ == nullptr) {
160     return 0;
161   }
162   return channel_args_->peer_port;
163 }
164 
GetTransportSecurityType() const165 absl::string_view EvaluateArgs::GetTransportSecurityType() const {
166   if (channel_args_ == nullptr) {
167     return "";
168   }
169   return channel_args_->transport_security_type;
170 }
171 
GetSpiffeId() const172 absl::string_view EvaluateArgs::GetSpiffeId() const {
173   if (channel_args_ == nullptr) {
174     return "";
175   }
176   return channel_args_->spiffe_id;
177 }
178 
GetCommonName() const179 absl::string_view EvaluateArgs::GetCommonName() const {
180   if (channel_args_ == nullptr) {
181     return "";
182   }
183   return channel_args_->common_name;
184 }
185 
186 }  // namespace grpc_core
187