summaryrefslogtreecommitdiffstats
path: root/sandbox/mac/xpc_message_server.cc
diff options
context:
space:
mode:
authorrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-19 02:30:11 +0000
committerrsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-19 02:30:11 +0000
commit737e70acd59fe8d1fca96bd7f3bd27a61336a146 (patch)
tree8e2995e01ce714f4ba03fb756714f38868ae95ec /sandbox/mac/xpc_message_server.cc
parent2f32cebd5614a37e715a1350e14376238f418a93 (diff)
downloadchromium_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.cc116
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