// Copyright 2019 The Crashpad Authors. All rights reserved.
//
// 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.

#include "util/linux/socket.h"

#include <unistd.h>

#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "third_party/lss/lss.h"

namespace crashpad {

// static
bool UnixCredentialSocket::CreateCredentialSocketpair(ScopedFileHandle* sock1,
                                                      ScopedFileHandle* sock2) {
  int socks[2];
  if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socks) != 0) {
    PLOG(ERROR) << "socketpair";
    return false;
  }
  ScopedFileHandle local_sock1(socks[0]);
  ScopedFileHandle local_sock2(socks[1]);

  int optval = 1;
  socklen_t optlen = sizeof(optval);
  if (setsockopt(local_sock1.get(), SOL_SOCKET, SO_PASSCRED, &optval, optlen) !=
          0 ||
      setsockopt(local_sock2.get(), SOL_SOCKET, SO_PASSCRED, &optval, optlen) !=
          0) {
    PLOG(ERROR) << "setsockopt";
    return false;
  }

  sock1->swap(local_sock1);
  sock2->swap(local_sock2);
  return true;
}

const size_t UnixCredentialSocket::kMaxSendRecvMsgFDs = 4;

// static
int UnixCredentialSocket::SendMsg(int fd,
                                  const void* buf,
                                  size_t buf_size,
                                  const int* fds,
                                  size_t fd_count) {
  // This function is intended to be used after a crash. fds is an integer
  // array instead of a vector to avoid forcing callers to provide a vector,
  // which they would have to create prior to the crash.
  if (fds && fd_count > kMaxSendRecvMsgFDs) {
    DLOG(ERROR) << "too many fds " << fd_count;
    return EINVAL;
  }

  iovec iov;
  iov.iov_base = const_cast<void*>(buf);
  iov.iov_len = buf_size;

  msghdr msg = {};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char cmsg_buf[CMSG_SPACE(sizeof(int) * kMaxSendRecvMsgFDs)];
  if (fds) {
    msg.msg_control = cmsg_buf;
    msg.msg_controllen = CMSG_SPACE(sizeof(int) * fd_count);

    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
    DCHECK(cmsg);

    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fd_count);
    memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * fd_count);
  }

  // TODO(jperaza): Use sys_sendmsg when lss has macros for maniuplating control
  // messages. https://crbug.com/crashpad/265
  if (HANDLE_EINTR(sendmsg(fd, &msg, MSG_NOSIGNAL)) < 0) {
    DPLOG(ERROR) << "sendmsg";
    return errno;
  }
  return 0;
}

// static
bool UnixCredentialSocket::RecvMsg(int fd,
                                   void* buf,
                                   size_t buf_size,
                                   ucred* creds,
                                   std::vector<ScopedFileHandle>* fds) {
  iovec iov;
  iov.iov_base = buf;
  iov.iov_len = buf_size;

  msghdr msg = {};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char cmsg_buf[CMSG_SPACE(sizeof(ucred)) +
                CMSG_SPACE(sizeof(int) * kMaxSendRecvMsgFDs)];
  msg.msg_control = cmsg_buf;
  msg.msg_controllen = sizeof(cmsg_buf);

  int res = HANDLE_EINTR(recvmsg(fd, &msg, 0));
  if (res < 0) {
    PLOG(ERROR) << "recvmsg";
    return false;
  }

  ucred* local_creds = nullptr;
  std::vector<ScopedFileHandle> local_fds;
  bool unhandled_cmsgs = false;

  for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
       cmsg;
       cmsg = CMSG_NXTHDR(&msg, cmsg)) {
    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
      int* fdp = reinterpret_cast<int*>(CMSG_DATA(cmsg));
      size_t fd_count = (reinterpret_cast<char*>(cmsg) + cmsg->cmsg_len -
                         reinterpret_cast<char*>(fdp)) /
                        sizeof(int);
      DCHECK_LE(fd_count, kMaxSendRecvMsgFDs);
      for (size_t index = 0; index < fd_count; ++index) {
        if (fds) {
          local_fds.emplace_back(fdp[index]);
        } else if (IGNORE_EINTR(close(fdp[index])) != 0) {
          PLOG(ERROR) << "close";
        }
      }
      continue;
    }

    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) {
      DCHECK(!local_creds);
      local_creds = reinterpret_cast<ucred*>(CMSG_DATA(cmsg));
      continue;
    }

    LOG(ERROR) << "unhandled cmsg " << cmsg->cmsg_level << ", "
               << cmsg->cmsg_type;
    unhandled_cmsgs = true;
  }

  if (unhandled_cmsgs) {
    return false;
  }

  if (msg.msg_name != nullptr || msg.msg_namelen != 0) {
    LOG(ERROR) << "unexpected msg name";
    return false;
  }

  if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) {
    LOG(ERROR) << "truncated msg";
    return false;
  }

  // Credentials are missing from the message either when the recv socket wasn't
  // configured with SO_PASSCRED or when all sending sockets have been closed.
  // In the latter case, res == 0. This case is also indistinguishable from an
  // empty message sent to a recv socket which hasn't set SO_PASSCRED.
  if (!local_creds) {
    LOG_IF(ERROR, res != 0) << "missing credentials";
    return false;
  }

  if (static_cast<size_t>(res) != buf_size) {
    LOG(ERROR) << "incorrect payload size " << res;
    return false;
  }

  *creds = *local_creds;
  if (fds) {
    fds->swap(local_fds);
  }
  return true;
}

}  // namespace crashpad
