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 |