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
19 #include <grpc/support/port_platform.h>
20
21 #ifdef GPR_WINDOWS
22
23 #include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
24
25 #include <shellapi.h>
26 #include <stdio.h>
27 #include <tchar.h>
28 #include <windows.h>
29
30 #include <grpc/support/alloc.h>
31 #include <grpc/support/log.h>
32 #include <grpc/support/sync.h>
33
34 namespace grpc_core {
35 namespace internal {
36
check_bios_data(const char *)37 bool check_bios_data(const char*) { return false; }
38
check_windows_registry_product_name(HKEY root_key,const char * reg_key_path,const char * reg_key_name)39 bool check_windows_registry_product_name(HKEY root_key,
40 const char* reg_key_path,
41 const char* reg_key_name) {
42 const size_t kProductNameBufferSize = 256;
43 char const expected_substr[] = "Google";
44
45 // Get the size of the string first to allocate our buffer. This includes
46 // enough space for the trailing NUL character that will be included.
47 DWORD buffer_size{};
48 auto rc = ::RegGetValueA(
49 root_key, reg_key_path, reg_key_name, RRF_RT_REG_SZ,
50 nullptr, // We know the type will be REG_SZ.
51 nullptr, // We're only fetching the size; no buffer given yet.
52 &buffer_size); // Fetch the size in bytes of the value, if it exists.
53 if (rc != 0) {
54 return false;
55 }
56
57 if (buffer_size > kProductNameBufferSize) {
58 return false;
59 }
60
61 // Retrieve the product name string.
62 char buffer[kProductNameBufferSize];
63 buffer_size = kProductNameBufferSize;
64 rc = ::RegGetValueA(
65 root_key, reg_key_path, reg_key_name, RRF_RT_REG_SZ,
66 nullptr, // We know the type will be REG_SZ.
67 static_cast<void*>(buffer), // Fetch the string value this time.
68 &buffer_size); // The string size in bytes, not including trailing NUL.
69 if (rc != 0) {
70 return false;
71 }
72
73 return strstr(buffer, expected_substr) != nullptr;
74 }
75
76 } // namespace internal
77 } // namespace grpc_core
78
79 static bool g_compute_engine_detection_done = false;
80 static bool g_is_on_compute_engine = false;
81 static gpr_mu g_mu;
82 static gpr_once g_once = GPR_ONCE_INIT;
83
init_mu(void)84 static void init_mu(void) { gpr_mu_init(&g_mu); }
85
grpc_alts_is_running_on_gcp()86 bool grpc_alts_is_running_on_gcp() {
87 char const reg_key_path[] = "SYSTEM\\HardwareConfig\\Current\\";
88 char const reg_key_name[] = "SystemProductName";
89
90 gpr_once_init(&g_once, init_mu);
91 gpr_mu_lock(&g_mu);
92 if (!g_compute_engine_detection_done) {
93 g_is_on_compute_engine =
94 grpc_core::internal::check_windows_registry_product_name(
95 HKEY_LOCAL_MACHINE, reg_key_path, reg_key_name);
96 g_compute_engine_detection_done = true;
97 }
98 gpr_mu_unlock(&g_mu);
99 return g_is_on_compute_engine;
100 }
101
102 #endif // GPR_WINDOWS
103