|
|
|
@ -22,6 +22,7 @@ |
|
|
|
|
|
|
|
|
|
#include <stdbool.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <limits> |
|
|
|
|
|
|
|
|
|
#include <grpc/slice_buffer.h> |
|
|
|
|
#include <grpc/support/alloc.h> |
|
|
|
@ -46,7 +47,8 @@ namespace { |
|
|
|
|
class SecurityHandshaker : public Handshaker { |
|
|
|
|
public: |
|
|
|
|
SecurityHandshaker(tsi_handshaker* handshaker, |
|
|
|
|
grpc_security_connector* connector); |
|
|
|
|
grpc_security_connector* connector, |
|
|
|
|
const grpc_channel_args* args); |
|
|
|
|
~SecurityHandshaker() override; |
|
|
|
|
void Shutdown(grpc_error* why) override; |
|
|
|
|
void DoHandshake(grpc_tcp_server_acceptor* acceptor, |
|
|
|
@ -97,15 +99,23 @@ class SecurityHandshaker : public Handshaker { |
|
|
|
|
grpc_closure on_peer_checked_; |
|
|
|
|
RefCountedPtr<grpc_auth_context> auth_context_; |
|
|
|
|
tsi_handshaker_result* handshaker_result_ = nullptr; |
|
|
|
|
size_t max_frame_size_ = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
SecurityHandshaker::SecurityHandshaker(tsi_handshaker* handshaker, |
|
|
|
|
grpc_security_connector* connector) |
|
|
|
|
grpc_security_connector* connector, |
|
|
|
|
const grpc_channel_args* args) |
|
|
|
|
: handshaker_(handshaker), |
|
|
|
|
connector_(connector->Ref(DEBUG_LOCATION, "handshake")), |
|
|
|
|
handshake_buffer_size_(GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE), |
|
|
|
|
handshake_buffer_( |
|
|
|
|
static_cast<uint8_t*>(gpr_malloc(handshake_buffer_size_))) { |
|
|
|
|
const grpc_arg* arg = |
|
|
|
|
grpc_channel_args_find(args, GRPC_ARG_TSI_MAX_FRAME_SIZE); |
|
|
|
|
if (arg != nullptr && arg->type == GRPC_ARG_INTEGER) { |
|
|
|
|
max_frame_size_ = grpc_channel_arg_get_integer( |
|
|
|
|
arg, {0, 0, std::numeric_limits<int>::max()}); |
|
|
|
|
} |
|
|
|
|
gpr_mu_init(&mu_); |
|
|
|
|
grpc_slice_buffer_init(&outgoing_); |
|
|
|
|
GRPC_CLOSURE_INIT(&on_handshake_data_sent_to_peer_, |
|
|
|
@ -201,7 +211,8 @@ void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) { |
|
|
|
|
// Create zero-copy frame protector, if implemented.
|
|
|
|
|
tsi_zero_copy_grpc_protector* zero_copy_protector = nullptr; |
|
|
|
|
tsi_result result = tsi_handshaker_result_create_zero_copy_grpc_protector( |
|
|
|
|
handshaker_result_, nullptr, &zero_copy_protector); |
|
|
|
|
handshaker_result_, max_frame_size_ == 0 ? nullptr : &max_frame_size_, |
|
|
|
|
&zero_copy_protector); |
|
|
|
|
if (result != TSI_OK && result != TSI_UNIMPLEMENTED) { |
|
|
|
|
error = grpc_set_tsi_error_result( |
|
|
|
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
@ -213,8 +224,9 @@ void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) { |
|
|
|
|
// Create frame protector if zero-copy frame protector is NULL.
|
|
|
|
|
tsi_frame_protector* protector = nullptr; |
|
|
|
|
if (zero_copy_protector == nullptr) { |
|
|
|
|
result = tsi_handshaker_result_create_frame_protector(handshaker_result_, |
|
|
|
|
nullptr, &protector); |
|
|
|
|
result = tsi_handshaker_result_create_frame_protector( |
|
|
|
|
handshaker_result_, max_frame_size_ == 0 ? nullptr : &max_frame_size_, |
|
|
|
|
&protector); |
|
|
|
|
if (result != TSI_OK) { |
|
|
|
|
error = grpc_set_tsi_error_result(GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
"Frame protector creation failed"), |
|
|
|
@ -459,7 +471,8 @@ class ClientSecurityHandshakerFactory : public HandshakerFactory { |
|
|
|
|
reinterpret_cast<grpc_channel_security_connector*>( |
|
|
|
|
grpc_security_connector_find_in_args(args)); |
|
|
|
|
if (security_connector) { |
|
|
|
|
security_connector->add_handshakers(interested_parties, handshake_mgr); |
|
|
|
|
security_connector->add_handshakers(args, interested_parties, |
|
|
|
|
handshake_mgr); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
~ClientSecurityHandshakerFactory() override = default; |
|
|
|
@ -474,7 +487,8 @@ class ServerSecurityHandshakerFactory : public HandshakerFactory { |
|
|
|
|
reinterpret_cast<grpc_server_security_connector*>( |
|
|
|
|
grpc_security_connector_find_in_args(args)); |
|
|
|
|
if (security_connector) { |
|
|
|
|
security_connector->add_handshakers(interested_parties, handshake_mgr); |
|
|
|
|
security_connector->add_handshakers(args, interested_parties, |
|
|
|
|
handshake_mgr); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
~ServerSecurityHandshakerFactory() override = default; |
|
|
|
@ -487,13 +501,14 @@ class ServerSecurityHandshakerFactory : public HandshakerFactory { |
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
RefCountedPtr<Handshaker> SecurityHandshakerCreate( |
|
|
|
|
tsi_handshaker* handshaker, grpc_security_connector* connector) { |
|
|
|
|
tsi_handshaker* handshaker, grpc_security_connector* connector, |
|
|
|
|
const grpc_channel_args* args) { |
|
|
|
|
// If no TSI handshaker was created, return a handshaker that always fails.
|
|
|
|
|
// Otherwise, return a real security handshaker.
|
|
|
|
|
if (handshaker == nullptr) { |
|
|
|
|
return MakeRefCounted<FailHandshaker>(); |
|
|
|
|
} else { |
|
|
|
|
return MakeRefCounted<SecurityHandshaker>(handshaker, connector); |
|
|
|
|
return MakeRefCounted<SecurityHandshaker>(handshaker, connector, args); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -509,6 +524,7 @@ void SecurityRegisterHandshakerFactories() { |
|
|
|
|
} // namespace grpc_core
|
|
|
|
|
|
|
|
|
|
grpc_handshaker* grpc_security_handshaker_create( |
|
|
|
|
tsi_handshaker* handshaker, grpc_security_connector* connector) { |
|
|
|
|
return SecurityHandshakerCreate(handshaker, connector).release(); |
|
|
|
|
tsi_handshaker* handshaker, grpc_security_connector* connector, |
|
|
|
|
const grpc_channel_args* args) { |
|
|
|
|
return SecurityHandshakerCreate(handshaker, connector, args).release(); |
|
|
|
|
} |
|
|
|
|