blob: 12144dfbde32851e43031d5ce7b295ed9d2b6d19 [file] [log] [blame]
// Copyright 2021 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/security/authorization/evaluate_args.h"
#include "src/core/lib/address_utils/parse_address.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/slice/slice_utils.h"
namespace grpc_core {
namespace {
absl::string_view GetAuthPropertyValue(grpc_auth_context* context,
const char* property_name) {
grpc_auth_property_iterator it =
grpc_auth_context_find_properties_by_name(context, property_name);
const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it);
if (prop == nullptr) {
gpr_log(GPR_DEBUG, "No value found for %s property.", property_name);
return "";
}
if (grpc_auth_property_iterator_next(&it) != nullptr) {
gpr_log(GPR_DEBUG, "Multiple values found for %s property.", property_name);
return "";
}
return absl::string_view(prop->value, prop->value_length);
}
void ParseEndpointUri(absl::string_view uri_text, std::string* address,
int* port) {
absl::StatusOr<URI> uri = URI::Parse(uri_text);
if (!uri.ok()) {
gpr_log(GPR_DEBUG, "Failed to parse uri.");
return;
}
absl::string_view host_view;
absl::string_view port_view;
if (!SplitHostPort(uri->path(), &host_view, &port_view)) {
gpr_log(GPR_DEBUG, "Failed to split %s into host and port.",
uri->path().c_str());
return;
}
*address = std::string(host_view);
if (!absl::SimpleAtoi(port_view, port)) {
gpr_log(GPR_DEBUG, "Port %s is out of range or null.",
std::string(port_view).c_str());
}
}
} // namespace
EvaluateArgs::PerChannelArgs::PerChannelArgs(grpc_auth_context* auth_context,
grpc_endpoint* endpoint) {
if (auth_context != nullptr) {
transport_security_type = GetAuthPropertyValue(
auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
spiffe_id =
GetAuthPropertyValue(auth_context, GRPC_PEER_SPIFFE_ID_PROPERTY_NAME);
common_name =
GetAuthPropertyValue(auth_context, GRPC_X509_CN_PROPERTY_NAME);
}
if (endpoint != nullptr) {
ParseEndpointUri(grpc_endpoint_get_local_address(endpoint), &local_address,
&local_port);
ParseEndpointUri(grpc_endpoint_get_peer(endpoint), &peer_address,
&peer_port);
}
}
absl::string_view EvaluateArgs::GetPath() const {
absl::string_view path;
if (metadata_ != nullptr && metadata_->idx.named.path != nullptr) {
grpc_linked_mdelem* elem = metadata_->idx.named.path;
const grpc_slice& val = GRPC_MDVALUE(elem->md);
path = StringViewFromSlice(val);
}
return path;
}
absl::string_view EvaluateArgs::GetHost() const {
absl::string_view host;
if (metadata_ != nullptr && metadata_->idx.named.host != nullptr) {
grpc_linked_mdelem* elem = metadata_->idx.named.host;
const grpc_slice& val = GRPC_MDVALUE(elem->md);
host = StringViewFromSlice(val);
}
return host;
}
absl::string_view EvaluateArgs::GetMethod() const {
absl::string_view method;
if (metadata_ != nullptr && metadata_->idx.named.method != nullptr) {
grpc_linked_mdelem* elem = metadata_->idx.named.method;
const grpc_slice& val = GRPC_MDVALUE(elem->md);
method = StringViewFromSlice(val);
}
return method;
}
std::multimap<absl::string_view, absl::string_view> EvaluateArgs::GetHeaders()
const {
std::multimap<absl::string_view, absl::string_view> headers;
if (metadata_ == nullptr) {
return headers;
}
for (grpc_linked_mdelem* elem = metadata_->list.head; elem != nullptr;
elem = elem->next) {
const grpc_slice& key = GRPC_MDKEY(elem->md);
const grpc_slice& val = GRPC_MDVALUE(elem->md);
headers.emplace(StringViewFromSlice(key), StringViewFromSlice(val));
}
return headers;
}
absl::optional<absl::string_view> EvaluateArgs::GetHeaderValue(
absl::string_view key, std::string* concatenated_value) const {
if (metadata_ == nullptr) {
return absl::nullopt;
}
return grpc_metadata_batch_get_value(metadata_, key, concatenated_value);
}
absl::string_view EvaluateArgs::GetLocalAddress() const {
if (channel_args_ == nullptr) {
return "";
}
return channel_args_->local_address;
}
int EvaluateArgs::GetLocalPort() const {
if (channel_args_ == nullptr) {
return 0;
}
return channel_args_->local_port;
}
absl::string_view EvaluateArgs::GetPeerAddress() const {
if (channel_args_ == nullptr) {
return "";
}
return channel_args_->peer_address;
}
int EvaluateArgs::GetPeerPort() const {
if (channel_args_ == nullptr) {
return 0;
}
return channel_args_->peer_port;
}
absl::string_view EvaluateArgs::GetTransportSecurityType() const {
if (channel_args_ == nullptr) {
return "";
}
return channel_args_->transport_security_type;
}
absl::string_view EvaluateArgs::GetSpiffeId() const {
if (channel_args_ == nullptr) {
return "";
}
return channel_args_->spiffe_id;
}
absl::string_view EvaluateArgs::GetCommonName() const {
if (channel_args_ == nullptr) {
return "";
}
return channel_args_->common_name;
}
} // namespace grpc_core