mirror of https://github.com/grpc/grpc.git
parent
6eb6c845aa
commit
c5f1eda10f
29 changed files with 2777 additions and 0 deletions
@ -0,0 +1,77 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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/credentials/local/local_credentials.h" |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
|
||||
#include "src/core/lib/channel/channel_args.h" |
||||
#include "src/core/lib/security/security_connector/local_security_connector.h" |
||||
|
||||
#define GRPC_CREDENTIALS_TYPE_LOCAL "Local" |
||||
|
||||
static void local_credentials_destruct(grpc_channel_credentials* creds) {} |
||||
|
||||
static void local_server_credentials_destruct(grpc_server_credentials* creds) {} |
||||
|
||||
static grpc_security_status local_create_security_connector( |
||||
grpc_channel_credentials* creds, |
||||
grpc_call_credentials* request_metadata_creds, const char* target_name, |
||||
const grpc_channel_args* args, grpc_channel_security_connector** sc, |
||||
grpc_channel_args** new_args) { |
||||
return grpc_local_channel_security_connector_create( |
||||
creds, request_metadata_creds, args, target_name, sc); |
||||
} |
||||
|
||||
static grpc_security_status local_server_create_security_connector( |
||||
grpc_server_credentials* creds, grpc_server_security_connector** sc) { |
||||
return grpc_local_server_security_connector_create(creds, sc); |
||||
} |
||||
|
||||
static const grpc_channel_credentials_vtable local_credentials_vtable = { |
||||
local_credentials_destruct, local_create_security_connector, |
||||
/*duplicate_without_call_credentials=*/nullptr}; |
||||
|
||||
static const grpc_server_credentials_vtable local_server_credentials_vtable = { |
||||
local_server_credentials_destruct, local_server_create_security_connector}; |
||||
|
||||
grpc_channel_credentials* grpc_local_credentials_create( |
||||
grpc_local_connect_type connect_type) { |
||||
auto creds = static_cast<grpc_local_credentials*>( |
||||
gpr_zalloc(sizeof(grpc_local_credentials))); |
||||
creds->connect_type = connect_type; |
||||
creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL; |
||||
creds->base.vtable = &local_credentials_vtable; |
||||
gpr_ref_init(&creds->base.refcount, 1); |
||||
return &creds->base; |
||||
} |
||||
|
||||
grpc_server_credentials* grpc_local_server_credentials_create( |
||||
grpc_local_connect_type connect_type) { |
||||
auto creds = static_cast<grpc_local_server_credentials*>( |
||||
gpr_zalloc(sizeof(grpc_local_server_credentials))); |
||||
creds->connect_type = connect_type; |
||||
creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL; |
||||
creds->base.vtable = &local_server_credentials_vtable; |
||||
gpr_ref_init(&creds->base.refcount, 1); |
||||
return &creds->base; |
||||
} |
@ -0,0 +1,40 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H |
||||
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpc/grpc_security.h> |
||||
|
||||
#include "src/core/lib/security/credentials/credentials.h" |
||||
|
||||
/* Main struct for grpc local channel credential. */ |
||||
typedef struct grpc_local_credentials { |
||||
grpc_channel_credentials base; |
||||
grpc_local_connect_type connect_type; |
||||
} grpc_local_credentials; |
||||
|
||||
/* Main struct for grpc local server credential. */ |
||||
typedef struct grpc_local_server_credentials { |
||||
grpc_server_credentials base; |
||||
grpc_local_connect_type connect_type; |
||||
} grpc_local_server_credentials; |
||||
|
||||
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H */ |
@ -0,0 +1,239 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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/security_connector/local_security_connector.h" |
||||
|
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/string_util.h> |
||||
|
||||
#include "src/core/ext/filters/client_channel/client_channel.h" |
||||
#include "src/core/lib/channel/channel_args.h" |
||||
#include "src/core/lib/security/credentials/local/local_credentials.h" |
||||
#include "src/core/lib/security/transport/security_handshaker.h" |
||||
#include "src/core/tsi/local_transport_security.h" |
||||
|
||||
#define GRPC_UDS_URL_SCHEME "unix" |
||||
#define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local" |
||||
|
||||
typedef struct { |
||||
grpc_channel_security_connector base; |
||||
char* target_name; |
||||
} grpc_local_channel_security_connector; |
||||
|
||||
typedef struct { |
||||
grpc_server_security_connector base; |
||||
} grpc_local_server_security_connector; |
||||
|
||||
static void local_channel_destroy(grpc_security_connector* sc) { |
||||
if (sc == nullptr) { |
||||
return; |
||||
} |
||||
auto c = reinterpret_cast<grpc_local_channel_security_connector*>(sc); |
||||
grpc_call_credentials_unref(c->base.request_metadata_creds); |
||||
grpc_channel_credentials_unref(c->base.channel_creds); |
||||
gpr_free(c->target_name); |
||||
gpr_free(sc); |
||||
} |
||||
|
||||
static void local_server_destroy(grpc_security_connector* sc) { |
||||
if (sc == nullptr) { |
||||
return; |
||||
} |
||||
auto c = reinterpret_cast<grpc_local_server_security_connector*>(sc); |
||||
grpc_server_credentials_unref(c->base.server_creds); |
||||
gpr_free(sc); |
||||
} |
||||
|
||||
static void local_channel_add_handshakers( |
||||
grpc_channel_security_connector* sc, |
||||
grpc_handshake_manager* handshake_manager) { |
||||
tsi_handshaker* handshaker = nullptr; |
||||
GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) == |
||||
TSI_OK); |
||||
grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( |
||||
handshaker, &sc->base)); |
||||
} |
||||
|
||||
static void local_server_add_handshakers( |
||||
grpc_server_security_connector* sc, |
||||
grpc_handshake_manager* handshake_manager) { |
||||
tsi_handshaker* handshaker = nullptr; |
||||
GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, &handshaker) == |
||||
TSI_OK); |
||||
grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( |
||||
handshaker, &sc->base)); |
||||
} |
||||
|
||||
static int local_channel_cmp(grpc_security_connector* sc1, |
||||
grpc_security_connector* sc2) { |
||||
grpc_local_channel_security_connector* c1 = |
||||
reinterpret_cast<grpc_local_channel_security_connector*>(sc1); |
||||
grpc_local_channel_security_connector* c2 = |
||||
reinterpret_cast<grpc_local_channel_security_connector*>(sc2); |
||||
int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); |
||||
if (c != 0) return c; |
||||
return strcmp(c1->target_name, c2->target_name); |
||||
} |
||||
|
||||
static int local_server_cmp(grpc_security_connector* sc1, |
||||
grpc_security_connector* sc2) { |
||||
grpc_local_server_security_connector* c1 = |
||||
reinterpret_cast<grpc_local_server_security_connector*>(sc1); |
||||
grpc_local_server_security_connector* c2 = |
||||
reinterpret_cast<grpc_local_server_security_connector*>(sc2); |
||||
return grpc_server_security_connector_cmp(&c1->base, &c2->base); |
||||
} |
||||
|
||||
static grpc_security_status local_auth_context_create(grpc_auth_context** ctx) { |
||||
if (ctx == nullptr) { |
||||
gpr_log(GPR_ERROR, "Invalid arguments to local_auth_context_create()"); |
||||
return GRPC_SECURITY_ERROR; |
||||
} |
||||
/* Create auth context. */ |
||||
*ctx = grpc_auth_context_create(nullptr); |
||||
grpc_auth_context_add_cstring_property( |
||||
*ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, |
||||
GRPC_LOCAL_TRANSPORT_SECURITY_TYPE); |
||||
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( |
||||
*ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1); |
||||
return GRPC_SECURITY_OK; |
||||
} |
||||
|
||||
static void local_check_peer(grpc_security_connector* sc, tsi_peer peer, |
||||
grpc_auth_context** auth_context, |
||||
grpc_closure* on_peer_checked) { |
||||
grpc_security_status status; |
||||
status = local_auth_context_create(auth_context); |
||||
grpc_error* error = status == GRPC_SECURITY_OK |
||||
? GRPC_ERROR_NONE |
||||
: GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
||||
"Could not create local auth context"); |
||||
GRPC_CLOSURE_SCHED(on_peer_checked, error); |
||||
} |
||||
|
||||
static grpc_security_connector_vtable local_channel_vtable = { |
||||
local_channel_destroy, local_check_peer, local_channel_cmp}; |
||||
|
||||
static grpc_security_connector_vtable local_server_vtable = { |
||||
local_server_destroy, local_check_peer, local_server_cmp}; |
||||
|
||||
static bool local_check_call_host(grpc_channel_security_connector* sc, |
||||
const char* host, |
||||
grpc_auth_context* auth_context, |
||||
grpc_closure* on_call_host_checked, |
||||
grpc_error** error) { |
||||
grpc_local_channel_security_connector* local_sc = |
||||
reinterpret_cast<grpc_local_channel_security_connector*>(sc); |
||||
if (host == nullptr || local_sc == nullptr || |
||||
strcmp(host, local_sc->target_name) != 0) { |
||||
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
||||
"local call host does not match target name"); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
static void local_cancel_check_call_host(grpc_channel_security_connector* sc, |
||||
grpc_closure* on_call_host_checked, |
||||
grpc_error* error) { |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
grpc_security_status grpc_local_channel_security_connector_create( |
||||
grpc_channel_credentials* channel_creds, |
||||
grpc_call_credentials* request_metadata_creds, |
||||
const grpc_channel_args* args, const char* target_name, |
||||
grpc_channel_security_connector** sc) { |
||||
if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) { |
||||
gpr_log( |
||||
GPR_ERROR, |
||||
"Invalid arguments to grpc_local_channel_security_connector_create()"); |
||||
return GRPC_SECURITY_ERROR; |
||||
} |
||||
// Check if local_connect_type is UDS. Only UDS is supported for now.
|
||||
grpc_local_credentials* creds = |
||||
reinterpret_cast<grpc_local_credentials*>(channel_creds); |
||||
if (creds->connect_type != UDS) { |
||||
gpr_log(GPR_ERROR, |
||||
"Invalid local channel type to " |
||||
"grpc_local_channel_security_connector_create()"); |
||||
return GRPC_SECURITY_ERROR; |
||||
} |
||||
// Check if target_name is a valid UDS address.
|
||||
const grpc_arg* server_uri_arg = |
||||
grpc_channel_args_find(args, GRPC_ARG_SERVER_URI); |
||||
const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg); |
||||
if (strncmp(GRPC_UDS_URL_SCHEME, server_uri_str, |
||||
strlen(GRPC_UDS_URL_SCHEME)) != 0) { |
||||
gpr_log(GPR_ERROR, |
||||
"Invalid target_name to " |
||||
"grpc_local_channel_security_connector_create()"); |
||||
return GRPC_SECURITY_ERROR; |
||||
} |
||||
auto c = static_cast<grpc_local_channel_security_connector*>( |
||||
gpr_zalloc(sizeof(grpc_local_channel_security_connector))); |
||||
gpr_ref_init(&c->base.base.refcount, 1); |
||||
c->base.base.vtable = &local_channel_vtable; |
||||
c->base.add_handshakers = local_channel_add_handshakers; |
||||
c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); |
||||
c->base.request_metadata_creds = |
||||
grpc_call_credentials_ref(request_metadata_creds); |
||||
c->base.check_call_host = local_check_call_host; |
||||
c->base.cancel_check_call_host = local_cancel_check_call_host; |
||||
c->base.base.url_scheme = |
||||
creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr; |
||||
c->target_name = gpr_strdup(target_name); |
||||
*sc = &c->base; |
||||
return GRPC_SECURITY_OK; |
||||
} |
||||
|
||||
grpc_security_status grpc_local_server_security_connector_create( |
||||
grpc_server_credentials* server_creds, |
||||
grpc_server_security_connector** sc) { |
||||
if (server_creds == nullptr || sc == nullptr) { |
||||
gpr_log( |
||||
GPR_ERROR, |
||||
"Invalid arguments to grpc_local_server_security_connector_create()"); |
||||
return GRPC_SECURITY_ERROR; |
||||
} |
||||
// Check if local_connect_type is UDS. Only UDS is supported for now.
|
||||
grpc_local_server_credentials* creds = |
||||
reinterpret_cast<grpc_local_server_credentials*>(server_creds); |
||||
if (creds->connect_type != UDS) { |
||||
gpr_log(GPR_ERROR, |
||||
"Invalid local server type to " |
||||
"grpc_local_server_security_connector_create()"); |
||||
return GRPC_SECURITY_ERROR; |
||||
} |
||||
auto c = static_cast<grpc_local_server_security_connector*>( |
||||
gpr_zalloc(sizeof(grpc_local_server_security_connector))); |
||||
gpr_ref_init(&c->base.base.refcount, 1); |
||||
c->base.base.vtable = &local_server_vtable; |
||||
c->base.server_creds = grpc_server_credentials_ref(server_creds); |
||||
c->base.base.url_scheme = |
||||
creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr; |
||||
c->base.add_handshakers = local_server_add_handshakers; |
||||
*sc = &c->base; |
||||
return GRPC_SECURITY_OK; |
||||
} |
@ -0,0 +1,58 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H |
||||
#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/security/context/security_context.h" |
||||
|
||||
/**
|
||||
* This method creates a local channel security connector. |
||||
* |
||||
* - channel_creds: channel credential instance. |
||||
* - request_metadata_creds: credential object which will be sent with each |
||||
* request. This parameter can be nullptr. |
||||
* - target_name: the name of the endpoint that the channel is connecting to. |
||||
* - args: channel args passed from the caller. |
||||
* - sc: address of local channel security connector instance to be returned |
||||
* from the method. |
||||
* |
||||
* It returns GRPC_SECURITY_OK on success, and an error stauts code on failure. |
||||
*/ |
||||
grpc_security_status grpc_local_channel_security_connector_create( |
||||
grpc_channel_credentials* channel_creds, |
||||
grpc_call_credentials* request_metadata_creds, |
||||
const grpc_channel_args* args, const char* target_name, |
||||
grpc_channel_security_connector** sc); |
||||
|
||||
/**
|
||||
* This method creates a local server security connector. |
||||
* |
||||
* - server_creds: server credential instance. |
||||
* - sc: address of local server security connector instance to be returned from |
||||
* the method. |
||||
* |
||||
* It returns GRPC_SECURITY_OK on success, and an error status code on failure. |
||||
*/ |
||||
grpc_security_status grpc_local_server_security_connector_create( |
||||
grpc_server_credentials* server_creds, grpc_server_security_connector** sc); |
||||
|
||||
#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H \ |
||||
*/ |
@ -0,0 +1,222 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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/tsi/local_transport_security.h" |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/string_util.h> |
||||
|
||||
#include "src/core/lib/iomgr/exec_ctx.h" |
||||
#include "src/core/tsi/transport_security_grpc.h" |
||||
|
||||
#define TSI_LOCAL_PEER_IDENTITY "local" |
||||
|
||||
/* Main struct for local TSI zero-copy frame protector. */ |
||||
typedef struct local_zero_copy_grpc_protector { |
||||
tsi_zero_copy_grpc_protector base; |
||||
} local_zero_copy_grpc_protector; |
||||
|
||||
/* Main struct for local TSI handshaker result. */ |
||||
typedef struct local_tsi_handshaker_result { |
||||
tsi_handshaker_result base; |
||||
char* peer_identity; |
||||
bool is_client; |
||||
} local_tsi_handshaker_result; |
||||
|
||||
/* Main struct for local TSI handshaker. */ |
||||
typedef struct local_tsi_handshaker { |
||||
tsi_handshaker base; |
||||
bool is_client; |
||||
} local_tsi_handshaker; |
||||
|
||||
/* --- tsi_zero_copy_grpc_protector methods implementation. --- */ |
||||
|
||||
static tsi_result local_zero_copy_grpc_protector_protect( |
||||
tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* unprotected_slices, |
||||
grpc_slice_buffer* protected_slices) { |
||||
if (self == nullptr || unprotected_slices == nullptr || |
||||
protected_slices == nullptr) { |
||||
gpr_log(GPR_ERROR, "Invalid nullptr arguments to zero-copy grpc protect."); |
||||
return TSI_INVALID_ARGUMENT; |
||||
} |
||||
grpc_slice_buffer_move_into(unprotected_slices, protected_slices); |
||||
return TSI_OK; |
||||
} |
||||
|
||||
static tsi_result local_zero_copy_grpc_protector_unprotect( |
||||
tsi_zero_copy_grpc_protector* self, grpc_slice_buffer* protected_slices, |
||||
grpc_slice_buffer* unprotected_slices) { |
||||
if (self == nullptr || unprotected_slices == nullptr || |
||||
protected_slices == nullptr) { |
||||
gpr_log(GPR_ERROR, |
||||
"Invalid nullptr arguments to zero-copy grpc unprotect."); |
||||
return TSI_INVALID_ARGUMENT; |
||||
} |
||||
grpc_slice_buffer_move_into(protected_slices, unprotected_slices); |
||||
return TSI_OK; |
||||
} |
||||
|
||||
static void local_zero_copy_grpc_protector_destroy( |
||||
tsi_zero_copy_grpc_protector* self) { |
||||
gpr_free(self); |
||||
} |
||||
|
||||
static const tsi_zero_copy_grpc_protector_vtable |
||||
local_zero_copy_grpc_protector_vtable = { |
||||
local_zero_copy_grpc_protector_protect, |
||||
local_zero_copy_grpc_protector_unprotect, |
||||
local_zero_copy_grpc_protector_destroy}; |
||||
|
||||
tsi_result local_zero_copy_grpc_protector_create( |
||||
tsi_zero_copy_grpc_protector** protector) { |
||||
if (grpc_core::ExecCtx::Get() == nullptr || protector == nullptr) { |
||||
gpr_log( |
||||
GPR_ERROR, |
||||
"Invalid nullptr arguments to local_zero_copy_grpc_protector create."); |
||||
return TSI_INVALID_ARGUMENT; |
||||
} |
||||
local_zero_copy_grpc_protector* impl = |
||||
static_cast<local_zero_copy_grpc_protector*>(gpr_zalloc(sizeof(*impl))); |
||||
impl->base.vtable = &local_zero_copy_grpc_protector_vtable; |
||||
*protector = &impl->base; |
||||
return TSI_OK; |
||||
} |
||||
|
||||
/* --- tsi_handshaker_result methods implementation. --- */ |
||||
|
||||
static tsi_result handshaker_result_extract_peer( |
||||
const tsi_handshaker_result* self, tsi_peer* peer) { |
||||
return TSI_OK; |
||||
} |
||||
|
||||
static tsi_result handshaker_result_create_zero_copy_grpc_protector( |
||||
const tsi_handshaker_result* self, size_t* max_output_protected_frame_size, |
||||
tsi_zero_copy_grpc_protector** protector) { |
||||
if (self == nullptr || protector == nullptr) { |
||||
gpr_log(GPR_ERROR, |
||||
"Invalid arguments to create_zero_copy_grpc_protector()"); |
||||
return TSI_INVALID_ARGUMENT; |
||||
} |
||||
tsi_result ok = local_zero_copy_grpc_protector_create(protector); |
||||
if (ok != TSI_OK) { |
||||
gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector"); |
||||
} |
||||
return ok; |
||||
} |
||||
|
||||
static void handshaker_result_destroy(tsi_handshaker_result* self) { |
||||
if (self == nullptr) { |
||||
return; |
||||
} |
||||
local_tsi_handshaker_result* result = |
||||
reinterpret_cast<local_tsi_handshaker_result*>( |
||||
const_cast<tsi_handshaker_result*>(self)); |
||||
gpr_free(result->peer_identity); |
||||
gpr_free(result); |
||||
} |
||||
|
||||
static const tsi_handshaker_result_vtable result_vtable = { |
||||
handshaker_result_extract_peer, |
||||
handshaker_result_create_zero_copy_grpc_protector, |
||||
nullptr, /* handshaker_result_create_frame_protector */ |
||||
nullptr, /* handshaker_result_get_unused_bytes */ |
||||
handshaker_result_destroy}; |
||||
|
||||
static tsi_result create_handshaker_result(bool is_client, |
||||
tsi_handshaker_result** self) { |
||||
if (self == nullptr) { |
||||
gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()"); |
||||
return TSI_INVALID_ARGUMENT; |
||||
} |
||||
local_tsi_handshaker_result* result = |
||||
static_cast<local_tsi_handshaker_result*>(gpr_zalloc(sizeof(*result))); |
||||
result->is_client = is_client; |
||||
result->base.vtable = &result_vtable; |
||||
/* Create a peer identity with random information that will be later converted
|
||||
* to auth context. Without this peer identity, the santiy check in {client, |
||||
* server}_auth_filter that verifies if the peer's auth context is obtained |
||||
* during handshakes will fail. Since the peer identity information in auth |
||||
* context is only checked for its existence (not actually used), we only |
||||
* populate some random data and later will provision more meaningful peer if |
||||
* needed (e.g., peer's pid/uid/gid from credentials). |
||||
*/ |
||||
result->peer_identity = gpr_strdup(TSI_LOCAL_PEER_IDENTITY); |
||||
*self = &result->base; |
||||
return TSI_OK; |
||||
} |
||||
|
||||
/* --- tsi_handshaker methods implementation. --- */ |
||||
|
||||
static tsi_result handshaker_next( |
||||
tsi_handshaker* self, const unsigned char* received_bytes, |
||||
size_t received_bytes_size, const unsigned char** bytes_to_send, |
||||
size_t* bytes_to_send_size, tsi_handshaker_result** result, |
||||
tsi_handshaker_on_next_done_cb cb, void* user_data) { |
||||
if (self == nullptr) { |
||||
gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()"); |
||||
return TSI_INVALID_ARGUMENT; |
||||
} |
||||
/* Note that there is no interaction between TSI peers, and all operations are
|
||||
* local. |
||||
*/ |
||||
local_tsi_handshaker* handshaker = |
||||
reinterpret_cast<local_tsi_handshaker*>(self); |
||||
*bytes_to_send_size = 0; |
||||
create_handshaker_result(handshaker->is_client, result); |
||||
return TSI_OK; |
||||
} |
||||
|
||||
static void handshaker_destroy(tsi_handshaker* self) { |
||||
if (self == nullptr) { |
||||
return; |
||||
} |
||||
local_tsi_handshaker* handshaker = |
||||
reinterpret_cast<local_tsi_handshaker*>(self); |
||||
gpr_free(handshaker); |
||||
} |
||||
|
||||
static const tsi_handshaker_vtable handshaker_vtable = { |
||||
nullptr, /* get_bytes_to_send_to_peer -- deprecated */ |
||||
nullptr, /* process_bytes_from_peer -- deprecated */ |
||||
nullptr, /* get_result -- deprecated */ |
||||
nullptr, /* extract_peer -- deprecated */ |
||||
nullptr, /* create_frame_protector -- deprecated */ |
||||
handshaker_destroy, |
||||
handshaker_next, |
||||
nullptr, /* shutdown */ |
||||
}; |
||||
|
||||
tsi_result local_tsi_handshaker_create(bool is_client, tsi_handshaker** self) { |
||||
if (self == nullptr) { |
||||
gpr_log(GPR_ERROR, "Invalid arguments to local_tsi_handshaker_create()"); |
||||
return TSI_INVALID_ARGUMENT; |
||||
} |
||||
local_tsi_handshaker* handshaker = |
||||
static_cast<local_tsi_handshaker*>(gpr_zalloc(sizeof(*handshaker))); |
||||
handshaker->is_client = is_client; |
||||
handshaker->base.vtable = &handshaker_vtable; |
||||
*self = &handshaker->base; |
||||
return TSI_OK; |
||||
} |
@ -0,0 +1,51 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_TSI_LOCAL_TRANSPORT_SECURITY_H |
||||
#define GRPC_CORE_TSI_LOCAL_TRANSPORT_SECURITY_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpc/grpc.h> |
||||
|
||||
#include "src/core/tsi/transport_security.h" |
||||
#include "src/core/tsi/transport_security_interface.h" |
||||
|
||||
#define TSI_LOCAL_NUM_OF_PEER_PROPERTIES 1 |
||||
#define TSI_LOCAL_PROCESS_ID_PEER_PROPERTY "process_id" |
||||
|
||||
/**
|
||||
* Main struct for local TSI handshaker. All APIs in the header are |
||||
* thread-comptabile. |
||||
*/ |
||||
typedef struct local_tsi_handshaker local_tsi_handshaker; |
||||
|
||||
/**
|
||||
* This method creates a local TSI handshaker instance. |
||||
* |
||||
* - is_client: boolean value indicating if the handshaker is used at the client |
||||
* (is_client = true) or server (is_client = false) side. The parameter is |
||||
* added for future extension. |
||||
* - self: address of local TSI handshaker instance to be returned from the |
||||
* method. |
||||
* |
||||
* It returns TSI_OK on success and an error status code on failure. |
||||
*/ |
||||
tsi_result local_tsi_handshaker_create(bool is_client, tsi_handshaker** self); |
||||
|
||||
#endif /* GRPC_CORE_TSI_LOCAL_TRANSPORT_SECURITY_H */ |
@ -0,0 +1,149 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 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 "test/core/end2end/end2end_tests.h" |
||||
|
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <unistd.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/string_util.h> |
||||
#include <grpc/support/sync.h> |
||||
|
||||
#include "src/core/ext/filters/client_channel/client_channel.h" |
||||
#include "src/core/ext/filters/http/server/http_server_filter.h" |
||||
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" |
||||
#include "src/core/lib/channel/connected_channel.h" |
||||
#include "src/core/lib/gpr/host_port.h" |
||||
#include "src/core/lib/gpr/string.h" |
||||
#include "src/core/lib/security/credentials/credentials.h" |
||||
#include "src/core/lib/surface/channel.h" |
||||
#include "src/core/lib/surface/server.h" |
||||
#include "test/core/util/port.h" |
||||
#include "test/core/util/test_config.h" |
||||
|
||||
typedef struct fullstack_fixture_data { |
||||
char* localaddr; |
||||
} fullstack_fixture_data; |
||||
|
||||
static int unique = 1; |
||||
|
||||
static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( |
||||
grpc_channel_args* client_args, grpc_channel_args* server_args) { |
||||
grpc_end2end_test_fixture f; |
||||
fullstack_fixture_data* ffd = static_cast<fullstack_fixture_data*>( |
||||
gpr_malloc(sizeof(fullstack_fixture_data))); |
||||
memset(&f, 0, sizeof(f)); |
||||
|
||||
gpr_asprintf(&ffd->localaddr, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), |
||||
unique++); |
||||
|
||||
f.fixture_data = ffd; |
||||
f.cq = grpc_completion_queue_create_for_next(nullptr); |
||||
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); |
||||
|
||||
return f; |
||||
} |
||||
|
||||
void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, |
||||
grpc_channel_args* client_args) { |
||||
grpc_channel_credentials* creds = grpc_local_credentials_create(UDS); |
||||
fullstack_fixture_data* ffd = |
||||
static_cast<fullstack_fixture_data*>(f->fixture_data); |
||||
f->client = |
||||
grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); |
||||
GPR_ASSERT(f->client != nullptr); |
||||
grpc_channel_credentials_release(creds); |
||||
} |
||||
|
||||
static int fail_server_auth_check(grpc_channel_args* server_args) { |
||||
size_t i; |
||||
if (server_args == nullptr) return 0; |
||||
for (i = 0; i < server_args->num_args; i++) { |
||||
if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == |
||||
0) { |
||||
return 1; |
||||
} |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static void process_auth_failure(void* state, grpc_auth_context* ctx, |
||||
const grpc_metadata* md, size_t md_count, |
||||
grpc_process_auth_metadata_done_cb cb, |
||||
void* user_data) { |
||||
GPR_ASSERT(state == nullptr); |
||||
cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr); |
||||
} |
||||
|
||||
void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, |
||||
grpc_channel_args* server_args) { |
||||
grpc_server_credentials* creds = grpc_local_server_credentials_create(UDS); |
||||
fullstack_fixture_data* ffd = |
||||
static_cast<fullstack_fixture_data*>(f->fixture_data); |
||||
if (f->server) { |
||||
grpc_server_destroy(f->server); |
||||
} |
||||
f->server = grpc_server_create(server_args, nullptr); |
||||
grpc_server_register_completion_queue(f->server, f->cq, nullptr); |
||||
if (fail_server_auth_check(server_args)) { |
||||
grpc_auth_metadata_processor processor = {process_auth_failure, nullptr, |
||||
nullptr}; |
||||
grpc_server_credentials_set_auth_metadata_processor(creds, processor); |
||||
} |
||||
GPR_ASSERT( |
||||
grpc_server_add_secure_http2_port(f->server, ffd->localaddr, creds)); |
||||
grpc_server_credentials_release(creds); |
||||
grpc_server_start(f->server); |
||||
} |
||||
|
||||
void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { |
||||
fullstack_fixture_data* ffd = |
||||
static_cast<fullstack_fixture_data*>(f->fixture_data); |
||||
gpr_free(ffd->localaddr); |
||||
gpr_free(ffd); |
||||
} |
||||
|
||||
/* All test configurations */ |
||||
static grpc_end2end_test_config configs[] = { |
||||
{"chttp2/fullstack_local", |
||||
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | |
||||
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | |
||||
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER | |
||||
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, |
||||
nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, |
||||
chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, |
||||
}; |
||||
|
||||
int main(int argc, char** argv) { |
||||
size_t i; |
||||
|
||||
grpc_test_init(argc, argv); |
||||
grpc_end2end_tests_pre_init(); |
||||
grpc_init(); |
||||
|
||||
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { |
||||
grpc_end2end_tests(argc, argv, configs[i]); |
||||
} |
||||
|
||||
grpc_shutdown(); |
||||
|
||||
return 0; |
||||
} |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue