// Copyright 2018 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.

#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/kill.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "content/browser/sandbox_parameters_mac.h"
#include "content/common/mac/font_loader.h"
#include "crypto/openssl_util.h"
#include "sandbox/mac/seatbelt.h"
#include "sandbox/mac/seatbelt_exec.h"
#include "services/service_manager/sandbox/mac/audio.sb.h"
#include "services/service_manager/sandbox/mac/cdm.sb.h"
#include "services/service_manager/sandbox/mac/common.sb.h"
#include "services/service_manager/sandbox/mac/gpu_v2.sb.h"
#include "services/service_manager/sandbox/mac/nacl_loader.sb.h"
#include "services/service_manager/sandbox/mac/pdf_compositor.sb.h"
#include "services/service_manager/sandbox/mac/ppapi.sb.h"
#include "services/service_manager/sandbox/mac/renderer.sb.h"
#include "services/service_manager/sandbox/mac/utility.sb.h"
#include "services/service_manager/sandbox/switches.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
#include "third_party/boringssl/src/include/openssl/rand.h"
#import "ui/base/clipboard/clipboard_util_mac.h"

namespace content {
namespace {

// crbug.com/740009: This allows the unit test to cleanup temporary directories,
// and is safe since this is only a unit test.
constexpr char kTempDirSuffix[] =
    "(allow file* (subpath \"/private/var/folders\"))";
constexpr char kExtraDataArg[] = "extra-data";

class SandboxMacTest : public base::MultiProcessTest {
 protected:
  base::CommandLine MakeCmdLine(const std::string& procname) override {
    base::CommandLine cl = MultiProcessTest::MakeCmdLine(procname);
    cl.AppendArg(
        base::StringPrintf("%s%d", sandbox::switches::kSeatbeltClient, pipe_));
    if (!extra_data_.empty()) {
      cl.AppendSwitchASCII(kExtraDataArg, extra_data_);
    }
    return cl;
  }

  std::string ProfileForSandbox(const std::string& sandbox_profile) {
    return std::string(service_manager::kSeatbeltPolicyString_common) +
           sandbox_profile + kTempDirSuffix;
  }

  void ExecuteWithParams(const std::string& procname,
                         const std::string& sub_profile,
                         void (*setup)(sandbox::SeatbeltExecClient*)) {
    std::string profile = ProfileForSandbox(sub_profile);
    sandbox::SeatbeltExecClient client;
    client.SetProfile(profile);
    setup(&client);

    pipe_ = client.GetReadFD();
    ASSERT_GE(pipe_, 0);

    base::LaunchOptions options;
    options.fds_to_remap.push_back(std::make_pair(pipe_, pipe_));

    base::Process process = SpawnChildWithOptions(procname, options);
    ASSERT_TRUE(process.IsValid());
    ASSERT_TRUE(client.SendProfile());

    int rv = -1;
    ASSERT_TRUE(base::WaitForMultiprocessTestChildExit(
        process, TestTimeouts::action_timeout(), &rv));
    EXPECT_EQ(0, rv);
  }

  void ExecuteInAudioSandbox(const std::string& procname) {
    ExecuteWithParams(procname, service_manager::kSeatbeltPolicyString_audio,
                      &content::SetupCommonSandboxParameters);
  }

  void ExecuteInCDMSandbox(const std::string& procname) {
    ExecuteWithParams(procname, service_manager::kSeatbeltPolicyString_cdm,
                      &content::SetupCDMSandboxParameters);
  }

  void ExecuteInGPUSandbox(const std::string& procname) {
    ExecuteWithParams(procname, service_manager::kSeatbeltPolicyString_gpu_v2,
                      &content::SetupCommonSandboxParameters);
  }

  void ExecuteInNaClSandbox(const std::string& procname) {
    ExecuteWithParams(procname,
                      service_manager::kSeatbeltPolicyString_nacl_loader,
                      &content::SetupCommonSandboxParameters);
  }

