Commit d3bda168 authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Migrate assorted bits from Mojo EDK to public APIs

Migrates Mac app shim support and security key remoting code away
from internal EDK APIs and over to newer, functionally equivalent
public APIs.

No functional changes here, just swapping out old types for new ones
and updating dependencies appropriately.

Note that this also duplicates some internal EDK code into the public
Mojo platform library. This code is shared by a few unrelated
parts of Chrome and really has nothing to do with Mojo, but there's
not a better home for it yet.

Bug: 844763
Change-Id: I40e7ff08f01d513fb046dc636ba3e4b1db1dbad2
Reviewed-on: https://chromium-review.googlesource.com/1099726
Commit-Queue: Ken Rockot <rockot@chromium.org>
Reviewed-by: default avatarJay Civelli <jcivelli@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Reviewed-by: default avatarJoe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567330}
parent 7853b97d
......@@ -40,11 +40,9 @@
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "mojo/edk/embedder/peer_connection.h"
#include "mojo/edk/embedder/scoped_ipc_support.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/system/isolated_connection.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
......@@ -149,7 +147,7 @@ class AppShimController : public IPC::Listener {
void Close();
base::FilePath user_data_dir_;
mojo::edk::PeerConnection peer_connection_;
mojo::IsolatedConnection mojo_connection_;
std::unique_ptr<IPC::ChannelProxy> channel_;
base::scoped_nsobject<AppShimDelegate> delegate_;
bool launch_app_done_;
......@@ -223,10 +221,8 @@ void AppShimController::CreateChannelAndSendLaunchApp(
const base::FilePath& socket_path) {
channel_ = IPC::ChannelProxy::Create(
IPC::ChannelMojo::CreateClientFactory(
peer_connection_.Connect(mojo::edk::ConnectionParams(
mojo::edk::TransportProtocol::kLegacy,
mojo::edk::CreateClientHandle(
mojo::edk::NamedPlatformHandle(socket_path.value())))),
mojo_connection_.Connect(
mojo::NamedPlatformChannel::ConnectToServer(socket_path.value())),
g_io_thread->task_runner().get(),
base::ThreadTaskRunnerHandle::Get()),
this, g_io_thread->task_runner().get(),
......
......@@ -14,7 +14,6 @@
#include "content/public/browser/browser_thread.h"
#include "ipc/ipc_channel_mojo.h"
#include "ipc/ipc_channel_proxy.h"
#include "mojo/edk/embedder/embedder.h"
AppShimHost::AppShimHost() : initial_launch_finished_(false) {}
......@@ -25,13 +24,12 @@ AppShimHost::~AppShimHost() {
handler->OnShimClose(this);
}
void AppShimHost::ServeChannel(mojo::edk::ScopedInternalPlatformHandle handle) {
void AppShimHost::ServeChannel(mojo::PlatformChannelEndpoint endpoint) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(!channel_.get());
channel_ = IPC::ChannelProxy::Create(
IPC::ChannelMojo::CreateServerFactory(
peer_connection_.Connect(mojo::edk::ConnectionParams(
mojo::edk::TransportProtocol::kLegacy, std::move(handle))),
mojo_connection_.Connect(std::move(endpoint)),
content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::IO)
.get(),
......
......@@ -14,8 +14,8 @@
#include "chrome/browser/apps/app_shim/app_shim_handler_mac.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "mojo/edk/embedder/peer_connection.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/public/cpp/platform/platform_channel_endpoint.h"
#include "mojo/public/cpp/system/isolated_connection.h"
namespace IPC {
class ChannelProxy;
......@@ -33,10 +33,10 @@ class AppShimHost : public IPC::Listener,
AppShimHost();
~AppShimHost() override;
// Creates a new server-side IPC channel at |handle|, which should contain a
// Creates a new server-side IPC channel at |endpoint|, which should contain a
// file descriptor of a channel created by an UnixDomainSocketAcceptor,
// and begins listening for messages on it.
void ServeChannel(mojo::edk::ScopedInternalPlatformHandle handle);
void ServeChannel(mojo::PlatformChannelEndpoint endpoint);
protected:
// IPC::Listener implementation.
......@@ -77,7 +77,7 @@ class AppShimHost : public IPC::Listener,
// Closes the channel and destroys the AppShimHost.
void Close();
mojo::edk::PeerConnection peer_connection_;
mojo::IsolatedConnection mojo_connection_;
std::unique_ptr<IPC::ChannelProxy> channel_;
std::string app_id_;
base::FilePath profile_path_;
......
......@@ -27,9 +27,8 @@
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "mojo/edk/embedder/peer_connection.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/system/isolated_connection.h"
namespace {
......@@ -52,7 +51,7 @@ class TestShimClient : public IPC::Listener {
void OnChannelError() override;
base::Thread io_thread_;
mojo::edk::PeerConnection peer_connection_;
mojo::IsolatedConnection mojo_connection_;
std::unique_ptr<IPC::ChannelProxy> channel_;
DISALLOW_COPY_AND_ASSIGN(TestShimClient);
......@@ -75,10 +74,8 @@ TestShimClient::TestShimClient() : io_thread_("TestShimClientIO") {
channel_ = IPC::ChannelProxy::Create(
IPC::ChannelMojo::CreateClientFactory(
peer_connection_.Connect(mojo::edk::ConnectionParams(
mojo::edk::TransportProtocol::kLegacy,
mojo::edk::CreateClientHandle(
mojo::edk::NamedPlatformHandle(socket_path.value())))),
mojo_connection_.Connect(
mojo::NamedPlatformChannel::ConnectToServer(socket_path.value())),
io_thread_.task_runner().get(), base::ThreadTaskRunnerHandle::Get()),
this, io_thread_.task_runner().get(),
base::ThreadTaskRunnerHandle::Get());
......
......@@ -11,7 +11,7 @@
#include "base/memory/ref_counted.h"
#include "chrome/browser/apps/app_shim/unix_domain_socket_acceptor.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/public/cpp/platform/platform_channel_endpoint.h"
namespace apps {
class ExtensionAppShimHandler;
......@@ -52,8 +52,7 @@ class AppShimHostManager : public apps::UnixDomainSocketAcceptor::Delegate,
virtual ~AppShimHostManager();
// UnixDomainSocketAcceptor::Delegate implementation.
void OnClientConnected(
mojo::edk::ScopedInternalPlatformHandle handle) override;
void OnClientConnected(mojo::PlatformChannelEndpoint endpoint) override;
void OnListenError() override;
// The |acceptor_| must be created on a thread which allows blocking I/O.
......
......@@ -22,9 +22,9 @@
namespace {
void CreateAppShimHost(mojo::edk::ScopedInternalPlatformHandle handle) {
void CreateAppShimHost(mojo::PlatformChannelEndpoint endpoint) {
// AppShimHost takes ownership of itself.
(new AppShimHost)->ServeChannel(std::move(handle));
(new AppShimHost)->ServeChannel(std::move(endpoint));
}
base::FilePath GetDirectoryInTmpTemplate(const base::FilePath& user_data_dir) {
......@@ -157,11 +157,11 @@ void AppShimHostManager::ListenOnIOThread() {
}
void AppShimHostManager::OnClientConnected(
mojo::edk::ScopedInternalPlatformHandle handle) {
mojo::PlatformChannelEndpoint endpoint) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
->PostTask(FROM_HERE,
base::Bind(&CreateAppShimHost, base::Passed(&handle)));
base::BindOnce(&CreateAppShimHost, std::move(endpoint)));
}
void AppShimHostManager::OnListenError() {
......
......@@ -8,8 +8,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop_current.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "mojo/edk/embedder/platform_channel_utils_posix.h"
#include "mojo/public/cpp/platform/socket_utils_posix.h"
namespace apps {
......@@ -17,8 +16,11 @@ UnixDomainSocketAcceptor::UnixDomainSocketAcceptor(const base::FilePath& path,
Delegate* delegate)
: server_listen_connection_watcher_(FROM_HERE),
named_pipe_(path.value()),
delegate_(delegate),
listen_handle_(mojo::edk::CreateServerHandle(named_pipe_)) {
delegate_(delegate) {
mojo::NamedPlatformChannel::Options options;
options.server_name = named_pipe_;
mojo::NamedPlatformChannel channel(options);
listen_handle_ = channel.TakeServerEndpoint();
DCHECK(delegate_);
}
......@@ -33,28 +35,30 @@ bool UnixDomainSocketAcceptor::Listen() {
// Watch the fd for connections, and turn any connections into
// active sockets.
base::MessageLoopCurrentForIO::Get()->WatchFileDescriptor(
listen_handle_.get().handle, true, base::MessagePumpForIO::WATCH_READ,
&server_listen_connection_watcher_, this);
listen_handle_.platform_handle().GetFD().get(), true,
base::MessagePumpForIO::WATCH_READ, &server_listen_connection_watcher_,
this);
return true;
}
// Called by libevent when we can read from the fd without blocking.
void UnixDomainSocketAcceptor::OnFileCanReadWithoutBlocking(int fd) {
DCHECK(fd == listen_handle_.get().handle);
mojo::edk::ScopedInternalPlatformHandle connection_handle;
if (!mojo::edk::ServerAcceptConnection(listen_handle_, &connection_handle)) {
DCHECK_EQ(fd, listen_handle_.platform_handle().GetFD().get());
base::ScopedFD connection_fd;
if (!mojo::AcceptSocketConnection(fd, &connection_fd)) {
Close();
delegate_->OnListenError();
return;
}
if (!connection_handle.is_valid()) {
if (!connection_fd.is_valid()) {
// The accept() failed, but not in such a way that the factory needs to be
// shut down.
return;
}
delegate_->OnClientConnected(std::move(connection_handle));
delegate_->OnClientConnected(mojo::PlatformChannelEndpoint(
mojo::PlatformHandle(std::move(connection_fd))));
}
void UnixDomainSocketAcceptor::OnFileCanWriteWithoutBlocking(int fd) {
......@@ -65,7 +69,7 @@ void UnixDomainSocketAcceptor::Close() {
if (!listen_handle_.is_valid())
return;
listen_handle_.reset();
if (unlink(named_pipe_.name.c_str()) < 0)
if (unlink(named_pipe_.c_str()) < 0)
PLOG(ERROR) << "unlink";
// Unregister libevent for the listening socket and close it.
......
......@@ -8,8 +8,9 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/message_loop/message_pump_for_io.h"
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/platform/platform_channel_endpoint.h"
#include "mojo/public/cpp/platform/platform_channel_server_endpoint.h"
namespace apps {
......@@ -24,8 +25,7 @@ class UnixDomainSocketAcceptor : public base::MessagePumpForIO::FdWatcher {
// Called when a client connects to the factory. It is the delegate's
// responsibility to create an IPC::Channel for the handle, or else close
// the file descriptor contained therein.
virtual void OnClientConnected(
mojo::edk::ScopedInternalPlatformHandle handle) = 0;
virtual void OnClientConnected(mojo::PlatformChannelEndpoint endpoint) = 0;
// Called when an error occurs and the channel is closed.
virtual void OnListenError() = 0;
......@@ -46,9 +46,9 @@ class UnixDomainSocketAcceptor : public base::MessagePumpForIO::FdWatcher {
void OnFileCanWriteWithoutBlocking(int fd) override;
base::MessagePumpForIO::FdWatchController server_listen_connection_watcher_;
mojo::edk::NamedPlatformHandle named_pipe_;
mojo::NamedPlatformChannel::ServerName named_pipe_;
Delegate* delegate_;
mojo::edk::ScopedInternalPlatformHandle listen_handle_;
mojo::PlatformChannelServerEndpoint listen_handle_;
DISALLOW_COPY_AND_ASSIGN(UnixDomainSocketAcceptor);
};
......
......@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/nacl/config.gni")
component("platform") {
output_name = "mojo_cpp_platform"
......@@ -22,6 +24,11 @@ component("platform") {
"platform_handle.cc",
]
if (is_posix && (!is_nacl || is_nacl_nonsfi)) {
public += [ "socket_utils_posix.h" ]
sources += [ "socket_utils_posix.cc" ]
}
public_deps = [
"//base",
]
......
......@@ -5,6 +5,7 @@
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
namespace mojo {
......@@ -24,6 +25,16 @@ NamedPlatformChannel::~NamedPlatformChannel() = default;
NamedPlatformChannel& NamedPlatformChannel::operator=(
NamedPlatformChannel&& other) = default;
// static
NamedPlatformChannel::ServerName NamedPlatformChannel::ServerNameFromUTF8(
base::StringPiece name) {
#if defined(OS_WIN)
return base::UTF8ToUTF16(name);
#else
return name.as_string();
#endif
}
void NamedPlatformChannel::PassServerNameOnCommandLine(
base::CommandLine* command_line) {
command_line->AppendSwitchNative(kNamedHandleSwitch, server_name_);
......
......@@ -73,6 +73,9 @@ class COMPONENT_EXPORT(MOJO_CPP_PLATFORM) NamedPlatformChannel {
return server_endpoint_;
}
// Helper to create a ServerName from a UTF8 string regardless of platform.
static ServerName ServerNameFromUTF8(base::StringPiece name);
// Passes the local server endpoint for the channel. On Windows, this is a
// named pipe server; on POSIX it's a bound, listening domain socket. In each
// case it should accept a single new connection.
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/public/cpp/platform/socket_utils_posix.h"
#include <stddef.h>
#include <sys/socket.h>
#include <unistd.h>
#if !defined(OS_NACL)
#include <sys/uio.h>
#endif
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "build/build_config.h"
namespace mojo {
namespace {
#if !defined(OS_NACL)
bool IsRecoverableError() {
return errno == ECONNABORTED || errno == EMFILE || errno == ENFILE ||
errno == ENOMEM || errno == ENOBUFS;
}
bool GetPeerEuid(base::PlatformFile fd, uid_t* peer_euid) {
#if defined(OS_MACOSX) || defined(OS_OPENBSD) || defined(OS_FREEBSD)
uid_t socket_euid;
gid_t socket_gid;
if (getpeereid(fd, &socket_euid, &socket_gid) < 0) {
PLOG(ERROR) << "getpeereid " << fd;
return false;
}
*peer_euid = socket_euid;
return true;
#else
struct ucred cred;
socklen_t cred_len = sizeof(cred);
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len) < 0) {
PLOG(ERROR) << "getsockopt " << fd;
return false;
}
if (static_cast<unsigned>(cred_len) < sizeof(cred)) {
NOTREACHED() << "Truncated ucred from SO_PEERCRED?";
return false;
}
*peer_euid = cred.uid;
return true;
#endif
}
bool IsPeerAuthorized(base::PlatformFile fd) {
uid_t peer_euid;
if (!GetPeerEuid(fd, &peer_euid))
return false;
if (peer_euid != geteuid()) {
DLOG(ERROR) << "Client euid is not authorized";
return false;
}
return true;
}
#endif // !defined(OS_NACL)
// NOTE: On Linux |SIGPIPE| is suppressed by passing |MSG_NOSIGNAL| to
// |sendmsg()|. On Mac we instead set |SO_NOSIGPIPE| on the socket itself.
#if defined(OS_MACOSX)
constexpr int kSendmsgFlags = 0;
#else
constexpr int kSendmsgFlags = MSG_NOSIGNAL;
#endif
constexpr size_t kMaxSendmsgHandles = 128;
} // namespace
ssize_t SendmsgWithHandles(base::PlatformFile socket,
struct iovec* iov,
size_t num_iov,
const std::vector<base::ScopedFD>& descriptors) {
DCHECK(iov);
DCHECK_GT(num_iov, 0u);
DCHECK(!descriptors.empty());
DCHECK_LE(descriptors.size(), kMaxSendmsgHandles);
char cmsg_buf[CMSG_SPACE(kMaxSendmsgHandles * sizeof(int))];
struct msghdr msg = {};
msg.msg_iov = iov;
msg.msg_iovlen = num_iov;
msg.msg_control = cmsg_buf;
msg.msg_controllen = CMSG_LEN(descriptors.size() * sizeof(int));
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(descriptors.size() * sizeof(int));
for (size_t i = 0; i < descriptors.size(); ++i) {
DCHECK_GE(descriptors[i].get(), 0);
reinterpret_cast<int*>(CMSG_DATA(cmsg))[i] = descriptors[i].get();
}
return HANDLE_EINTR(sendmsg(socket, &msg, kSendmsgFlags));
}
bool AcceptSocketConnection(base::PlatformFile server_fd,
base::ScopedFD* connection_fd,
bool check_peer_user) {
DCHECK_GE(server_fd, 0);
connection_fd->reset();
#if defined(OS_NACL)
NOTREACHED();
return false;
#else
base::ScopedFD accepted_handle(HANDLE_EINTR(accept(server_fd, nullptr, 0)));
if (!accepted_handle.is_valid())
return IsRecoverableError();
if (check_peer_user && !IsPeerAuthorized(accepted_handle.get()))
return true;
if (!base::SetNonBlocking(accepted_handle.get())) {
PLOG(ERROR) << "base::SetNonBlocking() failed " << accepted_handle.get();
return true;
}
*connection_fd = std::move(accepted_handle);
return true;
#endif // defined(OS_NACL)
}
} // namespace mojo
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MOJO_PUBLIC_CPP_PLATFORM_SOCKET_UTILS_POSIX_H_
#define MOJO_PUBLIC_CPP_PLATFORM_SOCKET_UTILS_POSIX_H_
#include <stddef.h>
#include <sys/types.h>
#include "base/component_export.h"
#include "base/files/platform_file.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/macros.h"
struct iovec; // Declared in <sys/uio.h>
namespace mojo {
// NOTE: Functions declared here really don't belong in Mojo, but they exist to
// support code which used to rely on internal parts of the Mojo implementation
// and there wasn't a much better home for them. Consider moving them to
// src/base or something.
// Wrapper around |sendmsg()| which makes it convenient to send attached file
// descriptors. All entries in |descriptors| must be valid and |descriptors|
// must be non-empty.
//
// Returns the same value as |sendmsg()|, i.e. -1 on error and otherwise the
// number of bytes sent. Note that the number of bytes sent may be smaller
// than the total data in |iov|.
//
// Note that regardless of success or failure, descriptors in |descriptors| are
// not closed.
COMPONENT_EXPORT(MOJO_CPP_PLATFORM)
ssize_t SendmsgWithHandles(base::PlatformFile socket,
struct iovec* iov,
size_t num_iov,
const std::vector<base::ScopedFD>& descriptors);
// Treats |server_fd| as a socket listening for new connections. Returns |false|
// if it encounters an unrecoverable error.
//
// If a connection wasn't established but the server is still OK, this returns
// |true| and leaves |*connection_fd| unchanged.
//
// If a connection was accepted, this returns |true| and |*connection_fd| is
// updated with a file descriptor for the new connection.
//
// Iff |check_peer_user| is |true|, connecting clients running as a different
// user from the server (i.e. the calling process) will be rejected.
COMPONENT_EXPORT(MOJO_CPP_PLATFORM)
bool AcceptSocketConnection(base::PlatformFile server_fd,
base::ScopedFD* connection_fd,
bool check_peer_user = true);
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_PLATFORM_SOCKET_UTILS_POSIX_H_
......@@ -36,7 +36,8 @@ source_set("security_key") {
deps = [
"//ipc",
"//mojo/edk",
"//mojo/public/cpp/platform",
"//mojo/public/cpp/system",
"//remoting/proto",
"//third_party/webrtc/modules/desktop_capture",
]
......@@ -59,6 +60,7 @@ source_set("main") {
]
deps = [
"//base:debugging_buildflags",
"//mojo/edk",
]
}
......
......@@ -14,9 +14,7 @@
#include "ipc/ipc_channel.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "mojo/edk/embedder/peer_connection.h"
#include "mojo/public/cpp/system/isolated_connection.h"
#include "remoting/host/chromoting_messages.h"
namespace remoting {
......@@ -61,24 +59,21 @@ bool FakeSecurityKeyIpcClient::SendSecurityKeyRequest(
void FakeSecurityKeyIpcClient::CloseIpcConnection() {
client_channel_.reset();
peer_connection_.reset();
mojo_connection_.reset();
channel_event_callback_.Run();
}
bool FakeSecurityKeyIpcClient::ConnectViaIpc(
const mojo::edk::NamedPlatformHandle& channel_handle) {
mojo::edk::ScopedInternalPlatformHandle handle =
mojo::edk::CreateClientHandle(channel_handle);
if (!handle.is_valid()) {
const mojo::NamedPlatformChannel::ServerName& server_name) {
mojo::PlatformChannelEndpoint endpoint =
mojo::NamedPlatformChannel::ConnectToServer(server_name);
if (!endpoint.is_valid())
return false;
}
peer_connection_ = std::make_unique<mojo::edk::PeerConnection>();
mojo_connection_ = std::make_unique<mojo::IsolatedConnection>();
client_channel_ = IPC::Channel::CreateClient(
peer_connection_
->Connect(mojo::edk::ConnectionParams(
mojo::edk::TransportProtocol::kLegacy, std::move(handle)))
.release(),
this, base::ThreadTaskRunnerHandle::Get());
mojo_connection_->Connect(std::move(endpoint)).release(), this,
base::ThreadTaskRunnerHandle::Get());
return client_channel_->Connect();
}
......
......@@ -11,7 +11,7 @@
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "remoting/host/security_key/security_key_ipc_client.h"
namespace IPC {
......@@ -20,9 +20,7 @@ class Message;
} // IPC
namespace mojo {
namespace edk {
class PeerConnection;
}
class IsolatedConnection;
}
namespace remoting {
......@@ -46,8 +44,8 @@ class FakeSecurityKeyIpcClient : public SecurityKeyIpcClient {
const ResponseCallback& response_callback) override;
void CloseIpcConnection() override;
// Connects as a client to the |channel_name| IPC Channel.
bool ConnectViaIpc(const mojo::edk::NamedPlatformHandle& channel_handle);
// Connects as a client to the |server_name| IPC Channel.
bool ConnectViaIpc(const mojo::NamedPlatformChannel::ServerName& server_name);
// Override of SendSecurityKeyRequest() interface method for tests which use
// an IPC channel for testing.
......@@ -107,7 +105,7 @@ class FakeSecurityKeyIpcClient : public SecurityKeyIpcClient {
base::Closure on_channel_connected_callback_;
// Used for sending/receiving security key messages between processes.
std::unique_ptr<mojo::edk::PeerConnection> peer_connection_;
std::unique_ptr<mojo::IsolatedConnection> mojo_connection_;
std::unique_ptr<IPC::Channel> client_channel_;
// Provides the contents of the last IPC message received.
......
......@@ -13,10 +13,8 @@
#include "ipc/ipc_channel.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "mojo/edk/embedder/peer_connection.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/system/isolated_connection.h"
#include "remoting/host/chromoting_messages.h"
#include "remoting/host/security_key/security_key_auth_handler.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -44,7 +42,7 @@ void FakeSecurityKeyIpcServer::SendRequest(const std::string& message_data) {
void FakeSecurityKeyIpcServer::CloseChannel() {
ipc_channel_.reset();
peer_connection_.reset();
mojo_connection_.reset();
channel_closed_callback_.Run();
}
......@@ -69,20 +67,19 @@ void FakeSecurityKeyIpcServer::OnChannelConnected(int32_t peer_pid) {
}
bool FakeSecurityKeyIpcServer::CreateChannel(
const mojo::edk::NamedPlatformHandle& channel_handle,
const mojo::NamedPlatformChannel::ServerName& server_name,
base::TimeDelta request_timeout) {
mojo::edk::CreateServerHandleOptions options;
mojo::NamedPlatformChannel::Options options;
options.server_name = server_name;
#if defined(OS_WIN)
options.enforce_uniqueness = false;
#endif
peer_connection_ = std::make_unique<mojo::edk::PeerConnection>();
mojo::NamedPlatformChannel channel(options);
mojo_connection_ = std::make_unique<mojo::IsolatedConnection>();
ipc_channel_ = IPC::Channel::CreateServer(
peer_connection_
->Connect(mojo::edk::ConnectionParams(
mojo::edk::TransportProtocol::kLegacy,
mojo::edk::CreateServerHandle(channel_handle, options)))
.release(),
this, base::ThreadTaskRunnerHandle::Get());
mojo_connection_->Connect(channel.TakeServerEndpoint()).release(), this,
base::ThreadTaskRunnerHandle::Get());
EXPECT_NE(nullptr, ipc_channel_);
return ipc_channel_->Connect();
}
......
......@@ -23,9 +23,7 @@ class Message;
} // IPC
namespace mojo {
namespace edk {
class PeerConnection;
}
class IsolatedConnection;
}
namespace remoting {
......@@ -46,7 +44,7 @@ class FakeSecurityKeyIpcServer : public SecurityKeyIpcServer,
~FakeSecurityKeyIpcServer() override;
// SecurityKeyIpcServer interface.
bool CreateChannel(const mojo::edk::NamedPlatformHandle& channel_handle,
bool CreateChannel(const mojo::NamedPlatformChannel::ServerName& server_name,
base::TimeDelta request_timeout) override;
bool SendResponse(const std::string& message_data) override;
......@@ -101,7 +99,7 @@ class FakeSecurityKeyIpcServer : public SecurityKeyIpcServer,
base::Closure send_response_callback_;
// Used for sending/receiving security key messages between processes.
std::unique_ptr<mojo::edk::PeerConnection> peer_connection_;
std::unique_ptr<mojo::IsolatedConnection> mojo_connection_;
std::unique_ptr<IPC::Channel> ipc_channel_;
// NOTE: Weak pointers must be invalidated before all other member variables.
......
......@@ -50,7 +50,7 @@ class SecurityKeyAuthHandlerWinTest : public testing::Test {
// Creates a new security key connection on the object under test.
void CreateSecurityKeyConnection(
const mojo::edk::NamedPlatformHandle& channel_handle);
const mojo::NamedPlatformChannel::ServerName& server_name);
// Uses |fake_ipc_client| to connect to the IPC server channel, it then
// validates internal state of the object under test and closes the connection
......@@ -58,7 +58,7 @@ class SecurityKeyAuthHandlerWinTest : public testing::Test {
void EstablishIpcConnection(
FakeSecurityKeyIpcClient* fake_ipc_client,
int expected_connection_id,
const mojo::edk::NamedPlatformHandle& channel_handle,
const mojo::NamedPlatformChannel::ServerName& server_name,
bool close_connection);
// Sends a security key response message using |fake_ipc_server| and
......@@ -82,7 +82,7 @@ class SecurityKeyAuthHandlerWinTest : public testing::Test {
// Returns a unique IPC channel handle which prevents conflicts when running
// tests concurrently.
std::string GetUniqueTestChannelHandle();
mojo::NamedPlatformChannel::ServerName GetUniqueTestChannelHandle();
// IPC tests require a valid MessageLoop to run.
base::MessageLoopForIO message_loop_;
......@@ -141,10 +141,10 @@ void SecurityKeyAuthHandlerWinTest::SendMessageToClient(
}
void SecurityKeyAuthHandlerWinTest::CreateSecurityKeyConnection(
const mojo::edk::NamedPlatformHandle& channel_handle) {
const mojo::NamedPlatformChannel::ServerName& server_name) {
ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest());
remoting::SetSecurityKeyIpcChannelForTest(channel_handle);
remoting::SetSecurityKeyIpcChannelForTest(server_name);
// Create a new SecurityKey IPC Server connection.
auth_handler_->CreateSecurityKeyConnection();
......@@ -153,7 +153,7 @@ void SecurityKeyAuthHandlerWinTest::CreateSecurityKeyConnection(
void SecurityKeyAuthHandlerWinTest::EstablishIpcConnection(
FakeSecurityKeyIpcClient* fake_ipc_client,
int expected_connection_id,
const mojo::edk::NamedPlatformHandle& channel_handle,
const mojo::NamedPlatformChannel::ServerName& server_name,
bool close_connection) {
size_t expected_connection_count =
auth_handler_->GetActiveConnectionCountForTest() + 1;
......@@ -162,7 +162,7 @@ void SecurityKeyAuthHandlerWinTest::EstablishIpcConnection(
fake_ipc_client->set_on_channel_connected_callback(
base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client->ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client->ConnectViaIpc(server_name));
WaitForOperationComplete();
// Retrieve the IPC server instance created when the client connected.
......@@ -243,23 +243,24 @@ void SecurityKeyAuthHandlerWinTest::CloseSecurityKeySessionIpcChannel(
ASSERT_FALSE(fake_ipc_server.get());
}
std::string SecurityKeyAuthHandlerWinTest::GetUniqueTestChannelHandle() {
mojo::NamedPlatformChannel::ServerName
SecurityKeyAuthHandlerWinTest::GetUniqueTestChannelHandle() {
std::string channel_name("Uber_Awesome_Super_Mega_Test_Channel.");
channel_name.append(IPC::Channel::GenerateUniqueRandomChannelID());
return channel_name;
return mojo::NamedPlatformChannel::ServerNameFromUTF8(channel_name);
}
TEST_F(SecurityKeyAuthHandlerWinTest, HandleSingleSecurityKeyRequest) {
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelHandle());
CreateSecurityKeyConnection(channel_handle);
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelHandle();
CreateSecurityKeyConnection(server_name);
ASSERT_FALSE(auth_handler_->IsValidConnectionId(kConnectionId1));
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(
base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
base::Unretained(this)));
EstablishIpcConnection(&fake_ipc_client, kConnectionId1, channel_handle,
EstablishIpcConnection(&fake_ipc_client, kConnectionId1, server_name,
/*close_connection=*/true);
// Retrieve the IPC server instance created when the client connected.
......@@ -283,8 +284,9 @@ TEST_F(SecurityKeyAuthHandlerWinTest, HandleSingleSecurityKeyRequest) {
}
TEST_F(SecurityKeyAuthHandlerWinTest, HandleConcurrentSecurityKeyRequests) {
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelHandle());
CreateSecurityKeyConnection(channel_handle);
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelHandle();
CreateSecurityKeyConnection(server_name);
// Create fake clients and connect each to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client_1(
......@@ -294,9 +296,9 @@ TEST_F(SecurityKeyAuthHandlerWinTest, HandleConcurrentSecurityKeyRequests) {
base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
base::Unretained(this)));
EstablishIpcConnection(&fake_ipc_client_1, kConnectionId1, channel_handle,
EstablishIpcConnection(&fake_ipc_client_1, kConnectionId1, server_name,
/*close_connection=*/true);
EstablishIpcConnection(&fake_ipc_client_2, kConnectionId2, channel_handle,
EstablishIpcConnection(&fake_ipc_client_2, kConnectionId2, server_name,
/*close_connection=*/true);
base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server_1 =
......@@ -336,15 +338,16 @@ TEST_F(SecurityKeyAuthHandlerWinTest, HandleConcurrentSecurityKeyRequests) {
}
TEST_F(SecurityKeyAuthHandlerWinTest, HandleSequentialSecurityKeyRequests) {
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelHandle());
CreateSecurityKeyConnection(channel_handle);
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelHandle();
CreateSecurityKeyConnection(server_name);
// Create fake clients to connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client_1(
base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
base::Unretained(this)));
EstablishIpcConnection(&fake_ipc_client_1, kConnectionId1, channel_handle,
EstablishIpcConnection(&fake_ipc_client_1, kConnectionId1, server_name,
/*close_connection=*/true);
base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server_1 =
......@@ -370,7 +373,7 @@ TEST_F(SecurityKeyAuthHandlerWinTest, HandleSequentialSecurityKeyRequests) {
FakeSecurityKeyIpcClient fake_ipc_client_2(
base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
base::Unretained(this)));
EstablishIpcConnection(&fake_ipc_client_2, kConnectionId2, channel_handle,
EstablishIpcConnection(&fake_ipc_client_2, kConnectionId2, server_name,
/*close_connection=*/true);
base::WeakPtr<FakeSecurityKeyIpcServer> fake_ipc_server_2 =
......@@ -394,15 +397,16 @@ TEST_F(SecurityKeyAuthHandlerWinTest, HandleSequentialSecurityKeyRequests) {
}
TEST_F(SecurityKeyAuthHandlerWinTest, HandleSecurityKeyErrorResponse) {
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelHandle());
CreateSecurityKeyConnection(channel_handle);
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelHandle();
CreateSecurityKeyConnection(server_name);
ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest());
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(
base::Bind(&SecurityKeyAuthHandlerWinTest::OperationComplete,
base::Unretained(this)));
EstablishIpcConnection(&fake_ipc_client, kConnectionId1, channel_handle,
EstablishIpcConnection(&fake_ipc_client, kConnectionId1, server_name,
/*close_connection=*/true);
// Retrieve the IPC server instance created when the client connected.
......@@ -429,7 +433,7 @@ TEST_F(SecurityKeyAuthHandlerWinTest, HandleSecurityKeyErrorResponse) {
ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest());
// Attempt to connect again after the error.
EstablishIpcConnection(&fake_ipc_client, kConnectionId2, channel_handle,
EstablishIpcConnection(&fake_ipc_client, kConnectionId2, server_name,
/*close_connection=*/true);
}
......
......@@ -14,8 +14,6 @@
#include "ipc/ipc_listener.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "remoting/host/chromoting_messages.h"
#include "remoting/host/ipc_constants.h"
#include "remoting/host/security_key/security_key_ipc_constants.h"
......@@ -34,7 +32,8 @@ bool SecurityKeyIpcClient::CheckForSecurityKeyIpcServerChannel() {
DCHECK(thread_checker_.CalledOnValidThread());
if (!channel_handle_.is_valid()) {
channel_handle_ = mojo::edk::CreateClientHandle(named_channel_handle_);
channel_handle_ =
mojo::NamedPlatformChannel::ConnectToServer(named_channel_handle_);
}
return channel_handle_.is_valid();
}
......@@ -82,8 +81,8 @@ void SecurityKeyIpcClient::CloseIpcConnection() {
}
void SecurityKeyIpcClient::SetIpcChannelHandleForTest(
const mojo::edk::NamedPlatformHandle& channel_handle) {
named_channel_handle_ = channel_handle;
const mojo::NamedPlatformChannel::ServerName& server_name) {
named_channel_handle_ = server_name;
}
void SecurityKeyIpcClient::SetExpectedIpcServerSessionIdForTest(
......@@ -193,13 +192,9 @@ void SecurityKeyIpcClient::ConnectToIpcChannel() {
return;
}
ipc_channel_ =
IPC::Channel::CreateClient(peer_connection_
.Connect(mojo::edk::ConnectionParams(
mojo::edk::TransportProtocol::kLegacy,
std::move(channel_handle_)))
.release(),
this, base::ThreadTaskRunnerHandle::Get());
ipc_channel_ = IPC::Channel::CreateClient(
mojo_connection_.Connect(std::move(channel_handle_)).release(), this,
base::ThreadTaskRunnerHandle::Get());
if (ipc_channel_->Connect()) {
return;
}
......
......@@ -12,9 +12,9 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "ipc/ipc_listener.h"
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/edk/embedder/peer_connection.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/platform/platform_channel_endpoint.h"
#include "mojo/public/cpp/system/isolated_connection.h"
namespace IPC {
class Channel;
......@@ -63,7 +63,7 @@ class SecurityKeyIpcClient : public IPC::Listener {
// Allows tests to override the IPC channel.
void SetIpcChannelHandleForTest(
const mojo::edk::NamedPlatformHandle& channel_handle);
const mojo::NamedPlatformChannel::ServerName& server_name);
// Allows tests to override the expected session ID.
void SetExpectedIpcServerSessionIdForTest(uint32_t expected_session_id);
......@@ -91,10 +91,10 @@ class SecurityKeyIpcClient : public IPC::Listener {
uint32_t expected_ipc_server_session_id_ = 0;
// Name of the initial IPC channel used to retrieve connection info.
mojo::edk::NamedPlatformHandle named_channel_handle_;
mojo::NamedPlatformChannel::ServerName named_channel_handle_;
// A handle for the IPC channel used for exchanging security key messages.
mojo::edk::ScopedInternalPlatformHandle channel_handle_;
mojo::PlatformChannelEndpoint channel_handle_;
// Signaled when the IPC connection is ready for security key requests.
ConnectedCallback connected_callback_;
......@@ -106,7 +106,7 @@ class SecurityKeyIpcClient : public IPC::Listener {
ResponseCallback response_callback_;
// Used for sending/receiving security key messages between processes.
mojo::edk::PeerConnection peer_connection_;
mojo::IsolatedConnection mojo_connection_;
std::unique_ptr<IPC::Channel> ipc_channel_;
base::ThreadChecker thread_checker_;
......
......@@ -12,7 +12,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "ipc/ipc_channel.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "remoting/host/security_key/fake_security_key_ipc_server.h"
#include "remoting/host/security_key/security_key_ipc_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -71,7 +71,7 @@ class SecurityKeyIpcClientTest : public testing::Test {
const std::string& response_data);
// Creates a unique IPC channel name to use for testing.
std::string GenerateUniqueTestChannelName();
mojo::NamedPlatformChannel::ServerName GenerateUniqueTestChannelName();
// IPC tests require a valid MessageLoop to run.
base::MessageLoopForIO message_loop_;
......@@ -177,20 +177,22 @@ void SecurityKeyIpcClientTest::ClientMessageReceived(
OperationComplete(/*failed=*/false);
}
std::string SecurityKeyIpcClientTest::GenerateUniqueTestChannelName() {
return GetChannelNamePathPrefixForTest() + kValidIpcChannelName +
IPC::Channel::GenerateUniqueRandomChannelID();
mojo::NamedPlatformChannel::ServerName
SecurityKeyIpcClientTest::GenerateUniqueTestChannelName() {
return mojo::NamedPlatformChannel::ServerNameFromUTF8(
GetChannelNamePathPrefixForTest() + kValidIpcChannelName +
IPC::Channel::GenerateUniqueRandomChannelID());
}
void SecurityKeyIpcClientTest::EstablishConnection(bool expect_connected,
bool expect_error) {
// Start up the security key forwarding session IPC channel first, that way
// we can provide the channel using the fake SecurityKeyAuthHandler later on.
mojo::edk::NamedPlatformHandle channel_handle(
GenerateUniqueTestChannelName());
security_key_ipc_client_.SetIpcChannelHandleForTest(channel_handle);
mojo::NamedPlatformChannel::ServerName server_name =
GenerateUniqueTestChannelName();
security_key_ipc_client_.SetIpcChannelHandleForTest(server_name);
ASSERT_TRUE(fake_ipc_server_.CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
ASSERT_TRUE(security_key_ipc_client_.CheckForSecurityKeyIpcServerChannel());
......@@ -311,7 +313,8 @@ TEST_F(SecurityKeyIpcClientTest, SendRequestBeforeEstablishingConnection) {
TEST_F(SecurityKeyIpcClientTest, NonExistentIpcServerChannel) {
security_key_ipc_client_.SetIpcChannelHandleForTest(
mojo::edk::NamedPlatformHandle(kNonexistentIpcChannelName));
mojo::NamedPlatformChannel::ServerNameFromUTF8(
kNonexistentIpcChannelName));
// Attempt to establish the conection (should fail since the IPC channel does
// not exist).
......
......@@ -14,7 +14,8 @@
#endif // defined(OS_POSIX)
namespace {
base::LazyInstance<mojo::edk::NamedPlatformHandle>::DestructorAtExit
base::LazyInstance<mojo::NamedPlatformChannel::ServerName>::DestructorAtExit
g_security_key_ipc_channel_name = LAZY_INSTANCE_INITIALIZER;
constexpr char kSecurityKeyIpcChannelName[] = "security_key_ipc_channel";
......@@ -25,18 +26,19 @@ namespace remoting {
const char kSecurityKeyConnectionError[] = "ssh_connection_error";
const mojo::edk::NamedPlatformHandle& GetSecurityKeyIpcChannel() {
if (!g_security_key_ipc_channel_name.Get().is_valid()) {
const mojo::NamedPlatformChannel::ServerName& GetSecurityKeyIpcChannel() {
if (g_security_key_ipc_channel_name.Get().empty()) {
g_security_key_ipc_channel_name.Get() =
mojo::edk::NamedPlatformHandle(kSecurityKeyIpcChannelName);
mojo::NamedPlatformChannel::ServerNameFromUTF8(
kSecurityKeyIpcChannelName);
}
return g_security_key_ipc_channel_name.Get();
}
void SetSecurityKeyIpcChannelForTest(
const mojo::edk::NamedPlatformHandle& channel_handle) {
g_security_key_ipc_channel_name.Get() = channel_handle;
const mojo::NamedPlatformChannel::ServerName& server_name) {
g_security_key_ipc_channel_name.Get() = server_name;
}
std::string GetChannelNamePathPrefixForTest() {
......
......@@ -7,7 +7,7 @@
#include <string>
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
namespace remoting {
......@@ -16,11 +16,11 @@ extern const char kSecurityKeyConnectionError[];
// Returns the name of the well-known IPC server channel used to initiate a
// security key forwarding session.
const mojo::edk::NamedPlatformHandle& GetSecurityKeyIpcChannel();
const mojo::NamedPlatformChannel::ServerName& GetSecurityKeyIpcChannel();
// Sets the name of the well-known IPC server channel for testing purposes.
void SetSecurityKeyIpcChannelForTest(
const mojo::edk::NamedPlatformHandle& channel_handle);
const mojo::NamedPlatformChannel::ServerName& server_name);
// Returns a path appropriate for placing a channel name. Without this path
// prefix, we may not have permission on linux to bind(2) a socket to a name in
......
......@@ -11,7 +11,7 @@
#include "base/callback_forward.h"
#include "base/time/time.h"
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "remoting/host/security_key/security_key_auth_handler.h"
namespace remoting {
......@@ -40,7 +40,7 @@ class SecurityKeyIpcServer {
// Creates and starts listening on an IPC channel with the given name.
virtual bool CreateChannel(
const mojo::edk::NamedPlatformHandle& channel_handle,
const mojo::NamedPlatformChannel::ServerName& server_name,
base::TimeDelta request_timeout) = 0;
// Sends a security key response IPC message via the IPC channel.
......
......@@ -18,10 +18,7 @@
#include "ipc/ipc_channel.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/named_platform_handle.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "mojo/edk/embedder/peer_connection.h"
#include "mojo/public/cpp/system/isolated_connection.h"
#include "remoting/base/logging.h"
#include "remoting/host/chromoting_messages.h"
#include "remoting/host/client_session_details.h"
......@@ -69,13 +66,14 @@ SecurityKeyIpcServerImpl::~SecurityKeyIpcServerImpl() {
}
bool SecurityKeyIpcServerImpl::CreateChannel(
const mojo::edk::NamedPlatformHandle& channel_handle,
const mojo::NamedPlatformChannel::ServerName& server_name,
base::TimeDelta request_timeout) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!ipc_channel_);
security_key_request_timeout_ = request_timeout;
mojo::edk::CreateServerHandleOptions options;
mojo::NamedPlatformChannel::Options options;
options.server_name = server_name;
#if defined(OS_WIN)
options.enforce_uniqueness = false;
// Create a named pipe owned by the current user (the LocalService account
......@@ -91,14 +89,12 @@ bool SecurityKeyIpcServerImpl::CreateChannel(
"O:%sG:%sD:(A;;GA;;;AU)", user_sid_utf8.c_str(), user_sid_utf8.c_str()));
#endif // defined(OS_WIN)
peer_connection_ = std::make_unique<mojo::edk::PeerConnection>();
mojo::NamedPlatformChannel channel(options);
mojo_connection_ = std::make_unique<mojo::IsolatedConnection>();
ipc_channel_ = IPC::Channel::CreateServer(
peer_connection_
->Connect(mojo::edk::ConnectionParams(
mojo::edk::TransportProtocol::kLegacy,
mojo::edk::CreateServerHandle(channel_handle, options)))
.release(),
this, base::ThreadTaskRunnerHandle::Get());
mojo_connection_->Connect(channel.TakeServerEndpoint()).release(), this,
base::ThreadTaskRunnerHandle::Get());
if (!ipc_channel_->Connect()) {
ipc_channel_.reset();
......@@ -215,7 +211,7 @@ void SecurityKeyIpcServerImpl::CloseChannel() {
ipc_channel_->Close();
connection_close_pending_ = false;
}
peer_connection_.reset();
mojo_connection_.reset();
}
} // namespace remoting
......@@ -28,9 +28,7 @@ class Message;
} // IPC
namespace mojo {
namespace edk {
class PeerConnection;
}
class IsolatedConnection;
}
namespace remoting {
......@@ -50,7 +48,7 @@ class SecurityKeyIpcServerImpl : public SecurityKeyIpcServer,
~SecurityKeyIpcServerImpl() override;
// SecurityKeyIpcServer implementation.
bool CreateChannel(const mojo::edk::NamedPlatformHandle& channel_handle,
bool CreateChannel(const mojo::NamedPlatformChannel::ServerName& server_name,
base::TimeDelta request_timeout) override;
bool SendResponse(const std::string& message_data) override;
......@@ -94,7 +92,7 @@ class SecurityKeyIpcServerImpl : public SecurityKeyIpcServer,
SecurityKeyAuthHandler::SendMessageCallback message_callback_;
// Used for sending/receiving security key messages between processes.
std::unique_ptr<mojo::edk::PeerConnection> peer_connection_;
std::unique_ptr<mojo::IsolatedConnection> mojo_connection_;
std::unique_ptr<IPC::Channel> ipc_channel_;
// Ensures SecurityKeyIpcServerImpl methods are called on the same thread.
......
......@@ -14,9 +14,8 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "ipc/ipc_channel.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/named_platform_handle_utils.h"
#include "mojo/edk/embedder/peer_connection.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/system/isolated_connection.h"
#include "remoting/host/client_session_details.h"
#include "remoting/host/security_key/fake_security_key_ipc_client.h"
#include "remoting/host/security_key/security_key_ipc_constants.h"
......@@ -50,7 +49,7 @@ class SecurityKeyIpcServerTest : public testing::Test,
// Returns a unique IPC channel name which prevents conflicts when running
// tests concurrently.
std::string GetUniqueTestChannelName();
mojo::NamedPlatformChannel::ServerName GetUniqueTestChannelName();
// Waits until the current |run_loop_| instance is signaled, then resets it.
void WaitForOperationComplete();
......@@ -129,21 +128,25 @@ void SecurityKeyIpcServerTest::SendRequestToClient(int connection_id,
OperationComplete();
}
std::string SecurityKeyIpcServerTest::GetUniqueTestChannelName() {
return GetChannelNamePathPrefixForTest() + "Super_Awesome_Test_Channel." +
mojo::NamedPlatformChannel::ServerName
SecurityKeyIpcServerTest::GetUniqueTestChannelName() {
std::string name = GetChannelNamePathPrefixForTest() +
"Super_Awesome_Test_Channel." +
IPC::Channel::GenerateUniqueRandomChannelID();
return mojo::NamedPlatformChannel::ServerNameFromUTF8(name);
}
TEST_F(SecurityKeyIpcServerTest, HandleSingleSecurityKeyRequest) {
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(security_key_ipc_server_->CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(base::Bind(
&SecurityKeyIpcServerTest::OperationComplete, base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
ASSERT_TRUE(fake_ipc_client.ipc_channel_connected());
......@@ -172,15 +175,16 @@ TEST_F(SecurityKeyIpcServerTest, HandleSingleSecurityKeyRequest) {
}
TEST_F(SecurityKeyIpcServerTest, HandleLargeSecurityKeyRequest) {
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(security_key_ipc_server_->CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(base::Bind(
&SecurityKeyIpcServerTest::OperationComplete, base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
ASSERT_FALSE(fake_ipc_client.invalid_session_error());
......@@ -209,15 +213,16 @@ TEST_F(SecurityKeyIpcServerTest, HandleLargeSecurityKeyRequest) {
}
TEST_F(SecurityKeyIpcServerTest, HandleReallyLargeSecurityKeyRequest) {
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(security_key_ipc_server_->CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(base::Bind(
&SecurityKeyIpcServerTest::OperationComplete, base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
ASSERT_FALSE(fake_ipc_client.invalid_session_error());
......@@ -246,15 +251,16 @@ TEST_F(SecurityKeyIpcServerTest, HandleReallyLargeSecurityKeyRequest) {
}
TEST_F(SecurityKeyIpcServerTest, HandleMultipleSecurityKeyRequests) {
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(security_key_ipc_server_->CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(base::Bind(
&SecurityKeyIpcServerTest::OperationComplete, base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
ASSERT_FALSE(fake_ipc_client.invalid_session_error());
......@@ -304,13 +310,14 @@ TEST_F(SecurityKeyIpcServerTest, InitialIpcConnectionTimeout_ConnectOnly) {
// the connection was closed. This test simulates the IPC Server being
// created, the client connecting to the OS channel, but never communicating
// over the channel.
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(security_key_ipc_server_->CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
base::Time start_time(base::Time::NowFromSystemTime());
mojo::edk::ScopedInternalPlatformHandle client_handle =
mojo::edk::CreateClientHandle(channel_handle);
mojo::PlatformChannelEndpoint client_endpoint =
mojo::NamedPlatformChannel::ConnectToServer(server_name);
WaitForOperationComplete();
base::TimeDelta elapsed_time = base::Time::NowFromSystemTime() - start_time;
......@@ -324,16 +331,15 @@ TEST_F(SecurityKeyIpcServerTest,
// the connection was closed. This test simulates the IPC Server being
// created, the client establishing a mojo connection, but never constructing
// an IPC::Channel over it.
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(security_key_ipc_server_->CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
base::Time start_time(base::Time::NowFromSystemTime());
mojo::edk::PeerConnection peer_connection;
mojo::ScopedMessagePipeHandle client_pipe =
peer_connection.Connect(mojo::edk::ConnectionParams(
mojo::edk::TransportProtocol::kLegacy,
mojo::edk::CreateClientHandle(channel_handle)));
mojo::IsolatedConnection mojo_connection;
mojo::ScopedMessagePipeHandle client_pipe = mojo_connection.Connect(
mojo::NamedPlatformChannel::ConnectToServer(server_name));
WaitForOperationComplete();
base::TimeDelta elapsed_time = base::Time::NowFromSystemTime() - start_time;
......@@ -345,15 +351,16 @@ TEST_F(SecurityKeyIpcServerTest, NoSecurityKeyRequestTimeout) {
// Create a channel and connect to it via IPC but do not send a request.
// The channel should be closed and cleaned up if the IPC client does not
// issue a request within the specified timeout period.
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(security_key_ipc_server_->CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(base::Bind(
&SecurityKeyIpcServerTest::OperationComplete, base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
ASSERT_FALSE(fake_ipc_client.invalid_session_error());
......@@ -373,14 +380,15 @@ TEST_F(SecurityKeyIpcServerTest, SecurityKeyResponseTimeout) {
// Create a channel, connect to it via IPC, and issue a request, but do
// not send a response. This simulates a client-side timeout.
base::TimeDelta request_timeout(base::TimeDelta::FromMilliseconds(50));
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(
security_key_ipc_server_->CreateChannel(channel_handle, request_timeout));
security_key_ipc_server_->CreateChannel(server_name, request_timeout));
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(base::Bind(
&SecurityKeyIpcServerTest::OperationComplete, base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
ASSERT_FALSE(fake_ipc_client.invalid_session_error());
......@@ -407,14 +415,15 @@ TEST_F(SecurityKeyIpcServerTest, SendResponseTimeout) {
// a response, but do not close the channel after that. The connection
// should be terminated after the initial timeout period has elapsed.
base::TimeDelta request_timeout(base::TimeDelta::FromMilliseconds(500));
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(
security_key_ipc_server_->CreateChannel(channel_handle, request_timeout));
security_key_ipc_server_->CreateChannel(server_name, request_timeout));
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(base::Bind(
&SecurityKeyIpcServerTest::OperationComplete, base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
ASSERT_FALSE(fake_ipc_client.invalid_session_error());
......@@ -442,9 +451,10 @@ TEST_F(SecurityKeyIpcServerTest, SendResponseTimeout) {
TEST_F(SecurityKeyIpcServerTest, CleanupPendingConnection) {
// Test that servers correctly close pending OS connections on
// |channel_handle|. If multiple servers do remain, the client may happen to
// |server_name|. If multiple servers do remain, the client may happen to
// connect to the correct server, so create and delete many servers.
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
for (int i = 0; i < 100; i++) {
security_key_ipc_server_ = remoting::SecurityKeyIpcServer::Create(
kTestConnectionId, this,
......@@ -455,7 +465,7 @@ TEST_F(SecurityKeyIpcServerTest, CleanupPendingConnection) {
base::Bind(&SecurityKeyIpcServerTest::OperationComplete,
base::Unretained(this)));
ASSERT_TRUE(security_key_ipc_server_->CreateChannel(
channel_handle,
server_name,
/*request_timeout=*/base::TimeDelta::FromMilliseconds(500)));
}
// The mojo system posts tasks as part of its cleanup, so run them all.
......@@ -464,7 +474,7 @@ TEST_F(SecurityKeyIpcServerTest, CleanupPendingConnection) {
// Create a fake client and connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client(base::Bind(
&SecurityKeyIpcServerTest::OperationComplete, base::Unretained(this)));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
ASSERT_FALSE(fake_ipc_client.invalid_session_error());
......@@ -498,13 +508,14 @@ TEST_F(SecurityKeyIpcServerTest, IpcConnectionFailsFromInvalidSession) {
peer_session_id_++;
base::TimeDelta request_timeout(base::TimeDelta::FromMilliseconds(500));
mojo::edk::NamedPlatformHandle channel_handle(GetUniqueTestChannelName());
mojo::NamedPlatformChannel::ServerName server_name =
GetUniqueTestChannelName();
ASSERT_TRUE(
security_key_ipc_server_->CreateChannel(channel_handle, request_timeout));
security_key_ipc_server_->CreateChannel(server_name, request_timeout));
// Create a fake client and attempt to connect to the IPC server channel.
FakeSecurityKeyIpcClient fake_ipc_client{base::DoNothing()};
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(channel_handle));
ASSERT_TRUE(fake_ipc_client.ConnectViaIpc(server_name));
WaitForOperationComplete();
// Verify the connection failed.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment