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