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

Side by Side Diff: remoting/host/win/host_service.cc

Issue 12378078: Initialize COM and configure security settings in the daemon. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR feedback Created 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/installer/win/chromoting.wxs ('k') | remoting/host/win/security_descriptor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // This file implements the Windows service controlling Me2Me host processes 5 // This file implements the Windows service controlling Me2Me host processes
6 // running within user sessions. 6 // running within user sessions.
7 7
8 #include "remoting/host/win/host_service.h" 8 #include "remoting/host/win/host_service.h"
9 9
10 #include <sddl.h>
10 #include <windows.h> 11 #include <windows.h>
11 #include <wtsapi32.h> 12 #include <wtsapi32.h>
12 13
13 #include "base/base_paths.h" 14 #include "base/base_paths.h"
14 #include "base/base_switches.h" 15 #include "base/base_switches.h"
15 #include "base/bind.h" 16 #include "base/bind.h"
16 #include "base/command_line.h" 17 #include "base/command_line.h"
17 #include "base/files/file_path.h" 18 #include "base/files/file_path.h"
18 #include "base/message_loop.h" 19 #include "base/message_loop.h"
19 #include "base/run_loop.h" 20 #include "base/run_loop.h"
20 #include "base/scoped_native_library.h" 21 #include "base/scoped_native_library.h"
21 #include "base/single_thread_task_runner.h" 22 #include "base/single_thread_task_runner.h"
22 #include "base/threading/thread.h" 23 #include "base/threading/thread.h"
23 #include "base/utf_string_conversions.h" 24 #include "base/utf_string_conversions.h"
25 #include "base/win/scoped_com_initializer.h"
24 #include "base/win/wrapped_window_proc.h" 26 #include "base/win/wrapped_window_proc.h"
25 #include "remoting/base/auto_thread.h" 27 #include "remoting/base/auto_thread.h"
26 #include "remoting/base/scoped_sc_handle_win.h" 28 #include "remoting/base/scoped_sc_handle_win.h"
27 #include "remoting/base/stoppable.h" 29 #include "remoting/base/stoppable.h"
28 #include "remoting/host/branding.h" 30 #include "remoting/host/branding.h"
29 #include "remoting/host/host_exit_codes.h" 31 #include "remoting/host/host_exit_codes.h"
30 #include "remoting/host/logging.h" 32 #include "remoting/host/logging.h"
33 #include "remoting/host/win/security_descriptor.h"
31 34
32 #if defined(REMOTING_MULTI_PROCESS) 35 #if defined(REMOTING_MULTI_PROCESS)
33 #include "remoting/host/daemon_process.h" 36 #include "remoting/host/daemon_process.h"
34 #endif // defined(REMOTING_MULTI_PROCESS) 37 #endif // defined(REMOTING_MULTI_PROCESS)
35 38
36 #include "remoting/host/win/core_resource.h" 39 #include "remoting/host/win/core_resource.h"
37 #include "remoting/host/win/wts_terminal_observer.h" 40 #include "remoting/host/win/wts_terminal_observer.h"
38 41
39 #if !defined(REMOTING_MULTI_PROCESS) 42 #if !defined(REMOTING_MULTI_PROCESS)
40 #include "remoting/host/win/wts_console_session_process_driver.h" 43 #include "remoting/host/win/wts_console_session_process_driver.h"
41 #endif // !defined(REMOTING_MULTI_PROCESS) 44 #endif // !defined(REMOTING_MULTI_PROCESS)
42 45
46 namespace remoting {
47
43 namespace { 48 namespace {
44 49
45 // Used to query the endpoint of an attached RDP client. 50 // Used to query the endpoint of an attached RDP client.
46 const WINSTATIONINFOCLASS kWinStationRemoteAddress = 51 const WINSTATIONINFOCLASS kWinStationRemoteAddress =
47 static_cast<WINSTATIONINFOCLASS>(29); 52 static_cast<WINSTATIONINFOCLASS>(29);
48 53
49 // Session id that does not represent any session. 54 // Session id that does not represent any session.
50 const uint32 kInvalidSessionId = 0xffffffffu; 55 const uint32 kInvalidSessionId = 0xffffffffu;
51 56
52 const char kIoThreadName[] = "I/O thread"; 57 const char kIoThreadName[] = "I/O thread";
53 58
54 // A window class for the session change notifications window. 59 // A window class for the session change notifications window.
55 const wchar_t kSessionNotificationWindowClass[] = 60 const wchar_t kSessionNotificationWindowClass[] =
56 L"Chromoting_SessionNotificationWindow"; 61 L"Chromoting_SessionNotificationWindow";
57 62
58 // Command line switches: 63 // Command line switches:
59 64
60 // "--console" runs the service interactively for debugging purposes. 65 // "--console" runs the service interactively for debugging purposes.
61 const char kConsoleSwitchName[] = "console"; 66 const char kConsoleSwitchName[] = "console";
62 67
68 // Concatenates ACE type, permissions and sid given as SDDL strings into an ACE
69 // definition in SDDL form.
70 #define SDDL_ACE(type, permissions, sid) \
71 L"(" type L";;" permissions L";;;" sid L")"
72
73 // Text representation of COM_RIGHTS_EXECUTE and COM_RIGHTS_EXECUTE_LOCAL
74 // permission bits that is used in the SDDL definition below.
75 #define SDDL_COM_EXECUTE_LOCAL L"0x3"
76
77 // A security descriptor allowing local processes running under SYSTEM or
78 // LocalService accounts at medium integrity level or higher to call COM
79 // methods exposed by the daemon.
80 const wchar_t kComProcessSd[] =
81 SDDL_OWNER L":" SDDL_LOCAL_SYSTEM
82 SDDL_GROUP L":" SDDL_LOCAL_SYSTEM
83 SDDL_DACL L":"
84 SDDL_ACE(SDDL_ACCESS_ALLOWED, SDDL_COM_EXECUTE_LOCAL, SDDL_LOCAL_SYSTEM)
85 SDDL_ACE(SDDL_ACCESS_ALLOWED, SDDL_COM_EXECUTE_LOCAL, SDDL_LOCAL_SERVICE)
86 SDDL_SACL L":"
87 SDDL_ACE(SDDL_MANDATORY_LABEL, SDDL_NO_EXECUTE_UP, SDDL_ML_MEDIUM);
88
89 #undef SDDL_ACE
90 #undef SDDL_COM_EXECUTE_LOCAL
91
92 // Allows incoming calls from clients running under SYSTEM or LocalService at
93 // medium integrity level.
94 bool InitializeComSecurity() {
95 // Convert the SDDL description into a security descriptor in absolute format.
96 ScopedSd relative_sd = ConvertSddlToSd(WideToUTF8(kComProcessSd));
97 if (!relative_sd) {
98 LOG_GETLASTERROR(ERROR) << "Failed to create a security descriptor";
99 return false;
100 }
101 ScopedSd absolute_sd;
102 ScopedAcl dacl;
103 ScopedSid group;
104 ScopedSid owner;
105 ScopedAcl sacl;
106 if (!MakeScopedAbsoluteSd(relative_sd, &absolute_sd, &dacl, &group, &owner,
107 &sacl)) {
108 LOG_GETLASTERROR(ERROR) << "MakeScopedAbsoluteSd() failed";
109 return false;
110 }
111
112 // Apply the security descriptor and the following settings:
113 // - The daemon authenticates that all data received is from the expected
114 // client.
115 // - The daemon can impersonate clients to check their identity but cannot
116 // act on their behalf.
117 // - The caller's identity on every call (Dynamic cloaking).
118 // - Activations where the activated COM server would run under the daemon's
119 // identity are prohibited.
120 HRESULT result = CoInitializeSecurity(
121 absolute_sd.get(),
122 -1, // Let COM choose which authentication services to register.
123 NULL, // See above.
124 NULL, // Reserved, must be NULL.
125 RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
126 RPC_C_IMP_LEVEL_IDENTIFY,
127 NULL, // Default authentication information is not provided.
128 EOAC_DYNAMIC_CLOAKING | EOAC_DISABLE_AAA,
129 NULL); /// Reserved, must be NULL
130 if (FAILED(result)) {
131 LOG(ERROR) << "CoInitializeSecurity() failed, result=0x"
132 << std::hex << result << std::dec << ".";
133 return false;
134 }
135
136 return true;
137 }
138
63 } // namespace 139 } // namespace
64 140
65 namespace remoting {
66
67 HostService* HostService::GetInstance() { 141 HostService* HostService::GetInstance() {
68 return Singleton<HostService>::get(); 142 return Singleton<HostService>::get();
69 } 143 }
70 144
71 bool HostService::InitWithCommandLine(const CommandLine* command_line) { 145 bool HostService::InitWithCommandLine(const CommandLine* command_line) {
72 CommandLine::StringVector args = command_line->GetArgs(); 146 CommandLine::StringVector args = command_line->GetArgs();
73 if (!args.empty()) { 147 if (!args.empty()) {
74 LOG(ERROR) << "No positional parameters expected."; 148 LOG(ERROR) << "No positional parameters expected.";
75 return false; 149 return false;
76 } 150 }
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 455
382 // Wait until the service thread completely exited to avoid concurrent 456 // Wait until the service thread completely exited to avoid concurrent
383 // teardown of objects registered with base::AtExitManager and object 457 // teardown of objects registered with base::AtExitManager and object
384 // destoyed by the service thread. 458 // destoyed by the service thread.
385 stopped_event_.Wait(); 459 stopped_event_.Wait();
386 460
387 return kSuccessExitCode; 461 return kSuccessExitCode;
388 } 462 }
389 463
390 void HostService::RunAsServiceImpl() { 464 void HostService::RunAsServiceImpl() {
391 MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); 465 MessageLoop message_loop(MessageLoop::TYPE_UI);
392 base::RunLoop run_loop; 466 base::RunLoop run_loop;
393 main_task_runner_ = message_loop.message_loop_proxy(); 467 main_task_runner_ = message_loop.message_loop_proxy();
394 468
395 // Register the service control handler. 469 // Register the service control handler.
396 service_status_handle_ = RegisterServiceCtrlHandlerExW( 470 service_status_handle_ = RegisterServiceCtrlHandlerExW(
397 kWindowsServiceName, &HostService::ServiceControlHandler, this); 471 kWindowsServiceName, &HostService::ServiceControlHandler, this);
398 if (service_status_handle_ == 0) { 472 if (service_status_handle_ == 0) {
399 LOG_GETLASTERROR(ERROR) 473 LOG_GETLASTERROR(ERROR)
400 << "Failed to register the service control handler"; 474 << "Failed to register the service control handler";
401 return; 475 return;
402 } 476 }
403 477
404 // Report running status of the service. 478 // Report running status of the service.
405 SERVICE_STATUS service_status; 479 SERVICE_STATUS service_status;
406 ZeroMemory(&service_status, sizeof(service_status)); 480 ZeroMemory(&service_status, sizeof(service_status));
407 service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 481 service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
408 service_status.dwCurrentState = SERVICE_RUNNING; 482 service_status.dwCurrentState = SERVICE_RUNNING;
409 service_status.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | 483 service_status.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN |
410 SERVICE_ACCEPT_STOP | 484 SERVICE_ACCEPT_STOP |
411 SERVICE_ACCEPT_SESSIONCHANGE; 485 SERVICE_ACCEPT_SESSIONCHANGE;
412 service_status.dwWin32ExitCode = kSuccessExitCode; 486 service_status.dwWin32ExitCode = kSuccessExitCode;
413 if (!SetServiceStatus(service_status_handle_, &service_status)) { 487 if (!SetServiceStatus(service_status_handle_, &service_status)) {
414 LOG_GETLASTERROR(ERROR) 488 LOG_GETLASTERROR(ERROR)
415 << "Failed to report service status to the service control manager"; 489 << "Failed to report service status to the service control manager";
416 return; 490 return;
417 } 491 }
418 492
493 // Initialize COM.
494 base::win::ScopedCOMInitializer com_initializer;
495 if (!com_initializer.succeeded())
496 return;
497
498 if (!InitializeComSecurity())
499 return;
500
419 CreateLauncher(scoped_refptr<AutoThreadTaskRunner>( 501 CreateLauncher(scoped_refptr<AutoThreadTaskRunner>(
420 new AutoThreadTaskRunner(main_task_runner_, 502 new AutoThreadTaskRunner(main_task_runner_,
421 run_loop.QuitClosure()))); 503 run_loop.QuitClosure())));
422 504
423 // Run the service. 505 // Run the service.
424 run_loop.Run(); 506 run_loop.Run();
425 507
426 // Tell SCM that the service is stopped. 508 // Tell SCM that the service is stopped.
427 service_status.dwCurrentState = SERVICE_STOPPED; 509 service_status.dwCurrentState = SERVICE_STOPPED;
428 service_status.dwControlsAccepted = 0; 510 service_status.dwControlsAccepted = 0;
429 if (!SetServiceStatus(service_status_handle_, &service_status)) { 511 if (!SetServiceStatus(service_status_handle_, &service_status)) {
430 LOG_GETLASTERROR(ERROR) 512 LOG_GETLASTERROR(ERROR)
431 << "Failed to report service status to the service control manager"; 513 << "Failed to report service status to the service control manager";
432 return; 514 return;
433 } 515 }
434 } 516 }
435 517
436 int HostService::RunInConsole() { 518 int HostService::RunInConsole() {
437 MessageLoop message_loop(MessageLoop::TYPE_UI); 519 MessageLoop message_loop(MessageLoop::TYPE_UI);
438 base::RunLoop run_loop; 520 base::RunLoop run_loop;
439 main_task_runner_ = message_loop.message_loop_proxy(); 521 main_task_runner_ = message_loop.message_loop_proxy();
440 522
441 int result = kInitializationFailed; 523 int result = kInitializationFailed;
442 524
525 // Initialize COM.
526 base::win::ScopedCOMInitializer com_initializer;
527 if (!com_initializer.succeeded())
528 return result;
529
530 if (!InitializeComSecurity())
531 return result;
532
443 // Subscribe to Ctrl-C and other console events. 533 // Subscribe to Ctrl-C and other console events.
444 if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) { 534 if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) {
445 LOG_GETLASTERROR(ERROR) 535 LOG_GETLASTERROR(ERROR)
446 << "Failed to set console control handler"; 536 << "Failed to set console control handler";
447 return result; 537 return result;
448 } 538 }
449 539
450 // Create a window for receiving session change notifications. 540 // Create a window for receiving session change notifications.
451 HWND window = NULL; 541 HWND window = NULL;
452 WNDCLASSEX window_class; 542 WNDCLASSEX window_class;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 int DaemonProcessMain() { 675 int DaemonProcessMain() {
586 HostService* service = HostService::GetInstance(); 676 HostService* service = HostService::GetInstance();
587 if (!service->InitWithCommandLine(CommandLine::ForCurrentProcess())) { 677 if (!service->InitWithCommandLine(CommandLine::ForCurrentProcess())) {
588 return kUsageExitCode; 678 return kUsageExitCode;
589 } 679 }
590 680
591 return service->Run(); 681 return service->Run();
592 } 682 }
593 683
594 } // namespace remoting 684 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/installer/win/chromoting.wxs ('k') | remoting/host/win/security_descriptor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698