• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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