local_security_connector.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #include <string.h>
24 
25 #include <string>
26 #include <utility>
27 
28 #include "absl/status/status.h"
29 #include "absl/status/statusor.h"
30 #include "absl/strings/string_view.h"
31 
32 #include <grpc/grpc.h>
34 #include <grpc/support/alloc.h>
35 #include <grpc/support/log.h>
37 
65 
66 #define GRPC_UDS_URI_PATTERN "unix:"
67 #define GRPC_ABSTRACT_UDS_URI_PATTERN "unix-abstract:"
68 #define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local"
69 
70 namespace {
71 
72 grpc_core::RefCountedPtr<grpc_auth_context> local_auth_context_create(
73  const tsi_peer* peer) {
74  /* Create auth context. */
76  grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
82  GPR_ASSERT(peer->property_count == 1);
83  const tsi_peer_property* prop = &peer->properties[0];
84  GPR_ASSERT(prop != nullptr);
88  prop->value.data, prop->value.length);
89  return ctx;
90 }
91 
92 void local_check_peer(tsi_peer peer, grpc_endpoint* ep,
94  grpc_closure* on_peer_checked,
96  grpc_resolved_address resolved_addr;
97  bool is_endpoint_local = false;
100  if (!uri.ok() || !grpc_parse_uri(*uri, &resolved_addr)) {
101  gpr_log(GPR_ERROR, "Could not parse endpoint address: %s",
102  std::string(local_addr.data(), local_addr.size()).c_str());
103  } else {
104  grpc_resolved_address addr_normalized;
106  grpc_sockaddr_is_v4mapped(&resolved_addr, &addr_normalized)
107  ? &addr_normalized
108  : &resolved_addr;
109  grpc_sockaddr* sock_addr = reinterpret_cast<grpc_sockaddr*>(&addr->addr);
110  // UDS
111  if (type == UDS && grpc_is_unix_socket(addr)) {
112  is_endpoint_local = true;
113  // IPV4
114  } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET) {
115  const grpc_sockaddr_in* addr4 =
116  reinterpret_cast<const grpc_sockaddr_in*>(sock_addr);
117  if (grpc_htonl(addr4->sin_addr.s_addr) == INADDR_LOOPBACK) {
118  is_endpoint_local = true;
119  }
120  // IPv6
121  } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET6) {
122  const grpc_sockaddr_in6* addr6 =
123  reinterpret_cast<const grpc_sockaddr_in6*>(addr);
124  if (memcmp(&addr6->sin6_addr, &in6addr_loopback,
125  sizeof(in6addr_loopback)) == 0) {
126  is_endpoint_local = true;
127  }
128  }
129  }
131  if (!is_endpoint_local) {
133  "Endpoint is neither UDS or TCP loopback address.");
134  grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
135  return;
136  }
137  // Add TSI_SECURITY_LEVEL_PEER_PROPERTY type peer property.
138  size_t new_property_count = peer.property_count + 1;
139  tsi_peer_property* new_properties = static_cast<tsi_peer_property*>(
140  gpr_zalloc(sizeof(*new_properties) * new_property_count));
141  for (size_t i = 0; i < peer.property_count; i++) {
142  new_properties[i] = peer.properties[i];
143  }
144  if (peer.properties != nullptr) gpr_free(peer.properties);
145  peer.properties = new_properties;
146  // TODO(yihuazhang): Set security level of local TCP to TSI_SECURITY_NONE.
147  const char* security_level =
150  TSI_SECURITY_LEVEL_PEER_PROPERTY, security_level,
151  &peer.properties[peer.property_count]);
152  if (result != TSI_OK) return;
153  peer.property_count++;
154  /* Create an auth context which is necessary to pass the santiy check in
155  * {client, server}_auth_filter that verifies if the peer's auth context is
156  * obtained during handshakes. The auth context is only checked for its
157  * existence and not actually used.
158  */
159  *auth_context = local_auth_context_create(&peer);
160  tsi_peer_destruct(&peer);
161  error = *auth_context != nullptr ? GRPC_ERROR_NONE
163  "Could not create local auth context");
164  grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, error);
165 }
166 
167 class grpc_local_channel_security_connector final
169  public:
170  grpc_local_channel_security_connector(
173  const char* target_name)
174  : grpc_channel_security_connector({}, std::move(channel_creds),
175  std::move(request_metadata_creds)),
176  target_name_(gpr_strdup(target_name)) {}
177 
178  ~grpc_local_channel_security_connector() override { gpr_free(target_name_); }
179 
180  void add_handshakers(
181  const grpc_channel_args* args, grpc_pollset_set* /*interested_parties*/,
182  grpc_core::HandshakeManager* handshake_manager) override {
183  tsi_handshaker* handshaker = nullptr;
185  handshake_manager->Add(
186  grpc_core::SecurityHandshakerCreate(handshaker, this, args));
187  }
188 
189  int cmp(const grpc_security_connector* other_sc) const override {
190  auto* other =
191  reinterpret_cast<const grpc_local_channel_security_connector*>(
192  other_sc);
193  int c = channel_security_connector_cmp(other);
194  if (c != 0) return c;
195  return strcmp(target_name_, other->target_name_);
196  }
197 
198  void check_peer(tsi_peer peer, grpc_endpoint* ep,
200  grpc_closure* on_peer_checked) override {
201  grpc_local_credentials* creds =
202  reinterpret_cast<grpc_local_credentials*>(mutable_channel_creds());
203  local_check_peer(peer, ep, auth_context, on_peer_checked,
204  creds->connect_type());
205  }
206 
207  void cancel_check_peer(grpc_closure* /*on_peer_checked*/,
208  grpc_error_handle error) override {
210  }
211 
213  absl::string_view host, grpc_auth_context*) override {
214  if (host.empty() || host != target_name_) {
216  "local call host does not match target name"));
217  }
219  }
220 
221  const char* target_name() const { return target_name_; }
222 
223  private:
224  char* target_name_;
225 };
226 
227 class grpc_local_server_security_connector final
229  public:
230  explicit grpc_local_server_security_connector(
232  : grpc_server_security_connector({}, std::move(server_creds)) {}
233  ~grpc_local_server_security_connector() override = default;
234 
235  void add_handshakers(
236  const grpc_channel_args* args, grpc_pollset_set* /*interested_parties*/,
237  grpc_core::HandshakeManager* handshake_manager) override {
238  tsi_handshaker* handshaker = nullptr;
240  handshake_manager->Add(
241  grpc_core::SecurityHandshakerCreate(handshaker, this, args));
242  }
243 
244  void check_peer(tsi_peer peer, grpc_endpoint* ep,
246  grpc_closure* on_peer_checked) override {
249  local_check_peer(peer, ep, auth_context, on_peer_checked,
250  creds->connect_type());
251  }
252 
253  void cancel_check_peer(grpc_closure* /*on_peer_checked*/,
254  grpc_error_handle error) override {
256  }
257 
258  int cmp(const grpc_security_connector* other) const override {
260  static_cast<const grpc_server_security_connector*>(other));
261  }
262 };
263 } // namespace
264 
269  const grpc_channel_args* args, const char* target_name) {
270  if (channel_creds == nullptr || target_name == nullptr) {
271  gpr_log(
272  GPR_ERROR,
273  "Invalid arguments to grpc_local_channel_security_connector_create()");
274  return nullptr;
275  }
276  // Perform sanity check on UDS address. For TCP local connection, the check
277  // will be done during check_peer procedure.
278  grpc_local_credentials* creds =
279  static_cast<grpc_local_credentials*>(channel_creds.get());
280  const grpc_arg* server_uri_arg =
282  const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg);
283  if (creds->connect_type() == UDS &&
284  strncmp(GRPC_UDS_URI_PATTERN, server_uri_str,
285  strlen(GRPC_UDS_URI_PATTERN)) != 0 &&
286  strncmp(GRPC_ABSTRACT_UDS_URI_PATTERN, server_uri_str,
287  strlen(GRPC_ABSTRACT_UDS_URI_PATTERN)) != 0) {
289  "Invalid UDS target name to "
290  "grpc_local_channel_security_connector_create()");
291  return nullptr;
292  }
293  return grpc_core::MakeRefCounted<grpc_local_channel_security_connector>(
294  channel_creds, request_metadata_creds, target_name);
295 }
296 
300  if (server_creds == nullptr) {
301  gpr_log(
302  GPR_ERROR,
303  "Invalid arguments to grpc_local_server_security_connector_create()");
304  return nullptr;
305  }
306  return grpc_core::MakeRefCounted<grpc_local_server_security_connector>(
307  std::move(server_creds));
308 }
grpc_arg
Definition: grpc_types.h:103
tsi_security_level_to_string
const char * tsi_security_level_to_string(tsi_security_level security_level)
Definition: transport_security.cc:70
GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME
#define GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME
Definition: grpc_security_constants.h:47
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
grpc_channel_arg_get_string
char * grpc_channel_arg_get_string(const grpc_arg *arg)
Definition: channel_args.cc:432
grpc_auth_context
Definition: security_context.h:63
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
tsi_peer::properties
tsi_peer_property * properties
Definition: transport_security_interface.h:239
tsi_peer_property::value
struct tsi_peer_property::@48 value
sockaddr_utils.h
ctx
Definition: benchmark-async.c:30
grpc_security_connector::check_peer
virtual void check_peer(tsi_peer peer, grpc_endpoint *ep, grpc_core::RefCountedPtr< grpc_auth_context > *auth_context, grpc_closure *on_peer_checked)=0
grpc_server_security_connector::add_handshakers
virtual void add_handshakers(const grpc_channel_args *args, grpc_pollset_set *interested_parties, grpc_core::HandshakeManager *handshake_mgr)=0
grpc_server_security_connector
Definition: security_connector.h:171
grpc_core::RefCountedPtr::get
T * get() const
Definition: ref_counted_ptr.h:146
tsi_handshaker
Definition: transport_security.h:84
grpc_core::SecurityHandshakerCreate
RefCountedPtr< Handshaker > SecurityHandshakerCreate(tsi_handshaker *handshaker, grpc_security_connector *connector, const grpc_channel_args *args)
Creates a security handshaker using handshaker.
Definition: security_handshaker.cc:658
TSI_SECURITY_LEVEL_PEER_PROPERTY
#define TSI_SECURITY_LEVEL_PEER_PROPERTY
Definition: transport_security_interface.h:226
grpc_pollset_set
struct grpc_pollset_set grpc_pollset_set
Definition: iomgr_fwd.h:23
tsi_peer_property::length
size_t length
Definition: transport_security_interface.h:234
string.h
local_transport_security.h
local_security_connector.h
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
client_channel.h
grpc_resolved_address
Definition: resolved_address.h:34
closure.h
grpc_local_credentials::connect_type
grpc_local_connect_type connect_type() const
Definition: local_credentials.h:49
ctx
static struct test_ctx ctx
Definition: test-ipc-send-recv.c:65
resolved_address.h
grpc_channel_security_connector::grpc_channel_security_connector
grpc_channel_security_connector(absl::string_view url_scheme, grpc_core::RefCountedPtr< grpc_channel_credentials > channel_creds, grpc_core::RefCountedPtr< grpc_call_credentials > request_metadata_creds)
Definition: security_connector.cc:37
grpc_core::URI::Parse
static absl::StatusOr< URI > Parse(absl::string_view uri_text)
Definition: uri_parser.cc:209
sockaddr.h
credentials.h
grpc_channel_args
Definition: grpc_types.h:132
grpc_is_unix_socket
int grpc_is_unix_socket(const grpc_resolved_address *resolved_addr)
Definition: unix_sockets_posix_noop.cc:46
LOCAL_TCP
@ LOCAL_TCP
Definition: grpc_security_constants.h:143
GRPC_UDS_URI_PATTERN
#define GRPC_UDS_URI_PATTERN
Definition: local_security_connector.cc:66
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
absl::UnauthenticatedError
Status UnauthenticatedError(absl::string_view message)
Definition: third_party/abseil-cpp/absl/status/status.cc:371
grpc_parse_uri
bool grpc_parse_uri(const grpc_core::URI &uri, grpc_resolved_address *resolved_addr)
Definition: parse_address.cc:293
socket_utils.h
grpc_security_connector
Definition: security_connector.h:61
grpc_auth_context_set_peer_identity_property_name
GRPCAPI int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx, const char *name)
Definition: security_context.cc:151
TSI_OK
@ TSI_OK
Definition: transport_security_interface.h:32
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
grpc_security_connector::cancel_check_peer
virtual void cancel_check_peer(grpc_closure *on_peer_checked, grpc_error_handle error)=0
string_util.h
parse_address.h
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME
#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME
Definition: grpc_security_constants.h:26
grpc_core::RefCountedPtr< grpc_auth_context >
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
absl::string_view::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:277
grpc_channel_security_connector::CheckCallHost
virtual grpc_core::ArenaPromise< absl::Status > CheckCallHost(absl::string_view host, grpc_auth_context *auth_context)=0
GRPC_ARG_SERVER_URI
#define GRPC_ARG_SERVER_URI
Definition: client_channel.h:89
grpc_channel_security_connector::mutable_channel_creds
grpc_channel_credentials * mutable_channel_creds()
Definition: security_connector.h:138
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
grpc.h
tsi_result
tsi_result
Definition: transport_security_interface.h:31
addr6
static struct sockaddr_in6 addr6
Definition: test-getnameinfo.c:34
grpc_htonl
uint32_t grpc_htonl(uint32_t hostlong)
grpc_core::HandshakeManager::Add
void Add(RefCountedPtr< Handshaker > handshaker)
Definition: src/core/lib/transport/handshaker.cc:63
arena_promise.h
grpc_auth_context_add_cstring_property
GRPCAPI void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx, const char *name, const char *value)
Definition: security_context.cc:268
grpc_local_credentials
Definition: local_credentials.h:36
tsi_peer_property::data
char * data
Definition: transport_security_interface.h:233
grpc_local_server_security_connector_create
grpc_core::RefCountedPtr< grpc_server_security_connector > grpc_local_server_security_connector_create(grpc_core::RefCountedPtr< grpc_server_credentials > server_creds)
Definition: local_security_connector.cc:298
error.h
grpc_channel_security_connector::add_handshakers
virtual void add_handshakers(const grpc_channel_args *args, grpc_pollset_set *interested_parties, grpc_core::HandshakeManager *handshake_mgr)=0
Registers handshakers with handshake_mgr.
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
grpc_local_server_credentials::connect_type
grpc_local_connect_type connect_type() const
Definition: local_credentials.h:72
tsi_peer_property::name
char * name
Definition: transport_security_interface.h:231
transport_security_interface.h
promise.h
tsi_local_handshaker_create
tsi_result tsi_local_handshaker_create(tsi_handshaker **self)
Definition: local_transport_security.cc:161
GRPC_ERROR_CREATE_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
Definition: error.h:291
grpc_local_server_credentials
Definition: local_credentials.h:62
tsi_peer_property
Definition: transport_security_interface.h:230
grpc_channel_security_connector::channel_security_connector_cmp
int channel_security_connector_cmp(const grpc_channel_security_connector *other) const
Definition: security_connector.cc:45
addr4
static struct sockaddr_in addr4
Definition: test-getnameinfo.c:33
unix_sockets_posix.h
security_handshaker.h
UDS
@ UDS
Definition: grpc_security_constants.h:143
tsi_peer
Definition: transport_security_interface.h:238
security_context.h
absl::StatusOr::ok
ABSL_MUST_USE_RESULT bool ok() const
Definition: abseil-cpp/absl/status/statusor.h:491
transport_security.h
grpc_core::ImmediateOkStatus
Definition: promise/promise.h:78
debug_location.h
grpc_core::ArenaPromise
Definition: arena_promise.h:152
poll.h
alloc.h
local_credentials.h
grpc_security_constants.h
grpc_local_channel_security_connector_create
grpc_core::RefCountedPtr< grpc_channel_security_connector > grpc_local_channel_security_connector_create(grpc_core::RefCountedPtr< grpc_channel_credentials > channel_creds, grpc_core::RefCountedPtr< grpc_call_credentials > request_metadata_creds, const grpc_channel_args *args, const char *target_name)
Definition: local_security_connector.cc:266
exec_ctx.h
handshaker.h
grpc_auth_context_add_property
GRPCAPI void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name, const char *value, size_t value_length)
Definition: security_context.cc:248
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
grpc_core::ExecCtx::Run
static void Run(const DebugLocation &location, grpc_closure *closure, grpc_error_handle error)
Definition: exec_ctx.cc:98
ref_counted_ptr.h
channel_args.h
sockaddr_in6::sin6_addr
struct ares_in6_addr sin6_addr
Definition: ares_ipv6.h:30
GRPC_ABSTRACT_UDS_URI_PATTERN
#define GRPC_ABSTRACT_UDS_URI_PATTERN
Definition: local_security_connector.cc:67
gpr_strdup
GPRAPI char * gpr_strdup(const char *src)
Definition: string.cc:39
grpc_channel_security_connector
Definition: security_connector.h:118
grpc_core::Immediate
promise_detail::Immediate< T > Immediate(T value)
Definition: promise/promise.h:73
grpc_server_security_connector::mutable_server_creds
grpc_server_credentials * mutable_server_creds()
Definition: security_connector.h:184
absl::string_view::empty
constexpr bool empty() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:292
TSI_PRIVACY_AND_INTEGRITY
@ TSI_PRIVACY_AND_INTEGRITY
Definition: transport_security_interface.h:56
grpc_core::HandshakeManager
Definition: handshaker.h:98
absl::StatusOr
Definition: abseil-cpp/absl/status/statusor.h:187
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
uri_parser.h
iomgr_fwd.h
grpc_endpoint_get_local_address
absl::string_view grpc_endpoint_get_local_address(grpc_endpoint *ep)
Definition: endpoint.cc:59
endpoint.h
grpc_error
Definition: error_internal.h:42
GRPC_LOCAL_TRANSPORT_SECURITY_TYPE
#define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE
Definition: local_security_connector.cc:68
grpc_security_connector::cmp
virtual int cmp(const grpc_security_connector *other) const =0
grpc_sockaddr_is_v4mapped
int grpc_sockaddr_is_v4mapped(const grpc_resolved_address *resolved_addr, grpc_resolved_address *resolved_addr4_out)
Definition: sockaddr_utils.cc:81
grpc_local_connect_type
grpc_local_connect_type
Definition: grpc_security_constants.h:143
absl::string_view::data
constexpr const_pointer data() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:336
grpc_closure
Definition: closure.h:56
grpc_channel_args_find
const grpc_arg * grpc_channel_args_find(const grpc_channel_args *args, const char *name)
Definition: channel_args.cc:393
tsi_peer_destruct
void tsi_peer_destruct(tsi_peer *self)
Definition: transport_security.cc:320
grpc_endpoint
Definition: endpoint.h:105
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
grpc_server_security_connector::grpc_server_security_connector
grpc_server_security_connector(absl::string_view url_scheme, grpc_core::RefCountedPtr< grpc_server_credentials > server_creds)
Definition: security_connector.cc:61
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
tsi_construct_string_peer_property_from_cstring
tsi_result tsi_construct_string_peer_property_from_cstring(const char *name, const char *value, tsi_peer_property *property)
Definition: transport_security.cc:340
tsi_peer::property_count
size_t property_count
Definition: transport_security_interface.h:240
grpc_server_security_connector::server_security_connector_cmp
int server_security_connector_cmp(const grpc_server_security_connector *other) const
Definition: security_connector.cc:67
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:16