// Copyright 2019 The Chromium OS 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 "login_manager/secret_util.h"

#include <unistd.h>

#include <utility>

#include <base/file_descriptor_posix.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/memory/read_only_shared_memory_region.h>
#include <base/process/process_handle.h>
#include <base/strings/string_number_conversions.h>
#include <crypto/sha2.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace login_manager {
namespace secret_util {

namespace {

// Maximum amount of data that can be sent through the pipe using |secret_util|
// methods.
// 64k of data, minus 64 bits for a preceding size. This number was chosen to
// fit all the data in a single pipe buffer and avoid blocking on write.
// (http://man7.org/linux/man-pages/man7/pipe.7.html)
const size_t kPipeSecretSizeLimit = 1024 * 64 - sizeof(size_t);

// Reads |data_size| from the pipe. Returns 'false' if it couldn't read
// |data_size| or if |data_size| was incorrect.
bool GetSecretDataSizeFromPipe(int in_secret_fd, size_t* data_size_out) {
  if (!base::ReadFromFD(in_secret_fd, reinterpret_cast<char*>(data_size_out),
                        sizeof(size_t))) {
    PLOG(ERROR) << "Could not read secret size from file.";
    return false;
  }

  if (*data_size_out == 0 || *data_size_out > kPipeSecretSizeLimit) {
    LOG(ERROR) << "Invalid data size read from file descriptor. Size read: "
               << *data_size_out;
    return false;
  }

  return true;
}

}  // namespace

// Limiting data size to 10MB here because it covers the current use cases,
// it can be increased if needed up to an operating system limit (man 1 lsipc).
const size_t kSharedMemorySecretSizeLimit = 10 * 1024 * 1024;

SharedMemoryUtil::~SharedMemoryUtil() = default;

base::ScopedFD SharedMemoryUtil::WriteDataToSharedMemory(
    const std::vector<uint8_t>& data) {
  size_t data_size = data.size();
  CHECK_LE(data_size, kSharedMemorySecretSizeLimit);
  // Creates a new base::ReadOnlySharedMemoryRegion instance mapped to a
  // base::WritableSharedMemoryMapping, which is the only way to modify the
  // content of the newly created region.
  auto shmem = base::ReadOnlySharedMemoryRegion::Create(data.size());
  if (!shmem.IsValid())
    return base::ScopedFD();
  memcpy(shmem.mapping.GetMemoryAs<uint8_t>(), data.data(), data.size());
  base::subtle::PlatformSharedMemoryRegion platform_shm =
      base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
          std::move(shmem.region));
  if (!platform_shm.IsValid())
    return base::ScopedFD();
  return base::ScopedFD(std::move(platform_shm.PassPlatformHandle().fd));
}

bool SharedMemoryUtil::ReadDataFromSharedMemory(
    const base::ScopedFD& in_data_fd,
    size_t data_size,
    std::vector<uint8_t>* out_data) {
  base::ScopedFD dup_in_data_fd(dup(in_data_fd.get()));
  base::ReadOnlySharedMemoryRegion shm_region =
      base::ReadOnlySharedMemoryRegion::Deserialize(
          base::subtle::PlatformSharedMemoryRegion::Take(
              std::move(dup_in_data_fd),
              base::subtle::PlatformSharedMemoryRegion::Mode::kReadOnly,
              data_size, base::UnguessableToken::Create()));
  if (!shm_region.IsValid())
    return false;
  base::ReadOnlySharedMemoryMapping shm_mapping = shm_region.Map();
  if (!shm_mapping.IsValid())
    return false;
  out_data->assign(shm_mapping.GetMemoryAs<uint8_t>(),
                   shm_mapping.GetMemoryAs<uint8_t>() + data_size);
  return true;
}

base::ScopedFD WriteSizeAndDataToPipe(const std::vector<uint8_t>& data) {
  size_t data_size = data.size();
  CHECK_LE(data_size, kPipeSecretSizeLimit);

  int fds[2];
  base::CreateLocalNonBlockingPipe(fds);
  base::ScopedFD read_dbus_fd(fds[0]);
  base::ScopedFD write_scoped_fd(fds[1]);

  base::WriteFileDescriptor(write_scoped_fd.get(),
                            reinterpret_cast<const char*>(&data_size),
                            sizeof(size_t));
  base::WriteFileDescriptor(write_scoped_fd.get(),
                            reinterpret_cast<const char*>(data.data()),
                            data_size);
  return read_dbus_fd;
}

bool SaveSecretFromPipe(password_provider::PasswordProviderInterface* provider,
                        const base::ScopedFD& in_secret_fd) {
  size_t data_size = 0;
  if (!GetSecretDataSizeFromPipe(in_secret_fd.get(), &data_size))
    return false;

  auto secret = password_provider::Password::CreateFromFileDescriptor(
      in_secret_fd.get(), data_size);

  if (!secret) {
    LOG(ERROR) << "Could not create secret from file descriptor.";
    return false;
  }

  if (!provider->SavePassword(*secret)) {
    LOG(ERROR) << "Could not save secret.";
    return false;
  }

  return true;
}

base::FilePath StringToSafeFilename(std::string data) {
  std::string sha256hash = crypto::SHA256HashString(data);
  return base::FilePath(base::HexEncode(sha256hash.data(), sha256hash.size()));
}

}  // namespace secret_util
}  // namespace login_manager
