chromium/sandbox/win/src/app_container_base.h

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

#ifndef SANDBOX_WIN_SRC_APP_CONTAINER_BASE_H_
#define SANDBOX_WIN_SRC_APP_CONTAINER_BASE_H_

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/win/access_token.h"
#include "base/win/security_descriptor.h"
#include "base/win/sid.h"
#include "base/win/windows_types.h"
#include "sandbox/win/src/app_container.h"
#include "sandbox/win/src/sandbox_types.h"

namespace sandbox {

class AppContainerBase final : public AppContainer {
 public:
  AppContainerBase(const wchar_t* package_name,
                   base::win::Sid package_sid,
                   AppContainerType type);
  AppContainerBase(const AppContainerBase&) = delete;
  AppContainerBase& operator=(const AppContainerBase&) = delete;
  ~AppContainerBase();

  bool AccessCheck(const wchar_t* object_name,
                   base::win::SecurityObjectType object_type,
                   DWORD desired_access,
                   DWORD* granted_access,
                   BOOL* access_status) override;
  void AddCapability(const wchar_t* capability_name) override;
  void AddCapability(base::win::WellKnownCapability capability) override;
  bool AddCapabilitySddl(const wchar_t* sddl_sid) override;
  void AddImpersonationCapability(const wchar_t* capability_name) override;
  void AddImpersonationCapability(
      base::win::WellKnownCapability capability) override;
  bool AddImpersonationCapabilitySddl(const wchar_t* sddl_sid) override;
  void SetEnableLowPrivilegeAppContainer(bool enable) override;
  bool GetEnableLowPrivilegeAppContainer() override;
  AppContainerType GetAppContainerType() override;
  const std::vector<base::win::Sid>& GetCapabilities() override;
  const std::vector<base::win::Sid>& GetImpersonationCapabilities() override;
  std::unique_ptr<SecurityCapabilities> GetSecurityCapabilities() override;

  // Get the package SID for this AC.
  const base::win::Sid& GetPackageSid() const;

  // Get the package name for this AC.
  const wchar_t* GetPackageName() const;

  // Creates a new AppContainer object. This will create a new profile
  // if it doesn't already exist. The profile must be deleted manually using
  // the Delete method if it's no longer required.
  static std::unique_ptr<AppContainerBase> CreateProfile(
      const wchar_t* package_name,
      const wchar_t* display_name,
      const wchar_t* description);

  // Creates a new AppContainer object. This will create a new profile
  // if it doesn't already exist. The profile must be deleted manually using
  // the `DeleteNoFirewall` method if it's no longer required. This differs from
  // the `CreateProfile` method in that it doesn't register the profile with the
  // system firewall which might remove contention and deadlock issues.
  static std::unique_ptr<AppContainerBase> CreateProfileNoFirewall(
      const wchar_t* package_name,
      const wchar_t* display_name);

  // Opens a derived AppContainer object. No checks will be made on
  // whether the package exists or not.
  static std::unique_ptr<AppContainerBase> Open(const wchar_t* package_name);

  // Creates a new Lowbox object. Need to followup with a call to build lowbox
  // token
  static std::unique_ptr<AppContainerBase> CreateLowbox(const wchar_t* sid);

  // Checks if a profile with a given name exists.
  static bool ProfileExists(const wchar_t* package_name);

  // Delete a profile based on name. Returns true if successful, or if the
  // package doesn't already exist.
  static bool Delete(const wchar_t* package_name);

  // Delete a profile based on name. Returns true if successful, or if the
  // package doesn't already exist. This differs from the `DeleteProfile`
  // method in that it doesn't delete the profile with the system firewall
  // which might remove contention and deadlock issues.
  static bool DeleteNoFirewall(const wchar_t* package_name);

  // Build an impersontion token from an existing token.
  // `token` specify the base token to create the new token from. Must have
  // TOKEN_DUPLICATE access. The token is created with the impersonation
  // capabilities list.
  std::optional<base::win::AccessToken> BuildImpersonationToken(
      const base::win::AccessToken& token);

  // Build a primary token from an existing token.
  // `token` specify the base token to create the new token from. Must have
  // TOKEN_DUPLICATE access. The token is created with the normal capabilities
  // list.
  std::optional<base::win::AccessToken> BuildPrimaryToken(
      const base::win::AccessToken& token);

 private:
  bool AddCapability(const std::optional<base::win::Sid>& capability_sid,
                     bool impersonation_only);

  std::wstring package_name_;
  base::win::Sid package_sid_;
  bool enable_low_privilege_app_container_;
  std::vector<base::win::Sid> capabilities_;
  std::vector<base::win::Sid> impersonation_capabilities_;
  AppContainerType type_;
};

}  // namespace sandbox

#endif  // SANDBOX_WIN_SRC_APP_CONTAINER_BASE_H_