| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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", NULL, LOGON32_LOGON_SERVICE, |
| 80 LOGON32_PROVIDER_DEFAULT, &temp_handle)) { | 80 LOGON32_PROVIDER_DEFAULT, &temp_handle)) { |
| 81 return false; | 81 return false; |
| 82 } | 82 } |
| 83 ScopedHandle token(temp_handle); | 83 ScopedHandle token(temp_handle); |
| 84 | 84 |
| 85 sandbox::RestrictedToken restricted_token; | 85 sandbox::RestrictedToken restricted_token; |
| 86 if (restricted_token.Init(token) != ERROR_SUCCESS) | 86 if (restricted_token.Init(token.Get()) != ERROR_SUCCESS) |
| 87 return false; | 87 return false; |
| 88 | 88 |
| 89 // Remove all privileges in the token. | 89 // Remove all privileges in the token. |
| 90 if (restricted_token.DeleteAllPrivileges(NULL) != ERROR_SUCCESS) | 90 if (restricted_token.DeleteAllPrivileges(NULL) != ERROR_SUCCESS) |
| 91 return false; | 91 return false; |
| 92 | 92 |
| 93 // Set low integrity level if supported by the OS. | 93 // Set low integrity level if supported by the OS. |
| 94 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { | 94 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
| 95 if (restricted_token.SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW) | 95 if (restricted_token.SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW) |
| 96 != ERROR_SUCCESS) { | 96 != ERROR_SUCCESS) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 // Create a restricted token that will be used to run the worker process. | 238 // Create a restricted token that will be used to run the worker process. |
| 239 ScopedHandle token; | 239 ScopedHandle token; |
| 240 if (!CreateRestrictedToken(&token)) { | 240 if (!CreateRestrictedToken(&token)) { |
| 241 PLOG(ERROR) << "Failed to create a restricted LocalService token"; | 241 PLOG(ERROR) << "Failed to create a restricted LocalService token"; |
| 242 ReportFatalError(); | 242 ReportFatalError(); |
| 243 return; | 243 return; |
| 244 } | 244 } |
| 245 | 245 |
| 246 // Determine our logon SID, so we can grant it access to our window station | 246 // Determine our logon SID, so we can grant it access to our window station |
| 247 // and desktop. | 247 // and desktop. |
| 248 ScopedSid logon_sid = GetLogonSid(token); | 248 ScopedSid logon_sid = GetLogonSid(token.Get()); |
| 249 if (!logon_sid) { | 249 if (!logon_sid) { |
| 250 PLOG(ERROR) << "Failed to retrieve the logon SID"; | 250 PLOG(ERROR) << "Failed to retrieve the logon SID"; |
| 251 ReportFatalError(); | 251 ReportFatalError(); |
| 252 return; | 252 return; |
| 253 } | 253 } |
| 254 | 254 |
| 255 // Create the process and thread security descriptors. | 255 // Create the process and thread security descriptors. |
| 256 ScopedSd process_sd = ConvertSddlToSd(kWorkerProcessSd); | 256 ScopedSd process_sd = ConvertSddlToSd(kWorkerProcessSd); |
| 257 ScopedSd thread_sd = ConvertSddlToSd(kWorkerThreadSd); | 257 ScopedSd thread_sd = ConvertSddlToSd(kWorkerThreadSd); |
| 258 if (!process_sd || !thread_sd) { | 258 if (!process_sd || !thread_sd) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 PLOG(ERROR) << "Failed to create a window station and desktop"; | 299 PLOG(ERROR) << "Failed to create a window station and desktop"; |
| 300 ReportFatalError(); | 300 ReportFatalError(); |
| 301 return; | 301 return; |
| 302 } | 302 } |
| 303 | 303 |
| 304 // Try to launch the worker process. The launched process inherits | 304 // Try to launch the worker process. The launched process inherits |
| 305 // the window station, desktop and pipe handles, created above. | 305 // the window station, desktop and pipe handles, created above. |
| 306 ScopedHandle worker_thread; | 306 ScopedHandle worker_thread; |
| 307 if (!LaunchProcessWithToken(command_line.GetProgram(), | 307 if (!LaunchProcessWithToken(command_line.GetProgram(), |
| 308 command_line.GetCommandLineString(), | 308 command_line.GetCommandLineString(), |
| 309 token, | 309 token.Get(), |
| 310 &process_attributes, | 310 &process_attributes, |
| 311 &thread_attributes, | 311 &thread_attributes, |
| 312 true, | 312 true, |
| 313 0, | 313 0, |
| 314 NULL, | 314 NULL, |
| 315 &worker_process, | 315 &worker_process, |
| 316 &worker_thread)) { | 316 &worker_thread)) { |
| 317 ReportFatalError(); | 317 ReportFatalError(); |
| 318 return; | 318 return; |
| 319 } | 319 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 339 channel_.reset(); | 339 channel_.reset(); |
| 340 } | 340 } |
| 341 | 341 |
| 342 void UnprivilegedProcessDelegate::KillProcess() { | 342 void UnprivilegedProcessDelegate::KillProcess() { |
| 343 DCHECK(CalledOnValidThread()); | 343 DCHECK(CalledOnValidThread()); |
| 344 | 344 |
| 345 channel_.reset(); | 345 channel_.reset(); |
| 346 event_handler_ = NULL; | 346 event_handler_ = NULL; |
| 347 | 347 |
| 348 if (worker_process_.IsValid()) { | 348 if (worker_process_.IsValid()) { |
| 349 TerminateProcess(worker_process_, CONTROL_C_EXIT); | 349 TerminateProcess(worker_process_.Get(), CONTROL_C_EXIT); |
| 350 worker_process_.Close(); | 350 worker_process_.Close(); |
| 351 } | 351 } |
| 352 } | 352 } |
| 353 | 353 |
| 354 bool UnprivilegedProcessDelegate::OnMessageReceived( | 354 bool UnprivilegedProcessDelegate::OnMessageReceived( |
| 355 const IPC::Message& message) { | 355 const IPC::Message& message) { |
| 356 DCHECK(CalledOnValidThread()); | 356 DCHECK(CalledOnValidThread()); |
| 357 | 357 |
| 358 return event_handler_->OnMessageReceived(message); | 358 return event_handler_->OnMessageReceived(message); |
| 359 } | 359 } |
| 360 | 360 |
| 361 void UnprivilegedProcessDelegate::OnChannelConnected(int32 peer_pid) { | 361 void UnprivilegedProcessDelegate::OnChannelConnected(int32 peer_pid) { |
| 362 DCHECK(CalledOnValidThread()); | 362 DCHECK(CalledOnValidThread()); |
| 363 | 363 |
| 364 DWORD pid = GetProcessId(worker_process_); | 364 DWORD pid = GetProcessId(worker_process_.Get()); |
| 365 if (pid != static_cast<DWORD>(peer_pid)) { | 365 if (pid != static_cast<DWORD>(peer_pid)) { |
| 366 LOG(ERROR) << "The actual client PID " << pid | 366 LOG(ERROR) << "The actual client PID " << pid |
| 367 << " does not match the one reported by the client: " | 367 << " does not match the one reported by the client: " |
| 368 << peer_pid; | 368 << peer_pid; |
| 369 ReportFatalError(); | 369 ReportFatalError(); |
| 370 return; | 370 return; |
| 371 } | 371 } |
| 372 | 372 |
| 373 event_handler_->OnChannelConnected(peer_pid); | 373 event_handler_->OnChannelConnected(peer_pid); |
| 374 } | 374 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 395 DCHECK(!worker_process_.IsValid()); | 395 DCHECK(!worker_process_.IsValid()); |
| 396 | 396 |
| 397 worker_process_ = worker_process.Pass(); | 397 worker_process_ = worker_process.Pass(); |
| 398 | 398 |
| 399 // Report a handle that can be used to wait for the worker process completion, | 399 // Report a handle that can be used to wait for the worker process completion, |
| 400 // query information about the process and duplicate handles. | 400 // query information about the process and duplicate handles. |
| 401 DWORD desired_access = | 401 DWORD desired_access = |
| 402 SYNCHRONIZE | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION; | 402 SYNCHRONIZE | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION; |
| 403 HANDLE temp_handle; | 403 HANDLE temp_handle; |
| 404 if (!DuplicateHandle(GetCurrentProcess(), | 404 if (!DuplicateHandle(GetCurrentProcess(), |
| 405 worker_process_, | 405 worker_process_.Get(), |
| 406 GetCurrentProcess(), | 406 GetCurrentProcess(), |
| 407 &temp_handle, | 407 &temp_handle, |
| 408 desired_access, | 408 desired_access, |
| 409 FALSE, | 409 FALSE, |
| 410 0)) { | 410 0)) { |
| 411 PLOG(ERROR) << "Failed to duplicate a handle"; | 411 PLOG(ERROR) << "Failed to duplicate a handle"; |
| 412 ReportFatalError(); | 412 ReportFatalError(); |
| 413 return; | 413 return; |
| 414 } | 414 } |
| 415 ScopedHandle limited_handle(temp_handle); | 415 ScopedHandle limited_handle(temp_handle); |
| 416 | 416 |
| 417 event_handler_->OnProcessLaunched(limited_handle.Pass()); | 417 event_handler_->OnProcessLaunched(limited_handle.Pass()); |
| 418 } | 418 } |
| 419 | 419 |
| 420 } // namespace remoting | 420 } // namespace remoting |
| OLD | NEW |