diff options
Diffstat (limited to 'src/core/lib')
13 files changed, 1262 insertions, 0 deletions
diff --git a/src/core/lib/security/credentials/alts/alts_credentials.cc b/src/core/lib/security/credentials/alts/alts_credentials.cc new file mode 100644 index 0000000000..fa05d901bf --- /dev/null +++ b/src/core/lib/security/credentials/alts/alts_credentials.cc @@ -0,0 +1,119 @@ +/* + * + * 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/alts/alts_credentials.h" + +#include <cstring> + +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/lib/security/credentials/alts/check_gcp_environment.h" +#include "src/core/lib/security/security_connector/alts_security_connector.h" + +#define GRPC_CREDENTIALS_TYPE_ALTS "Alts" +#define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080" + +static void alts_credentials_destruct(grpc_channel_credentials* creds) { + grpc_alts_credentials* alts_creds = + reinterpret_cast<grpc_alts_credentials*>(creds); + grpc_alts_credentials_options_destroy(alts_creds->options); + gpr_free(alts_creds->handshaker_service_url); +} + +static void alts_server_credentials_destruct(grpc_server_credentials* creds) { + grpc_alts_server_credentials* alts_creds = + reinterpret_cast<grpc_alts_server_credentials*>(creds); + grpc_alts_credentials_options_destroy(alts_creds->options); + gpr_free(alts_creds->handshaker_service_url); +} + +static grpc_security_status alts_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_alts_channel_security_connector_create( + creds, request_metadata_creds, target_name, sc); +} + +static grpc_security_status alts_server_create_security_connector( + grpc_server_credentials* creds, grpc_server_security_connector** sc) { + return grpc_alts_server_security_connector_create(creds, sc); +} + +static const grpc_channel_credentials_vtable alts_credentials_vtable = { + alts_credentials_destruct, alts_create_security_connector, + /*duplicate_without_call_credentials=*/nullptr}; + +static const grpc_server_credentials_vtable alts_server_credentials_vtable = { + alts_server_credentials_destruct, alts_server_create_security_connector}; + +grpc_channel_credentials* grpc_alts_credentials_create_customized( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url, bool enable_untrusted_alts) { + if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) { + return nullptr; + } + auto creds = static_cast<grpc_alts_credentials*>( + gpr_zalloc(sizeof(grpc_alts_credentials))); + creds->options = grpc_alts_credentials_options_copy(options); + creds->handshaker_service_url = + handshaker_service_url == nullptr + ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) + : gpr_strdup(handshaker_service_url); + creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS; + creds->base.vtable = &alts_credentials_vtable; + gpr_ref_init(&creds->base.refcount, 1); + return &creds->base; +} + +grpc_server_credentials* grpc_alts_server_credentials_create_customized( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url, bool enable_untrusted_alts) { + if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) { + return nullptr; + } + auto creds = static_cast<grpc_alts_server_credentials*>( + gpr_zalloc(sizeof(grpc_alts_server_credentials))); + creds->options = grpc_alts_credentials_options_copy(options); + creds->handshaker_service_url = + handshaker_service_url == nullptr + ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL) + : gpr_strdup(handshaker_service_url); + creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS; + creds->base.vtable = &alts_server_credentials_vtable; + gpr_ref_init(&creds->base.refcount, 1); + return &creds->base; +} + +grpc_channel_credentials* grpc_alts_credentials_create( + const grpc_alts_credentials_options* options) { + return grpc_alts_credentials_create_customized( + options, GRPC_ALTS_HANDSHAKER_SERVICE_URL, false); +} + +grpc_server_credentials* grpc_alts_server_credentials_create( + const grpc_alts_credentials_options* options) { + return grpc_alts_server_credentials_create_customized( + options, GRPC_ALTS_HANDSHAKER_SERVICE_URL, false); +} diff --git a/src/core/lib/security/credentials/alts/alts_credentials.h b/src/core/lib/security/credentials/alts/alts_credentials.h new file mode 100644 index 0000000000..621789cf65 --- /dev/null +++ b/src/core/lib/security/credentials/alts/alts_credentials.h @@ -0,0 +1,102 @@ +/* + * + * 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_ALTS_ALTS_CREDENTIALS_H +#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_ALTS_CREDENTIALS_H + +#include <grpc/support/port_platform.h> + +#include <grpc/grpc_security.h> + +#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" +#include "src/core/lib/security/credentials/credentials.h" + +/* Main struct for grpc ALTS channel credential. */ +typedef struct grpc_alts_credentials { + grpc_channel_credentials base; + grpc_alts_credentials_options* options; + char* handshaker_service_url; +} grpc_alts_credentials; + +/* Main struct for grpc ALTS server credential. */ +typedef struct grpc_alts_server_credentials { + grpc_server_credentials base; + grpc_alts_credentials_options* options; + char* handshaker_service_url; +} grpc_alts_server_credentials; + +/** + * This method creates an ALTS channel credential object. + * + * - options: grpc ALTS credentials options instance for client. + * + * It returns the created ALTS channel credential object. + */ +grpc_channel_credentials* grpc_alts_credentials_create( + const grpc_alts_credentials_options* options); + +/** + * This method creates an ALTS server credential object. + * + * - options: grpc ALTS credentials options instance for server. + * + * It returns the created ALTS server credential object. + */ +grpc_server_credentials* grpc_alts_server_credentials_create( + const grpc_alts_credentials_options* options); + +/** + * This method creates an ALTS channel credential object with customized + * information provided by caller. + * + * - options: grpc ALTS credentials options instance for client. + * - handshaker_service_url: address of ALTS handshaker service in the format of + * "host:port". If it's nullptr, the address of default metadata server will + * be used. + * - enable_untrusted_alts: a boolean flag used to enable ALTS in untrusted + * mode. This mode can be enabled when we are sure ALTS is running on GCP or + * for testing purpose. + * + * It returns nullptr if the flag is disabled AND ALTS is not running on GCP. + * Otherwise, it returns the created credential object. + */ + +grpc_channel_credentials* grpc_alts_credentials_create_customized( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url, bool enable_untrusted_alts); + +/** + * This method creates an ALTS server credential object with customized + * information provided by caller. + * + * - options: grpc ALTS credentials options instance for server. + * - handshaker_service_url: address of ALTS handshaker service in the format of + * "host:port". If it's nullptr, the address of default metadata server will + * be used. + * - enable_untrusted_alts: a boolean flag used to enable ALTS in untrusted + * mode. This mode can be enabled when we are sure ALTS is running on GCP or + * for testing purpose. + * + * It returns nullptr if the flag is disabled and ALTS is not running on GCP. + * Otherwise, it returns the created credential object. + */ +grpc_server_credentials* grpc_alts_server_credentials_create_customized( + const grpc_alts_credentials_options* options, + const char* handshaker_service_url, bool enable_untrusted_alts); + +#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_ALTS_CREDENTIALS_H */ diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment.cc b/src/core/lib/security/credentials/alts/check_gcp_environment.cc new file mode 100644 index 0000000000..96807876cf --- /dev/null +++ b/src/core/lib/security/credentials/alts/check_gcp_environment.cc @@ -0,0 +1,72 @@ +/* + * + * 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/alts/check_gcp_environment.h" + +#include <ctype.h> +#include <stdio.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +const size_t kBiosDataBufferSize = 256; + +static char* trim(const char* src) { + if (src == nullptr) { + return nullptr; + } + char* des = nullptr; + size_t start = 0, end = strlen(src) - 1; + /* find the last character that is not a whitespace. */ + while (end != 0 && isspace(src[end])) { + end--; + } + /* find the first character that is not a whitespace. */ + while (start < strlen(src) && isspace(src[start])) { + start++; + } + if (start <= end) { + des = static_cast<char*>( + gpr_zalloc(sizeof(char) * (end - start + 2 /* '\0' */))); + memcpy(des, src + start, end - start + 1); + } + return des; +} + +namespace grpc_core { +namespace internal { + +char* read_bios_file(const char* bios_file) { + FILE* fp = fopen(bios_file, "r"); + if (!fp) { + gpr_log(GPR_ERROR, "BIOS data file cannot be opened."); + return nullptr; + } + char buf[kBiosDataBufferSize + 1]; + size_t ret = fread(buf, sizeof(char), kBiosDataBufferSize, fp); + buf[ret] = '\0'; + char* trimmed_buf = trim(buf); + fclose(fp); + return trimmed_buf; +} + +} // namespace internal +} // namespace grpc_core diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment.h b/src/core/lib/security/credentials/alts/check_gcp_environment.h new file mode 100644 index 0000000000..aea4cea643 --- /dev/null +++ b/src/core/lib/security/credentials/alts/check_gcp_environment.h @@ -0,0 +1,57 @@ +/* + * + * 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_ALTS_CHECK_GCP_ENVIRONMENT_H +#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_CHECK_GCP_ENVIRONMENT_H + +namespace grpc_core { +namespace internal { + +/** + * This method is a helper function that reads a file containing system bios + * data. Exposed for testing only. + * + * - bios_file: a file containing BIOS data used to determine GCE tenancy + * information. + * + * It returns a buffer containing the data read from the file. + */ +char* read_bios_file(const char* bios_file); + +/** + * This method checks if system BIOS data contains Google-specific phrases. + * Exposed for testing only. + * + * - bios_data: a buffer containing system BIOS data. + * + * It returns true if the BIOS data contains Google-specific phrases, and false + * otherwise. + */ +bool check_bios_data(const char* bios_data); + +} // namespace internal +} // namespace grpc_core + +/** + * This method checks if a VM (Windows or Linux) is running within Google + * compute Engine (GCE) or not. It returns true if the VM is running in GCE and + * false otherwise. + */ +bool grpc_alts_is_running_on_gcp(); + +#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_CHECK_GCP_ENVIRONMENT_H */ diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc b/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc new file mode 100644 index 0000000000..7c4d7a71cd --- /dev/null +++ b/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc @@ -0,0 +1,67 @@ +/* + * + * 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> + +#ifdef GPR_LINUX + +#include "src/core/lib/security/credentials/alts/check_gcp_environment.h" + +#include <grpc/support/alloc.h> +#include <grpc/support/sync.h> + +#include <string.h> + +#define GRPC_ALTS_EXPECT_NAME_GOOGLE "Google" +#define GRPC_ALTS_EXPECT_NAME_GCE "Google Compute Engine" +#define GRPC_ALTS_PRODUCT_NAME_FILE "/sys/class/dmi/id/product_name" + +static bool g_compute_engine_detection_done = false; +static bool g_is_on_compute_engine = false; +static gpr_mu g_mu; +static gpr_once g_once = GPR_ONCE_INIT; + +namespace grpc_core { +namespace internal { + +bool check_bios_data(const char* bios_data_file) { + char* bios_data = read_bios_file(bios_data_file); + bool result = (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GOOGLE)) || + (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GCE)); + gpr_free(bios_data); + return result; +} + +} // namespace internal +} // namespace grpc_core + +static void init_mu(void) { gpr_mu_init(&g_mu); } + +bool grpc_alts_is_running_on_gcp() { + gpr_once_init(&g_once, init_mu); + gpr_mu_lock(&g_mu); + if (!g_compute_engine_detection_done) { + g_is_on_compute_engine = + grpc_core::internal::check_bios_data(GRPC_ALTS_PRODUCT_NAME_FILE); + g_compute_engine_detection_done = true; + } + gpr_mu_unlock(&g_mu); + return g_is_on_compute_engine; +} + +#endif // GPR_LINUX diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc b/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc new file mode 100644 index 0000000000..d97681b86d --- /dev/null +++ b/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc @@ -0,0 +1,33 @@ +/* + * + * 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> + +#if !defined(GPR_LINUX) && !defined(GPR_WINDOWS) + +#include "src/core/lib/security/credentials/alts/check_gcp_environment.h" + +#include <grpc/support/log.h> + +bool grpc_alts_is_running_on_gcp() { + gpr_log(GPR_ERROR, + "Platforms other than Linux and Windows are not supported"); + return false; +} + +#endif // !defined(LINUX) && !defined(GPR_WINDOWS) diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc b/src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc new file mode 100644 index 0000000000..55efe0e9dd --- /dev/null +++ b/src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc @@ -0,0 +1,114 @@ +/* + * + * 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> + +#ifdef GPR_WINDOWS + +#include "src/core/lib/security/credentials/alts/check_gcp_environment.h" + +#include <shellapi.h> +#include <stdio.h> +#include <tchar.h> +#include <windows.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/sync.h> + +#define GRPC_ALTS_EXPECT_NAME_GOOGLE "Google" +#define GRPC_ALTS_WINDOWS_CHECK_COMMAND "powershell.exe" +#define GRPC_ALTS_WINDOWS_CHECK_COMMAND_ARGS \ + "(Get-WmiObject -Class Win32_BIOS).Manufacturer" +#define GRPC_ALTS_WINDOWS_CHECK_BIOS_FILE "windows_bios.data" + +const size_t kBiosDataBufferSize = 256; + +static bool g_compute_engine_detection_done = false; +static bool g_is_on_compute_engine = false; +static gpr_mu g_mu; +static gpr_once g_once = GPR_ONCE_INIT; + +namespace grpc_core { +namespace internal { + +bool check_bios_data(const char* bios_data_file) { + char* bios_data = read_bios_file(bios_data_file); + bool result = !strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GOOGLE); + remove(GRPC_ALTS_WINDOWS_CHECK_BIOS_FILE); + gpr_free(bios_data); + return result; +} + +} // namespace internal +} // namespace grpc_core + +static void init_mu(void) { gpr_mu_init(&g_mu); } + +static bool run_powershell() { + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + HANDLE h = CreateFile(_T(GRPC_ALTS_WINDOWS_CHECK_BIOS_FILE), GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, &sa, OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) { + gpr_log(GPR_ERROR, "CreateFile failed (%d).", GetLastError()); + return false; + } + PROCESS_INFORMATION pi; + STARTUPINFO si; + DWORD flags = CREATE_NO_WINDOW; + ZeroMemory(&pi, sizeof(pi)); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags |= STARTF_USESTDHANDLES; + si.hStdInput = NULL; + si.hStdError = h; + si.hStdOutput = h; + TCHAR cmd[kBiosDataBufferSize]; + _sntprintf(cmd, kBiosDataBufferSize, _T("%s %s"), + _T(GRPC_ALTS_WINDOWS_CHECK_COMMAND), + _T(GRPC_ALTS_WINDOWS_CHECK_COMMAND_ARGS)); + if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, + &pi)) { + gpr_log(GPR_ERROR, "CreateProcess failed (%d).\n", GetLastError()); + return false; + } + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + CloseHandle(h); + return true; +} + +bool grpc_alts_is_running_on_gcp() { + gpr_once_init(&g_once, init_mu); + gpr_mu_lock(&g_mu); + if (!g_compute_engine_detection_done) { + g_is_on_compute_engine = + run_powershell() && + grpc_core::internal::check_bios_data(GRPC_ALTS_WINDOWS_CHECK_BIOS_FILE); + g_compute_engine_detection_done = true; + } + gpr_mu_unlock(&g_mu); + return g_is_on_compute_engine; +} + +#endif // GPR_WINDOWS diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc b/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc new file mode 100644 index 0000000000..7d54e8346f --- /dev/null +++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc @@ -0,0 +1,126 @@ +/* + * + * 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 <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/security/credentials/alts/grpc_alts_credentials_options.h" +#include "src/core/tsi/alts/handshaker/transport_security_common_api.h" + +static grpc_alts_credentials_options* alts_client_options_copy( + const grpc_alts_credentials_options* options); + +static void alts_client_options_destroy(grpc_alts_credentials_options* options); + +static target_service_account* target_service_account_create( + const char* service_account) { + if (service_account == nullptr) { + return nullptr; + } + auto* sa = static_cast<target_service_account*>( + gpr_zalloc(sizeof(target_service_account))); + sa->data = gpr_strdup(service_account); + return sa; +} + +bool grpc_alts_credentials_client_options_add_target_service_account( + grpc_alts_credentials_client_options* options, + const char* service_account) { + if (options == nullptr || service_account == nullptr) { + gpr_log( + GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_alts_credentials_client_options_add_target_service_account()"); + return false; + } + target_service_account* node = target_service_account_create(service_account); + node->next = options->target_account_list_head; + options->target_account_list_head = node; + return true; +} + +static void target_service_account_destroy( + target_service_account* service_account) { + if (service_account == nullptr) { + return; + } + gpr_free(service_account->data); + gpr_free(service_account); +} + +static const grpc_alts_credentials_options_vtable vtable = { + alts_client_options_copy, alts_client_options_destroy}; + +grpc_alts_credentials_options* grpc_alts_credentials_client_options_create() { + auto client_options = static_cast<grpc_alts_credentials_client_options*>( + gpr_zalloc(sizeof(grpc_alts_credentials_client_options))); + client_options->base.vtable = &vtable; + return &client_options->base; +} + +static grpc_alts_credentials_options* alts_client_options_copy( + const grpc_alts_credentials_options* options) { + if (options == nullptr) { + return nullptr; + } + grpc_alts_credentials_options* new_options = + grpc_alts_credentials_client_options_create(); + auto new_client_options = + reinterpret_cast<grpc_alts_credentials_client_options*>(new_options); + /* Copy target service accounts. */ + target_service_account* prev = nullptr; + auto node = + (reinterpret_cast<const grpc_alts_credentials_client_options*>(options)) + ->target_account_list_head; + while (node != nullptr) { + target_service_account* new_node = + target_service_account_create(node->data); + if (prev == nullptr) { + new_client_options->target_account_list_head = new_node; + } else { + prev->next = new_node; + } + prev = new_node; + node = node->next; + } + /* Copy rpc protocol versions. */ + grpc_gcp_rpc_protocol_versions_copy(&options->rpc_versions, + &new_options->rpc_versions); + return new_options; +} + +static void alts_client_options_destroy( + grpc_alts_credentials_options* options) { + if (options == nullptr) { + return; + } + auto* client_options = + reinterpret_cast<grpc_alts_credentials_client_options*>(options); + target_service_account* node = client_options->target_account_list_head; + while (node != nullptr) { + target_service_account* next_node = node->next; + target_service_account_destroy(node); + node = next_node; + } +} diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc b/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc new file mode 100644 index 0000000000..d428171540 --- /dev/null +++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc @@ -0,0 +1,46 @@ +/* + * + * 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/alts/grpc_alts_credentials_options.h" + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +grpc_alts_credentials_options* grpc_alts_credentials_options_copy( + const grpc_alts_credentials_options* options) { + if (options != nullptr && options->vtable != nullptr && + options->vtable->copy != nullptr) { + return options->vtable->copy(options); + } + /* An error occurred. */ + gpr_log(GPR_ERROR, + "Invalid arguments to grpc_alts_credentials_options_copy()"); + return nullptr; +} + +void grpc_alts_credentials_options_destroy( + grpc_alts_credentials_options* options) { + if (options != nullptr) { + if (options->vtable != nullptr && options->vtable->destruct != nullptr) { + options->vtable->destruct(options); + } + gpr_free(options); + } +} diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h b/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h new file mode 100644 index 0000000000..4e46d9f2de --- /dev/null +++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h @@ -0,0 +1,112 @@ +/* + * + * 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_ALTS_GRPC_ALTS_CREDENTIALS_OPTIONS_H +#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_GRPC_ALTS_CREDENTIALS_OPTIONS_H + +#include <grpc/support/port_platform.h> + +#include <stdbool.h> + +#include "src/core/tsi/alts/handshaker/transport_security_common_api.h" + +/** + * Main interface for ALTS credentials options. The options will contain + * information that will be passed from grpc to TSI layer such as RPC protocol + * versions. ALTS client (channel) and server credentials will have their own + * implementation of this interface. The APIs listed in this header are + * thread-compatible. + */ +typedef struct grpc_alts_credentials_options grpc_alts_credentials_options; + +/* V-table for grpc_alts_credentials_options */ +typedef struct grpc_alts_credentials_options_vtable { + grpc_alts_credentials_options* (*copy)( + const grpc_alts_credentials_options* options); + void (*destruct)(grpc_alts_credentials_options* options); +} grpc_alts_credentials_options_vtable; + +struct grpc_alts_credentials_options { + const struct grpc_alts_credentials_options_vtable* vtable; + grpc_gcp_rpc_protocol_versions rpc_versions; +}; + +typedef struct target_service_account { + struct target_service_account* next; + char* data; +} target_service_account; + +/** + * Main struct for ALTS client credentials options. The options contain a + * a list of target service accounts (if specified) used for secure naming + * check. + */ +typedef struct grpc_alts_credentials_client_options { + grpc_alts_credentials_options base; + target_service_account* target_account_list_head; +} grpc_alts_credentials_client_options; + +/** + * Main struct for ALTS server credentials options. The options currently + * do not contain any server-specific fields. + */ +typedef struct grpc_alts_credentials_server_options { + grpc_alts_credentials_options base; +} grpc_alts_credentials_server_options; + +/** + * This method performs a deep copy on grpc_alts_credentials_options instance. + * + * - options: a grpc_alts_credentials_options instance that needs to be copied. + * + * It returns a new grpc_alts_credentials_options instance on success and NULL + * on failure. + */ +grpc_alts_credentials_options* grpc_alts_credentials_options_copy( + const grpc_alts_credentials_options* options); + +/** + * This method destroys a grpc_alts_credentials_options instance by + * de-allocating all of its occupied memory. + * + * - options: a grpc_alts_credentials_options instance that needs to be + * destroyed. + */ +void grpc_alts_credentials_options_destroy( + grpc_alts_credentials_options* options); + +/* This method creates a grpc ALTS credentials client options instance. */ +grpc_alts_credentials_options* grpc_alts_credentials_client_options_create(); + +/* This method creates a grpc ALTS credentials server options instance. */ +grpc_alts_credentials_options* grpc_alts_credentials_server_options_create(); + +/** + * This method adds a target service account to grpc ALTS credentials client + * options instance. + * + * - options: grpc ALTS credentials client options instance. + * - service_account: service account of target endpoint. + * + * It returns true on success and false on failure. + */ +bool grpc_alts_credentials_client_options_add_target_service_account( + grpc_alts_credentials_client_options* options, const char* service_account); + +#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_ALTS_GRPC_ALTS_CREDENTIALS_OPTIONS_H \ + */ diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc b/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc new file mode 100644 index 0000000000..62aa7a620a --- /dev/null +++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc @@ -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. + * + */ + +#include <grpc/support/port_platform.h> + +#include <stdlib.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" +#include "src/core/tsi/alts/handshaker/transport_security_common_api.h" + +static grpc_alts_credentials_options* alts_server_options_copy( + const grpc_alts_credentials_options* options); + +static void alts_server_options_destroy( + grpc_alts_credentials_options* options) {} + +static const grpc_alts_credentials_options_vtable vtable = { + alts_server_options_copy, alts_server_options_destroy}; + +grpc_alts_credentials_options* grpc_alts_credentials_server_options_create() { + grpc_alts_credentials_server_options* server_options = + static_cast<grpc_alts_credentials_server_options*>( + gpr_zalloc(sizeof(*server_options))); + server_options->base.vtable = &vtable; + return &server_options->base; +} + +static grpc_alts_credentials_options* alts_server_options_copy( + const grpc_alts_credentials_options* options) { + if (options == nullptr) { + return nullptr; + } + grpc_alts_credentials_options* new_options = + grpc_alts_credentials_server_options_create(); + /* Copy rpc protocol versions. */ + grpc_gcp_rpc_protocol_versions_copy(&options->rpc_versions, + &new_options->rpc_versions); + return new_options; +} diff --git a/src/core/lib/security/security_connector/alts_security_connector.cc b/src/core/lib/security/security_connector/alts_security_connector.cc new file mode 100644 index 0000000000..5ff7d7938b --- /dev/null +++ b/src/core/lib/security/security_connector/alts_security_connector.cc @@ -0,0 +1,287 @@ +/* + * + * 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/alts_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/lib/security/credentials/alts/alts_credentials.h" +#include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/lib/transport/transport.h" +#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" + +typedef struct { + grpc_channel_security_connector base; + char* target_name; +} grpc_alts_channel_security_connector; + +typedef struct { + grpc_server_security_connector base; +} grpc_alts_server_security_connector; + +static void alts_channel_destroy(grpc_security_connector* sc) { + if (sc == nullptr) { + return; + } + auto c = reinterpret_cast<grpc_alts_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 alts_server_destroy(grpc_security_connector* sc) { + if (sc == nullptr) { + return; + } + auto c = reinterpret_cast<grpc_alts_server_security_connector*>(sc); + grpc_server_credentials_unref(c->base.server_creds); + gpr_free(sc); +} + +static void alts_channel_add_handshakers( + grpc_channel_security_connector* sc, + grpc_handshake_manager* handshake_manager) { + tsi_handshaker* handshaker = nullptr; + auto c = reinterpret_cast<grpc_alts_channel_security_connector*>(sc); + grpc_alts_credentials* creds = + reinterpret_cast<grpc_alts_credentials*>(c->base.channel_creds); + GPR_ASSERT(alts_tsi_handshaker_create(creds->options, c->target_name, + creds->handshaker_service_url, true, + &handshaker) == TSI_OK); + grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( + handshaker, &sc->base)); +} + +static void alts_server_add_handshakers( + grpc_server_security_connector* sc, + grpc_handshake_manager* handshake_manager) { + tsi_handshaker* handshaker = nullptr; + auto c = reinterpret_cast<grpc_alts_server_security_connector*>(sc); + grpc_alts_server_credentials* creds = + reinterpret_cast<grpc_alts_server_credentials*>(c->base.server_creds); + GPR_ASSERT(alts_tsi_handshaker_create(creds->options, nullptr, + creds->handshaker_service_url, false, + &handshaker) == TSI_OK); + grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( + handshaker, &sc->base)); +} + +static void alts_set_rpc_protocol_versions( + grpc_gcp_rpc_protocol_versions* rpc_versions) { + grpc_gcp_rpc_protocol_versions_set_max(rpc_versions, + GRPC_PROTOCOL_VERSION_MAX_MAJOR, + GRPC_PROTOCOL_VERSION_MAX_MINOR); + grpc_gcp_rpc_protocol_versions_set_min(rpc_versions, + GRPC_PROTOCOL_VERSION_MIN_MAJOR, + GRPC_PROTOCOL_VERSION_MIN_MINOR); +} + +namespace grpc_core { +namespace internal { + +grpc_security_status grpc_alts_auth_context_from_tsi_peer( + const tsi_peer* peer, grpc_auth_context** ctx) { + if (peer == nullptr || ctx == nullptr) { + gpr_log(GPR_ERROR, + "Invalid arguments to grpc_alts_auth_context_from_tsi_peer()"); + return GRPC_SECURITY_ERROR; + } + *ctx = nullptr; + /* Validate certificate type. */ + const tsi_peer_property* cert_type_prop = + tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY); + if (cert_type_prop == nullptr || + strncmp(cert_type_prop->value.data, TSI_ALTS_CERTIFICATE_TYPE, + cert_type_prop->value.length) != 0) { + gpr_log(GPR_ERROR, "Invalid or missing certificate type property."); + return GRPC_SECURITY_ERROR; + } + /* Validate RPC protocol versions. */ + const tsi_peer_property* rpc_versions_prop = + tsi_peer_get_property_by_name(peer, TSI_ALTS_RPC_VERSIONS); + if (rpc_versions_prop == nullptr) { + gpr_log(GPR_ERROR, "Missing rpc protocol versions property."); + return GRPC_SECURITY_ERROR; + } + grpc_gcp_rpc_protocol_versions local_versions, peer_versions; + alts_set_rpc_protocol_versions(&local_versions); + grpc_slice slice = grpc_slice_from_copied_buffer( + rpc_versions_prop->value.data, rpc_versions_prop->value.length); + bool decode_result = + grpc_gcp_rpc_protocol_versions_decode(slice, &peer_versions); + grpc_slice_unref(slice); + if (!decode_result) { + gpr_log(GPR_ERROR, "Invalid peer rpc protocol versions."); + return GRPC_SECURITY_ERROR; + } + /* TODO: Pass highest common rpc protocol version to grpc caller. */ + bool check_result = grpc_gcp_rpc_protocol_versions_check( + &local_versions, &peer_versions, nullptr); + if (!check_result) { + gpr_log(GPR_ERROR, "Mismatch of local and peer rpc protocol versions."); + 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_ALTS_TRANSPORT_SECURITY_TYPE); + size_t i = 0; + for (i = 0; i < peer->property_count; i++) { + const tsi_peer_property* tsi_prop = &peer->properties[i]; + /* Add service account to auth context. */ + if (strcmp(tsi_prop->name, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 0) { + grpc_auth_context_add_property( + *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, tsi_prop->value.data, + tsi_prop->value.length); + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( + *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1); + } + } + if (!grpc_auth_context_peer_is_authenticated(*ctx)) { + gpr_log(GPR_ERROR, "Invalid unauthenticated peer."); + GRPC_AUTH_CONTEXT_UNREF(*ctx, "test"); + *ctx = nullptr; + return GRPC_SECURITY_ERROR; + } + return GRPC_SECURITY_OK; +} + +} // namespace internal +} // namespace grpc_core + +static void alts_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + grpc_security_status status; + status = grpc_core::internal::grpc_alts_auth_context_from_tsi_peer( + &peer, auth_context); + tsi_peer_destruct(&peer); + grpc_error* error = + status == GRPC_SECURITY_OK + ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Could not get ALTS auth context from TSI peer"); + GRPC_CLOSURE_SCHED(on_peer_checked, error); +} + +static int alts_channel_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + grpc_alts_channel_security_connector* c1 = + reinterpret_cast<grpc_alts_channel_security_connector*>(sc1); + grpc_alts_channel_security_connector* c2 = + reinterpret_cast<grpc_alts_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 alts_server_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + grpc_alts_server_security_connector* c1 = + reinterpret_cast<grpc_alts_server_security_connector*>(sc1); + grpc_alts_server_security_connector* c2 = + reinterpret_cast<grpc_alts_server_security_connector*>(sc2); + return grpc_server_security_connector_cmp(&c1->base, &c2->base); +} + +static grpc_security_connector_vtable alts_channel_vtable = { + alts_channel_destroy, alts_check_peer, alts_channel_cmp}; + +static grpc_security_connector_vtable alts_server_vtable = { + alts_server_destroy, alts_check_peer, alts_server_cmp}; + +static bool alts_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_alts_channel_security_connector* alts_sc = + reinterpret_cast<grpc_alts_channel_security_connector*>(sc); + if (host == nullptr || alts_sc == nullptr || + strcmp(host, alts_sc->target_name) != 0) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "ALTS call host does not match target name"); + } + return true; +} + +static void alts_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_alts_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, 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_alts_channel_security_connector_create()"); + return GRPC_SECURITY_ERROR; + } + auto c = static_cast<grpc_alts_channel_security_connector*>( + gpr_zalloc(sizeof(grpc_alts_channel_security_connector))); + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.vtable = &alts_channel_vtable; + c->base.add_handshakers = alts_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 = alts_check_call_host; + c->base.cancel_check_call_host = alts_cancel_check_call_host; + grpc_alts_credentials* creds = + reinterpret_cast<grpc_alts_credentials*>(c->base.channel_creds); + alts_set_rpc_protocol_versions(&creds->options->rpc_versions); + c->target_name = gpr_strdup(target_name); + *sc = &c->base; + return GRPC_SECURITY_OK; +} + +grpc_security_status grpc_alts_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_alts_server_security_connector_create()"); + return GRPC_SECURITY_ERROR; + } + auto c = static_cast<grpc_alts_server_security_connector*>( + gpr_zalloc(sizeof(grpc_alts_server_security_connector))); + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.vtable = &alts_server_vtable; + c->base.server_creds = grpc_server_credentials_ref(server_creds); + c->base.add_handshakers = alts_server_add_handshakers; + grpc_alts_server_credentials* creds = + reinterpret_cast<grpc_alts_server_credentials*>(c->base.server_creds); + alts_set_rpc_protocol_versions(&creds->options->rpc_versions); + *sc = &c->base; + return GRPC_SECURITY_OK; +} diff --git a/src/core/lib/security/security_connector/alts_security_connector.h b/src/core/lib/security/security_connector/alts_security_connector.h new file mode 100644 index 0000000000..e7e4cffe2a --- /dev/null +++ b/src/core/lib/security/security_connector/alts_security_connector.h @@ -0,0 +1,69 @@ +/* + * + * 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_ALTS_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" + +#define GRPC_ALTS_TRANSPORT_SECURITY_TYPE "alts" + +/** + * This method creates an ALTS 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. + * - sc: address of ALTS 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_alts_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, const char* target_name, + grpc_channel_security_connector** sc); + +/** + * This method creates an ALTS server security connector. + * + * - server_creds: server credential instance. + * - sc: address of ALTS 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_alts_server_security_connector_create( + grpc_server_credentials* server_creds, grpc_server_security_connector** sc); + +namespace grpc_core { +namespace internal { + +/* Exposed only for testing. */ +grpc_security_status grpc_alts_auth_context_from_tsi_peer( + const tsi_peer* peer, grpc_auth_context** ctx); + +} // namespace internal +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H \ + */ |