  void ExecuteInPDFSandbox(const std::string& procname) {
    ExecuteWithParams(procname,
                      service_manager::kSeatbeltPolicyString_pdf_compositor,
                      &content::SetupCommonSandboxParameters);
  }

  void ExecuteInPpapiSandbox(const std::string& procname) {
    ExecuteWithParams(procname, service_manager::kSeatbeltPolicyString_ppapi,
                      &content::SetupPPAPISandboxParameters);
  }

  void ExecuteInRendererSandbox(const std::string& procname) {
    ExecuteWithParams(procname, service_manager::kSeatbeltPolicyString_renderer,
                      &content::SetupCommonSandboxParameters);
  }

  void ExecuteInUtilitySandbox(const std::string& procname) {
    ExecuteWithParams(procname, service_manager::kSeatbeltPolicyString_utility,
                      [](sandbox::SeatbeltExecClient* client) -> void {
                        content::SetupUtilitySandboxParameters(
                            client, *base::CommandLine::ForCurrentProcess());
                      });
  }

  void ExecuteInAllSandboxTypes(const std::string& multiprocess_main,
                                base::RepeatingClosure after_each) {
    using ExecuteFuncT = void (SandboxMacTest::*)(const std::string&);
    constexpr ExecuteFuncT kExecuteFuncs[] = {
        &SandboxMacTest::ExecuteInAudioSandbox,
        &SandboxMacTest::ExecuteInCDMSandbox,
        &SandboxMacTest::ExecuteInGPUSandbox,
        &SandboxMacTest::ExecuteInNaClSandbox,
        &SandboxMacTest::ExecuteInPDFSandbox,
        &SandboxMacTest::ExecuteInPpapiSandbox,
        &SandboxMacTest::ExecuteInRendererSandbox,
        &SandboxMacTest::ExecuteInUtilitySandbox,
    };

    for (ExecuteFuncT execute_func : kExecuteFuncs) {
      (this->*execute_func)(multiprocess_main);
      if (!after_each.is_null()) {
        after_each.Run();
      }
    }
  }

