diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-19 02:30:11 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-19 02:30:11 +0000 |
commit | 737e70acd59fe8d1fca96bd7f3bd27a61336a146 (patch) | |
tree | 8e2995e01ce714f4ba03fb756714f38868ae95ec /sandbox/mac/xpc_message_server.cc | |
parent | 2f32cebd5614a37e715a1350e14376238f418a93 (diff) | |
download | chromium_src-737e70acd59fe8d1fca96bd7f3bd27a61336a146.zip chromium_src-737e70acd59fe8d1fca96bd7f3bd27a61336a146.tar.gz chromium_src-737e70acd59fe8d1fca96bd7f3bd27a61336a146.tar.bz2 |
Add an XPC implementation of sandbox::MessageServer.
BUG=382931
R=mark@chromium.org
Review URL: https://codereview.chromium.org/404893002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284288 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/mac/xpc_message_server.cc')
-rw-r--r-- | sandbox/mac/xpc_message_server.cc | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/sandbox/mac/xpc_message_server.cc b/sandbox/mac/xpc_message_server.cc new file mode 100644 index 0000000..12c8d56 --- /dev/null +++ b/sandbox/mac/xpc_message_server.cc @@ -0,0 +1,116 @@ +// Copyright 2014 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 "sandbox/mac/xpc_message_server.h" + +#include <bsm/libbsm.h> + +#include <string> + +#include "base/mac/mach_logging.h" +#include "base/strings/stringprintf.h" +#include "sandbox/mac/dispatch_source_mach.h" +#include "sandbox/mac/xpc.h" + +namespace sandbox { + +XPCMessageServer::XPCMessageServer(MessageDemuxer* demuxer, + mach_port_t server_receive_right) + : demuxer_(demuxer), + server_port_(server_receive_right), + reply_message_(NULL) { +} + +XPCMessageServer::~XPCMessageServer() { +} + +bool XPCMessageServer::Initialize() { + // Allocate a port for use as a new server port if one was not passed to the + // constructor. + if (!server_port_.is_valid()) { + mach_port_t port; + kern_return_t kr; + if ((kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, + &port)) != KERN_SUCCESS) { + MACH_LOG(ERROR, kr) << "Failed to allocate new server port."; + return false; + } + server_port_.reset(port); + } + + std::string label = base::StringPrintf( + "org.chromium.sandbox.XPCMessageServer.%p", demuxer_); + dispatch_source_.reset(new DispatchSourceMach( + label.c_str(), server_port_.get(), ^{ ReceiveMessage(); })); + dispatch_source_->Resume(); + + return true; +} + +pid_t XPCMessageServer::GetMessageSenderPID(IPCMessage request) { + audit_token_t token; + xpc_dictionary_get_audit_token(request.xpc, &token); + // TODO(rsesek): In the 10.7 SDK, there's audit_token_to_pid(). + pid_t sender_pid; + audit_token_to_au32(token, + NULL, NULL, NULL, NULL, NULL, &sender_pid, NULL, NULL); + return sender_pid; +} + +IPCMessage XPCMessageServer::CreateReply(IPCMessage request) { + if (!reply_message_) + reply_message_ = xpc_dictionary_create_reply(request.xpc); + + IPCMessage reply; + reply.xpc = reply_message_; + return reply; +} + +bool XPCMessageServer::SendReply(IPCMessage reply) { + int rv = xpc_pipe_routine_reply(reply.xpc); + if (rv) { + LOG(ERROR) << "Failed to xpc_pipe_routine_reply(): " << rv; + return false; + } + return true; +} + +void XPCMessageServer::ForwardMessage(IPCMessage request, + mach_port_t destination) { + xpc_pipe_t pipe = xpc_pipe_create_from_port(destination, 0); + int rv = xpc_pipe_routine_forward(pipe, request.xpc); + if (rv) { + LOG(ERROR) << "Failed to xpc_pipe_routine_forward(): " << rv; + } + xpc_release(pipe); +} + +void XPCMessageServer::RejectMessage(IPCMessage request, int error_code) { + IPCMessage reply = CreateReply(request); + xpc_dictionary_set_int64(reply.xpc, "error", error_code); + SendReply(reply); +} + +mach_port_t XPCMessageServer::GetServerPort() const { + return server_port_.get(); +} + +void XPCMessageServer::ReceiveMessage() { + IPCMessage request; + int rv = xpc_pipe_receive(server_port_, &request.xpc); + if (rv) { + LOG(ERROR) << "Failed to xpc_pipe_receive(): " << rv; + return; + } + + demuxer_->DemuxMessage(request); + + xpc_release(request.xpc); + if (reply_message_) { + xpc_release(reply_message_); + reply_message_ = NULL; + } +} + +} // namespace sandbox |