| Index: remoting/host/win/host_service.cc
|
| diff --git a/remoting/host/win/host_service.cc b/remoting/host/win/host_service.cc
|
| index 71ef8b23b61478f874637cc86e8893a5b1b4f941..b760b0f77aa85f8f070dead259c0fef2f48b868b 100644
|
| --- a/remoting/host/win/host_service.cc
|
| +++ b/remoting/host/win/host_service.cc
|
| @@ -7,6 +7,7 @@
|
|
|
| #include "remoting/host/win/host_service.h"
|
|
|
| +#include <sddl.h>
|
| #include <windows.h>
|
| #include <wtsapi32.h>
|
|
|
| @@ -21,6 +22,7 @@
|
| #include "base/single_thread_task_runner.h"
|
| #include "base/threading/thread.h"
|
| #include "base/utf_string_conversions.h"
|
| +#include "base/win/scoped_com_initializer.h"
|
| #include "base/win/wrapped_window_proc.h"
|
| #include "remoting/base/auto_thread.h"
|
| #include "remoting/base/scoped_sc_handle_win.h"
|
| @@ -28,6 +30,7 @@
|
| #include "remoting/host/branding.h"
|
| #include "remoting/host/host_exit_codes.h"
|
| #include "remoting/host/logging.h"
|
| +#include "remoting/host/win/security_descriptor.h"
|
|
|
| #if defined(REMOTING_MULTI_PROCESS)
|
| #include "remoting/host/daemon_process.h"
|
| @@ -40,6 +43,8 @@
|
| #include "remoting/host/win/wts_console_session_process_driver.h"
|
| #endif // !defined(REMOTING_MULTI_PROCESS)
|
|
|
| +namespace remoting {
|
| +
|
| namespace {
|
|
|
| // Used to query the endpoint of an attached RDP client.
|
| @@ -60,9 +65,78 @@ const wchar_t kSessionNotificationWindowClass[] =
|
| // "--console" runs the service interactively for debugging purposes.
|
| const char kConsoleSwitchName[] = "console";
|
|
|
| -} // namespace
|
| +// Concatenates ACE type, permissions and sid given as SDDL strings into an ACE
|
| +// definition in SDDL form.
|
| +#define SDDL_ACE(type, permissions, sid) \
|
| + L"(" type L";;" permissions L";;;" sid L")"
|
| +
|
| +// Text representation of COM_RIGHTS_EXECUTE and COM_RIGHTS_EXECUTE_LOCAL
|
| +// permission bits that is used in the SDDL definition below.
|
| +#define SDDL_COM_EXECUTE_LOCAL L"0x3"
|
| +
|
| +// A security descriptor allowing local processes running under SYSTEM or
|
| +// LocalService accounts at medium integrity level or higher to call COM
|
| +// methods exposed by the daemon.
|
| +const wchar_t kComProcessSd[] =
|
| + SDDL_OWNER L":" SDDL_LOCAL_SYSTEM
|
| + SDDL_GROUP L":" SDDL_LOCAL_SYSTEM
|
| + SDDL_DACL L":"
|
| + SDDL_ACE(SDDL_ACCESS_ALLOWED, SDDL_COM_EXECUTE_LOCAL, SDDL_LOCAL_SYSTEM)
|
| + SDDL_ACE(SDDL_ACCESS_ALLOWED, SDDL_COM_EXECUTE_LOCAL, SDDL_LOCAL_SERVICE)
|
| + SDDL_SACL L":"
|
| + SDDL_ACE(SDDL_MANDATORY_LABEL, SDDL_NO_EXECUTE_UP, SDDL_ML_MEDIUM);
|
| +
|
| +#undef SDDL_ACE
|
| +#undef SDDL_COM_EXECUTE_LOCAL
|
| +
|
| +// Allows incoming calls from clients running under SYSTEM or LocalService at
|
| +// medium integrity level.
|
| +bool InitializeComSecurity() {
|
| + // Convert the SDDL description into a security descriptor in absolute format.
|
| + ScopedSd relative_sd = ConvertSddlToSd(WideToUTF8(kComProcessSd));
|
| + if (!relative_sd) {
|
| + LOG_GETLASTERROR(ERROR) << "Failed to create a security descriptor";
|
| + return false;
|
| + }
|
| + ScopedSd absolute_sd;
|
| + ScopedAcl dacl;
|
| + ScopedSid group;
|
| + ScopedSid owner;
|
| + ScopedAcl sacl;
|
| + if (!MakeScopedAbsoluteSd(relative_sd, &absolute_sd, &dacl, &group, &owner,
|
| + &sacl)) {
|
| + LOG_GETLASTERROR(ERROR) << "MakeScopedAbsoluteSd() failed";
|
| + return false;
|
| + }
|
|
|
| -namespace remoting {
|
| + // Apply the security descriptor and the following settings:
|
| + // - The daemon authenticates that all data received is from the expected
|
| + // client.
|
| + // - The daemon can impersonate clients to check their identity but cannot
|
| + // act on their behalf.
|
| + // - The caller's identity on every call (Dynamic cloaking).
|
| + // - Activations where the activated COM server would run under the daemon's
|
| + // identity are prohibited.
|
| + HRESULT result = CoInitializeSecurity(
|
| + absolute_sd.get(),
|
| + -1, // Let COM choose which authentication services to register.
|
| + NULL, // See above.
|
| + NULL, // Reserved, must be NULL.
|
| + RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
|
| + RPC_C_IMP_LEVEL_IDENTIFY,
|
| + NULL, // Default authentication information is not provided.
|
| + EOAC_DYNAMIC_CLOAKING | EOAC_DISABLE_AAA,
|
| + NULL); /// Reserved, must be NULL
|
| + if (FAILED(result)) {
|
| + LOG(ERROR) << "CoInitializeSecurity() failed, result=0x"
|
| + << std::hex << result << std::dec << ".";
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +} // namespace
|
|
|
| HostService* HostService::GetInstance() {
|
| return Singleton<HostService>::get();
|
| @@ -388,7 +462,7 @@ int HostService::RunAsService() {
|
| }
|
|
|
| void HostService::RunAsServiceImpl() {
|
| - MessageLoop message_loop(MessageLoop::TYPE_DEFAULT);
|
| + MessageLoop message_loop(MessageLoop::TYPE_UI);
|
| base::RunLoop run_loop;
|
| main_task_runner_ = message_loop.message_loop_proxy();
|
|
|
| @@ -416,6 +490,14 @@ void HostService::RunAsServiceImpl() {
|
| return;
|
| }
|
|
|
| + // Initialize COM.
|
| + base::win::ScopedCOMInitializer com_initializer;
|
| + if (!com_initializer.succeeded())
|
| + return;
|
| +
|
| + if (!InitializeComSecurity())
|
| + return;
|
| +
|
| CreateLauncher(scoped_refptr<AutoThreadTaskRunner>(
|
| new AutoThreadTaskRunner(main_task_runner_,
|
| run_loop.QuitClosure())));
|
| @@ -440,6 +522,14 @@ int HostService::RunInConsole() {
|
|
|
| int result = kInitializationFailed;
|
|
|
| + // Initialize COM.
|
| + base::win::ScopedCOMInitializer com_initializer;
|
| + if (!com_initializer.succeeded())
|
| + return result;
|
| +
|
| + if (!InitializeComSecurity())
|
| + return result;
|
| +
|
| // Subscribe to Ctrl-C and other console events.
|
| if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) {
|
| LOG_GETLASTERROR(ERROR)
|
|
|