blob: 3b67a5b36ef2b63361bd61abbb1646dfd9bb6b54 [file] [log] [blame]
[email protected]c2b374402012-03-12 19:23:071// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/host/sas_injector.h"
6
Joe Downingdbffadb2018-10-08 19:46:247#include <memory>
8#include <utility>
9
Joe Downing7c84a3cc2021-08-26 00:28:4310#include "base/files/file_path.h"
[email protected]c2b374402012-03-12 19:23:0711#include "base/logging.h"
Joe Downing7c84a3cc2021-08-26 00:28:4312#include "base/scoped_native_library.h"
[email protected]c2b374402012-03-12 19:23:0713#include "base/win/registry.h"
[email protected]c2b374402012-03-12 19:23:0714
15namespace remoting {
16
17namespace {
18
[email protected]c2b374402012-03-12 19:23:0719// The registry key and value holding the policy controlling software SAS
20// generation.
[email protected]8cdb83f2012-06-20 17:24:4321const wchar_t kSystemPolicyKeyName[] =
22 L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
23const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration";
[email protected]c2b374402012-03-12 19:23:0724
[email protected]e8f8dcee2012-11-02 00:16:0525const DWORD kEnableSoftwareSasByServices = 1;
[email protected]c2b374402012-03-12 19:23:0726
Joe Downing7c84a3cc2021-08-26 00:28:4327// https://docs.microsoft.com/en-us/windows/win32/api/sas/nf-sas-sendsas
28typedef void(NTAPI* SendSASFunction)(BOOL);
29
[email protected]c2b374402012-03-12 19:23:0730// Toggles the default software SAS generation policy to enable SAS generation
[email protected]e8f8dcee2012-11-02 00:16:0531// by services. Non-default policy is not changed.
[email protected]c2b374402012-03-12 19:23:0732class ScopedSoftwareSasPolicy {
33 public:
34 ScopedSoftwareSasPolicy();
Peter Boströme9178e42021-09-22 18:11:4935
36 ScopedSoftwareSasPolicy(const ScopedSoftwareSasPolicy&) = delete;
37 ScopedSoftwareSasPolicy& operator=(const ScopedSoftwareSasPolicy&) = delete;
38
[email protected]c2b374402012-03-12 19:23:0739 ~ScopedSoftwareSasPolicy();
40
41 bool Apply();
42
43 private:
44 // The handle of the registry key were SoftwareSASGeneration policy is stored.
45 base::win::RegKey system_policy_;
46
[email protected]c2b374402012-03-12 19:23:0747 // True if the policy needs to be restored.
Joe Downingdbffadb2018-10-08 19:46:2448 bool restore_policy_ = false;
[email protected]c2b374402012-03-12 19:23:0749};
50
Joe Downingdbffadb2018-10-08 19:46:2451ScopedSoftwareSasPolicy::ScopedSoftwareSasPolicy() = default;
[email protected]c2b374402012-03-12 19:23:0752
53ScopedSoftwareSasPolicy::~ScopedSoftwareSasPolicy() {
54 // Restore the default policy by deleting the value that we have set.
55 if (restore_policy_) {
[email protected]96e2c552012-04-14 05:21:5456 LONG result = system_policy_.DeleteValue(kSoftwareSasValueName);
[email protected]c2b374402012-03-12 19:23:0757 if (result != ERROR_SUCCESS) {
58 SetLastError(result);
[email protected]ad8cfa92014-05-21 20:06:2359 PLOG(ERROR) << "Failed to restore the software SAS generation policy";
[email protected]c2b374402012-03-12 19:23:0760 }
61 }
62}
63
64bool ScopedSoftwareSasPolicy::Apply() {
65 // Query the currently set SoftwareSASGeneration policy.
66 LONG result = system_policy_.Open(HKEY_LOCAL_MACHINE,
[email protected]96e2c552012-04-14 05:21:5467 kSystemPolicyKeyName,
[email protected]c2b374402012-03-12 19:23:0768 KEY_QUERY_VALUE | KEY_SET_VALUE |
69 KEY_WOW64_64KEY);
70 if (result != ERROR_SUCCESS) {
71 SetLastError(result);
[email protected]ad8cfa92014-05-21 20:06:2372 PLOG(ERROR) << "Failed to open 'HKLM\\" << kSystemPolicyKeyName << "'";
[email protected]c2b374402012-03-12 19:23:0773 return false;
74 }
75
[email protected]96e2c552012-04-14 05:21:5476 bool custom_policy = system_policy_.HasValue(kSoftwareSasValueName);
[email protected]c2b374402012-03-12 19:23:0777
78 // Override the default policy (i.e. there is no value in the registry) only.
79 if (!custom_policy) {
[email protected]96e2c552012-04-14 05:21:5480 result = system_policy_.WriteValue(kSoftwareSasValueName,
[email protected]e8f8dcee2012-11-02 00:16:0581 kEnableSoftwareSasByServices);
[email protected]c2b374402012-03-12 19:23:0782 if (result != ERROR_SUCCESS) {
83 SetLastError(result);
[email protected]ad8cfa92014-05-21 20:06:2384 PLOG(ERROR) << "Failed to enable software SAS generation by services";
[email protected]c2b374402012-03-12 19:23:0785 return false;
86 } else {
87 restore_policy_ = true;
88 }
89 }
90
91 return true;
92}
93
94} // namespace
95
joedow19d55d32016-06-03 20:55:1596// Sends Secure Attention Sequence. Checks the current policy before sending.
[email protected]c2b374402012-03-12 19:23:0797class SasInjectorWin : public SasInjector {
98 public:
99 SasInjectorWin();
Joe Downing7c84a3cc2021-08-26 00:28:43100 SasInjectorWin(const SasInjectorWin&) = delete;
101 SasInjectorWin& operator=(const SasInjectorWin&) = delete;
nick697f4292015-04-23 18:22:31102 ~SasInjectorWin() override;
[email protected]c2b374402012-03-12 19:23:07103
104 // SasInjector implementation.
nick697f4292015-04-23 18:22:31105 bool InjectSas() override;
[email protected]c2b374402012-03-12 19:23:07106};
107
Joe Downingdbffadb2018-10-08 19:46:24108SasInjectorWin::SasInjectorWin() = default;
[email protected]c2b374402012-03-12 19:23:07109
Joe Downingdbffadb2018-10-08 19:46:24110SasInjectorWin::~SasInjectorWin() = default;
[email protected]c2b374402012-03-12 19:23:07111
112bool SasInjectorWin::InjectSas() {
[email protected]c2b374402012-03-12 19:23:07113 // Enable software SAS generation by services and send SAS. SAS can still fail
[email protected]e8f8dcee2012-11-02 00:16:05114 // if the policy does not allow services to generate software SAS.
[email protected]c2b374402012-03-12 19:23:07115 ScopedSoftwareSasPolicy enable_sas;
joedow19d55d32016-06-03 20:55:15116 if (!enable_sas.Apply()) {
Joe Downing7c84a3cc2021-08-26 00:28:43117 LOG(ERROR) << "SAS policy could not be applied, skipping SAS injection.";
[email protected]b9a06b32012-08-17 23:52:13118 return false;
[email protected]6672f382012-11-15 17:37:01119 }
[email protected]b9a06b32012-08-17 23:52:13120
Joe Downing7c84a3cc2021-08-26 00:28:43121 // Use LoadLibrary here as sas.dll is not consistently shipped on all Windows
122 // SKUs (notably server releases) and linking against it prevents the host
123 // from starting correctly.
124 bool sas_injected = false;
125 base::ScopedNativeLibrary library(base::FilePath(L"sas.dll"));
126 if (library.is_valid()) {
127 SendSASFunction send_sas_func = reinterpret_cast<SendSASFunction>(
128 library.GetFunctionPointer("SendSAS"));
129 if (send_sas_func) {
130 sas_injected = true;
131 send_sas_func(/*AsUser=*/FALSE);
132 } else {
133 LOG(ERROR) << "SendSAS() not found in sas.dll, skipping SAS injection.";
134 }
135 } else {
136 LOG(ERROR) << "sas.dll could not be loaded, skipping SAS injection.";
137 }
138 return sas_injected;
[email protected]b9a06b32012-08-17 23:52:13139}
140
dcheng0765c492016-04-06 22:41:53141std::unique_ptr<SasInjector> SasInjector::Create() {
Joe Downingdbffadb2018-10-08 19:46:24142 return std::make_unique<SasInjectorWin>();
[email protected]c2b374402012-03-12 19:23:07143}
144
145} // namespace remoting