Home | History | Annotate | Download | only in mac
      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.
      4 
      5 #ifndef SANDBOX_MAC_MACH_MESSAGE_SERVER_H_
      6 #define SANDBOX_MAC_MACH_MESSAGE_SERVER_H_
      7 
      8 #include <dispatch/dispatch.h>
      9 #include <mach/mach.h>
     10 
     11 #include "base/mac/scoped_mach_port.h"
     12 #include "base/mac/scoped_mach_vm.h"
     13 
     14 namespace sandbox {
     15 
     16 // A delegate interface for MachMessageServer that handles processing of
     17 // incoming intercepted IPC messages.
     18 class MessageDemuxer {
     19  public:
     20   // Handle a |request| message and optionally create a |reply|. Both message
     21   // objects are owned by the server. Use the server's methods to send a
     22   // reply message.
     23   virtual void DemuxMessage(mach_msg_header_t* request,
     24                             mach_msg_header_t* reply) = 0;
     25 
     26  protected:
     27   virtual ~MessageDemuxer() {}
     28 };
     29 
     30 // A Mach message server that operates a receive port. Messages are received
     31 // and then passed to the MessageDemuxer for handling. The Demuxer
     32 // can use the server class to send a reply, forward the message to a
     33 // different port, or reply to the message with a MIG error.
     34 class MachMessageServer {
     35  public:
     36   // Creates a new Mach message server that will send messages to |demuxer|
     37   // for handling. If the |server_receive_right| is non-NULL, this class will
     38   // take ownership of the port and it will be used to receive messages.
     39   // Otherwise the server will create a new receive right.
     40   // The maximum size of messages is specified by |buffer_size|.
     41   MachMessageServer(MessageDemuxer* demuxer,
     42                     mach_port_t server_receive_right,
     43                     mach_msg_size_t buffer_size);
     44   ~MachMessageServer();
     45 
     46   // Initializes the class and starts running the message server. If this
     47   // returns false, no other methods may be called on this class.
     48   bool Initialize();
     49 
     50   // Given a received request message, returns the PID of the sending process.
     51   pid_t GetMessageSenderPID(mach_msg_header_t* request);
     52 
     53   // Sends a reply message. Returns true if the message was sent successfully.
     54   bool SendReply(mach_msg_header_t* reply);
     55 
     56   // Forwards the original |request| to the |destination| for handling.
     57   void ForwardMessage(mach_msg_header_t* request, mach_port_t destination);
     58 
     59   // Replies to the message with the specified |error_code| as a MIG
     60   // error_reply RetCode.
     61   void RejectMessage(mach_msg_header_t* reply, int error_code);
     62 
     63   mach_port_t server_port() const { return server_port_.get(); }
     64 
     65  private:
     66   // Event handler for the |server_source_| that reads a message from the queue
     67   // and processes it.
     68   void ReceiveMessage();
     69 
     70   // The demuxer delegate. Weak.
     71   MessageDemuxer* demuxer_;
     72 
     73   // The Mach port on which the server is receiving requests.
     74   base::mac::ScopedMachReceiveRight server_port_;
     75 
     76   // The dispatch queue used to service the server_source_.
     77   dispatch_queue_t server_queue_;
     78 
     79   // A MACH_RECV dispatch source for the server_port_.
     80   dispatch_source_t server_source_;
     81 
     82   // The size of the two message buffers below.
     83   const mach_msg_size_t buffer_size_;
     84 
     85   // Request and reply buffers used in ReceiveMessage.
     86   base::mac::ScopedMachVM request_buffer_;
     87   base::mac::ScopedMachVM reply_buffer_;
     88 
     89   // Whether or not ForwardMessage() was called during ReceiveMessage().
     90   bool did_forward_message_;
     91 };
     92 
     93 }  // namespace sandbox
     94 
     95 #endif  // SANDBOX_MAC_MACH_MESSAGE_SERVER_H_
     96