// Copyright 2014 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef CRASHPAD_UTIL_MACH_CHILD_PORT_HANDSHAKE_H_
#define CRASHPAD_UTIL_MACH_CHILD_PORT_HANDSHAKE_H_

#include <mach/mach.h>

#include <string>
#include <tuple>

#include "base/files/scoped_file.h"
#include "util/mach/child_port_types.h"

namespace crashpad {

namespace test {
namespace {
class ChildPortHandshakeTest;
}  // namespace
}  // namespace test

//! \brief Implements a handshake protocol that allows processes to exchange
//!     port rights.
//!
//! Ordinarily, there is no way for parent and child processes to exchange port
//! rights, outside of the rights that children inherit from their parents.
//! These include task-special ports and exception ports, but all of these have
//! system-defined uses, and cannot reliably be replaced: in a multi-threaded
//! parent, it is impossible to temporarily change an inheritable port while
//! maintaining a guarantee that another thread will not attempt to use it, and
//! in children, it difficult to guarantee that nothing will attempt to use an
//! inheritable port before it can be replaced with the correct one. This latter
//! concern is becoming increasingly more pronounced as system libraries perform
//! more operations that rely on an inherited port in module initializers.
//!
//! The protocol implemented by this class involves a server that runs in one
//! process. The server is published with the bootstrap server, which the other
//! process has access to because the bootstrap port is one of the inherited
//! task-special ports. The two processes also share a pipe, which the server
//! can write to and the client can read from. The server will write a random
//! token to this pipe, along with the name under which its service has been
//! registered with the bootstrap server. The client can then obtain a send
//! right to this service with `bootstrap_look_up()`, and send a check-in
//! message containing the token value and the port right of its choice by
//! calling `child_port_check_in()`.
//!
//! The inclusion of the token authenticates the client to the server. This is
//! necessary because the service is published with the bootstrap server, which
//! opens up access to it to more than the intended client. Because the token is
//! passed to the client by a shared pipe, it constitutes a shared secret not
//! known by other processes that may have incidental access to the server. The
//! ChildPortHandshake server considers its randomly-generated token valid until
//! a client checks in with it. This mechanism is used instead of examining the
//! request message’s audit trailer to verify the sender’s process ID because in
//! some process architectures, it may be impossible to verify the client’s
//! process ID.
//!
//! The shared pipe serves another purpose: the server monitors it for an
//! end-of-file (no readers) condition. Once detected, it will stop its blocking
//! wait for a client to check in. This mechanism was also chosen for its
//! ability to function properly in diverse process architectures.
//!
//! This class can be used to allow a child process to provide its parent with a
//! send right to its task port, in cases where it is desirable for the parent
//! to have such access. It can also be used to allow a parent process to
//! transfer a receive right to a child process that implements the server for
//! that right, or for a child process to establish its own server and provide
//! its parent with a send right to that server, for cases where a service is
//! provided and it is undesirable or impossible to provide it via the bootstrap
//! or launchd interfaces.
//!
//! Example parent process, running a client that sends a receive right to its
//! child:
//! \code
//!   ChildPortHandshake child_port_handshake;
//!   base::ScopedFD server_write_fd = child_port_handshake.ServerWriteFD();
//!   std::string server_write_fd_string =
//!       base::StringPrintf("%d", server_write_fd.get());
//!
//!   pid_t pid = fork();
//!   if (pid == 0) {
//!     // Child
//!
//!     // Close all file descriptors above STDERR_FILENO except for
//!     // server_write_fd. Let the child know what file descriptor to use for
//!     // server_write_fd by passing it as argv[1]. Example code for the child
//!     // process is below.
//!     CloseMultipleNowOrOnExec(STDERR_FILENO + 1, server_write_fd.get());
//!     execlp("./child", "child", server_write_fd_string.c_str(), nullptr);
//!   }
//!
//!   // Parent
//!
//!   // Close the child’s end of the pipe.
//!   server_write_fd.reset();
//!
//!   // Make a new Mach receive right.
//!   base::apple::ScopedMachReceiveRight
//!       receive_right(NewMachPort(MACH_PORT_RIGHT_RECEIVE));
//!
//!   // Make a send right corresponding to the receive right.
//!   mach_port_t send_right;
//!   mach_msg_type_name_t send_right_type;
//!   mach_port_extract_right(mach_task_self(),
//!                           receive_right.get(),
//!                           MACH_MSG_TYPE_MAKE_SEND,
//!                           &send_right,
//!                           &send_right_type);
//!   base::apple::ScopedMachSendRight send_right_owner(send_right);
//!
//!   // Send the receive right to the child process, retaining the send right
//!   // for use in the parent process.
//!   if (child_port_handshake.RunClient(receive_right.get(),
//!                                      MACH_MSG_TYPE_MOVE_RECEIVE)) {
//!     std::ignore = receive_right.release();
//!   }
//! \endcode
//!
//! Example child process, running a server that receives a receive right from
//! its parent:
//! \code
//!   int main(int argc, char* argv[]) {
//!     // The parent passed server_write_fd in argv[1].
//!     base::ScopedFD server_write_fd(atoi(argv[1]));
//!
//!     // Obtain a receive right from the parent process.
//!     base::apple::ScopedMachReceiveRight receive_right(
//!         ChildPortHandshake::RunServerForFD(
//!             std::move(server_write_fd),
//!             ChildPortHandshake::PortRightType::kReceiveRight));
//!   }
//! \endcode
class ChildPortHandshake {
 public:
  //! \brief Controls whether a receive or send right is expected to be
  //!     obtained from the client by the server’s call to RunServer().
  enum class PortRightType {
    //! \brief The server expects to receive a receive right.
    kReceiveRight = 0,

