• 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/evaluate_args.h"
16 
17 #include <grpc/grpc_security_constants.h>
18 #include <grpc/support/port_platform.h>
19 #include <string.h>
20 
21 #include "absl/log/log.h"
22 #include "absl/status/status.h"
23 #include "absl/status/statusor.h"
24 #include "absl/strings/match.h"
25 #include "absl/strings/numbers.h"
26 #include "src/core/handshaker/endpoint_info/endpoint_info_handshaker.h"
27 #include "src/core/lib/address_utils/parse_address.h"
28 #include "src/core/lib/security/credentials/tls/tls_utils.h"
29 #include "src/core/lib/slice/slice.h"
30 #include "src/core/util/host_port.h"
31 #include "src/core/util/uri.h"
32 
33 namespace grpc_core {
34 
35 namespace {
36 
ParseEndpointUri(absl::string_view uri_text)37 EvaluateArgs::PerChannelArgs::Address ParseEndpointUri(
38     absl::string_view uri_text) {
39   EvaluateArgs::PerChannelArgs::Address address;
40   absl::StatusOr<URI> uri = URI::Parse(uri_text);
41   if (!uri.ok()) {
42     VLOG(2) << "Failed to parse uri.";
43     return address;
44   }
45   absl::string_view host_view;
46   absl::string_view port_view;
47   if (!SplitHostPort(uri->path(), &host_view, &port_view)) {
48     VLOG(2) << "Failed to split " << uri->path() << " into host and port.";
49     return address;
50   }
51   if (!absl::SimpleAtoi(port_view, &address.port)) {
52     VLOG(2) << "Port " << port_view << " is out of range or null.";
53   }
54   address.address_str = std::string(host_view);
55   auto resolved_address = StringToSockaddr(uri->path());
56   if (!resolved_address.ok()) {
57     VLOG(2) << "Address \"" << uri->path()
58             << "\" is not IPv4/IPv6. Error: " << resolved_address.status();
59     memset(&address.address, 0, sizeof(address.address));
60   } else {
61     address.address = *resolved_address;
62   }
63   return address;
64 }
65 
66 }  // namespace
67 
PerChannelArgs(grpc_auth_context * auth_context,const ChannelArgs & args)68 EvaluateArgs::PerChannelArgs::PerChannelArgs(grpc_auth_context* auth_context,
69                                              const ChannelArgs& args) {
70   if (auth_context != nullptr) {
71     transport_security_type = GetAuthPropertyValue(
72         auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
73     spiffe_id =
74         GetAuthPropertyValue(auth_context, GRPC_PEER_SPIFFE_ID_PROPERTY_NAME);
75     uri_sans = GetAuthPropertyArray(auth_context, GRPC_PEER_URI_PROPERTY_NAME);
76     dns_sans = GetAuthPropertyArray(auth_context, GRPC_PEER_DNS_PROPERTY_NAME);
77     common_name =
78         GetAuthPropertyValue(auth_context, GRPC_X509_CN_PROPERTY_NAME);
79     subject =
80         GetAuthPropertyValue(auth_context, GRPC_X509_SUBJECT_PROPERTY_NAME);
81   }
82   local_address = ParseEndpointUri(
83       args.GetString(GRPC_ARG_ENDPOINT_LOCAL_ADDRESS).value_or(""));
84   peer_address = ParseEndpointUri(
85       args.GetString(GRPC_ARG_ENDPOINT_PEER_ADDRESS).value_or(""));
86 }
87 
GetPath() const88 absl::string_view EvaluateArgs::GetPath() const {
89   if (metadata_ != nullptr) {
90     const auto* path = metadata_->get_pointer(HttpPathMetadata());
91     if (path != nullptr) {
92       return path->as_string_view();
93     }
94   }
95   return absl::string_view();
96 }
97 
GetAuthority() const98 absl::string_view EvaluateArgs::GetAuthority() const {
99   absl::string_view authority;
100   if (metadata_ != nullptr) {
101     if (auto* authority_md = metadata_->get_pointer(HttpAuthorityMetadata())) {
102       authority = authority_md->as_string_view();
103     }
104   }
105   return authority;
106 }
107 
GetMethod() const108 absl::string_view EvaluateArgs::GetMethod() const {
109   if (metadata_ != nullptr) {
110     auto method_md = metadata_->get(HttpMethodMetadata());
111     if (method_md.has_value()) {
112       return HttpMethodMetadata::Encode(*method_md).as_string_view();
113     }
114   }
115   return absl::string_view();
116 }
117 
GetHeaderValue(absl::string_view key,std::string * concatenated_value) const118 absl::optional<absl::string_view> EvaluateArgs::GetHeaderValue(
119     absl::string_view key, std::string* concatenated_value) const {
120   if (metadata_ == nullptr) {
121     return absl::nullopt;
122   }
123   if (absl::EqualsIgnoreCase(key, "te")) {
124     return absl::nullopt;
125   }
126   if (absl::EqualsIgnoreCase(key, "host")) {
127     // Maps legacy host header to :authority.
128     return GetAuthority();
129   }
130   return metadata_->GetStringValue(key, concatenated_value);
131 }
132 
GetLocalAddress() const133 grpc_resolved_address EvaluateArgs::GetLocalAddress() const {
134   if (channel_args_ == nullptr) {
135     return {};
136   }
137   return channel_args_->local_address.address;
138 }
139 
GetLocalAddressString() const140 absl::string_view EvaluateArgs::GetLocalAddressString() const {
141   if (channel_args_ == nullptr) {
142     return "";
143   }
144   return channel_args_->local_address.address_str;
145 }
146 
GetLocalPort() const147 int EvaluateArgs::GetLocalPort() const {
148   if (channel_args_ == nullptr) {
149     return 0;
150   }
151   return channel_args_->local_address.port;
152 }
153 
GetPeerAddress() const154 grpc_resolved_address EvaluateArgs::GetPeerAddress() const {
155   if (channel_args_ == nullptr) {
156     return {};
157   }
158   return channel_args_->peer_address.address;
159 }
160 
GetPeerAddressString() const161 absl::string_view EvaluateArgs::GetPeerAddressString() const {
162   if (channel_args_ == nullptr) {
163     return "";
164   }
165   return channel_args_->peer_address.address_str;
166 }
167 
GetPeerPort() const168 int EvaluateArgs::GetPeerPort() const {
169   if (channel_args_ == nullptr) {
170     return 0;
171   }
172   return channel_args_->peer_address.port;
173 }
174 
GetTransportSecurityType() const175 absl::string_view EvaluateArgs::GetTransportSecurityType() const {
176   if (channel_args_ == nullptr) {
177     return "";
178   }
179   return channel_args_->transport_security_type;
180 }
181 
GetSpiffeId() const182 absl::string_view EvaluateArgs::GetSpiffeId() const {
183   if (channel_args_ == nullptr) {
184     return "";
185   }
186   return channel_args_->spiffe_id;
187 }
188 
GetUriSans() const189 std::vector<absl::string_view> EvaluateArgs::GetUriSans() const {
190   if (channel_args_ == nullptr) {
191     return {};
192   }
193   return channel_args_->uri_sans;
194 }
195 
GetDnsSans() const196 std::vector<absl::string_view> EvaluateArgs::GetDnsSans() const {
197   if (channel_args_ == nullptr) {
198     return {};
199   }
200   return channel_args_->dns_sans;
201 }
202 
GetCommonName() const203 absl::string_view EvaluateArgs::GetCommonName() const {
204   if (channel_args_ == nullptr) {
205     return "";
206   }
207   return channel_args_->common_name;
208 }
209 
GetSubject() const210 absl::string_view EvaluateArgs::GetSubject() const {
211   if (channel_args_ == nullptr) {
212     return "";
213   }
214   return channel_args_->subject;
215 }
216 
217 }  // namespace grpc_core
218