Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(815)

Unified Diff: remoting/host/sas_sender_win.cc

Issue 9617027: Chromoting: Implemented security attention sequence (SAS) emulation on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/host/sas_sender_win.cc
diff --git a/remoting/host/sas_sender_win.cc b/remoting/host/sas_sender_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..12ffa0b6cbc252503e65f8e3f53a642bdb48444c
--- /dev/null
+++ b/remoting/host/sas_sender_win.cc
@@ -0,0 +1,185 @@
+// 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_sender_win.h"
+
+#include <string>
+
+#include "base/logging.h"
+#include "base/file_path.h"
+#include "base/native_library.h"
+#include "base/path_service.h"
+#include "base/utf_string_conversions.h"
+#include "base/win/registry.h"
+#include "base/win/windows_version.h"
+
+namespace remoting {
+
+namespace {
+
+// Names of the API and library implementing software SAS generation.
+const FilePath::CharType kSasDllFileName[] =
+ FILE_PATH_LITERAL("sas.dll");
+const char kSendSasName[] = "SendSAS";
+
+// The prototype of SendSAS().
+typedef VOID (WINAPI *SendSasFunc)(BOOL);
+
+// The registry key and value holding the policy controlling software SAS
+// generation.
+const char kSystemPolicyKeyName[] =
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
+const char kSoftwareSasValueName[] = "SoftwareSASGeneration";
+
+const DWORD kEnableSoftwareSasByServices = 1;
+
+// Toggles the default software SAS generation policy to enable SAS generation
+// by services. Non-default policy is not channged.
+class ScopedSoftwareSasPolicy {
+ public:
+ ScopedSoftwareSasPolicy();
+ ~ScopedSoftwareSasPolicy();
+
+ bool Apply();
+
+ private:
+ // The handle of the registry key were SoftwareSASGeneration policy is stored.
+ base::win::RegKey system_policy_;
+
+ // Name of the registry value holding the policy.
+ string16 value_name_;
+
+ // 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(value_name_.c_str());
+ if (result != ERROR_SUCCESS) {
+ SetLastError(result);
+ LOG_GETLASTERROR(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,
+ ASCIIToUTF16(kSystemPolicyKeyName).c_str(),
+ KEY_QUERY_VALUE | KEY_SET_VALUE |
+ KEY_WOW64_64KEY);
+ if (result != ERROR_SUCCESS) {
+ SetLastError(result);
+ LOG_GETLASTERROR(ERROR) << "Failed to open 'HKLM\\"
+ << kSystemPolicyKeyName << "'";
+ return false;
+ }
+
+ value_name_ = ASCIIToUTF16(kSoftwareSasValueName);
+ bool custom_policy = system_policy_.HasValue(value_name_.c_str());
+
+ // Override the default policy (i.e. there is no value in the registry) only.
+ if (!custom_policy) {
+ result = system_policy_.WriteValue(value_name_.c_str(),
+ kEnableSoftwareSasByServices);
+ if (result != ERROR_SUCCESS) {
+ SetLastError(result);
+ LOG_GETLASTERROR(ERROR)
+ << "Failed to enable software SAS generation by services";
+ return false;
+ } else {
+ restore_policy_ = true;
+ }
+ }
+
+ return true;
+}
+
+} // namespace
+
+// Sends the security attention sequence using the SendSAS() function from
+// sas.dll. This library is shipped starting from Win7/W2K8 R2 only. However
+// Win7 SDK includes a redistributable verion of the same library that works on
+// Vista/W2K8. We install the latter along with our binaries.
+class SasSenderVista : public SasSender {
Wez 2012/03/07 01:56:13 Why is this SasSanderVista rather than SasSenderWi
alexeypa (please no reviews) 2012/03/07 19:59:08 Because, potentially, we can have a different impl
Wez 2012/03/08 00:01:33 That's fine - this version is SasSenderWin, and on
alexeypa (please no reviews) 2012/03/08 01:52:54 Once we do that the naming will become odd: why is
+ public:
+ SasSenderVista();
+ virtual ~SasSenderVista();
+
+ // SasSender implementation.
+ virtual bool Send() OVERRIDE;
+
+ private:
+ base::NativeLibrary sas_dll_;
+ SendSasFunc send_sas_;
+};
+
+SasSenderVista::SasSenderVista() : sas_dll_(NULL), send_sas_(NULL) {
+}
+
+SasSenderVista::~SasSenderVista() {
+ if (sas_dll_ != NULL) {
+ base::UnloadNativeLibrary(sas_dll_);
+ }
+}
+
+bool SasSenderVista::Send() {
+ // Load sas.dll. The library is expected to be in
+ // the same folder as this binary.
Wez 2012/03/07 01:56:13 nit: Premature line-wrap.
alexeypa (please no reviews) 2012/03/07 19:59:08 Done.
+ if (sas_dll_ == NULL) {
+ FilePath exe_path;
+ if (!PathService::Get(base::FILE_EXE, &exe_path)) {
+ LOG(ERROR) << "Failed to get the executable file name.";
+ return false;
+ }
+
+ std::string error;
+ sas_dll_ = base::LoadNativeLibrary(
+ exe_path.DirName().Append(kSasDllFileName),
+ &error);
+ if (sas_dll_ == NULL) {
+ LOG(ERROR) << "Failed to load '" << kSasDllFileName << "'";
+ return false;
+ }
+ }
+
+ // Get the pointer to sas!SendSAS().
+ if (send_sas_ == NULL) {
+ send_sas_ = reinterpret_cast<SendSasFunc>(
+ base::GetFunctionPointerFromNativeLibrary(sas_dll_, kSendSasName));
+ if (send_sas_ == NULL) {
+ LOG(ERROR) << "Failed to retrieve the address of '" << kSendSasName
+ << "()'";
+ return false;
+ }
+ }
+
+ // Enable software SAS generation by services and send SAS. SAS can still fail
+ // if the policy does not applow services to generate software SAS.
Wez 2012/03/07 01:56:13 typo: allow
alexeypa (please no reviews) 2012/03/07 19:59:08 Done.
+ ScopedSoftwareSasPolicy enable_sas;
+ if (enable_sas.Apply()) {
+ (*send_sas_)(FALSE);
Wez 2012/03/07 01:56:13 Is it a problem for us to call SendSAS if the poli
alexeypa (please no reviews) 2012/03/07 19:59:08 Yes. It does nothing if the policy is not enabled.
Wez 2012/03/08 00:01:33 So we shouldn't be testing the result of |enable_s
alexeypa (please no reviews) 2012/03/08 01:52:54 No, we should. False means 'something is badly wro
+ }
+
+ return true;
Wez 2012/03/07 01:56:13 Do you mean to return true whether or not the poli
alexeypa (please no reviews) 2012/03/07 19:59:08 Yes. False is returned only if any of the operatio
Wez 2012/03/08 00:01:33 Is it worth returning false, in that case, since t
alexeypa (please no reviews) 2012/03/08 01:52:54 We should (and do) behave differently. See above.
+}
+
+scoped_ptr<SasSender> SasSender::Create() {
+ if (base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) {
+ return scoped_ptr<SasSender>(new SasSenderVista());
+ }
+
+ return scoped_ptr<SasSender>();
+}
+
+} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698