    //! \brief The server expects to receive a send or send-once right.
    kSendRight,
  };

  ChildPortHandshake();

  ChildPortHandshake(const ChildPortHandshake&) = delete;
  ChildPortHandshake& operator=(const ChildPortHandshake&) = delete;

  ~ChildPortHandshake();

  //! \brief Obtains the “read” side of the pipe, to be used by the client.
  //!
  //! This file descriptor must be passed to RunClientForFD().
  //!
  //! \return The file descriptor that the client should read from.
  base::ScopedFD ClientReadFD();

  //! \brief Obtains the “write” side of the pipe, to be used by the server.
  //!
  //! This file descriptor must be passed to RunServerForFD().
  //!
  //! \return The file descriptor that the server should write to.
  base::ScopedFD ServerWriteFD();

  //! \brief Runs the server.
  //!
  //! This method closes the “read” side of the pipe in-process, so that the
  //! client process holds the only file descriptor that can read from the pipe.
  //! It then calls RunServerForFD() using the “write” side of the pipe. If
  //! ClientReadFD() has already been called in the server process, the caller
  //! must ensure that the file descriptor returned by ClientReadFD() is closed
  //! prior to calling this method.
  mach_port_t RunServer(PortRightType port_right_type);

  //! \brief Runs the client.
  //!
  //! This method closes the “write” side of the pipe in-process, so that the
  //! server process holds the only file descriptor that can write to the pipe.
  //! It then calls RunClientForFD() using the “read” side of the pipe. If
  //! ServerWriteFD() has already been called in the client process, the caller
  //! must ensure that the file descriptor returned by ServerWriteFD() is closed
  //! prior to calling this method.
  //!
  //! \return `true` on success, `false` on failure with a message logged.
  bool RunClient(mach_port_t port, mach_msg_type_name_t right_type);

  //! \brief Runs the server.
  //!
  //! If a ChildPortHandshake object is available, don’t call this static
  //! function. Instead, call RunServer(), which wraps this function. When using
  //! this function, the caller is responsible for ensuring that the client
  //! “read” side of the pipe is closed in the server process prior to calling
  //! this function.
  //!
  //! This function performs these tasks:
  //!  - Creates a random token and sends it via the pipe.
  //!  - Checks its service in with the bootstrap server, and sends the name
  //!    of its bootstrap service mapping via the pipe.
  //!  - Simultaneously receives messages on its Mach server and monitors the
  //!    pipe for end-of-file. This is a blocking operation.
  //!  - When a Mach message is received, calls HandleChildPortCheckIn() to
  //!    interpret and validate it, and if the message is valid, returns the
  //!    port right extracted from the message. If the message is not valid,
  //!    this method will continue waiting for a valid message. Valid messages
  //!    are properly formatted and have the correct token. The right carried in
  //!    a valid message will be returned. If a message is not valid, this
  //!    method will continue waiting for pipe EOF or a valid message.
  //!  - When notified of pipe EOF, returns `MACH_PORT_NULL`.
  //!  - Regardless of return value, destroys the server’s receive right and
  //!    closes the pipe.
  //!
  //! \param[in] server_write_fd The write side of the pipe shared with the
  //!     client process. This function takes ownership of this file descriptor,
  //!     and will close it prior to returning.
  //! \param[in] port_right_type The port right type expected to be received
  //!     from the client. If the port right received from the client does not
  //!     match the expected type, the received port right will be destroyed,
  //!     and `MACH_PORT_NULL` will be returned.
  //!
  //! \return On success, the port right provided by the client. The caller
  //!     takes ownership of this right. On failure, `MACH_PORT_NULL`,
  //!     indicating that the client did not check in properly before
  //!     terminating, where termination is detected by detecting that the read
  //!     side of the shared pipe has closed. On failure, a message indicating
  //!     the nature of the failure will be logged.
  static mach_port_t RunServerForFD(base::ScopedFD server_write_fd,
                                    PortRightType port_right_type);

