// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/network_sandbox.h"

#include "base/dcheck_is_on.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/task/thread_pool.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/browser/network_sandbox_grant_result.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/network_service_util.h"
#include "content/public/common/content_client.h"
#include "sql/database.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>

#include "base/win/security_util.h"
#include "base/win/sid.h"
#include "content/browser/network_service_instance_impl.h"
#include "content/common/features.h"
#include "sandbox/policy/features.h"
#endif  // BUILDFLAG(IS_WIN)

namespace content {

namespace {

// A filename that represents that the data contained within `data_directory`
// has been migrated successfully and the data in `unsandboxed_data_path` is now
// invalid.
const base::FilePath::CharType kCheckpointFileName[] =
    FILE_PATH_LITERAL("NetworkDataMigrated");

// A platform specific set of parameters that is used when granting the sandbox
// access to the network context data.
struct SandboxParameters {
#if BUILDFLAG(IS_WIN)
  std::wstring lpac_capability_name;
#if DCHECK_IS_ON()
  bool sandbox_enabled;
#endif  // DCHECK_IS_ON()
#endif  // BUILDFLAG(IS_WIN)
};

// Deletes the old data for a data file called `filename` from `old_path`. If
// `file_path` refers to an SQL database then `is_sql` should be set to true,
// and the journal file will also be deleted.
//
// Returns SandboxGrantResult::kSuccess if the all delete operations completed
// successfully. Returns SandboxGrantResult::kFailedToDeleteData if a file could
// not be deleted.
SandboxGrantResult MaybeDeleteOldData(
    const base::FilePath& old_path,
    const std::optional<base::FilePath>& filename,
    bool is_sql) {
  // The path to the specific data file might not have been specified in the
  // network context params. In that case, nothing to delete.
  if (!filename.has_value())
    return SandboxGrantResult::kSuccess;

  // Check old path exists, and is a directory.
  DCHECK(base::DirectoryExists(old_path));

  base::FilePath old_file_path = old_path.Append(*filename);

  SandboxGrantResult last_error = SandboxGrantResult::kSuccess;
  // File might have already been deleted, or simply does not exist yet.
  if (base::PathExists(old_file_path)) {
    if (!base::DeleteFile(old_file_path)) {
      PLOG(ERROR) << "Failed to delete file " << old_file_path;
      // Continue on error.
      last_error = SandboxGrantResult::kFailedToDeleteOldData;
    }
  }

  if (!is_sql)
    return last_error;

  base::FilePath old_journal_path = sql::Database::JournalPath(old_file_path);
  // There might not be a journal file, or it's already been deleted.
  if (!base::PathExists(old_journal_path))
    return last_error;

  if (base::PathExists(old_journal_path)) {
    if (!base::DeleteFile(old_journal_path)) {
      PLOG(ERROR) << "Failed to delete file " << old_journal_path;
      // Continue on error.
      last_error = SandboxGrantResult::kFailedToDeleteOldData;
    }
  }

  return last_error;
}

// Copies data file called `filename` from `old_path` to `new_path` (which must
// both be directories). If `file_path` refers to an SQL database then `is_sql`
// should be set to true, and the journal file will also be migrated.
// Destination files will be overwritten if they exist already.
//
// Returns SandboxGrantResult::kSuccess if the operation completed successfully.
// Returns SandboxGrantResult::kFailedToCopyData if a file could not be copied.
SandboxGrantResult MaybeCopyData(const base::FilePath& old_path,
                                 const base::FilePath& new_path,
                                 const std::optional<base::FilePath>& filename,
                                 bool is_sql) {
  // The path to the specific data file might not have been specified in the
  // network context params. In that case, no files need to be moved.
  if (!filename.has_value())
    return SandboxGrantResult::kSuccess;

  // Check both paths exist, and are directories.
  DCHECK(base::DirectoryExists(old_path) && base::DirectoryExists(new_path));

  base::FilePath old_file_path = old_path.Append(*filename);
  base::FilePath new_file_path = new_path.Append(*filename);

  // Note that this code will overwrite the new file with the old file even if
  // it exists already.
  if (base::PathExists(old_file_path)) {
    // Delete file to make sure that inherited permissions are set on the new
    // file.
    base::DeleteFile(new_file_path);
    if (!base::CopyFile(old_file_path, new_file_path)) {
      PLOG(ERROR) << "Failed to copy file " << old_file_path << " to "
                  << new_file_path;
      // Do not attempt to copy journal file if copy of main database file
      // fails.
      return SandboxGrantResult::kFailedToCopyData;
    }
  }

  if (!is_sql)
    return SandboxGrantResult::kSuccess;

  base::FilePath old_journal_path = sql::Database::JournalPath(old_file_path);
  // There might not be a journal file, or it's already been moved.
  if (!base::PathExists(old_journal_path))
    return SandboxGrantResult::kSuccess;

  base::FilePath new_journal_path = sql::Database::JournalPath(new_file_path);

  // Delete file to make sure that inherited permissions are set on the new
  // file.
  base::DeleteFile(new_journal_path);

  if (!base::CopyFile(old_journal_path, new_journal_path)) {
    PLOG(ERROR) << "Failed to copy file " << old_journal_path << " to "
                << new_journal_path;
    return SandboxGrantResult::kFailedToCopyData;
  }

  return SandboxGrantResult::kSuccess;
}

// Deletes old data from `unsandboxed_data_path` if a migration operation has
// been successful.
SandboxGrantResult CleanUpOldData(
    network::mojom::NetworkContextParams* params) {
  // Never delete old data unless the checkpoint file exists.
  DCHECK(base::PathExists(
      params->file_paths->data_directory.path().Append(kCheckpointFileName)));

  SandboxGrantResult last_error = SandboxGrantResult::kSuccess;
  SandboxGrantResult result = MaybeDeleteOldData(
      *params->file_paths->unsandboxed_data_path,
      params->file_paths->cookie_database_name, /*is_sql=*/true);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;

  result = MaybeDeleteOldData(
      *params->file_paths->unsandboxed_data_path,
      params->file_paths->http_server_properties_file_name, /*is_sql=*/false);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;

  result = MaybeDeleteOldData(
      *params->file_paths->unsandboxed_data_path,
      params->file_paths->transport_security_persister_file_name,
      /*is_sql=*/false);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;

  result = MaybeDeleteOldData(
      *params->file_paths->unsandboxed_data_path,
      params->file_paths->reporting_and_nel_store_database_name,
      /*is_sql=*/true);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;

  result = MaybeDeleteOldData(*params->file_paths->unsandboxed_data_path,
                              params->file_paths->trust_token_database_name,
                              /*is_sql=*/true);
  if (result != SandboxGrantResult::kSuccess)
    last_error = result;
  return last_error;
}

// Grants the sandbox access to the specified `path`, which must be a directory
// that exists.  On Windows, the LPAC capability name should be supplied in the
// `sandbox_params` to specify the name of the LPAC capability to be applied to
// the path.  On platforms which support directory transfer, the directory is
// opened as a handle which is then sent to the NetworkService.
// Returns true if the sandbox was successfully granted access to the path.
bool MaybeGrantAccessToDataPath(const SandboxParameters& sandbox_params,
                                network::TransferableDirectory* directory) {
  // There is no need to set file permissions if the network service is running
  // in-process.
  if (IsInProcessNetworkService())
    return true;
  // Only do this on directories.
  if (!base::DirectoryExists(directory->path())) {
    return false;
  }

#if BUILDFLAG(IS_WIN)
  // On platforms that don't support the LPAC sandbox, do nothing.
  if (!sandbox::policy::features::IsNetworkSandboxSupported()) {
    return true;
  }
  DCHECK(!sandbox_params.lpac_capability_name.empty());
  auto ac_sids = base::win::Sid::FromNamedCapabilityVector(
      {sandbox_params.lpac_capability_name});

  static constexpr DWORD kAccessMask =
      GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
  static constexpr DWORD kInheritance =
      CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;

  // For cache dir only, ACL the parent above the "Cache_Data" directory to
  // ensure that rename/delete operations can take place correctly.
  base::FilePath directory_to_acl = directory->path();

  if (directory_to_acl.BaseName() == base::FilePath(kCacheDataDirectoryName)) {
    directory_to_acl = directory_to_acl.DirName();
  }
  // If LPAC capability already has access to the directory then avoid
  // granting access again. This is a performance optimization.
  if (HasAccessToPath(directory_to_acl, ac_sids, kAccessMask, kInheritance)) {
    return true;
  }

  // Grant recursive access to directory. This also means new files in the
  // directory will inherit the ACE.
  return base::win::GrantAccessToPath(directory_to_acl, ac_sids, kAccessMask,
                                      kInheritance, /*recursive=*/true);
#else
  if (directory->IsOpenForTransferRequired()) {
    directory->OpenForTransfer();
    return true;
  }

  return true;
#endif  // BUILDFLAG(IS_WIN)
}

// See the description in the header file.
//
// This process has a few stages:
// 1. Create and grant the sandbox access to the cache dir.
// 2. If `data_directory` is not specified then the caller is using in-memory
// storage and so there's nothing to do. END.
// 3. If `unsandboxed_data_path` is not specified then the caller is not aware
// of the sandbox or migration, and the steps terminate here with
// `data_directory` used by the network context and END.
// 4. If migration has already taken place, regardless of whether it's requested
// this time, grant the sandbox access to the `data_directory` (since this needs
// to be done every time), and terminate here with `data_directory` being used.
// END.
// 5. If migration is not requested, then terminate here with
// `unsandboxed_data_path` being used. END.
// 6. At this point, migration has been requested and hasn't already happened,
// so begin a migration attempt. If any of these steps fail, then bail out, and
// `unsandboxed_data_path` is used.
// 7. Grant the sandbox access to the `data_directory` (this is done before
// copying the files to use inherited ACLs when copying files on Windows).
// 8. Copy all the data files one by one from the `unsandboxed_data_path` to the
// `data_directory`.
// 9. Once all the files have been copied, lay down the Checkpoint file in the
// `data_directory`.
// 10. Delete all the original files (if they exist) from
// `unsandboxed_data_path`.
SandboxGrantResult MaybeGrantSandboxAccessToNetworkContextData(
    const SandboxParameters& sandbox_params,
    network::mojom::NetworkContextParams* params) {
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
#if BUILDFLAG(IS_WIN)
#if DCHECK_IS_ON()
  params->win_permissions_set = true;
#endif
#endif  // BUILDFLAG(IS_WIN)

  // No file paths (e.g. in-memory context) so nothing to do.
  if (!params->file_paths) {
    return SandboxGrantResult::kDidNotAttemptToGrantSandboxAccess;
  }

  // HTTP cache path is special, and not under `data_directory` so must also
  // be granted access. Continue attempting to grant access to the other files
  // if this part fails.
  if (params->file_paths->http_cache_directory && params->http_cache_enabled) {
    // The path must exist for the cache ACL to be set. Create if needed.
    if (base::CreateDirectory(
            params->file_paths->http_cache_directory->path())) {
      // Note, this code always grants access to the cache directory even when
      // the sandbox is not enabled. This is a optimization (on Windows)
      // because by setting the ACL on the directory earlier rather than
      // later, it ensures that any new files created by the cache subsystem
      // get the inherited ACE rather than having to set them manually later.
      SCOPED_UMA_HISTOGRAM_TIMER("NetworkService.TimeToGrantCacheAccess");
      TRACE_EVENT("startup", "NetworkSandbox.MaybeGrantAccessToDataPath");
      if (!MaybeGrantAccessToDataPath(
              sandbox_params, &*params->file_paths->http_cache_directory)) {
        PLOG(ERROR) << "Failed to grant sandbox access to cache directory "
                    << params->file_paths->http_cache_directory->path();
      }
    }
  }
  if (params->file_paths->shared_dictionary_directory &&
      params->shared_dictionary_enabled) {
    SCOPED_UMA_HISTOGRAM_TIMER(
        "NetworkService.TimeToGrantSharedDictionaryAccess");
    // The path must exist for the cache ACL to be set. Create if needed.
    if (base::CreateDirectory(
            params->file_paths->shared_dictionary_directory->path())) {
      if (!MaybeGrantAccessToDataPath(
              sandbox_params,
              &*params->file_paths->shared_dictionary_directory)) {
        PLOG(ERROR) << "Failed to grant sandbox access to shared dictionary "
                       "directory "
                    << params->file_paths->shared_dictionary_directory->path();
      }
    }
  }

  // No data directory, so rest of the files and databases are in memory.
  // Nothing to do.
  if (params->file_paths->data_directory.path().empty()) {
    return SandboxGrantResult::kDidNotAttemptToGrantSandboxAccess;
  }

  if (!params->file_paths->unsandboxed_data_path.has_value()) {
#if BUILDFLAG(IS_WIN) && DCHECK_IS_ON()
    // On Windows, if network sandbox is enabled then there a migration must
    // happen, so a `unsandboxed_data_path` must be specified.
    DCHECK(!sandbox_params.sandbox_enabled);
#endif
    // Trigger migration should never be requested if `unsandboxed_data_path` is
    // not set.
    DCHECK(!params->file_paths->trigger_migration);
    // Nothing to do here if `unsandboxed_data_path` is not specified.
    return SandboxGrantResult::kDidNotAttemptToGrantSandboxAccess;
  }

  // If these paths are ever the same then this is a mistake, as the file
  // permissions will be applied to the top level path which could contain other
  // data that should not be accessible by the network sandbox.
  DCHECK_NE(params->file_paths->data_directory.path(),
            *params->file_paths->unsandboxed_data_path);

  // Four cases need to be handled here.
  //
  // 1. No Checkpoint file, and `trigger_migration` is false: Data is still in
  // `unsandboxed_data_path` and sandbox does not need to be granted access. No
  // migration happens.
  // 2. No Checkpoint file, and `trigger_migration` is true: Data is in
  // `unsandboxed_data_path` and needs to be migrated to `data_directory`, and
  // the sandbox needs to be granted access to `data_directory`.
  // 3. Checkpoint file, and `trigger_migration` is false: Data is in
  // `data_directory` (already migrated) and sandbox needs to be granted access
  // to `data_directory`.
  // 4. Checkpoint file, and `trigger_migration` is true: Data is in
  // `data_directory` (already migrated) and sandbox needs to be granted access
  // to `data_directory`. This is the same as above and `trigger_migration`
  // changes nothing, as it's already happened.
  base::FilePath checkpoint_filename =
      params->file_paths->data_directory.path().Append(kCheckpointFileName);
  bool migration_already_happened = base::PathExists(checkpoint_filename);

  // Case 1. above where nothing is done.
  if (!params->file_paths->trigger_migration && !migration_already_happened) {
#if BUILDFLAG(IS_WIN) && DCHECK_IS_ON()
    // On Windows, if network sandbox is enabled then there a migration must
    // happen, so `trigger_migration` must be true, or a migration must have
    // already happened.
    DCHECK(!sandbox_params.sandbox_enabled);
#endif
    return SandboxGrantResult::kNoMigrationRequested;
  }

  // Create the `data_directory` if necessary so access can be granted to it.
  // Note that if a migration has already happened then this does nothing, as
  // the directory already exists.
  if (!base::CreateDirectory(params->file_paths->data_directory.path())) {
    PLOG(ERROR) << "Failed to create network context data directory "
                << params->file_paths->data_directory.path();
    // This is a fatal error, if the `data_directory` does not exist then
    // migration cannot be attempted. In this case the network context will
    // operate using `unsandboxed_data_path` and the migration attempt will be
    // retried the next time the same network context is created with
    // `trigger_migration` set.
    return SandboxGrantResult::kFailedToCreateDataDirectory;
  }

  {
    SCOPED_UMA_HISTOGRAM_TIMER("NetworkService.TimeToGrantDataAccess");
    // This must be done on each load of the network context for two
    // platform-specific reasons:
    //
    // 1. On Windows Chrome, the LPAC SID for each channel is different so it is
    // possible that this data might be read by a different channel and we need
    // to explicitly support that.
    // 2. Other platforms such as macOS and Linux need to grant access each time
    // as they do not rely on filesystem permissions, but runtime sandbox broker
    // permissions.
    if (!MaybeGrantAccessToDataPath(sandbox_params,
                                    &params->file_paths->data_directory)) {
      PLOG(ERROR)
          << "Failed to grant sandbox access to network context data directory "
          << params->file_paths->data_directory.path();
      // If migration has already happened there isn't much that can be done
      // about this, the data has already moved, but the sandbox might not have
      // access.
      if (migration_already_happened)
        return SandboxGrantResult::kMigrationAlreadySucceededWithNoAccess;
      // If migration hasn't happened yet, then fail here, and do not attempt to
      // migrate or proceed further. Better to just leave the data where it is.
      // In this case `unsandboxed_data_path` will continue to be used and the
      // migration attempt will be retried the next time the same network
      // context is created with `trigger_migration` set.
      return SandboxGrantResult::kFailedToGrantSandboxAccessToData;
    }
  }  // SCOPED_UMA_HISTOGRAM_TIMER

  // This covers cases 3. and 4. where a migration has already happened.
  if (migration_already_happened) {
    // Migration succeeded in an earlier attempt and `data_directory` is valid,
    // but clean up any old data that might have failed to delete in the last
    // attempt.
    SandboxGrantResult cleanup_result = CleanUpOldData(params);
    if (cleanup_result != SandboxGrantResult::kSuccess)
      return cleanup_result;
    return SandboxGrantResult::kMigrationAlreadySucceeded;
  }

  SandboxGrantResult result;
  // Reaching here means case 2. where a migration hasn't yet happened, but it's
  // been requested.
  //
  // Now attempt to migrate the data from the `unsandboxed_data_path` to the new
  // `data_directory`. This code can be removed from content once migration has
  // taken place.
  //
  // This code has a three stage process.
  // 1. An attempt is made to copy all the data files from the old location to
  // the new location.
  // 2. A checkpoint file ("NetworkData") is then placed in the new directory to
  // mark that the data there is valid and should be used.
  // 3. The old files are deleted.
  //
  // A failure half way through stage 1 or 2 will mean that the old data should
  // be used instead of the new data. A failure to delete the files will cause
  // a retry attempt next time the same network context is created.
  {
    // Stage 1: Copy the data files. Note: This might copy files over the top of
    // existing files if it was partially successful in an earlier attempt.
    SCOPED_UMA_HISTOGRAM_TIMER("NetworkService.TimeToMigrateData");
    result = MaybeCopyData(*params->file_paths->unsandboxed_data_path,
                           params->file_paths->data_directory.path(),
                           params->file_paths->cookie_database_name,
                           /*is_sql=*/true);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    result = MaybeCopyData(*params->file_paths->unsandboxed_data_path,
                           params->file_paths->data_directory.path(),
                           params->file_paths->http_server_properties_file_name,
                           /*is_sql=*/false);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    result = MaybeCopyData(
        *params->file_paths->unsandboxed_data_path,
        params->file_paths->data_directory.path(),
        params->file_paths->transport_security_persister_file_name,
        /*is_sql=*/false);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    result =
        MaybeCopyData(*params->file_paths->unsandboxed_data_path,
                      params->file_paths->data_directory.path(),
                      params->file_paths->reporting_and_nel_store_database_name,
                      /*is_sql=*/true);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    result = MaybeCopyData(*params->file_paths->unsandboxed_data_path,
                           params->file_paths->data_directory.path(),
                           params->file_paths->trust_token_database_name,
                           /*is_sql=*/true);
    if (result != SandboxGrantResult::kSuccess)
      return result;

    // Files all copied successfully. Can now proceed to Stage 2 and write the
    // checkpoint filename.
    base::File checkpoint_file(
        checkpoint_filename,
        base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
    if (!checkpoint_file.IsValid())
      return SandboxGrantResult::kFailedToCreateCheckpointFile;
  }  // SCOPED_UMA_HISTOGRAM_TIMER

  // Double check the checkpoint file is there. This should never happen.
  if (!base::PathExists(checkpoint_filename))
    return SandboxGrantResult::kFailedToCreateCheckpointFile;

  // Success, proceed to Stage 3 and clean up old files.
  SandboxGrantResult cleanup_result = CleanUpOldData(params);
  if (cleanup_result != SandboxGrantResult::kSuccess)
    return cleanup_result;

  return SandboxGrantResult::kSuccess;
}

}  // namespace

void GrantSandboxAccessOnThreadPool(
    network::mojom::NetworkContextParamsPtr params,
    base::OnceCallback<void(network::mojom::NetworkContextParamsPtr,
                            SandboxGrantResult)> result_callback) {
  SandboxParameters sandbox_params = {};
#if BUILDFLAG(IS_WIN)
  sandbox_params.lpac_capability_name =
      GetContentClient()->browser()->GetLPACCapabilityNameForNetworkService();
#if DCHECK_IS_ON()
  sandbox_params.sandbox_enabled =
      GetContentClient()->browser()->ShouldSandboxNetworkService();
#endif  // DCHECK_IS_ON()
#endif  // BUILDFLAG(IS_WIN)
  base::OnceCallback<SandboxGrantResult()> worker_task =
      base::BindOnce(&MaybeGrantSandboxAccessToNetworkContextData,
                     sandbox_params, params.get());
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
      std::move(worker_task),
      base::BindOnce(std::move(result_callback), std::move(params)));
}

}  // namespace content
