tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

security_util.cc (3443B)


      1 // Copyright 2021 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/win/security_util.h"
      6 
      7 #include <windows.h>
      8 #include <winternl.h>
      9 
     10 #include "base/check.h"
     11 #include "base/files/file_path.h"
     12 #include "base/logging.h"
     13 #include "base/threading/scoped_blocking_call.h"
     14 #include "base/win/access_control_list.h"
     15 #include "base/win/scoped_handle.h"
     16 #include "base/win/security_descriptor.h"
     17 #include "third_party/abseil-cpp/absl/types/optional.h"
     18 
     19 namespace base {
     20 namespace win {
     21 
     22 namespace {
     23 
     24 bool AddACEToPath(const FilePath& path,
     25                  const std::vector<Sid>& sids,
     26                  DWORD access_mask,
     27                  DWORD inheritance,
     28                  bool recursive,
     29                  SecurityAccessMode access_mode) {
     30  DCHECK(!path.empty());
     31  if (sids.empty()) {
     32    return true;
     33  }
     34  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
     35                                                base::BlockingType::MAY_BLOCK);
     36 
     37  absl::optional<SecurityDescriptor> sd =
     38      SecurityDescriptor::FromFile(path, DACL_SECURITY_INFORMATION);
     39  if (!sd) {
     40    return false;
     41  }
     42 
     43  std::vector<ExplicitAccessEntry> entries;
     44  for (const Sid& sid : sids) {
     45    entries.emplace_back(sid, access_mode, access_mask, inheritance);
     46  }
     47 
     48  if (!sd->SetDaclEntries(entries)) {
     49    return false;
     50  }
     51 
     52  if (recursive) {
     53    return sd->WriteToFile(path, DACL_SECURITY_INFORMATION);
     54  }
     55 
     56  ScopedHandle handle(::CreateFile(path.value().c_str(), WRITE_DAC, 0, nullptr,
     57                                   OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
     58                                   nullptr));
     59  if (!handle.is_valid()) {
     60    DPLOG(ERROR) << "Failed opening path \"" << path.value()
     61                 << "\" to write DACL";
     62    return false;
     63  }
     64  return sd->WriteToHandle(handle.get(), SecurityObjectType::kKernel,
     65                           DACL_SECURITY_INFORMATION);
     66 }
     67 
     68 }  // namespace
     69 
     70 bool GrantAccessToPath(const FilePath& path,
     71                       const std::vector<Sid>& sids,
     72                       DWORD access_mask,
     73                       DWORD inheritance,
     74                       bool recursive) {
     75  return AddACEToPath(path, sids, access_mask, inheritance, recursive,
     76                      SecurityAccessMode::kGrant);
     77 }
     78 
     79 bool DenyAccessToPath(const FilePath& path,
     80                      const std::vector<Sid>& sids,
     81                      DWORD access_mask,
     82                      DWORD inheritance,
     83                      bool recursive) {
     84  return AddACEToPath(path, sids, access_mask, inheritance, recursive,
     85                      SecurityAccessMode::kDeny);
     86 }
     87 
     88 std::vector<Sid> CloneSidVector(const std::vector<Sid>& sids) {
     89  std::vector<Sid> clone;
     90  clone.reserve(sids.size());
     91  for (const Sid& sid : sids) {
     92    clone.push_back(sid.Clone());
     93  }
     94  return clone;
     95 }
     96 
     97 void AppendSidVector(std::vector<Sid>& base_sids,
     98                     const std::vector<Sid>& append_sids) {
     99  for (const Sid& sid : append_sids) {
    100    base_sids.push_back(sid.Clone());
    101  }
    102 }
    103 
    104 absl::optional<ACCESS_MASK> GetGrantedAccess(HANDLE handle) {
    105  PUBLIC_OBJECT_BASIC_INFORMATION basic_info = {};
    106  if (!NT_SUCCESS(::NtQueryObject(handle, ObjectBasicInformation, &basic_info,
    107                                  sizeof(basic_info), nullptr))) {
    108    return absl::nullopt;
    109  }
    110  return basic_info.GrantedAccess;
    111 }
    112 
    113 }  // namespace win
    114 }  // namespace base