Skip to content

Commit 4e8d117

Browse files
committed
✨ Check signature status of runtimes, include in report
Seeing some more impersonation runtimes, should at least include them in the report
1 parent 79a197e commit 4e8d117

9 files changed

Lines changed: 95 additions & 58 deletions

src/APILayerDetails.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ APILayerDetails::APILayerDetails(const std::filesystem::path& jsonPath) {
121121
} catch (const std::filesystem::filesystem_error&) {
122122
}
123123

124-
mSignature = platform.GetAPILayerSignature(mLibraryPath);
124+
mSignature = platform.GetSharedLibrarySignature(mLibraryPath);
125125

126126
mState = State::Loaded;
127127
}

src/Platform.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ std::optional<Runtime> GetRuntimeFromPath(const std::filesystem::path& path) {
1818
return Runtime(path);
1919
}
2020

21-
std::expected<std::string, Runtime::ManifestError> GetRuntimeName(
22-
const std::filesystem::path& path) {
23-
using enum Runtime::ManifestError;
21+
std::expected<Runtime::ManifestData, Runtime::ManifestData::Error>
22+
GetRuntimeManifestData(const std::filesystem::path& path) {
23+
using enum Runtime::ManifestData::Error;
2424
try {
2525
if (!std::filesystem::exists(path)) {
2626
return std::unexpected {FileNotFound};
@@ -32,11 +32,31 @@ std::expected<std::string, Runtime::ManifestError> GetRuntimeName(
3232
}
3333

3434
const auto json = nlohmann::json::parse(f);
35-
if (json.contains("runtime") && json.at("runtime").contains("name")) {
36-
return json.at("runtime").at("name");
35+
if (!json.contains("runtime")) {
36+
return std::unexpected {InvalidJson};
3737
}
38+
const auto& data = json.at("runtime");
3839

39-
return std::unexpected {FieldNotPresent};
40+
Runtime::ManifestData ret {};
41+
if (data.contains("name")) {
42+
ret.mName = data.at("name");
43+
}
44+
if (data.contains("library_path")) {
45+
const std::filesystem::path libraryPath {
46+
data.at("library_path").get<std::string>()};
47+
if (libraryPath.is_absolute()) {
48+
ret.mLibraryPath = libraryPath;
49+
} else {
50+
ret.mLibraryPath = weakly_canonical(path.parent_path() / libraryPath);
51+
}
52+
}
53+
54+
if ((!ret.mLibraryPath.empty()) && exists(ret.mLibraryPath)) {
55+
ret.mLibrarySignature
56+
= Platform::Get().GetSharedLibrarySignature(ret.mLibraryPath);
57+
}
58+
59+
return ret;
4060
} catch (const std::filesystem::filesystem_error&) {
4161
return std::unexpected {FileNotReadable};
4262
} catch (const nlohmann::json::exception&) {
@@ -48,7 +68,7 @@ std::expected<std::string, Runtime::ManifestError> GetRuntimeName(
4868

4969
Runtime::Runtime(const std::filesystem::path& path)
5070
: mPath(path),
51-
mName(GetRuntimeName(path)) {}
71+
mManifestData(GetRuntimeManifestData(path)) {}
5272

5373
AvailableRuntime::AvailableRuntime(
5474
const std::filesystem::path& path,

src/Platform.hpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,25 @@ struct DPIChangeInfo {
2525
};
2626

2727
struct Runtime {
28-
enum class ManifestError {
29-
FileNotFound,
30-
FileNotReadable,
31-
InvalidJson,
32-
FieldNotPresent,
28+
struct ManifestData {
29+
enum class Error {
30+
FileNotFound,
31+
FileNotReadable,
32+
InvalidJson,
33+
};
34+
// Defaults to mLibrarypath if not set
35+
std::string mName;
36+
std::filesystem::path mLibraryPath;
37+
std::expected<APILayerSignature, APILayerSignature::Error>
38+
mLibrarySignature;
3339
};
3440

3541
Runtime() = delete;
3642
explicit Runtime(const std::filesystem::path& path);
3743

3844
std::filesystem::path mPath;
39-
std::expected<std::string, ManifestError> mName;
45+
46+
std::expected<ManifestData, ManifestData::Error> mManifestData;
4047
};
4148

4249
struct AvailableRuntime : Runtime {
@@ -67,7 +74,7 @@ class Platform {
6774
const std::filesystem::path& path) = 0;
6875

6976
virtual std::expected<APILayerSignature, APILayerSignature::Error>
70-
GetAPILayerSignature(const std::filesystem::path&) = 0;
77+
GetSharedLibrarySignature(const std::filesystem::path&) = 0;
7178
virtual std::expected<LoaderData, LoaderData::Error> GetLoaderData(
7279
Architecture) = 0;
7380
virtual std::expected<LoaderData, LoaderData::Error> WaitForLoaderData(

src/SaveReport.cpp

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,32 @@ static std::string GenerateActiveRuntimeText(
154154
if (!runtime) {
155155
return std::format("❌ Active {} runtime: NONE\n", archName);
156156
}
157-
158-
if (!runtime->mName) {
159-
if (runtime->mName.error() != Runtime::ManifestError::FieldNotPresent) {
160-
return std::format(
161-
"🚨 Active {} runtime: CORRUPTED - {}\n",
162-
archName,
163-
runtime->mPath.string());
164-
}
157+
const auto manifest = runtime->mManifestData;
158+
if (!manifest) {
165159
return std::format(
166-
"✅ Active {} runtime: {}\n", archName, runtime->mPath.string());
160+
"❌ Invalid {} manifest at `{}`: {}\n",
161+
archName,
162+
runtime->mPath.string(),
163+
magic_enum::enum_name(manifest.error()));
164+
}
165+
166+
std::string out = runtime->mPath.string();
167+
if (manifest->mName != runtime->mPath) {
168+
out += std::format(" ()", manifest->mName);
169+
}
170+
171+
bool ok = true;
172+
if (manifest->mLibrarySignature) {
173+
out += fmt::format(
174+
" (signed by '{}')", manifest->mLibrarySignature->mSignedBy);
175+
} else {
176+
ok = false;
177+
out += fmt::format(
178+
" - 🚨 bad signature: {}",
179+
magic_enum::enum_name(manifest->mLibrarySignature.error()));
167180
}
168181

169-
return std::format(
170-
"✅ Active {} runtime: \"{}\" - {}\n",
171-
archName,
172-
runtime->mName.value(),
173-
runtime->mPath.string());
182+
return std::format("{} {}\n", ok ? "" : "🚨", out);
174183
}
175184

176185
static std::string GenerateAvailableRuntimesText(
@@ -183,26 +192,17 @@ static std::string GenerateAvailableRuntimesText(
183192
}
184193

185194
for (auto&& runtime: runtimes) {
186-
if (runtime.mName) {
195+
if (!runtime.mManifestData) {
187196
ret += fmt::format(
188-
" - \"{}\" - {}", runtime.mName.value(), runtime.mPath.string());
189-
} else {
190-
using enum Runtime::ManifestError;
191-
switch (runtime.mName.error()) {
192-
case FieldNotPresent:
193-
ret += fmt::format(" - {}", runtime.mPath.string());
194-
break;
195-
case FileNotFound:
196-
ret += fmt::format(" - ❌ FILE MISSING: {}", runtime.mPath.string());
197-
break;
198-
case FileNotReadable:
199-
case InvalidJson:
200-
ret += fmt::format(
201-
" - ❌ FILE NOT READABLE: {}", runtime.mPath.string());
202-
break;
203-
}
197+
" - ❌ {}: 🚨 {}\n",
198+
runtime.mPath.string(),
199+
magic_enum::enum_name(runtime.mManifestData.error()));
200+
continue;
204201
}
205202

203+
ret += fmt::format(
204+
" - \"{}\" - {}", runtime.mManifestData->mName, runtime.mPath.string());
205+
206206
switch (runtime.mDiscoverability) {
207207
case AvailableRuntime::Discoverability::Discoverable:
208208
ret += " (discoverable)\n";

src/linters/SkippedByLoaderLinter.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@ class SkippedByLoaderLinter final : public Linter {
3333
}
3434

3535
const auto runtime = Platform::Get().GetActiveRuntime();
36-
const auto runtimeString
37-
= runtime ? runtime->mName.value_or(runtime->mPath.string()) : "NONE";
36+
if (!runtime) {
37+
return;
38+
}
39+
const auto runtimeManifest = runtime->mManifestData;
40+
if (!runtimeManifest) {
41+
return;
42+
}
3843

3944
for (const auto& [layer, details]: layers) {
4045
if (details.mState != APILayerDetails::State::Loaded) {
@@ -75,7 +80,7 @@ class SkippedByLoaderLinter final : public Linter {
7580
fmt::format(
7681
"Layer `{}` is blocked by your current OpenXR runtime ('{}')",
7782
layer.mManifestPath.string(),
78-
runtimeString),
83+
runtimeManifest->mName),
7984
LayerKeySet {layer});
8085
continue;
8186
}
@@ -86,7 +91,7 @@ class SkippedByLoaderLinter final : public Linter {
8691
"Layer `{}` appears enabled, but is not loaded by OpenXR; it may "
8792
"be blocked by your OpenXR runtime ('{}')",
8893
layer.mManifestPath.string(),
89-
runtimeString),
94+
runtimeManifest->mName),
9095
LayerKeySet {layer});
9196
}
9297
}

src/linters/windows/ViveLayersLinter.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@ class ViveLayersLinter final : public Linter {
2323
if (!runtime) {
2424
return {};
2525
}
26-
if (runtime->mName == "SteamVR") {
26+
const auto runtimeManifest = runtime->mManifestData;
27+
if (!runtimeManifest) {
2728
return {};
2829
}
29-
if (runtime->mName == "VIVE_OpenXR") {
30+
if (runtimeManifest->mName == "SteamVR") {
31+
return {};
32+
}
33+
if (runtimeManifest->mName == "VIVE_OpenXR") {
3034
// Included with ViveConsole from Steam, but not registered by default.
3135
// Just used for the Vive Focus and Cosmos
3236
return {};
3337
}
34-
const auto runtimeName = runtime->mName.value_or(runtime->mPath.string());
3538

3639
static const std::unordered_set<std::string_view> LayerNames {
3740
"XR_APILAYER_VIVE_MR",
@@ -56,7 +59,7 @@ class ViveLayersLinter final : public Linter {
5659
"currently using '{}'; this can cause game crashes or other "
5760
"issues.",
5861
details.mName,
59-
runtimeName),
62+
runtimeManifest->mName),
6063
layer));
6164
}
6265
return ret;

src/windows/CheckForUpdates.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ AutoUpdateProcess CheckForUpdates() {
8484
return {};
8585
}
8686

87-
if (!Platform::Get().GetAPILayerSignature(updater)) {
87+
if (!Platform::Get().GetSharedLibrarySignature(updater)) {
8888
MessageBoxW(
8989
nullptr,
9090
L"The auto-updater has been tampered with; you should check your system "

src/windows/WindowsPlatform.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,8 @@ std::filesystem::file_time_type WindowsPlatform::GetFileChangeTime(
381381
}
382382

383383
std::expected<APILayerSignature, APILayerSignature::Error>
384-
WindowsPlatform::GetAPILayerSignature(const std::filesystem::path& dllPath) {
384+
WindowsPlatform::GetSharedLibrarySignature(
385+
const std::filesystem::path& dllPath) {
385386
using enum APILayerSignature::Error;
386387
if (!std::filesystem::exists(dllPath)) {
387388
return std::unexpected {FilesystemError};
@@ -898,7 +899,8 @@ WindowsPlatform::SpawnLoaderData(
898899
return std::unexpected {
899900
LoaderData::CanNotFindHelperExecutableError {helper}};
900901
}
901-
if (const auto signature = Get().GetAPILayerSignature(helper); !signature) {
902+
if (const auto signature = Get().GetSharedLibrarySignature(helper);
903+
!signature) {
902904
constexpr auto AllowUnsigned =
903905
#ifdef ALLOW_UNSIGNED_LOADER_DATA_HELPERS
904906
true;

src/windows/WindowsPlatform.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class WindowsPlatform final : public Platform {
4040
const std::filesystem::path& path) override;
4141

4242
std::expected<APILayerSignature, APILayerSignature::Error>
43-
GetAPILayerSignature(const std::filesystem::path&) override;
43+
GetSharedLibrarySignature(const std::filesystem::path&) override;
4444

4545
std::vector<std::string> GetEnabledExplicitAPILayers() override;
4646
std::optional<std::vector<std::filesystem::path>> GetOverridePaths()

0 commit comments

Comments
 (0)