| Index: sandbox/mac/xpc_message_server.cc
|
| diff --git a/sandbox/mac/xpc_message_server.cc b/sandbox/mac/xpc_message_server.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..12c8d56e365bd5ce8d1499cf18f6d2c49e9211d4
|
| --- /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
|
|
|