1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/sas_injector.h"
#include <windows.h>
#include <sas.h>
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/win/registry.h"
namespace remoting {
namespace {
// The registry key and value holding the policy controlling software SAS
// generation.
const wchar_t kSystemPolicyKeyName[] =
L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration";
const DWORD kEnableSoftwareSasByServices = 1;
// Toggles the default software SAS generation policy to enable SAS generation
// by services. Non-default policy is not changed.
class ScopedSoftwareSasPolicy {
public:
ScopedSoftwareSasPolicy();
~ScopedSoftwareSasPolicy();
bool Apply();
private:
// The handle of the registry key were SoftwareSASGeneration policy is stored.
base::win::RegKey system_policy_;
// True if the policy needs to be restored.
bool restore_policy_;
DISALLOW_COPY_AND_ASSIGN(ScopedSoftwareSasPolicy);
};
ScopedSoftwareSasPolicy::ScopedSoftwareSasPolicy()
: restore_policy_(false) {
}
ScopedSoftwareSasPolicy::~ScopedSoftwareSasPolicy() {
// Restore the default policy by deleting the value that we have set.
if (restore_policy_) {
LONG result = system_policy_.DeleteValue(kSoftwareSasValueName);
if (result != ERROR_SUCCESS) {
SetLastError(result);
PLOG(ERROR) << "Failed to restore the software SAS generation policy";
}
}
}
bool ScopedSoftwareSasPolicy::Apply() {
// Query the currently set SoftwareSASGeneration policy.
LONG result = system_policy_.Open(HKEY_LOCAL_MACHINE,
kSystemPolicyKeyName,
KEY_QUERY_VALUE | KEY_SET_VALUE |
KEY_WOW64_64KEY);
if (result != ERROR_SUCCESS) {
SetLastError(result);
PLOG(ERROR) << "Failed to open 'HKLM\\" << kSystemPolicyKeyName << "'";
return false;
}
bool custom_policy = system_policy_.HasValue(kSoftwareSasValueName);
// Override the default policy (i.e. there is no value in the registry) only.
if (!custom_policy) {
result = system_policy_.WriteValue(kSoftwareSasValueName,
kEnableSoftwareSasByServices);
if (result != ERROR_SUCCESS) {
SetLastError(result);
PLOG(ERROR) << "Failed to enable software SAS generation by services";
return false;
} else {
restore_policy_ = true;
}
}
return true;
}
} // namespace
// Sends Secure Attention Sequence. Checks the current policy before sending.
class SasInjectorWin : public SasInjector {
public:
SasInjectorWin();
~SasInjectorWin() override;
// SasInjector implementation.
bool InjectSas() override;
private:
DISALLOW_COPY_AND_ASSIGN(SasInjectorWin);
};
SasInjectorWin::SasInjectorWin() {}
SasInjectorWin::~SasInjectorWin() {
}
bool SasInjectorWin::InjectSas() {
// Enable software SAS generation by services and send SAS. SAS can still fail
// if the policy does not allow services to generate software SAS.
ScopedSoftwareSasPolicy enable_sas;
if (!enable_sas.Apply()) {
return false;
}
SendSAS(/*AsUser=*/FALSE);
return true;
}
std::unique_ptr<SasInjector> SasInjector::Create() {
return base::WrapUnique(new SasInjectorWin());
}
} // namespace remoting
|