tor-browser

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

sid.cc (12043B)


      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/sid.h"
      6 
      7 #include <windows.h>
      8 
      9 #include <sddl.h>
     10 #include <stdint.h>
     11 #include <stdlib.h>
     12 
     13 #include <iterator>
     14 #include <map>
     15 #include <utility>
     16 
     17 #include "base/check.h"
     18 #include "base/no_destructor.h"
     19 #include "base/rand_util.h"
     20 #include "base/ranges/algorithm.h"
     21 #include "base/strings/string_util_win.h"
     22 #include "base/win/scoped_handle.h"
     23 #include "base/win/scoped_localalloc.h"
     24 #include "base/win/windows_version.h"
     25 #if defined(MOZ_SANDBOX)
     26 #include <winternl.h>
     27 #else
     28 #include "third_party/boringssl/src/include/openssl/crypto.h"
     29 #include "third_party/boringssl/src/include/openssl/sha.h"
     30 #endif
     31 
     32 namespace base::win {
     33 
     34 namespace {
     35 
     36 template <typename Iterator>
     37 Sid FromSubAuthorities(const SID_IDENTIFIER_AUTHORITY& identifier_authority,
     38                       size_t sub_authority_count,
     39                       Iterator sub_authorities) {
     40  DCHECK(sub_authority_count <= SID_MAX_SUB_AUTHORITIES);
     41  BYTE sid_buffer[SECURITY_MAX_SID_SIZE];
     42  SID* sid = reinterpret_cast<SID*>(sid_buffer);
     43  sid->Revision = SID_REVISION;
     44  sid->SubAuthorityCount = static_cast<UCHAR>(sub_authority_count);
     45  sid->IdentifierAuthority = identifier_authority;
     46  for (size_t index = 0; index < sub_authority_count; ++index) {
     47    sid->SubAuthority[index] = static_cast<DWORD>(*sub_authorities++);
     48  }
     49  DCHECK(::IsValidSid(sid));
     50  return *Sid::FromPSID(sid);
     51 }
     52 
     53 Sid FromSubAuthorities(const SID_IDENTIFIER_AUTHORITY& identifier_authority,
     54                       std::initializer_list<int32_t> sub_authorities) {
     55  return FromSubAuthorities(identifier_authority, sub_authorities.size(),
     56                            sub_authorities.begin());
     57 }
     58 
     59 Sid FromNtAuthority(std::initializer_list<int32_t> sub_authorities) {
     60  return FromSubAuthorities(SECURITY_NT_AUTHORITY, sub_authorities);
     61 }
     62 
     63 int32_t WellKnownCapabilityToRid(WellKnownCapability capability) {
     64  switch (capability) {
     65    case WellKnownCapability::kInternetClient:
     66      return SECURITY_CAPABILITY_INTERNET_CLIENT;
     67    case WellKnownCapability::kInternetClientServer:
     68      return SECURITY_CAPABILITY_INTERNET_CLIENT_SERVER;
     69    case WellKnownCapability::kPrivateNetworkClientServer:
     70      return SECURITY_CAPABILITY_PRIVATE_NETWORK_CLIENT_SERVER;
     71    case WellKnownCapability::kPicturesLibrary:
     72      return SECURITY_CAPABILITY_PICTURES_LIBRARY;
     73    case WellKnownCapability::kVideosLibrary:
     74      return SECURITY_CAPABILITY_VIDEOS_LIBRARY;
     75    case WellKnownCapability::kMusicLibrary:
     76      return SECURITY_CAPABILITY_MUSIC_LIBRARY;
     77    case WellKnownCapability::kDocumentsLibrary:
     78      return SECURITY_CAPABILITY_DOCUMENTS_LIBRARY;
     79    case WellKnownCapability::kEnterpriseAuthentication:
     80      return SECURITY_CAPABILITY_ENTERPRISE_AUTHENTICATION;
     81    case WellKnownCapability::kSharedUserCertificates:
     82      return SECURITY_CAPABILITY_SHARED_USER_CERTIFICATES;
     83    case WellKnownCapability::kRemovableStorage:
     84      return SECURITY_CAPABILITY_REMOVABLE_STORAGE;
     85    case WellKnownCapability::kAppointments:
     86      return SECURITY_CAPABILITY_APPOINTMENTS;
     87    case WellKnownCapability::kContacts:
     88      return SECURITY_CAPABILITY_CONTACTS;
     89  }
     90 }
     91 
     92 }  // namespace
     93 
     94 Sid::Sid(const void* sid, size_t length)
     95    : sid_(static_cast<const char*>(sid),
     96           static_cast<const char*>(sid) + length) {
     97  DCHECK(::IsValidSid(GetPSID()));
     98 }
     99 
    100 Sid Sid::FromKnownCapability(WellKnownCapability capability) {
    101  int32_t capability_rid = WellKnownCapabilityToRid(capability);
    102  return FromSubAuthorities(SECURITY_APP_PACKAGE_AUTHORITY,
    103                            {SECURITY_CAPABILITY_BASE_RID, capability_rid});
    104 }
    105 
    106 typedef NTSTATUS(WINAPI* RtlDeriveCapabilitySidsFromNameFunction)(
    107    PCUNICODE_STRING SourceString, PSID CapabilityGroupSid, PSID CapabilitySid);
    108 
    109 Sid Sid::FromNamedCapability(const std::wstring& capability_name) {
    110  static const base::NoDestructor<std::map<std::wstring, WellKnownCapability>>
    111      known_capabilities(
    112          {{L"INTERNETCLIENT", WellKnownCapability::kInternetClient},
    113           {L"INTERNETCLIENTSERVER",
    114            WellKnownCapability::kInternetClientServer},
    115           {L"PRIVATENETWORKCLIENTSERVER",
    116            WellKnownCapability::kPrivateNetworkClientServer},
    117           {L"PICTURESLIBRARY", WellKnownCapability::kPicturesLibrary},
    118           {L"VIDEOSLIBRARY", WellKnownCapability::kVideosLibrary},
    119           {L"MUSICLIBRARY", WellKnownCapability::kMusicLibrary},
    120           {L"DOCUMENTSLIBRARY", WellKnownCapability::kDocumentsLibrary},
    121           {L"ENTERPRISEAUTHENTICATION",
    122            WellKnownCapability::kEnterpriseAuthentication},
    123           {L"SHAREDUSERCERTIFICATES",
    124            WellKnownCapability::kSharedUserCertificates},
    125           {L"REMOVABLESTORAGE", WellKnownCapability::kRemovableStorage},
    126           {L"APPOINTMENTS", WellKnownCapability::kAppointments},
    127           {L"CONTACTS", WellKnownCapability::kContacts}});
    128 
    129  std::wstring cap_upper = base::ToUpperASCII(capability_name);
    130  auto known_cap = known_capabilities->find(cap_upper);
    131  if (known_cap != known_capabilities->end()) {
    132    return FromKnownCapability(known_cap->second);
    133  }
    134 
    135  HMODULE ntdll_handle = ::GetModuleHandleW(L"ntdll.dll");
    136  CHECK(ntdll_handle);
    137  auto derive_capability_sids =
    138      reinterpret_cast<RtlDeriveCapabilitySidsFromNameFunction>(
    139          ::GetProcAddress(ntdll_handle, "RtlDeriveCapabilitySidsFromName"));
    140  if (!derive_capability_sids) {
    141    return Sid();
    142  }
    143 
    144  UNICODE_STRING name = {};
    145  ::RtlInitUnicodeString(&name, capability_name.c_str());
    146  BYTE capability_sid[SECURITY_MAX_SID_SIZE];
    147  BYTE group_sid[SECURITY_MAX_SID_SIZE];
    148 
    149  NTSTATUS status = derive_capability_sids(&name, group_sid, capability_sid);
    150  if (!NT_SUCCESS(status)) {
    151    return Sid();
    152  }
    153 
    154  return Sid(capability_sid, ::GetLengthSid(capability_sid));
    155 }
    156 
    157 Sid Sid::FromKnownSid(WellKnownSid type) {
    158  switch (type) {
    159    case WellKnownSid::kNull:
    160      return FromSubAuthorities(SECURITY_NULL_SID_AUTHORITY,
    161                                {SECURITY_NULL_RID});
    162    case WellKnownSid::kWorld:
    163      return FromSubAuthorities(SECURITY_WORLD_SID_AUTHORITY,
    164                                {SECURITY_WORLD_RID});
    165    case WellKnownSid::kCreatorOwner:
    166      return FromSubAuthorities(SECURITY_CREATOR_SID_AUTHORITY,
    167                                {SECURITY_CREATOR_OWNER_RID});
    168    case WellKnownSid::kCreatorOwnerRights:
    169      return FromSubAuthorities(SECURITY_CREATOR_SID_AUTHORITY,
    170                                {SECURITY_CREATOR_OWNER_RIGHTS_RID});
    171    case WellKnownSid::kNetwork:
    172      return FromNtAuthority({SECURITY_NETWORK_RID});
    173    case WellKnownSid::kBatch:
    174      return FromNtAuthority({SECURITY_BATCH_RID});
    175    case WellKnownSid::kInteractive:
    176      return FromNtAuthority({SECURITY_INTERACTIVE_RID});
    177    case WellKnownSid::kService:
    178      return FromNtAuthority({SECURITY_SERVICE_RID});
    179    case WellKnownSid::kAnonymous:
    180      return FromNtAuthority({SECURITY_ANONYMOUS_LOGON_RID});
    181    case WellKnownSid::kSelf:
    182      return FromNtAuthority({SECURITY_PRINCIPAL_SELF_RID});
    183    case WellKnownSid::kAuthenticatedUser:
    184      return FromNtAuthority({SECURITY_AUTHENTICATED_USER_RID});
    185    case WellKnownSid::kRestricted:
    186      return FromNtAuthority({SECURITY_RESTRICTED_CODE_RID});
    187    case WellKnownSid::kWriteRestricted:
    188      return FromNtAuthority({SECURITY_WRITE_RESTRICTED_CODE_RID});
    189    case WellKnownSid::kLocalSystem:
    190      return FromNtAuthority({SECURITY_LOCAL_SYSTEM_RID});
    191    case WellKnownSid::kLocalService:
    192      return FromNtAuthority({SECURITY_LOCAL_SERVICE_RID});
    193    case WellKnownSid::kNetworkService:
    194      return FromNtAuthority({SECURITY_NETWORK_SERVICE_RID});
    195    case WellKnownSid::kBuiltinAdministrators:
    196      return FromNtAuthority(
    197          {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS});
    198    case WellKnownSid::kBuiltinUsers:
    199      return FromNtAuthority(
    200          {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS});
    201    case WellKnownSid::kBuiltinGuests:
    202      return FromNtAuthority(
    203          {SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS});
    204    case WellKnownSid::kUntrustedLabel:
    205      return FromIntegrityLevel(SECURITY_MANDATORY_UNTRUSTED_RID);
    206    case WellKnownSid::kLowLabel:
    207      return FromIntegrityLevel(SECURITY_MANDATORY_LOW_RID);
    208    case WellKnownSid::kMediumLabel:
    209      return FromIntegrityLevel(SECURITY_MANDATORY_MEDIUM_RID);
    210    case WellKnownSid::kHighLabel:
    211      return FromIntegrityLevel(SECURITY_MANDATORY_HIGH_RID);
    212    case WellKnownSid::kSystemLabel:
    213      return FromIntegrityLevel(SECURITY_MANDATORY_SYSTEM_RID);
    214    case WellKnownSid::kAllApplicationPackages:
    215      return FromSubAuthorities(SECURITY_APP_PACKAGE_AUTHORITY,
    216                                {SECURITY_APP_PACKAGE_BASE_RID,
    217                                 SECURITY_BUILTIN_PACKAGE_ANY_PACKAGE});
    218    case WellKnownSid::kAllRestrictedApplicationPackages:
    219      return FromSubAuthorities(
    220          SECURITY_APP_PACKAGE_AUTHORITY,
    221          {SECURITY_APP_PACKAGE_BASE_RID,
    222           SECURITY_BUILTIN_PACKAGE_ANY_RESTRICTED_PACKAGE});
    223  }
    224 }
    225 
    226 absl::optional<Sid> Sid::FromSddlString(const std::wstring& sddl_sid) {
    227  PSID psid = nullptr;
    228  if (!::ConvertStringSidToSid(sddl_sid.c_str(), &psid)) {
    229    return absl::nullopt;
    230  }
    231  auto psid_alloc = TakeLocalAlloc(psid);
    232  return FromPSID(psid_alloc.get());
    233 }
    234 
    235 absl::optional<Sid> Sid::FromPSID(PSID sid) {
    236  DCHECK(sid);
    237  if (!sid || !::IsValidSid(sid))
    238    return absl::nullopt;
    239  return Sid(sid, ::GetLengthSid(sid));
    240 }
    241 
    242 Sid Sid::GenerateRandomSid() {
    243  DWORD sub_authorities[4] = {};
    244  RandBytes(&sub_authorities, sizeof(sub_authorities));
    245  return FromSubAuthorities(SECURITY_NULL_SID_AUTHORITY,
    246                            std::size(sub_authorities), sub_authorities);
    247 }
    248 
    249 Sid Sid::FromIntegrityLevel(DWORD integrity_level) {
    250  return FromSubAuthorities(SECURITY_MANDATORY_LABEL_AUTHORITY, 1,
    251                            &integrity_level);
    252 }
    253 
    254 absl::optional<std::vector<Sid>> Sid::FromSddlStringVector(
    255    const std::vector<std::wstring>& sddl_sids) {
    256  std::vector<Sid> converted_sids;
    257  converted_sids.reserve(sddl_sids.size());
    258  for (const std::wstring& sddl_sid : sddl_sids) {
    259    absl::optional<Sid> sid = FromSddlString(sddl_sid);
    260    if (!sid)
    261      return absl::nullopt;
    262    converted_sids.push_back(std::move(*sid));
    263  }
    264  return converted_sids;
    265 }
    266 
    267 std::vector<Sid> Sid::FromNamedCapabilityVector(
    268    const std::vector<std::wstring>& capability_names) {
    269  std::vector<Sid> sids;
    270  ranges::transform(capability_names, std::back_inserter(sids),
    271                    FromNamedCapability);
    272  return sids;
    273 }
    274 
    275 std::vector<Sid> Sid::FromKnownCapabilityVector(
    276    const std::vector<WellKnownCapability>& capabilities) {
    277  std::vector<Sid> sids;
    278  ranges::transform(capabilities, std::back_inserter(sids),
    279                    FromKnownCapability);
    280  return sids;
    281 }
    282 
    283 std::vector<Sid> Sid::FromKnownSidVector(
    284    const std::vector<WellKnownSid>& known_sids) {
    285  std::vector<Sid> sids;
    286  ranges::transform(known_sids, std::back_inserter(sids), FromKnownSid);
    287  return sids;
    288 }
    289 
    290 Sid::Sid(WellKnownSid known_sid) : Sid(FromKnownSid(known_sid)) {}
    291 Sid::Sid(WellKnownCapability known_capability)
    292    : Sid(FromKnownCapability(known_capability)) {}
    293 Sid::Sid(Sid&& sid) = default;
    294 Sid& Sid::operator=(Sid&&) = default;
    295 Sid::~Sid() = default;
    296 
    297 PSID Sid::GetPSID() const {
    298  DCHECK(!sid_.empty());
    299  return const_cast<char*>(sid_.data());
    300 }
    301 
    302 absl::optional<std::wstring> Sid::ToSddlString() const {
    303  LPWSTR sid = nullptr;
    304  if (!::ConvertSidToStringSid(GetPSID(), &sid))
    305    return absl::nullopt;
    306  auto sid_ptr = TakeLocalAlloc(sid);
    307  return sid_ptr.get();
    308 }
    309 
    310 Sid Sid::Clone() const {
    311  return Sid(sid_.data(), sid_.size());
    312 }
    313 
    314 bool Sid::Equal(PSID sid) const {
    315  return !!::EqualSid(GetPSID(), sid);
    316 }
    317 
    318 bool Sid::operator==(const Sid& sid) const {
    319  return Equal(sid.GetPSID());
    320 }
    321 
    322 bool Sid::operator!=(const Sid& sid) const {
    323  return !(operator==(sid));
    324 }
    325 
    326 }  // namespace base::win