Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / sandbox / mac / xpc_message_server.cc
blob1cd5c63f386243331acd1be0577704c28b378349
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sandbox/mac/xpc_message_server.h"
7 #include <bsm/libbsm.h>
9 #include <string>
11 #include "base/mac/mach_logging.h"
12 #include "base/strings/stringprintf.h"
13 #include "sandbox/mac/xpc.h"
15 #if defined(MAC_OS_X_VERSION_10_7) && \
16 MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
17 // Redeclare methods that only exist on 10.7+ to suppress
18 // -Wpartial-availability warnings.
19 extern "C" {
20 XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL_ALL
21 xpc_object_t
22 xpc_dictionary_create_reply(xpc_object_t original);
23 } // extern "C"
24 #endif
26 namespace sandbox {
28 XPCMessageServer::XPCMessageServer(MessageDemuxer* demuxer,
29 mach_port_t server_receive_right)
30 : demuxer_(demuxer),
31 server_port_(server_receive_right),
32 reply_message_(NULL) {
35 XPCMessageServer::~XPCMessageServer() {
38 bool XPCMessageServer::Initialize() {
39 // Allocate a port for use as a new server port if one was not passed to the
40 // constructor.
41 if (!server_port_.is_valid()) {
42 mach_port_t port;
43 kern_return_t kr;
44 if ((kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
45 &port)) != KERN_SUCCESS) {
46 MACH_LOG(ERROR, kr) << "Failed to allocate new server port.";
47 return false;
49 server_port_.reset(port);
52 std::string label = base::StringPrintf(
53 "org.chromium.sandbox.XPCMessageServer.%p", demuxer_);
54 dispatch_source_.reset(new base::DispatchSourceMach(
55 label.c_str(), server_port_.get(), ^{ ReceiveMessage(); }));
56 dispatch_source_->Resume();
58 return true;
61 pid_t XPCMessageServer::GetMessageSenderPID(IPCMessage request) {
62 audit_token_t token;
63 xpc_dictionary_get_audit_token(request.xpc, &token);
64 // TODO(rsesek): In the 10.7 SDK, there's audit_token_to_pid().
65 pid_t sender_pid;
66 audit_token_to_au32(token,
67 NULL, NULL, NULL, NULL, NULL, &sender_pid, NULL, NULL);
68 return sender_pid;
71 IPCMessage XPCMessageServer::CreateReply(IPCMessage request) {
72 if (!reply_message_)
73 reply_message_ = xpc_dictionary_create_reply(request.xpc);
75 IPCMessage reply;
76 reply.xpc = reply_message_;
77 return reply;
80 bool XPCMessageServer::SendReply(IPCMessage reply) {
81 int rv = xpc_pipe_routine_reply(reply.xpc);
82 if (rv) {
83 LOG(ERROR) << "Failed to xpc_pipe_routine_reply(): " << rv;
84 return false;
86 return true;
89 void XPCMessageServer::ForwardMessage(IPCMessage request,
90 mach_port_t destination) {
91 xpc_pipe_t pipe = xpc_pipe_create_from_port(destination, 0);
92 int rv = xpc_pipe_routine_forward(pipe, request.xpc);
93 if (rv) {
94 LOG(ERROR) << "Failed to xpc_pipe_routine_forward(): " << rv;
96 xpc_release(pipe);
99 void XPCMessageServer::RejectMessage(IPCMessage request, int error_code) {
100 IPCMessage reply = CreateReply(request);
101 xpc_dictionary_set_int64(reply.xpc, "error", error_code);
102 SendReply(reply);
105 mach_port_t XPCMessageServer::GetServerPort() const {
106 return server_port_.get();
109 void XPCMessageServer::ReceiveMessage() {
110 IPCMessage request;
111 int rv = xpc_pipe_receive(server_port_, &request.xpc);
112 if (rv) {
113 LOG(ERROR) << "Failed to xpc_pipe_receive(): " << rv;
114 return;
117 demuxer_->DemuxMessage(request);
119 xpc_release(request.xpc);
120 if (reply_message_) {
121 xpc_release(reply_message_);
122 reply_message_ = NULL;
126 } // namespace sandbox