tor-browser

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

machine_id_win.cc (4095B)


      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      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 <windows.h>
      6 #include <sddl.h>  // For ConvertSidToStringSidW.
      7 
      8 #include <memory>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "mozilla/ArrayUtils.h"
     13 
     14 #include "rlz/lib/assert.h"
     15 
     16 namespace rlz_lib {
     17 
     18 namespace {
     19 
     20 bool GetSystemVolumeSerialNumber(int* number) {
     21  if (!number)
     22    return false;
     23 
     24  *number = 0;
     25 
     26  // Find the system root path (e.g: C:\).
     27  wchar_t system_path[MAX_PATH + 1];
     28  if (!GetSystemDirectoryW(system_path, MAX_PATH))
     29    return false;
     30 
     31  wchar_t* first_slash = wcspbrk(system_path, L"\\/");
     32  if (first_slash != NULL)
     33    *(first_slash + 1) = 0;
     34 
     35  DWORD number_local = 0;
     36  if (!GetVolumeInformationW(system_path, NULL, 0, &number_local, NULL, NULL,
     37                             NULL, 0))
     38    return false;
     39 
     40  *number = (int)number_local;
     41  return true;
     42 }
     43 
     44 bool GetComputerSid(const wchar_t* account_name, SID* sid, DWORD sid_size) {
     45  static const DWORD kStartDomainLength = 128;  // reasonable to start with
     46 
     47  std::unique_ptr<wchar_t[]> domain_buffer(new wchar_t[kStartDomainLength]);
     48  DWORD domain_size = kStartDomainLength;
     49  DWORD sid_dword_size = sid_size;
     50  SID_NAME_USE sid_name_use;
     51 
     52  BOOL success = ::LookupAccountNameW(NULL, account_name, sid,
     53                                      &sid_dword_size, domain_buffer.get(),
     54                                      &domain_size, &sid_name_use);
     55  if (!success && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
     56    // We could have gotten the insufficient buffer error because
     57    // one or both of sid and szDomain was too small. Check for that
     58    // here.
     59    if (sid_dword_size > sid_size)
     60      return false;
     61 
     62    if (domain_size > kStartDomainLength)
     63      domain_buffer.reset(new wchar_t[domain_size]);
     64 
     65    success = ::LookupAccountNameW(NULL, account_name, sid, &sid_dword_size,
     66                                   domain_buffer.get(), &domain_size,
     67                                   &sid_name_use);
     68  }
     69 
     70  return success != FALSE;
     71 }
     72 
     73 std::vector<uint8_t> ConvertSidToBytes(SID* sid) {
     74  std::wstring sid_string;
     75 #if _WIN32_WINNT >= 0x500
     76  wchar_t* sid_buffer = NULL;
     77  if (ConvertSidToStringSidW(sid, &sid_buffer)) {
     78    sid_string = sid_buffer;
     79    LocalFree(sid_buffer);
     80  }
     81 #else
     82  SID_IDENTIFIER_AUTHORITY* sia = ::GetSidIdentifierAuthority(sid);
     83 
     84  if(sia->Value[0] || sia->Value[1]) {
     85    base::SStringPrintf(
     86        &sid_string, L"S-%d-0x%02hx%02hx%02hx%02hx%02hx%02hx",
     87        SID_REVISION, (USHORT)sia->Value[0], (USHORT)sia->Value[1],
     88        (USHORT)sia->Value[2], (USHORT)sia->Value[3], (USHORT)sia->Value[4],
     89        (USHORT)sia->Value[5]);
     90  } else {
     91    ULONG authority = 0;
     92    for (int i = 2; i < 6; ++i) {
     93      authority <<= 8;
     94      authority |= sia->Value[i];
     95    }
     96    base::SStringPrintf(&sid_string, L"S-%d-%lu", SID_REVISION, authority);
     97  }
     98 
     99  int sub_auth_count = *::GetSidSubAuthorityCount(sid);
    100  for(int i = 0; i < sub_auth_count; ++i)
    101    base::StringAppendF(&sid_string, L"-%lu", *::GetSidSubAuthority(sid, i));
    102 #endif
    103 
    104  // Get the contents of the string as a bunch of bytes.
    105  return std::vector<uint8_t>(
    106           reinterpret_cast<uint8_t*>(&sid_string[0]),
    107           reinterpret_cast<uint8_t*>(&sid_string[sid_string.size()]));
    108 }
    109 
    110 }  // namespace
    111 
    112 bool GetRawMachineId(std::vector<uint8_t>* sid_bytes, int* volume_id) {
    113  // Calculate the Windows SID.
    114 
    115  wchar_t computer_name[MAX_COMPUTERNAME_LENGTH + 1] = {0};
    116  DWORD size = std::size(computer_name);
    117 
    118  if (GetComputerNameW(computer_name, &size)) {
    119    char sid_buffer[SECURITY_MAX_SID_SIZE];
    120    SID* sid = reinterpret_cast<SID*>(sid_buffer);
    121    if (GetComputerSid(computer_name, sid, SECURITY_MAX_SID_SIZE)) {
    122      *sid_bytes = ConvertSidToBytes(sid);
    123    }
    124  }
    125 
    126  // Get the system drive volume serial number.
    127  *volume_id = 0;
    128  if (!GetSystemVolumeSerialNumber(volume_id)) {
    129    ASSERT_STRING("GetMachineId: Failed to retrieve volume serial number");
    130    *volume_id = 0;
    131  }
    132 
    133  return true;
    134 }
    135 
    136 }  // namespace rlz_lib