// Copyright 2016 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 <windows.h>
#include <sddl.h>

#include <memory>

#include "base/command_line.h"
#include "base/memory/free_deleter.h"
#include "base/memory/shared_memory.h"
#include "base/process/process.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "base/win/scoped_handle.h"
#include "base/win/win_util.h"
#include "starboard/memory.h"
#include "starboard/types.h"
#include "testing/multiprocess_func_list.h"

namespace base {
namespace {
const char* kHandleSwitchName = "shared_memory_win_test_switch";

// Creates a process token with a low integrity SID.
win::ScopedHandle CreateLowIntegritySID() {
  HANDLE process_token_raw = nullptr;
  BOOL success = ::OpenProcessToken(GetCurrentProcess(),
                                    TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT |
                                        TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY,
                                    &process_token_raw);
  if (!success)
    return base::win::ScopedHandle();
  win::ScopedHandle process_token(process_token_raw);

  HANDLE lowered_process_token_raw = nullptr;
  success =
      ::DuplicateTokenEx(process_token.Get(), 0, NULL, SecurityImpersonation,
                         TokenPrimary, &lowered_process_token_raw);
  if (!success)
    return base::win::ScopedHandle();
  win::ScopedHandle lowered_process_token(lowered_process_token_raw);

  // Low integrity SID
  WCHAR integrity_sid_string[20] = L"S-1-16-4096";
  PSID integrity_sid = nullptr;
  success = ::ConvertStringSidToSid(integrity_sid_string, &integrity_sid);
  if (!success)
    return base::win::ScopedHandle();

  TOKEN_MANDATORY_LABEL TIL = {};
  TIL.Label.Attributes = SE_GROUP_INTEGRITY;
  TIL.Label.Sid = integrity_sid;
  success = ::SetTokenInformation(
      lowered_process_token.Get(), TokenIntegrityLevel, &TIL,
      sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(integrity_sid));
  if (!success)
    return base::win::ScopedHandle();
  return lowered_process_token;
}

// Reads a HANDLE from the pipe as a raw int, least significant digit first.
win::ScopedHandle ReadHandleFromPipe(HANDLE pipe) {
  // Read from parent pipe.
  const size_t buf_size = 1000;
  char buffer[buf_size];
  SbMemorySet(buffer, 0, buf_size);
  DWORD bytes_read;
  BOOL success = ReadFile(pipe, buffer, buf_size, &bytes_read, NULL);

  if (!success || bytes_read == 0) {
    LOG(ERROR) << "Failed to read handle from pipe.";
    return win::ScopedHandle();
  }

  int handle_as_int = 0;
  int power_of_ten = 1;
  for (unsigned int i = 0; i < bytes_read; ++i) {
    handle_as_int += buffer[i] * power_of_ten;
    power_of_ten *= 10;
  }

  return win::ScopedHandle(reinterpret_cast<HANDLE>(handle_as_int));
}

// Writes a HANDLE to a pipe as a raw int, least significant digit first.
void WriteHandleToPipe(HANDLE pipe, HANDLE handle) {
  uint32_t handle_as_int = base::win::HandleToUint32(handle);

  std::unique_ptr<char, base::FreeDeleter> buffer(
      static_cast<char*>(SbMemoryAllocate(1000)));
  size_t index = 0;
  while (handle_as_int > 0) {
    buffer.get()[index] = handle_as_int % 10;
    handle_as_int /= 10;
    ++index;
  }

  ::ConnectNamedPipe(pipe, nullptr);
  DWORD written;
  ASSERT_TRUE(::WriteFile(pipe, buffer.get(), index, &written, NULL));
}

// Creates a communication pipe with the given name.
win::ScopedHandle CreateCommunicationPipe(const std::wstring& name) {
  return win::ScopedHandle(CreateNamedPipe(name.c_str(),  // pipe name
                                           PIPE_ACCESS_DUPLEX, PIPE_WAIT, 255,
                                           1000, 1000, 0, NULL));
}

// Generates a random name for a communication pipe.
std::wstring CreateCommunicationPipeName() {
  uint64_t rand_values[4];
  RandBytes(&rand_values, sizeof(rand_values));
  std::wstring child_pipe_name = StringPrintf(
      L"\\\\.\\pipe\\SharedMemoryWinTest_%016llx%016llx%016llx%016llx",
      rand_values[0], rand_values[1], rand_values[2], rand_values[3]);
  return child_pipe_name;
}

class SharedMemoryWinTest : public base::MultiProcessTest {
 protected:
  CommandLine MakeCmdLine(const std::string& procname) override {
    CommandLine line = base::MultiProcessTest::MakeCmdLine(procname);
    line.AppendSwitchASCII(kHandleSwitchName, communication_pipe_name_);
    return line;
  }

