| Index: ipc/ipc_channel_factory.cc
|
| diff --git a/ipc/ipc_channel_factory.cc b/ipc/ipc_channel_factory.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8f4bc30581eb064c085999cbe3352ec6f16acc78
|
| --- /dev/null
|
| +++ b/ipc/ipc_channel_factory.cc
|
| @@ -0,0 +1,88 @@
|
| +// Copyright 2013 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 "ipc/ipc_channel_factory.h"
|
| +
|
| +#include <errno.h>
|
| +#include <fcntl.h>
|
| +#include <stddef.h>
|
| +#include <sys/socket.h>
|
| +#include <sys/stat.h>
|
| +#include <sys/types.h>
|
| +#include <sys/un.h>
|
| +#include <unistd.h>
|
| +
|
| +#include "base/file_util.h"
|
| +#include "base/logging.h"
|
| +#include "ipc/ipc_channel_posix.h"
|
| +#include "ipc/unix_domain_socket_util.h"
|
| +
|
| +namespace IPC {
|
| +
|
| +ChannelFactory::ChannelFactory(const std::string& path, Delegate* delegate)
|
| + : path_(path), delegate_(delegate), listen_pipe_(-1) {
|
| + if (!CreatePipe()) {
|
| + // The pipe may have been closed already.
|
| + LOG(WARNING) << "Unable to create pipe named \"" << path << "\"";
|
| + }
|
| +}
|
| +
|
| +bool ChannelFactory::CreatePipe() {
|
| + DCHECK(listen_pipe_ == -1);
|
| +
|
| + int local_pipe = -1;
|
| +
|
| + // Create the socket.
|
| + if (!CreateServerUnixDomainSocket(path_, &local_pipe))
|
| + return false;
|
| +
|
| + listen_pipe_ = local_pipe;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool ChannelFactory::Listen() {
|
| + if (listen_pipe_ == -1) {
|
| + DLOG(INFO) << "Factory creation failed: " << path_.value();
|
| + return false;
|
| + }
|
| + // Watch the pipe for connections, and turn any connections into
|
| + // active sockets.
|
| + MessageLoopForIO::current()->WatchFileDescriptor(
|
| + listen_pipe_,
|
| + true,
|
| + MessageLoopForIO::WATCH_READ,
|
| + &server_listen_connection_watcher_,
|
| + this);
|
| + return true;
|
| +}
|
| +
|
| +// Called by libevent when we can read from the pipe without blocking.
|
| +void ChannelFactory::OnFileCanReadWithoutBlocking(int fd) {
|
| + DCHECK(fd == listen_pipe_);
|
| + int new_pipe = 0;
|
| + if (!ServerAcceptConnection(listen_pipe_, &new_pipe)) {
|
| + /*Close();
|
| + listener()->OnChannelListenError();*/
|
| + return;
|
| + }
|
| +
|
| + // Verify that the IPC channel peer is running as the same user.
|
| + uid_t client_euid;
|
| + if (!GetPeerEuid(new_pipe, &client_euid)) {
|
| + DLOG(ERROR) << "Unable to query client euid";
|
| + // TODO close new pipe
|
| + return;
|
| + }
|
| + if (client_euid != geteuid()) {
|
| + DLOG(WARNING) << "Client euid is not authorised";
|
| + // TODO close new pipe
|
| + return;
|
| + }
|
| +
|
| + ChannelHandle handle("", base::FileDescriptor(new_pipe, true));
|
| + delegate_->OnClientConnected(handle);
|
| +}
|
| +
|
| +}
|
|
|