Index: mojo/edk/system/node_controller.cc |
diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc |
index ca568c372ac8f5ecd61df9facc068481d49df151..c8a1d829107c5c64f7af2cfc8b59f46c0bc1f60d 100644 |
--- a/mojo/edk/system/node_controller.cc |
+++ b/mojo/edk/system/node_controller.cc |
@@ -116,16 +116,26 @@ void NodeController::SetIOTaskRunner( |
} |
void NodeController::ConnectToChild(base::ProcessHandle process_handle, |
- ScopedPlatformHandle platform_handle) { |
+ ScopedPlatformHandle platform_handle, |
+ const std::string& secret) { |
+#if !defined(OS_WIN) |
+ // We don't require or support secret validation on non-Windows platforms. |
+ CHECK(secret.empty()); |
+#endif |
io_task_runner_->PostTask( |
FROM_HERE, |
base::Bind(&NodeController::ConnectToChildOnIOThread, |
- base::Unretained(this), |
- process_handle, |
- base::Passed(&platform_handle))); |
+ base::Unretained(this), process_handle, |
+ base::Passed(&platform_handle), secret)); |
} |
-void NodeController::ConnectToParent(ScopedPlatformHandle platform_handle) { |
+void NodeController::ConnectToParent(ScopedPlatformHandle platform_handle, |
+ const std::string& secret) { |
+#if !defined(OS_WIN) |
+ // We don't require or support secret validation on non-Windows platforms. |
+ CHECK(secret.empty()); |
+#endif |
+ |
// TODO(amistry): Consider the need for a broker on Windows. |
#if defined(OS_POSIX) |
// On posix, use the bootstrap channel for the broker and receive the node's |
@@ -137,8 +147,8 @@ void NodeController::ConnectToParent(ScopedPlatformHandle platform_handle) { |
io_task_runner_->PostTask( |
FROM_HERE, |
base::Bind(&NodeController::ConnectToParentOnIOThread, |
- base::Unretained(this), |
- base::Passed(&platform_handle))); |
+ base::Unretained(this), base::Passed(&platform_handle), |
+ secret)); |
} |
void NodeController::SetPortObserver( |
@@ -180,6 +190,19 @@ void NodeController::ReservePort(const std::string& token, |
void NodeController::MergePortIntoParent(const std::string& token, |
const ports::PortRef& port) { |
+ { |
+ // This request may be coming from within the process that reserved the |
+ // "parent" side (e.g. for Chrome single-process mode), so if this token is |
+ // reserved locally, merge locally instead. |
+ base::AutoLock lock(reserved_ports_lock_); |
+ auto it = reserved_ports_.find(token); |
+ if (it != reserved_ports_.end()) { |
+ node_->MergePorts(port, name_, it->second.name()); |
+ reserved_ports_.erase(it); |
+ return; |
+ } |
+ } |
+ |
scoped_refptr<NodeChannel> parent = GetParentChannel(); |
if (parent) { |
parent->RequestPortMerge(port.name(), token); |
@@ -215,7 +238,8 @@ void NodeController::RequestShutdown(const base::Closure& callback) { |
void NodeController::ConnectToChildOnIOThread( |
base::ProcessHandle process_handle, |
- ScopedPlatformHandle platform_handle) { |
+ ScopedPlatformHandle platform_handle, |
+ const std::string& secret) { |
DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); |
#if defined(OS_POSIX) |
@@ -242,13 +266,15 @@ void NodeController::ConnectToChildOnIOThread( |
channel->SetRemoteNodeName(token); |
channel->SetRemoteProcessHandle(process_handle); |
+ channel->SetExpectedSecret(secret); |
channel->Start(); |
channel->AcceptChild(name_, token); |
} |
void NodeController::ConnectToParentOnIOThread( |
- ScopedPlatformHandle platform_handle) { |
+ ScopedPlatformHandle platform_handle, |
+ const std::string& secret) { |
DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); |
base::AutoLock lock(parent_lock_); |
@@ -260,6 +286,16 @@ void NodeController::ConnectToParentOnIOThread( |
bootstrap_parent_channel_ = |
NodeChannel::Create(this, std::move(platform_handle), io_task_runner_); |
bootstrap_parent_channel_->Start(); |
+ |
+ if (!secret.empty()) { |
+ // On Windows we start out by sending a secret token to the parent process |
+ // which it will use to authenticate our end of the pipe. |
+#if !defined(OS_WIN) |
+ // We don't ever want to send a secret on non-Windows. |
+ NOTREACHED(); |
+#endif |
+ bootstrap_parent_channel_->SendSecret(secret); |
+ } |
} |
scoped_refptr<NodeChannel> NodeController::GetPeerChannel( |