  //! \brief Runs the client.
  //!
  //! If a ChildPortHandshake object is available, don’t call this static
  //! function. Instead, call RunClient(), which wraps this function. When using
  //! this function, the caller is responsible for ensuring that the server
  //! “write” side of the pipe is closed in the client process prior to calling
  //! this function.
  //!
  //! This function performs these tasks:
  //!  - Reads the token from the pipe.
  //!  - Reads the bootstrap service name from the pipe.
  //!  - Obtains a send right to the server by calling `bootstrap_look_up()`.
  //!  - Sends a check-in message to the server by calling
  //!    `child_port_check_in()`, providing the token and the user-supplied port
  //!    right.
  //!  - Deallocates the send right to the server, and closes the pipe.
  //!
  //! There is no return value because `child_port_check_in()` is a MIG
  //! `simpleroutine`, and the server does not send a reply. This allows
  //! check-in to occur without blocking to wait for a reply.
  //!
  //! \param[in] client_read_fd The “read” side of the pipe shared with the
  //!     server process. This function takes ownership of this file descriptor,
  //!     and will close it prior to returning.
  //! \param[in] port The port right that will be passed to the server by
  //!     `child_port_check_in()`.
  //! \param[in] right_type The right type to furnish the server with. If \a
  //!     port is a send right, this can be `MACH_MSG_TYPE_COPY_SEND` or
  //!     `MACH_MSG_TYPE_MOVE_SEND`. If \a port is a send-once right, this can
  //!     be `MACH_MSG_TYPE_MOVE_SEND_ONCE`. If \a port is a receive right, this
  //!     can be `MACH_MSG_TYPE_MAKE_SEND`, `MACH_MSG_TYPE_MAKE_SEND_ONCE`, or
  //!     `MACH_MSG_TYPE_MOVE_RECEIVE`.
  //!
  //! \return `true` on success, `false` on failure with a message logged. On
  //!     failure, the port right corresponding to a \a right_type of
  //!     `MACH_MSG_TYPE_MOVE_*` is not consumed, and the caller must dispose of
  //!     the right if necessary.
  static bool RunClientForFD(base::ScopedFD client_read_fd,
                             mach_port_t port,
                             mach_msg_type_name_t right_type);

 private:
  //! \brief Runs the read-from-pipe portion of the client’s side of the
  //!     handshake. This is an implementation detail of RunClient and is only
  //!     exposed for testing purposes.
  //!
  //! When using this function and RunClientInternal_SendCheckIn(), the caller
  //! is responsible for closing \a pipe_read at an appropriate time, normally
  //! after calling RunClientInternal_SendCheckIn().
  //!
  //! \param[in] pipe_read The “read” side of the pipe shared with the server
  //!     process.
  //! \param[out] token The token value read from \a pipe_read.
  //! \param[out] service_name The service name as registered with the bootstrap
  //!     server, read from \a pipe_read.
  //!
  //! \return `true` on success, `false` on failure with a message logged.
  static bool RunClientInternal_ReadPipe(int pipe_read,
                                         child_port_token_t* token,
                                         std::string* service_name);

  //! \brief Runs the check-in portion of the client’s side of the handshake.
  //!     This is an implementation detail of RunClient and is only exposed for
  //!     testing purposes.
  //!
  //! When using this RunClientInternal_ReadPipe() and this function, the caller
  //! is responsible for closing the “read” side of the pipe at an appropriate
  //! time, normally after calling this function.
  //!
  //! \param[in] service_name The service name as registered with the bootstrap
  //!     server, to be looked up with `bootstrap_look_up()`.
  //! \param[in] token The token value to provide during check-in.
  //! \param[in] port The port that will be passed to the server by
  //!     `child_port_check_in()`.
  //! \param[in] right_type The right type to furnish the server with.
  //!
  //! \return `true` on success, `false` on failure with a message logged.
  static bool RunClientInternal_SendCheckIn(const std::string& service_name,
                                            child_port_token_t token,
                                            mach_port_t port,
                                            mach_msg_type_name_t right_type);

  base::ScopedFD client_read_fd_;
  base::ScopedFD server_write_fd_;

  friend class test::ChildPortHandshakeTest;
};

}  // namespace crashpad

#endif  // CRASHPAD_UTIL_MACH_CHILD_PORT_HANDSHAKE_H_
