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

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 | « no previous file | 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 is SDDL form.
Wez 2013/03/05 02:25:28 typo: is -> in
alexeypa (please no reviews) 2013/03/05 18:00:28 Done.
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 that gives SYSTEM and LocalSystem accounts
78 // COM_RIGHTS_EXECUTE and COM_RIGHTS_EXECUTE_LOCAL rights. The descriptor
79 // specifies a mandatory label with "no execute up" policy for medium integrity
80 // level.
Wez 2013/03/05 02:25:28 nit: Clarify why, e.g. "The descriptor has the "no
alexeypa (please no reviews) 2013/03/05 18:00:28 Done.
81 const wchar_t kComProcessSd[] =
82 SDDL_OWNER L":" SDDL_LOCAL_SYSTEM
83 SDDL_GROUP L":" SDDL_LOCAL_SYSTEM
84 SDDL_DACL L":"
85 SDDL_ACE(SDDL_ACCESS_ALLOWED, SDDL_COM_EXECUTE_LOCAL, SDDL_LOCAL_SYSTEM)
86 SDDL_ACE(SDDL_ACCESS_ALLOWED, SDDL_COM_EXECUTE_LOCAL, SDDL_LOCAL_SERVICE)
87 SDDL_SACL L":"
88 SDDL_ACE(SDDL_MANDATORY_LABEL, SDDL_NO_EXECUTE_UP, SDDL_ML_MEDIUM);
89
90 #undef SDDL_ACE
91 #undef SDDL_COM_EXECUTE_LOCAL
92
93 // Allows incoming calls from clients running under SYSTEM or LocalSystem at
94 // medium integrity level.
95 bool InitializeComSecurity() {
96 // Convert the SDDL description into a security descriptor in absolute format.
97 ScopedSd relative_sd = ConvertSddlToSd(WideToUTF8(kComProcessSd));
98 if (!relative_sd) {
99 LOG_GETLASTERROR(ERROR) << "Failed to create a security descriptor";
100 return false;
101 }
102 ScopedSd absolute_sd;
103 ScopedAcl dacl;
104 ScopedSid group;
105 ScopedSid owner;
106 ScopedAcl sacl;
107 if (!MakeScopedAbsoluteSd(relative_sd, &absolute_sd, &dacl, &group, &owner,
108 &sacl)) {
109 LOG_GETLASTERROR(ERROR) << "MakeScopedAbsoluteSd() failed";
110 return false;
111 }
112
113 // Apply the security descriptor and the following settings:
114 // - The daemon authenticates that all data received is from the expected
115 // client.
116 // - The daemon can check identity of the client but cannot act on its
117 // behalf.
118 // - Dynamic cloaking is used. DCOM verifies the caller's identify on every
Wez 2013/03/05 02:25:28 nit: Is the second sentence just a description of
Wez 2013/03/05 02:25:28 typo: identity
alexeypa (please no reviews) 2013/03/05 18:00:28 Done.
alexeypa (please no reviews) 2013/03/05 18:00:28 No.
119 // call.
120 // - Activations where the activated COM server would run under the daemon's
121 // identify are prohibited.
Wez 2013/03/05 02:25:28 typo: identify -> identity
alexeypa (please no reviews) 2013/03/05 18:00:28 Done.
122 HRESULT result = CoInitializeSecurity(
123 absolute_sd.get(),
124 -1,
Wez 2013/03/05 02:25:28 nit: Comment the numeric/NULL parameters, e.g. -1,
alexeypa (please no reviews) 2013/03/05 18:00:28 Done.
125 NULL,
126 NULL,
127 RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
128 RPC_C_IMP_LEVEL_IDENTIFY,
129 NULL,
130 EOAC_DYNAMIC_CLOAKING | EOAC_DISABLE_AAA,
131 NULL);
132 if (FAILED(result)) {
133 LOG(ERROR) << "CoInitializeSecurity() failed, result=0x"
134 << std::hex << result << std::dec << ".";
135 return false;
136 }
137
138 return true;
139 }
140
63 } // namespace 141 } // namespace
64 142
65 namespace remoting {
66
67 HostService* HostService::GetInstance() { 143 HostService* HostService::GetInstance() {
68 return Singleton<HostService>::get(); 144 return Singleton<HostService>::get();
69 } 145 }
70 146
71 bool HostService::InitWithCommandLine(const CommandLine* command_line) { 147 bool HostService::InitWithCommandLine(const CommandLine* command_line) {
72 CommandLine::StringVector args = command_line->GetArgs(); 148 CommandLine::StringVector args = command_line->GetArgs();
73 if (!args.empty()) { 149 if (!args.empty()) {
74 LOG(ERROR) << "No positional parameters expected."; 150 LOG(ERROR) << "No positional parameters expected.";
75 return false; 151 return false;
76 } 152 }
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 457
382 // Wait until the service thread completely exited to avoid concurrent 458 // Wait until the service thread completely exited to avoid concurrent
383 // teardown of objects registered with base::AtExitManager and object 459 // teardown of objects registered with base::AtExitManager and object
384 // destoyed by the service thread. 460 // destoyed by the service thread.
385 stopped_event_.Wait(); 461 stopped_event_.Wait();
386 462
387 return kSuccessExitCode; 463 return kSuccessExitCode;
388 } 464 }
389 465
390 void HostService::RunAsServiceImpl() { 466 void HostService::RunAsServiceImpl() {
391 MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); 467 MessageLoop message_loop(MessageLoop::TYPE_UI);
392 base::RunLoop run_loop; 468 base::RunLoop run_loop;
393 main_task_runner_ = message_loop.message_loop_proxy(); 469 main_task_runner_ = message_loop.message_loop_proxy();
394 470
395 // Register the service control handler. 471 // Register the service control handler.
396 service_status_handle_ = RegisterServiceCtrlHandlerExW( 472 service_status_handle_ = RegisterServiceCtrlHandlerExW(
397 kWindowsServiceName, &HostService::ServiceControlHandler, this); 473 kWindowsServiceName, &HostService::ServiceControlHandler, this);
398 if (service_status_handle_ == 0) { 474 if (service_status_handle_ == 0) {
399 LOG_GETLASTERROR(ERROR) 475 LOG_GETLASTERROR(ERROR)
400 << "Failed to register the service control handler"; 476 << "Failed to register the service control handler";
401 return; 477 return;
402 } 478 }
403 479
404 // Report running status of the service. 480 // Report running status of the service.
405 SERVICE_STATUS service_status; 481 SERVICE_STATUS service_status;
406 ZeroMemory(&service_status, sizeof(service_status)); 482 ZeroMemory(&service_status, sizeof(service_status));
407 service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 483 service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
408 service_status.dwCurrentState = SERVICE_RUNNING; 484 service_status.dwCurrentState = SERVICE_RUNNING;
409 service_status.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | 485 service_status.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN |
410 SERVICE_ACCEPT_STOP | 486 SERVICE_ACCEPT_STOP |
411 SERVICE_ACCEPT_SESSIONCHANGE; 487 SERVICE_ACCEPT_SESSIONCHANGE;
412 service_status.dwWin32ExitCode = kSuccessExitCode; 488 service_status.dwWin32ExitCode = kSuccessExitCode;
413 if (!SetServiceStatus(service_status_handle_, &service_status)) { 489 if (!SetServiceStatus(service_status_handle_, &service_status)) {
414 LOG_GETLASTERROR(ERROR) 490 LOG_GETLASTERROR(ERROR)
415 << "Failed to report service status to the service control manager"; 491 << "Failed to report service status to the service control manager";
416 return; 492 return;
417 } 493 }
418 494
495 // Initialize COM.
496 base::win::ScopedCOMInitializer com_initializer;
497 if (!com_initializer.succeeded())
498 return;
499
500 if (!InitializeComSecurity())
501 return;
502
419 CreateLauncher(scoped_refptr<AutoThreadTaskRunner>( 503 CreateLauncher(scoped_refptr<AutoThreadTaskRunner>(
420 new AutoThreadTaskRunner(main_task_runner_, 504 new AutoThreadTaskRunner(main_task_runner_,
421 run_loop.QuitClosure()))); 505 run_loop.QuitClosure())));
422 506
423 // Run the service. 507 // Run the service.
424 run_loop.Run(); 508 run_loop.Run();
425 509
426 // Tell SCM that the service is stopped. 510 // Tell SCM that the service is stopped.
427 service_status.dwCurrentState = SERVICE_STOPPED; 511 service_status.dwCurrentState = SERVICE_STOPPED;
428 service_status.dwControlsAccepted = 0; 512 service_status.dwControlsAccepted = 0;
429 if (!SetServiceStatus(service_status_handle_, &service_status)) { 513 if (!SetServiceStatus(service_status_handle_, &service_status)) {
430 LOG_GETLASTERROR(ERROR) 514 LOG_GETLASTERROR(ERROR)
431 << "Failed to report service status to the service control manager"; 515 << "Failed to report service status to the service control manager";
432 return; 516 return;
433 } 517 }
434 } 518 }
435 519
436 int HostService::RunInConsole() { 520 int HostService::RunInConsole() {
437 MessageLoop message_loop(MessageLoop::TYPE_UI); 521 MessageLoop message_loop(MessageLoop::TYPE_UI);
438 base::RunLoop run_loop; 522 base::RunLoop run_loop;
439 main_task_runner_ = message_loop.message_loop_proxy(); 523 main_task_runner_ = message_loop.message_loop_proxy();
440 524
441 int result = kInitializationFailed; 525 int result = kInitializationFailed;
442 526
527 // Initialize COM.
528 base::win::ScopedCOMInitializer com_initializer;
529 if (!com_initializer.succeeded())
530 return result;
531
532 if (!InitializeComSecurity())
533 return result;
534
443 // Subscribe to Ctrl-C and other console events. 535 // Subscribe to Ctrl-C and other console events.
444 if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) { 536 if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) {
445 LOG_GETLASTERROR(ERROR) 537 LOG_GETLASTERROR(ERROR)
446 << "Failed to set console control handler"; 538 << "Failed to set console control handler";
447 return result; 539 return result;
448 } 540 }
449 541
450 // Create a window for receiving session change notifications. 542 // Create a window for receiving session change notifications.
451 HWND window = NULL; 543 HWND window = NULL;
452 WNDCLASSEX window_class; 544 WNDCLASSEX window_class;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 int DaemonProcessMain() { 677 int DaemonProcessMain() {
586 HostService* service = HostService::GetInstance(); 678 HostService* service = HostService::GetInstance();
587 if (!service->InitWithCommandLine(CommandLine::ForCurrentProcess())) { 679 if (!service->InitWithCommandLine(CommandLine::ForCurrentProcess())) {
588 return kUsageExitCode; 680 return kUsageExitCode;
589 } 681 }
590 682
591 return service->Run(); 683 return service->Run();
592 } 684 }
593 685
594 } // namespace remoting 686 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | remoting/host/win/security_descriptor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698