// 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/xpc.h"

namespace sandbox {

XPCMessageServer::XPCMessageServer(MessageDemuxer* demuxer,
                                   mach_port_t server_receive_right)
    : demuxer_(demuxer),
      server_port_(server_receive_right),
      reply_message_(NULL) {
  CHECK(InitializeXPC());
}

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 base::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) {
  if (!reply.xpc)
    return false;

  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);
  // The message wasn't expecting a reply, so rejecting means ignoring it.
  if (reply.xpc) {
    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_.get(), &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
