Commit b9a06b30 authored by alexeypa@chromium.org's avatar alexeypa@chromium.org

[Chromoting] Call SendSAS() directly from the host.

In order to call SendSAS() successfully the calling process's binary has to:
 - be signed.
 - be installed under %ProgramFiles% or %SystemRoot%\system32.
 - specify uiAccess='true' in the manifest.
 - run under SYSTEM or the currently logged-on user.

All of those requirements are met now, so SendSAS() can be called directly.

BUG=135217

Review URL: https://chromiumcodereview.appspot.com/10836224

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152191 0039d316-1c4b-4281-b951-d872f2087c98
parent 7eaa5920
...@@ -8,10 +8,3 @@ ...@@ -8,10 +8,3 @@
#include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_macros.h"
#define IPC_MESSAGE_START ChromotingMsgStart #define IPC_MESSAGE_START ChromotingMsgStart
//-----------------------------------------------------------------------------
// The Chrmomoting session messages
// Asks the service to send the Secure Attention Sequence (SAS) to the current
// console session.
IPC_MESSAGE_CONTROL0(ChromotingHostMsg_SendSasToConsole)
...@@ -14,14 +14,15 @@ ...@@ -14,14 +14,15 @@
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "base/win/registry.h" #include "base/win/registry.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "remoting/host/win/desktop.h"
#include "remoting/host/win/scoped_thread_desktop.h"
namespace remoting { namespace remoting {
namespace { namespace {
// Names of the API and library implementing software SAS generation. // Names of the API and library implementing software SAS generation.
const FilePath::CharType kSasDllFileName[] = const FilePath::CharType kSasDllFileName[] = FILE_PATH_LITERAL("sas.dll");
FILE_PATH_LITERAL("sas.dll");
const char kSendSasName[] = "SendSAS"; const char kSendSasName[] = "SendSAS";
// The prototype of SendSAS(). // The prototype of SendSAS().
...@@ -33,10 +34,10 @@ const wchar_t kSystemPolicyKeyName[] = ...@@ -33,10 +34,10 @@ const wchar_t kSystemPolicyKeyName[] =
L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration"; const wchar_t kSoftwareSasValueName[] = L"SoftwareSASGeneration";
const DWORD kEnableSoftwareSasByServices = 1; const DWORD kEnableSoftwareSasByApps = 2;
// Toggles the default software SAS generation policy to enable SAS generation // Toggles the default software SAS generation policy to enable SAS generation
// by services. Non-default policy is not changed. // by applications. Non-default policy is not changed.
class ScopedSoftwareSasPolicy { class ScopedSoftwareSasPolicy {
public: public:
ScopedSoftwareSasPolicy(); ScopedSoftwareSasPolicy();
...@@ -88,7 +89,7 @@ bool ScopedSoftwareSasPolicy::Apply() { ...@@ -88,7 +89,7 @@ bool ScopedSoftwareSasPolicy::Apply() {
// Override the default policy (i.e. there is no value in the registry) only. // Override the default policy (i.e. there is no value in the registry) only.
if (!custom_policy) { if (!custom_policy) {
result = system_policy_.WriteValue(kSoftwareSasValueName, result = system_policy_.WriteValue(kSoftwareSasValueName,
kEnableSoftwareSasByServices); kEnableSoftwareSasByApps);
if (result != ERROR_SUCCESS) { if (result != ERROR_SUCCESS) {
SetLastError(result); SetLastError(result);
LOG_GETLASTERROR(ERROR) LOG_GETLASTERROR(ERROR)
...@@ -121,6 +122,18 @@ class SasInjectorWin : public SasInjector { ...@@ -121,6 +122,18 @@ class SasInjectorWin : public SasInjector {
SendSasFunc send_sas_; SendSasFunc send_sas_;
}; };
// Emulates Secure Attention Sequence (Ctrl+Alt+Del) by switching to
// the Winlogon desktop and injecting Ctrl+Alt+Del as a hot key.
// N.B. Windows XP/W2K3 only.
class SasInjectorXp : public SasInjector {
public:
SasInjectorXp();
virtual ~SasInjectorXp();
// SasInjector implementation.
virtual bool InjectSas() OVERRIDE;
};
SasInjectorWin::SasInjectorWin() : send_sas_(NULL) { SasInjectorWin::SasInjectorWin() : send_sas_(NULL) {
} }
...@@ -157,7 +170,7 @@ bool SasInjectorWin::InjectSas() { ...@@ -157,7 +170,7 @@ bool SasInjectorWin::InjectSas() {
} }
// Enable software SAS generation by services and send SAS. SAS can still fail // Enable software SAS generation by services and send SAS. SAS can still fail
// if the policy does not allow services to generate software SAS. // if the policy does not allow applications to generate software SAS.
ScopedSoftwareSasPolicy enable_sas; ScopedSoftwareSasPolicy enable_sas;
if (!enable_sas.Apply()) if (!enable_sas.Apply())
return false; return false;
...@@ -166,12 +179,43 @@ bool SasInjectorWin::InjectSas() { ...@@ -166,12 +179,43 @@ bool SasInjectorWin::InjectSas() {
return true; return true;
} }
SasInjectorXp::SasInjectorXp() {
}
SasInjectorXp::~SasInjectorXp() {
}
bool SasInjectorXp::InjectSas() {
const wchar_t kWinlogonDesktopName[] = L"Winlogon";
const wchar_t kSasWindowClassName[] = L"SAS window class";
const wchar_t kSasWindowTitle[] = L"SAS window";
scoped_ptr<remoting::Desktop> winlogon_desktop(
remoting::Desktop::GetDesktop(kWinlogonDesktopName));
if (!winlogon_desktop.get())
return false;
remoting::ScopedThreadDesktop desktop;
if (!desktop.SetThreadDesktop(winlogon_desktop.Pass()))
return false;
HWND window = FindWindow(kSasWindowClassName, kSasWindowTitle);
if (!window)
return false;
PostMessage(window,
WM_HOTKEY,
0,
MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));
return true;
}
scoped_ptr<SasInjector> SasInjector::Create() { scoped_ptr<SasInjector> SasInjector::Create() {
if (base::win::GetVersion() >= base::win::VERSION_VISTA) { if (base::win::GetVersion() < base::win::VERSION_VISTA) {
return scoped_ptr<SasInjector>(new SasInjectorXp());
} else {
return scoped_ptr<SasInjector>(new SasInjectorWin()); return scoped_ptr<SasInjector>(new SasInjectorWin());
} }
return scoped_ptr<SasInjector>();
} }
} // namespace remoting } // namespace remoting
...@@ -14,15 +14,12 @@ ...@@ -14,15 +14,12 @@
#include "ipc/ipc_channel.h" #include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_channel_proxy.h"
#include "remoting/host/chromoting_messages.h" #include "remoting/host/chromoting_messages.h"
#include "remoting/host/sas_injector.h"
#include "remoting/host/win/desktop.h" #include "remoting/host/win/desktop.h"
#include "remoting/host/win/scoped_thread_desktop.h"
#include "remoting/proto/event.pb.h" #include "remoting/proto/event.pb.h"
namespace { namespace {
// The command line switch specifying the name of the Chromoting IPC channel.
const char kProcessChannelId[] = "chromoting-ipc";
const uint32 kUsbLeftControl = 0x0700e0; const uint32 kUsbLeftControl = 0x0700e0;
const uint32 kUsbRightControl = 0x0700e4; const uint32 kUsbRightControl = 0x0700e4;
const uint32 kUsbLeftAlt = 0x0700e2; const uint32 kUsbLeftAlt = 0x0700e2;
...@@ -38,33 +35,6 @@ bool CheckCtrlAndAltArePressed(const std::set<uint32>& pressed_keys) { ...@@ -38,33 +35,6 @@ bool CheckCtrlAndAltArePressed(const std::set<uint32>& pressed_keys) {
(ctrl_keys + alt_keys == pressed_keys.size()); (ctrl_keys + alt_keys == pressed_keys.size());
} }
// Emulates Secure Attention Sequence (Ctrl+Alt+Del) by switching to
// the Winlogon desktop and injecting Ctrl+Alt+Del as a hot key.
// N.B. Windows XP/W2K3 only.
void EmulateSecureAttentionSequence() {
const wchar_t kWinlogonDesktopName[] = L"Winlogon";
const wchar_t kSasWindowClassName[] = L"SAS window class";
const wchar_t kSasWindowTitle[] = L"SAS window";
scoped_ptr<remoting::Desktop> winlogon_desktop(
remoting::Desktop::GetDesktop(kWinlogonDesktopName));
if (!winlogon_desktop.get())
return;
remoting::ScopedThreadDesktop desktop;
if (!desktop.SetThreadDesktop(winlogon_desktop.Pass()))
return;
HWND window = FindWindow(kSasWindowClassName, kSasWindowTitle);
if (!window)
return;
PostMessage(window,
WM_HOTKEY,
0,
MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));
}
} // namespace } // namespace
namespace remoting { namespace remoting {
...@@ -85,16 +55,6 @@ SessionEventExecutorWin::SessionEventExecutorWin( ...@@ -85,16 +55,6 @@ SessionEventExecutorWin::SessionEventExecutorWin(
// |weak_ptr_| and |weak_ptr_factory_| share a ThreadChecker, so the // |weak_ptr_| and |weak_ptr_factory_| share a ThreadChecker, so the
// following line affects both of them. // following line affects both of them.
weak_ptr_factory_.DetachFromThread(); weak_ptr_factory_.DetachFromThread();
std::string channel_name =
CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kProcessChannelId);
// Connect to the Chromoting IPC channel if the name was passed in the command
// line.
if (!channel_name.empty()) {
chromoting_channel_.reset(new IPC::ChannelProxy(
channel_name, IPC::Channel::MODE_CLIENT, this, io_task_runner));
}
} }
SessionEventExecutorWin::~SessionEventExecutorWin() { SessionEventExecutorWin::~SessionEventExecutorWin() {
...@@ -157,11 +117,9 @@ void SessionEventExecutorWin::InjectKeyEvent(const KeyEvent& event) { ...@@ -157,11 +117,9 @@ void SessionEventExecutorWin::InjectKeyEvent(const KeyEvent& event) {
CheckCtrlAndAltArePressed(pressed_keys_)) { CheckCtrlAndAltArePressed(pressed_keys_)) {
VLOG(3) << "Sending Secure Attention Sequence to console"; VLOG(3) << "Sending Secure Attention Sequence to console";
if (base::win::GetVersion() == base::win::VERSION_XP) { if (sas_injector_.get() == NULL)
EmulateSecureAttentionSequence(); sas_injector_ = SasInjector::Create();
} else if (chromoting_channel_.get()) { sas_injector_->InjectSas();
chromoting_channel_->Send(new ChromotingHostMsg_SendSasToConsole());
}
} }
pressed_keys_.insert(event.usb_keycode()); pressed_keys_.insert(event.usb_keycode());
...@@ -187,10 +145,6 @@ void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) { ...@@ -187,10 +145,6 @@ void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) {
nested_executor_->InjectMouseEvent(event); nested_executor_->InjectMouseEvent(event);
} }
bool SessionEventExecutorWin::OnMessageReceived(const IPC::Message& message) {
return false;
}
void SessionEventExecutorWin::SwitchToInputDesktop() { void SessionEventExecutorWin::SwitchToInputDesktop() {
// Switch to the desktop receiving user input if different from the current // Switch to the desktop receiving user input if different from the current
// one. // one.
......
...@@ -24,8 +24,9 @@ class ChannelProxy; ...@@ -24,8 +24,9 @@ class ChannelProxy;
namespace remoting { namespace remoting {
class SessionEventExecutorWin : public EventExecutor, class SasInjector;
public IPC::Listener {
class SessionEventExecutorWin : public EventExecutor {
public: public:
SessionEventExecutorWin( SessionEventExecutorWin(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
...@@ -46,9 +47,6 @@ class SessionEventExecutorWin : public EventExecutor, ...@@ -46,9 +47,6 @@ class SessionEventExecutorWin : public EventExecutor,
virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE;
virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE; virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE;
// IPC::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private: private:
// Switches to the desktop receiving a user input if different from // Switches to the desktop receiving a user input if different from
// the current one. // the current one.
...@@ -61,8 +59,7 @@ class SessionEventExecutorWin : public EventExecutor, ...@@ -61,8 +59,7 @@ class SessionEventExecutorWin : public EventExecutor,
ScopedThreadDesktop desktop_; ScopedThreadDesktop desktop_;
// The Chromoting IPC channel connecting the host with the service. scoped_ptr<SasInjector> sas_injector_;
scoped_ptr<IPC::ChannelProxy> chromoting_channel_;
// Keys currently pressed by the client, used to detect Ctrl-Alt-Del. // Keys currently pressed by the client, used to detect Ctrl-Alt-Del.
std::set<uint32> pressed_keys_; std::set<uint32> pressed_keys_;
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_macros.h"
#include "remoting/host/constants.h" #include "remoting/host/constants.h"
#include "remoting/host/chromoting_messages.h" #include "remoting/host/chromoting_messages.h"
#include "remoting/host/sas_injector.h"
#include "remoting/host/win/launch_process_with_token.h" #include "remoting/host/win/launch_process_with_token.h"
#include "remoting/host/win/wts_console_monitor.h" #include "remoting/host/win/wts_console_monitor.h"
...@@ -207,13 +206,7 @@ void WtsSessionProcessLauncher::OnChannelConnected() { ...@@ -207,13 +206,7 @@ void WtsSessionProcessLauncher::OnChannelConnected() {
bool WtsSessionProcessLauncher::OnMessageReceived(const IPC::Message& message) { bool WtsSessionProcessLauncher::OnMessageReceived(const IPC::Message& message) {
DCHECK(main_message_loop_->BelongsToCurrentThread()); DCHECK(main_message_loop_->BelongsToCurrentThread());
bool handled = true; return false;
IPC_BEGIN_MESSAGE_MAP(WtsSessionProcessLauncher, message)
IPC_MESSAGE_HANDLER(ChromotingHostMsg_SendSasToConsole,
OnSendSasToConsole)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
} }
void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) { void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) {
...@@ -441,18 +434,4 @@ void WtsSessionProcessLauncher::OnLauncherStopped() { ...@@ -441,18 +434,4 @@ void WtsSessionProcessLauncher::OnLauncherStopped() {
} }
} }
void WtsSessionProcessLauncher::OnSendSasToConsole() {
DCHECK(main_message_loop_->BelongsToCurrentThread());
if (attached_) {
if (sas_injector_.get() == NULL) {
sas_injector_ = SasInjector::Create();
}
if (sas_injector_.get() != NULL) {
sas_injector_->InjectSas();
}
}
}
} // namespace remoting } // namespace remoting
...@@ -32,7 +32,6 @@ class Message; ...@@ -32,7 +32,6 @@ class Message;
namespace remoting { namespace remoting {
class SasInjector;
class WtsConsoleMonitor; class WtsConsoleMonitor;
class WtsSessionProcessLauncher class WtsSessionProcessLauncher
...@@ -99,10 +98,6 @@ class WtsSessionProcessLauncher ...@@ -99,10 +98,6 @@ class WtsSessionProcessLauncher
// Called when the launcher reports the process to be stopped. // Called when the launcher reports the process to be stopped.
void OnLauncherStopped(); void OnLauncherStopped();
// Sends the Secure Attention Sequence to the session represented by
// |session_token_|.
void OnSendSasToConsole();
// |true| if this object is currently attached to the console session. // |true| if this object is currently attached to the console session.
bool attached_; bool attached_;
...@@ -147,8 +142,6 @@ class WtsSessionProcessLauncher ...@@ -147,8 +142,6 @@ class WtsSessionProcessLauncher
// The token to be used to launch a process in a different session. // The token to be used to launch a process in a different session.
base::win::ScopedHandle session_token_; base::win::ScopedHandle session_token_;
scoped_ptr<SasInjector> sas_injector_;
DISALLOW_COPY_AND_ASSIGN(WtsSessionProcessLauncher); DISALLOW_COPY_AND_ASSIGN(WtsSessionProcessLauncher);
}; };
......
...@@ -597,8 +597,6 @@ ...@@ -597,8 +597,6 @@
'host/daemon_process.cc', 'host/daemon_process.cc',
'host/daemon_process.h', 'host/daemon_process.h',
'host/daemon_process_win.cc', 'host/daemon_process_win.cc',
'host/sas_injector.h',
'host/sas_injector_win.cc',
'host/usage_stats_consent.h', 'host/usage_stats_consent.h',
'host/usage_stats_consent_win.cc', 'host/usage_stats_consent_win.cc',
'host/win/host_service.cc', 'host/win/host_service.cc',
...@@ -1274,6 +1272,8 @@ ...@@ -1274,6 +1272,8 @@
'host/register_support_host_request.h', 'host/register_support_host_request.h',
'host/remote_input_filter.cc', 'host/remote_input_filter.cc',
'host/remote_input_filter.h', 'host/remote_input_filter.h',
'host/sas_injector.h',
'host/sas_injector_win.cc',
'host/screen_recorder.cc', 'host/screen_recorder.cc',
'host/screen_recorder.h', 'host/screen_recorder.h',
'host/server_log_entry.cc', 'host/server_log_entry.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment