Skip to content

Commit c88476c

Browse files
committed
fix: fix all windows related errors in secret.cpp
deal with annoying windows types and wstrings
1 parent be8c356 commit c88476c

File tree

3 files changed

+51
-18
lines changed

3 files changed

+51
-18
lines changed

src/lobby/credentials/secret.cpp

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -138,31 +138,37 @@ secret::SecretStorage::store(const std::string& key, const std::string& value, b
138138

139139
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
140140

141+
#include <fmt/format.h>
142+
#include <spdlog/spdlog.h>
141143

142144
namespace {
143145

144146
namespace constants {
145-
constexpr const char* property_name = "OOPetris Payload";
147+
constexpr const wchar_t* property_name = L"OOPetris Payload";
146148

147-
constexpr const char* key_name_prefix = "OOPetris_key__";
149+
constexpr const wchar_t* key_name_prefix = L"OOPetris_key__";
148150

149-
constexpr const char* used_algorithm = BCRYPT_AES_ALGORITHM;
151+
constexpr const wchar_t* used_algorithm = BCRYPT_AES_ALGORITHM;
150152
} // namespace constants
151153

152-
std::string get_key_name(const std::string& key) {
153-
return constants::key_name_prefix + key;
154+
std::wstring get_key_name(const std::string& key) {
155+
std::wstring result{ constants::key_name_prefix };
156+
for (auto& normal_char : key) {
157+
result += normal_char;
158+
}
159+
return result;
154160
}
155161

156162
helper::expected<NCRYPT_KEY_HANDLE, std::string>
157-
get_handle_from_name(KeyringType type, NCRYPT_PROV_HANDLE phProvider, const std::string& key) {
163+
get_handle_from_name(secret::KeyringType type, NCRYPT_PROV_HANDLE phProvider, const std::string& key) {
158164

159165

160166
NCRYPT_KEY_HANDLE key_handle{};
161167

162168
auto key_name = get_key_name(key);
163169

164170
// the key is of type user, if not specified otherwise, session mode is not supported
165-
DWORD flags = (type == KeyringType::Persistent ? NCRYPT_MACHINE_KEY_FLAG : 0);
171+
DWORD flags = (type == secret::KeyringType::Persistent ? NCRYPT_MACHINE_KEY_FLAG : 0);
166172

167173
// 0 means no dwLegacyKeySpec
168174
auto result = NCryptOpenKey(phProvider, &key_handle, key_name.c_str(), 0, flags);
@@ -181,7 +187,7 @@ namespace {
181187
secret::SecretStorage::SecretStorage(KeyringType type) : m_type{ type }, m_phProvider{} {
182188

183189
if (type == KeyringType::Session) {
184-
spdlog::warning("KeyringType Session is not supported, using KeyringType User");
190+
spdlog::warn("KeyringType Session is not supported, using KeyringType User");
185191
m_type = KeyringType::User;
186192
}
187193

@@ -204,7 +210,7 @@ secret::SecretStorage::~SecretStorage() {
204210
auto maybe_key_handle = get_handle_from_name(m_type, m_phProvider, key);
205211

206212
if (not maybe_key_handle.has_value()) {
207-
return return helper::unexpected<std::string>{ maybe_key_handle.error() };
213+
return helper::unexpected<std::string>{ maybe_key_handle.error() };
208214
}
209215

210216
auto key_handle = maybe_key_handle.value();
@@ -221,17 +227,17 @@ secret::SecretStorage::~SecretStorage() {
221227
};
222228
}
223229

224-
char* buffer = new char[bytes_needed];
230+
PBYTE buffer = new BYTE[bytes_needed];
225231

226-
DOWRD bytes_written{};
232+
DWORD bytes_written{};
227233

228-
auto result = NCryptGetProperty(key_handle, constants::property_name, &buffer, bytes_needed, &bytes_written, 0);
234+
auto result2 = NCryptGetProperty(key_handle, constants::property_name, buffer, bytes_needed, &bytes_written, 0);
229235

230-
if (result != ERROR_SUCCESS) {
236+
if (result2 != ERROR_SUCCESS) {
231237
NCryptFreeObject(key_handle);
232238
delete[] buffer;
233239
return helper::unexpected<std::string>{
234-
fmt::format("Error while loading a key, getting the property failed: {}", result)
240+
fmt::format("Error while loading a key, getting the property failed: {}", result2)
235241
};
236242
}
237243

@@ -245,7 +251,7 @@ secret::SecretStorage::~SecretStorage() {
245251

246252
NCryptFreeObject(key_handle);
247253

248-
auto result_string = std::string{ static_cast<char*>(buffer), static_cast<char*>(buffer) + bytes_needed };
254+
auto result_string = std::string{ reinterpret_cast<char*>(buffer), reinterpret_cast<char*>(buffer) + bytes_needed };
249255

250256
delete[] buffer;
251257

@@ -260,8 +266,13 @@ secret::SecretStorage::store(const std::string& key, const std::string& value, b
260266
auto key_name = get_key_name(key);
261267

262268
// the key is of type user, if not specified otherwise, session mode is not supported, also prefer VBS, but not require it, take the update flag also in consideration
263-
DWORD flags = (m_type == KeyringType::Persistent ? NCRYPT_MACHINE_KEY_FLAG : 0)
264-
| (update ? NCRYPT_OVERWRITE_KEY_FLAG : 0) | NCRYPT_PREFER_VBS_FLAG;
269+
DWORD flags = (m_type == secret::KeyringType::Persistent ? NCRYPT_MACHINE_KEY_FLAG : 0)
270+
| (update ? NCRYPT_OVERWRITE_KEY_FLAG : 0)
271+
#ifdef NCRYPT_PREFER_VBS_FLAG
272+
| NCRYPT_PREFER_VBS_FLAG;
273+
#else
274+
;
275+
#endif
265276

266277
// 0 means no dwLegacyKeySpec
267278
auto result = NCryptCreatePersistedKey(
@@ -274,7 +285,14 @@ secret::SecretStorage::store(const std::string& key, const std::string& value, b
274285

275286
DWORD flags2 = m_type == KeyringType::Persistent ? NCRYPT_PERSIST_FLAG : 0;
276287

277-
auto result2 = NCryptSetProperty(key_handle, constants::property_name, value.c_str(), value.size(), flags2);
288+
PBYTE buffer = new BYTE[value.size()];
289+
290+
std::memcpy(buffer, value.c_str(), value.size());
291+
292+
auto result2 =
293+
NCryptSetProperty(key_handle, constants::property_name, buffer, static_cast<DWORD>(value.size()), flags2);
294+
295+
delete[] buffer;
278296

279297
if (result2 != ERROR_SUCCESS) {
280298
NCryptFreeObject(key_handle);

src/lobby/credentials/secret.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,17 @@
1111

1212
#include <keyutils.h>
1313
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
14+
15+
#ifndef NOMINMAX
16+
#define NOMINMAX
17+
#endif
18+
19+
#include <winsock2.h>
20+
21+
#include <windows.h>
22+
1423
#include <ncrypt.h>
24+
1525
#endif
1626

1727
namespace secret {

tools/dependencies/meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ if build_application
283283
if host_machine.system() == 'linux' or (meson.is_cross_build() and host_machine.system() == 'android')
284284
keyutils_dep = dependency('keyutils', required: true, allow_fallback: true)
285285
graphics_lib += {'deps': [graphics_lib.get('deps'), keyutils_dep]}
286+
elif host_machine.system() == 'windows'
287+
c = meson.get_compiler('c')
288+
289+
ncrypt_dep = c.find_library('ncrypt')
290+
graphics_lib += {'deps': [graphics_lib.get('deps'), ncrypt_dep]}
286291
endif
287292

288293
build_installer = get_option('build_installer')

0 commit comments

Comments
 (0)