Index: remoting/host/wts_session_process_launcher_win.cc |
diff --git a/remoting/host/wts_session_process_launcher_win.cc b/remoting/host/wts_session_process_launcher_win.cc |
index c5e42dacceff16e9e07833a4bae75cb937b79d27..5076a9e1d3e91a5928955b572e8fadfc419eb04b 100644 |
--- a/remoting/host/wts_session_process_launcher_win.cc |
+++ b/remoting/host/wts_session_process_launcher_win.cc |
@@ -10,9 +10,15 @@ |
#include <windows.h> |
#include "base/logging.h" |
+#include "base/threading/thread.h" |
#include "base/utf_string_conversions.h" |
#include "base/win/scoped_handle.h" |
+#include "ipc/ipc_channel_proxy.h" |
+#include "ipc/ipc_message.h" |
+#include "ipc/ipc_message_macros.h" |
+#include "remoting/host/chromoting_session_messages.h" |
+#include "remoting/host/sas_injector_win.h" |
#include "remoting/host/wts_console_monitor_win.h" |
using base::win::ScopedHandle; |
@@ -28,6 +34,9 @@ const int kMinLaunchDelaySeconds = 1; |
// Name of the default session desktop. |
const char kDefaultDesktopName[] = "winsta0\\default"; |
+// Name of the chromoting service IPC channel. |
+const char kChromotingSessionChannelName[] = "chromoting_session"; |
+ |
// Takes the process token and makes a copy of it. The returned handle will have |
// |desired_access| rights. |
bool CopyProcessToken(DWORD desired_access, |
@@ -155,8 +164,10 @@ namespace remoting { |
WtsSessionProcessLauncher::WtsSessionProcessLauncher( |
WtsConsoleMonitor* monitor, |
- const FilePath& host_binary) |
+ const FilePath& host_binary, |
+ base::Thread* io_thread) |
: host_binary_(host_binary), |
+ io_thread_(io_thread), |
monitor_(monitor), |
state_(StateDetached) { |
monitor_->AddWtsConsoleObserver(this); |
@@ -167,6 +178,7 @@ WtsSessionProcessLauncher::~WtsSessionProcessLauncher() { |
DCHECK(!timer_.IsRunning()); |
DCHECK(process_.handle() == NULL); |
DCHECK(process_watcher_.GetWatchedObject() == NULL); |
+ DCHECK(chromoting_session_.get() == NULL); |
monitor_->RemoveWtsConsoleObserver(this); |
} |
@@ -176,10 +188,30 @@ void WtsSessionProcessLauncher::LaunchProcess() { |
DCHECK(!timer_.IsRunning()); |
DCHECK(process_.handle() == NULL); |
DCHECK(process_watcher_.GetWatchedObject() == NULL); |
+ DCHECK(chromoting_session_.get() == NULL); |
+ |
+ launch_time_ = base::Time::Now(); |
+ |
+ // Create the chromoting service IPC channel on the I/O thread. |
+ // N.B. IPC::Channel passes NULL as the security attributes pointer to |
+ // CreateNamedPipe() so the pipe gets the default security descriptor. |
+ // The ACLs in the default security descriptor for a named pipe grant |
+ // full control to the LocalSystem account, administrators, and |
+ // the creator owner. They also grant read access to members of the |
+ // Everyone group and the anonymous account. |
+ // |
+ // IPC::Channel also specifies the PIPE_ACCESS_DUPLEX mode for |
+ // the created pipe. A client has to specify the same duplex mode in |
+ // order to connect. Which means that clients with read-only access |
+ // (Everyone and anonymous) will not be able to connect. |
Wez
2012/03/08 00:01:33
nit: ... to connect, which means ...
The comment
alexeypa (please no reviews)
2012/03/08 01:52:54
Actually, there is much more serious problem with
|
+ chromoting_session_.reset(new IPC::ChannelProxy( |
+ kChromotingSessionChannelName, |
+ IPC::Channel::MODE_SERVER, |
+ this, |
+ io_thread_->message_loop_proxy().get())); |
// Try to launch the process and attach an object watcher to the returned |
// handle so that we get notified when the process terminates. |
- launch_time_ = base::Time::Now(); |
if (LaunchProcessAsUser(host_binary_, session_token_, &process_)) { |
if (process_watcher_.StartWatching(process_.handle(), this)) { |
state_ = StateAttached; |
@@ -188,6 +220,7 @@ void WtsSessionProcessLauncher::LaunchProcess() { |
LOG(ERROR) << "Failed to arm the process watcher."; |
process_.Terminate(0); |
process_.Close(); |
+ chromoting_session_.reset(); |
} |
} |
@@ -206,10 +239,12 @@ void WtsSessionProcessLauncher::OnObjectSignaled(HANDLE object) { |
DCHECK(!timer_.IsRunning()); |
DCHECK(process_.handle() != NULL); |
DCHECK(process_watcher_.GetWatchedObject() == NULL); |
+ DCHECK(chromoting_session_.get() != NULL); |
// The host process has been terminated for some reason. The handle can now be |
// closed. |
process_.Close(); |
+ chromoting_session_.reset(); |
// Expand the backoff interval if the process has died quickly or reset it if |
// it was up longer than the maximum backoff delay. |
@@ -230,11 +265,34 @@ void WtsSessionProcessLauncher::OnObjectSignaled(HANDLE object) { |
this, &WtsSessionProcessLauncher::LaunchProcess); |
} |
+bool WtsSessionProcessLauncher::OnMessageReceived(const IPC::Message& message) { |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(WtsSessionProcessLauncher, message) |
+ IPC_MESSAGE_HANDLER(ChromotingSessionMsg_SendSasToConsole, |
+ OnSendSasToConsole) |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ return handled; |
+} |
+ |
+void WtsSessionProcessLauncher::OnSendSasToConsole() { |
+ if (state_ == StateAttached) { |
+ if (sas_injector_.get() == NULL) { |
+ sas_injector_ = SasInjector::Create(); |
+ } |
+ |
+ if (sas_injector_.get() != NULL) { |
+ sas_injector_->InjectSas(); |
+ } |
+ } |
+} |
+ |
void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) { |
DCHECK(state_ == StateDetached); |
DCHECK(!timer_.IsRunning()); |
DCHECK(process_.handle() == NULL); |
DCHECK(process_watcher_.GetWatchedObject() == NULL); |
+ DCHECK(chromoting_session_.get() == NULL); |
// Temporarily enable the SE_TCB_NAME privilege. The privileged token is |
// created as needed and kept for later reuse. |
@@ -250,7 +308,7 @@ void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) { |
return; |
} |
- // While the SE_TCB_NAME progolege is enabled, create a session token for |
+ // While the SE_TCB_NAME privilege is enabled, create a session token for |
// the launched process. |
bool result = CreateSessionToken(session_id, &session_token_); |
@@ -276,12 +334,14 @@ void WtsSessionProcessLauncher::OnSessionDetached() { |
DCHECK(!timer_.IsRunning()); |
DCHECK(process_.handle() == NULL); |
DCHECK(process_watcher_.GetWatchedObject() == NULL); |
+ DCHECK(chromoting_session_.get() == NULL); |
break; |
case StateStarting: |
DCHECK(timer_.IsRunning()); |
DCHECK(process_.handle() == NULL); |
DCHECK(process_watcher_.GetWatchedObject() == NULL); |
+ DCHECK(chromoting_session_.get() == NULL); |
timer_.Stop(); |
launch_backoff_ = base::TimeDelta(); |
@@ -292,10 +352,12 @@ void WtsSessionProcessLauncher::OnSessionDetached() { |
DCHECK(!timer_.IsRunning()); |
DCHECK(process_.handle() != NULL); |
DCHECK(process_watcher_.GetWatchedObject() != NULL); |
+ DCHECK(chromoting_session_.get() != NULL); |
process_watcher_.StopWatching(); |
process_.Terminate(0); |
process_.Close(); |
+ chromoting_session_.reset(); |
state_ = StateDetached; |
break; |
} |