  std::string communication_pipe_name_;
};

MULTIPROCESS_TEST_MAIN(LowerPermissions) {
  std::string handle_name =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kHandleSwitchName);
  std::wstring handle_name16 = SysUTF8ToWide(handle_name);
  win::ScopedHandle parent_pipe(
      ::CreateFile(handle_name16.c_str(),  // pipe name
                   GENERIC_READ,
                   0,              // no sharing
                   NULL,           // default security attributes
                   OPEN_EXISTING,  // opens existing pipe
                   0,              // default attributes
                   NULL));         // no template file
  if (parent_pipe.Get() == INVALID_HANDLE_VALUE) {
    LOG(ERROR) << "Failed to open communication pipe.";
    return 1;
  }

  win::ScopedHandle received_handle = ReadHandleFromPipe(parent_pipe.Get());
  if (!received_handle.Get()) {
    LOG(ERROR) << "Failed to read handle from pipe.";
    return 1;
  }

  // Attempting to add the WRITE_DAC permission should fail.
  HANDLE duped_handle;
  BOOL success = ::DuplicateHandle(GetCurrentProcess(), received_handle.Get(),
                                   GetCurrentProcess(), &duped_handle,
                                   FILE_MAP_READ | WRITE_DAC, FALSE, 0);
  if (success) {
    LOG(ERROR) << "Should not have been able to add WRITE_DAC permission.";
    return 1;
  }

  // Attempting to add the FILE_MAP_WRITE permission should fail.
  success = ::DuplicateHandle(GetCurrentProcess(), received_handle.Get(),
                              GetCurrentProcess(), &duped_handle,
                              FILE_MAP_READ | FILE_MAP_WRITE, FALSE, 0);
  if (success) {
    LOG(ERROR) << "Should not have been able to add FILE_MAP_WRITE permission.";
    return 1;
  }

  // Attempting to duplicate the HANDLE with the same permissions should
  // succeed.
  success = ::DuplicateHandle(GetCurrentProcess(), received_handle.Get(),
                              GetCurrentProcess(), &duped_handle, FILE_MAP_READ,
                              FALSE, 0);
  if (!success) {
    LOG(ERROR) << "Failed to duplicate handle.";
    return 4;
  }
  ::CloseHandle(duped_handle);
  return 0;
}

TEST_F(SharedMemoryWinTest, LowerPermissions) {
  std::wstring communication_pipe_name = CreateCommunicationPipeName();
  communication_pipe_name_ = SysWideToUTF8(communication_pipe_name);

  win::ScopedHandle communication_pipe =
      CreateCommunicationPipe(communication_pipe_name);
  ASSERT_TRUE(communication_pipe.Get());

  win::ScopedHandle lowered_process_token = CreateLowIntegritySID();
  ASSERT_TRUE(lowered_process_token.Get());

  base::LaunchOptions options;
  options.as_user = lowered_process_token.Get();
  base::Process process = SpawnChildWithOptions("LowerPermissions", options);
  ASSERT_TRUE(process.IsValid());

  SharedMemory memory;
  memory.CreateAndMapAnonymous(1001);

  // Duplicate into child process, giving only FILE_MAP_READ permissions.
  HANDLE raw_handle = nullptr;
  ::DuplicateHandle(::GetCurrentProcess(), memory.handle().GetHandle(),
                    process.Handle(), &raw_handle,
                    FILE_MAP_READ | SECTION_QUERY, FALSE, 0);
  ASSERT_TRUE(raw_handle);

  WriteHandleToPipe(communication_pipe.Get(), raw_handle);

  int exit_code;
  EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
                                             &exit_code));
  EXPECT_EQ(0, exit_code);
}

}  // namespace
}  // namespace base