  int pipe_{0};
  std::string extra_data_{};
};

void CheckCreateSeatbeltServer() {
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  const base::CommandLine::StringVector& argv = cl->argv();
  std::vector<char*> argv_cstr(argv.size());
  for (size_t i = 0; i < argv.size(); ++i) {
    argv_cstr[i] = const_cast<char*>(argv[i].c_str());
  }
  auto result = sandbox::SeatbeltExecServer::CreateFromArguments(
      argv_cstr[0], argv_cstr.size(), argv_cstr.data());

  CHECK(result.sandbox_required);
  CHECK(result.server);
  CHECK(result.server->InitializeSandbox());
}

std::string GetExtraDataValue() {
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  return cl->GetSwitchValueASCII(kExtraDataArg);
}

}  // namespace

MULTIPROCESS_TEST_MAIN(RendererWriteProcess) {
  CheckCreateSeatbeltServer();

  // Test that the renderer cannot write to the home directory.
  NSString* test_file = [NSHomeDirectory()
      stringByAppendingPathComponent:@"e539dd6f-6b38-4f6a-af2c-809a5ea96e1c"];
  int fd = HANDLE_EINTR(
      open(base::SysNSStringToUTF8(test_file).c_str(), O_CREAT | O_RDWR));
  CHECK(-1 == fd);
  CHECK_EQ(errno, EPERM);

  return 0;
}

TEST_F(SandboxMacTest, RendererCannotWriteHomeDir) {
  ExecuteInRendererSandbox("RendererWriteProcess");
}

MULTIPROCESS_TEST_MAIN(ClipboardAccessProcess) {
  CheckCreateSeatbeltServer();

  std::string pasteboard_name = GetExtraDataValue();
  CHECK(!pasteboard_name.empty());
  CHECK([NSPasteboard pasteboardWithName:base::SysUTF8ToNSString(
                                             pasteboard_name)] == nil);
  CHECK([NSPasteboard generalPasteboard] == nil);

  return 0;
}

TEST_F(SandboxMacTest, ClipboardAccess) {
  scoped_refptr<ui::UniquePasteboard> pb = new ui::UniquePasteboard;
  ASSERT_TRUE(pb->get());
  EXPECT_EQ([[pb->get() types] count], 0U);

  extra_data_ = base::SysNSStringToUTF8([pb->get() name]);

  ExecuteInAllSandboxTypes("ClipboardAccessProcess",
                           base::BindRepeating(
                               [](scoped_refptr<ui::UniquePasteboard> pb) {
                                 ASSERT_EQ([[pb->get() types] count], 0U);
                               },
                               pb));
}

MULTIPROCESS_TEST_MAIN(SSLProcess) {
  CheckCreateSeatbeltServer();

  crypto::EnsureOpenSSLInit();
  // Ensure that RAND_bytes is functional within the sandbox.
  uint8_t byte;
  CHECK(RAND_bytes(&byte, 1) == 1);
  return 0;
}

TEST_F(SandboxMacTest, SSLInitTest) {
  ExecuteInAllSandboxTypes("SSLProcess", base::RepeatingClosure());
}

MULTIPROCESS_TEST_MAIN(FontLoadingProcess) {
  // Create a shared memory handle to mimic what the browser process does.
  std::string font_file_path = GetExtraDataValue();
  CHECK(!font_file_path.empty());

  std::string font_data;
  CHECK(base::ReadFileToString(base::FilePath(font_file_path), &font_data));

  size_t font_data_length = font_data.length();
  CHECK(font_data_length > 0);

  auto font_shmem = mojo::SharedBufferHandle::Create(font_data_length);
  CHECK(font_shmem.is_valid());

  mojo::ScopedSharedBufferMapping mapping = font_shmem->Map(font_data_length);
  CHECK(mapping);

  memcpy(mapping.get(), font_data.c_str(), font_data_length);

  // Now init the sandbox.
  CheckCreateSeatbeltServer();

  mojo::ScopedSharedBufferHandle shmem_handle =
      font_shmem->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY);
  CHECK(shmem_handle.is_valid());

  base::ScopedCFTypeRef<CGFontRef> cgfont;
  CHECK(FontLoader::CGFontRefFromBuffer(
      std::move(shmem_handle), font_data_length, cgfont.InitializeInto()));
  CHECK(cgfont);

  base::ScopedCFTypeRef<CTFontRef> ctfont(
      CTFontCreateWithGraphicsFont(cgfont.get(), 16.0, NULL, NULL));
  CHECK(ctfont);

  // Do something with the font to make sure it's loaded.
  CGFloat cap_height = CTFontGetCapHeight(ctfont);
  CHECK(cap_height > 0.0);

  return 0;
}

TEST_F(SandboxMacTest, FontLoadingTest) {
  base::FilePath temp_file_path;
  FILE* temp_file = base::CreateAndOpenTemporaryFile(&temp_file_path);
  ASSERT_TRUE(temp_file);
  base::ScopedFILE temp_file_closer(temp_file);

  std::unique_ptr<FontLoader::ResultInternal> result =
      FontLoader::LoadFontForTesting(base::ASCIIToUTF16("Geeza Pro"), 16);
  ASSERT_TRUE(result);
  ASSERT_TRUE(result->font_data.is_valid());
  uint64_t font_data_size = result->font_data->GetSize();
  EXPECT_GT(font_data_size, 0U);
  EXPECT_GT(result->font_id, 0U);

  mojo::ScopedSharedBufferMapping mapping =
      result->font_data->Map(font_data_size);
  ASSERT_TRUE(mapping);

  base::WriteFileDescriptor(fileno(temp_file),
                            static_cast<const char*>(mapping.get()),
                            font_data_size);

  extra_data_ = temp_file_path.value();
  ExecuteInRendererSandbox("FontLoadingProcess");
  temp_file_closer.reset();
  ASSERT_TRUE(base::DeleteFile(temp_file_path, false));
}

}  // namespace content
