| OLD | NEW |
| 1 | 1 |
| 2 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
| 5 // | 5 // |
| 6 // This file implements the Windows service controlling Me2Me host processes | 6 // This file implements the Windows service controlling Me2Me host processes |
| 7 // running within user sessions. | 7 // running within user sessions. |
| 8 | 8 |
| 9 #include "remoting/host/win/unprivileged_process_delegate.h" | 9 #include "remoting/host/win/unprivileged_process_delegate.h" |
| 10 | 10 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 // full access to the threads. It gives READ_CONTROL, SYNCHRONIZE, | 69 // full access to the threads. It gives READ_CONTROL, SYNCHRONIZE, |
| 70 // THREAD_QUERY_INFORMATION and THREAD_TERMINATE rights to the built-in | 70 // THREAD_QUERY_INFORMATION and THREAD_TERMINATE rights to the built-in |
| 71 // administrators group. | 71 // administrators group. |
| 72 const char kWorkerThreadSd[] = "O:SYG:SYD:(A;;GA;;;SY)(A;;0x120801;;;BA)"; | 72 const char kWorkerThreadSd[] = "O:SYG:SYD:(A;;GA;;;SY)(A;;0x120801;;;BA)"; |
| 73 | 73 |
| 74 // Creates a token with limited access that will be used to run the worker | 74 // Creates a token with limited access that will be used to run the worker |
| 75 // process. | 75 // process. |
| 76 bool CreateRestrictedToken(ScopedHandle* token_out) { | 76 bool CreateRestrictedToken(ScopedHandle* token_out) { |
| 77 // Create a token representing LocalService account. | 77 // Create a token representing LocalService account. |
| 78 HANDLE temp_handle; | 78 HANDLE temp_handle; |
| 79 if (!LogonUser(L"LocalService", L"NT AUTHORITY", NULL, LOGON32_LOGON_SERVICE, | 79 if (!LogonUser(L"LocalService", L"NT AUTHORITY", nullptr, |
| 80 LOGON32_PROVIDER_DEFAULT, &temp_handle)) { | 80 LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, |
| 81 &temp_handle)) { |
| 81 return false; | 82 return false; |
| 82 } | 83 } |
| 83 ScopedHandle token(temp_handle); | 84 ScopedHandle token(temp_handle); |
| 84 | 85 |
| 85 sandbox::RestrictedToken restricted_token; | 86 sandbox::RestrictedToken restricted_token; |
| 86 if (restricted_token.Init(token.Get()) != ERROR_SUCCESS) | 87 if (restricted_token.Init(token.Get()) != ERROR_SUCCESS) |
| 87 return false; | 88 return false; |
| 88 | 89 |
| 89 // Remove all privileges in the token. | 90 // Remove all privileges in the token. |
| 90 if (restricted_token.DeleteAllPrivileges(NULL) != ERROR_SUCCESS) | 91 if (restricted_token.DeleteAllPrivileges(nullptr) != ERROR_SUCCESS) |
| 91 return false; | 92 return false; |
| 92 | 93 |
| 93 // Set low integrity level if supported by the OS. | 94 // Set low integrity level if supported by the OS. |
| 94 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { | 95 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
| 95 if (restricted_token.SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW) | 96 if (restricted_token.SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW) |
| 96 != ERROR_SUCCESS) { | 97 != ERROR_SUCCESS) { |
| 97 return false; | 98 return false; |
| 98 } | 99 } |
| 99 } | 100 } |
| 100 | 101 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | | 186 DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | |
| 186 DESKTOP_SWITCHDESKTOP | DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER; | 187 DESKTOP_SWITCHDESKTOP | DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER; |
| 187 | 188 |
| 188 security_attributes.nLength = sizeof(security_attributes); | 189 security_attributes.nLength = sizeof(security_attributes); |
| 189 security_attributes.lpSecurityDescriptor = desktop_sd.get(); | 190 security_attributes.lpSecurityDescriptor = desktop_sd.get(); |
| 190 security_attributes.bInheritHandle = TRUE; | 191 security_attributes.bInheritHandle = TRUE; |
| 191 | 192 |
| 192 // The default desktop of the interactive window station is called "Default". | 193 // The default desktop of the interactive window station is called "Default". |
| 193 // Name the created desktop the same way in case any code relies on that. | 194 // Name the created desktop the same way in case any code relies on that. |
| 194 // The desktop name should not make any difference though. | 195 // The desktop name should not make any difference though. |
| 195 handles.SetDesktop(CreateDesktop(L"Default", NULL, NULL, 0, desired_access, | 196 handles.SetDesktop(CreateDesktop(L"Default", nullptr, nullptr, 0, |
| 196 &security_attributes)); | 197 desired_access, &security_attributes)); |
| 197 | 198 |
| 198 // Switch back to the original window station. | 199 // Switch back to the original window station. |
| 199 if (!SetProcessWindowStation(current_window_station)) { | 200 if (!SetProcessWindowStation(current_window_station)) { |
| 200 PLOG(ERROR) << "SetProcessWindowStation() failed"; | 201 PLOG(ERROR) << "SetProcessWindowStation() failed"; |
| 201 return false; | 202 return false; |
| 202 } | 203 } |
| 203 | 204 |
| 204 if (!handles.desktop()) { | 205 if (!handles.desktop()) { |
| 205 PLOG(ERROR) << "CreateDesktop() failed"; | 206 PLOG(ERROR) << "CreateDesktop() failed"; |
| 206 return false; | 207 return false; |
| 207 } | 208 } |
| 208 | 209 |
| 209 handles.Swap(*handles_out); | 210 handles.Swap(*handles_out); |
| 210 return true; | 211 return true; |
| 211 } | 212 } |
| 212 | 213 |
| 213 } // namespace | 214 } // namespace |
| 214 | 215 |
| 215 UnprivilegedProcessDelegate::UnprivilegedProcessDelegate( | 216 UnprivilegedProcessDelegate::UnprivilegedProcessDelegate( |
| 216 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, | 217 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
| 217 scoped_ptr<base::CommandLine> target_command) | 218 scoped_ptr<base::CommandLine> target_command) |
| 218 : io_task_runner_(io_task_runner), | 219 : io_task_runner_(io_task_runner), |
| 219 event_handler_(NULL), | 220 event_handler_(nullptr), |
| 220 target_command_(target_command.Pass()) { | 221 target_command_(target_command.Pass()) { |
| 221 } | 222 } |
| 222 | 223 |
| 223 UnprivilegedProcessDelegate::~UnprivilegedProcessDelegate() { | 224 UnprivilegedProcessDelegate::~UnprivilegedProcessDelegate() { |
| 224 DCHECK(CalledOnValidThread()); | 225 DCHECK(CalledOnValidThread()); |
| 225 DCHECK(!channel_); | 226 DCHECK(!channel_); |
| 226 DCHECK(!worker_process_.IsValid()); | 227 DCHECK(!worker_process_.IsValid()); |
| 227 } | 228 } |
| 228 | 229 |
| 229 void UnprivilegedProcessDelegate::LaunchProcess( | 230 void UnprivilegedProcessDelegate::LaunchProcess( |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 // Try to launch the worker process. The launched process inherits | 305 // Try to launch the worker process. The launched process inherits |
| 305 // the window station, desktop and pipe handles, created above. | 306 // the window station, desktop and pipe handles, created above. |
| 306 ScopedHandle worker_thread; | 307 ScopedHandle worker_thread; |
| 307 if (!LaunchProcessWithToken(command_line.GetProgram(), | 308 if (!LaunchProcessWithToken(command_line.GetProgram(), |
| 308 command_line.GetCommandLineString(), | 309 command_line.GetCommandLineString(), |
| 309 token.Get(), | 310 token.Get(), |
| 310 &process_attributes, | 311 &process_attributes, |
| 311 &thread_attributes, | 312 &thread_attributes, |
| 312 true, | 313 true, |
| 313 0, | 314 0, |
| 314 NULL, | 315 nullptr, |
| 315 &worker_process, | 316 &worker_process, |
| 316 &worker_thread)) { | 317 &worker_thread)) { |
| 317 ReportFatalError(); | 318 ReportFatalError(); |
| 318 return; | 319 return; |
| 319 } | 320 } |
| 320 } | 321 } |
| 321 | 322 |
| 322 channel_ = server.Pass(); | 323 channel_ = server.Pass(); |
| 323 ReportProcessLaunched(worker_process.Pass()); | 324 ReportProcessLaunched(worker_process.Pass()); |
| 324 } | 325 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 336 void UnprivilegedProcessDelegate::CloseChannel() { | 337 void UnprivilegedProcessDelegate::CloseChannel() { |
| 337 DCHECK(CalledOnValidThread()); | 338 DCHECK(CalledOnValidThread()); |
| 338 | 339 |
| 339 channel_.reset(); | 340 channel_.reset(); |
| 340 } | 341 } |
| 341 | 342 |
| 342 void UnprivilegedProcessDelegate::KillProcess() { | 343 void UnprivilegedProcessDelegate::KillProcess() { |
| 343 DCHECK(CalledOnValidThread()); | 344 DCHECK(CalledOnValidThread()); |
| 344 | 345 |
| 345 channel_.reset(); | 346 channel_.reset(); |
| 346 event_handler_ = NULL; | 347 event_handler_ = nullptr; |
| 347 | 348 |
| 348 if (worker_process_.IsValid()) { | 349 if (worker_process_.IsValid()) { |
| 349 TerminateProcess(worker_process_.Get(), CONTROL_C_EXIT); | 350 TerminateProcess(worker_process_.Get(), CONTROL_C_EXIT); |
| 350 worker_process_.Close(); | 351 worker_process_.Close(); |
| 351 } | 352 } |
| 352 } | 353 } |
| 353 | 354 |
| 354 bool UnprivilegedProcessDelegate::OnMessageReceived( | 355 bool UnprivilegedProcessDelegate::OnMessageReceived( |
| 355 const IPC::Message& message) { | 356 const IPC::Message& message) { |
| 356 DCHECK(CalledOnValidThread()); | 357 DCHECK(CalledOnValidThread()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 378 | 379 |
| 379 event_handler_->OnChannelError(); | 380 event_handler_->OnChannelError(); |
| 380 } | 381 } |
| 381 | 382 |
| 382 void UnprivilegedProcessDelegate::ReportFatalError() { | 383 void UnprivilegedProcessDelegate::ReportFatalError() { |
| 383 DCHECK(CalledOnValidThread()); | 384 DCHECK(CalledOnValidThread()); |
| 384 | 385 |
| 385 channel_.reset(); | 386 channel_.reset(); |
| 386 | 387 |
| 387 WorkerProcessLauncher* event_handler = event_handler_; | 388 WorkerProcessLauncher* event_handler = event_handler_; |
| 388 event_handler_ = NULL; | 389 event_handler_ = nullptr; |
| 389 event_handler->OnFatalError(); | 390 event_handler->OnFatalError(); |
| 390 } | 391 } |
| 391 | 392 |
| 392 void UnprivilegedProcessDelegate::ReportProcessLaunched( | 393 void UnprivilegedProcessDelegate::ReportProcessLaunched( |
| 393 base::win::ScopedHandle worker_process) { | 394 base::win::ScopedHandle worker_process) { |
| 394 DCHECK(CalledOnValidThread()); | 395 DCHECK(CalledOnValidThread()); |
| 395 DCHECK(!worker_process_.IsValid()); | 396 DCHECK(!worker_process_.IsValid()); |
| 396 | 397 |
| 397 worker_process_ = worker_process.Pass(); | 398 worker_process_ = worker_process.Pass(); |
| 398 | 399 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 411 PLOG(ERROR) << "Failed to duplicate a handle"; | 412 PLOG(ERROR) << "Failed to duplicate a handle"; |
| 412 ReportFatalError(); | 413 ReportFatalError(); |
| 413 return; | 414 return; |
| 414 } | 415 } |
| 415 ScopedHandle limited_handle(temp_handle); | 416 ScopedHandle limited_handle(temp_handle); |
| 416 | 417 |
| 417 event_handler_->OnProcessLaunched(limited_handle.Pass()); | 418 event_handler_->OnProcessLaunched(limited_handle.Pass()); |
| 418 } | 419 } |
| 419 | 420 |
| 420 } // namespace remoting | 421 } // namespace remoting |
| OLD | NEW |