| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/enterprise/signals/device_info_fetcher_mac.h" |
| |
| #import <Foundation/Foundation.h> |
| #include <MacTypes.h> |
| #include <dlfcn.h> |
| #include <ifaddrs.h> |
| #include <net/if.h> |
| #include <net/if_dl.h> |
| |
| #include "base/files/file_util.h" |
| #include "base/mac/mac_util.h" |
| #include "base/process/launch.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/system/sys_info.h" |
| #include "net/base/network_interfaces.h" |
| |
| namespace enterprise_signals { |
| |
| namespace { |
| |
| std::string GetDeviceModel() { |
| return base::SysInfo::HardwareModelName(); |
| } |
| |
| std::string GetOsVersion() { |
| return base::SysInfo::OperatingSystemVersion(); |
| } |
| |
| std::string GetDeviceHostName() { |
| return net::GetHostName(); |
| } |
| |
| std::string GetSerialNumber() { |
| return base::mac::GetPlatformSerialNumber(); |
| } |
| |
| SettingValue GetScreenlockSecured() { |
| // Use the login private framework since there is no official way to |
| // obtain the screen lock value (at least for now). |
| using SACScreenLockEnabledType = Boolean (*)(); |
| static const auto SACScreenLockEnabled = []() -> SACScreenLockEnabledType { |
| void* const login_framework = dlopen( |
| "/System/Library/PrivateFrameworks/login.framework/Versions/A/login", |
| RTLD_LAZY | RTLD_LOCAL); |
| if (!login_framework) { |
| return nullptr; |
| } |
| return reinterpret_cast<SACScreenLockEnabledType>( |
| dlsym(login_framework, "SACScreenLockEnabled")); |
| }(); |
| |
| if (!SACScreenLockEnabled) { |
| return SettingValue::UNKNOWN; |
| } |
| |
| return SACScreenLockEnabled() ? SettingValue::ENABLED |
| : SettingValue::DISABLED; |
| } |
| |
| SettingValue GetDiskEncrypted() { |
| base::FilePath fdesetup_path("/usr/bin/fdesetup"); |
| if (!base::PathExists(fdesetup_path)) |
| return SettingValue::UNKNOWN; |
| |
| base::CommandLine command(fdesetup_path); |
| command.AppendArg("status"); |
| std::string output; |
| if (!base::GetAppOutput(command, &output)) |
| return SettingValue::UNKNOWN; |
| |
| if (output.find("FileVault is On") != std::string::npos) |
| return SettingValue::ENABLED; |
| if (output.find("FileVault is Off") != std::string::npos) |
| return SettingValue::DISABLED; |
| |
| return SettingValue::UNKNOWN; |
| } |
| |
| std::vector<std::string> GetMacAddresses() { |
| std::vector<std::string> result; |
| struct ifaddrs* ifa = nullptr; |
| |
| if (getifaddrs(&ifa) != 0) |
| return result; |
| |
| struct ifaddrs* interface = ifa; |
| for (; interface != nullptr; interface = interface->ifa_next) { |
| if (interface->ifa_addr == nullptr || |
| interface->ifa_addr->sa_family != AF_LINK) { |
| continue; |
| } |
| struct sockaddr_dl* sdl = |
| reinterpret_cast<struct sockaddr_dl*>(interface->ifa_addr); |
| if (!sdl || sdl->sdl_alen != 6) |
| continue; |
| char* link_address = static_cast<char*>(LLADDR(sdl)); |
| result.push_back(base::StringPrintf( |
| "%02x:%02x:%02x:%02x:%02x:%02x", link_address[0] & 0xff, |
| link_address[1] & 0xff, link_address[2] & 0xff, link_address[3] & 0xff, |
| link_address[4] & 0xff, link_address[5] & 0xff)); |
| } |
| freeifaddrs(ifa); |
| return result; |
| } |
| |
| } // namespace |
| |
| DeviceInfoFetcherMac::DeviceInfoFetcherMac() = default; |
| |
| DeviceInfoFetcherMac::~DeviceInfoFetcherMac() = default; |
| |
| DeviceInfo DeviceInfoFetcherMac::Fetch() { |
| DeviceInfo device_info; |
| device_info.os_name = "macOS"; |
| device_info.os_version = GetOsVersion(); |
| device_info.device_host_name = GetDeviceHostName(); |
| device_info.device_model = GetDeviceModel(); |
| device_info.serial_number = GetSerialNumber(); |
| device_info.screen_lock_secured = GetScreenlockSecured(); |
| device_info.disk_encrypted = GetDiskEncrypted(); |
| device_info.mac_addresses = GetMacAddresses(); |
| return device_info; |
| } |
| |
| } // namespace enterprise_signals |