Merge pull request #59 from PasteBar/machine-id-changes

Machine id changes
This commit is contained in:
Sergey 2024-05-26 02:22:59 -04:00 committed by GitHub
commit d68fc19bae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 158 additions and 141 deletions

View File

@ -0,0 +1,5 @@
---
'pastebar-app': patch
---
Updated hardware uuid detection for Mac and Windows

74
src-tauri/Cargo.lock generated
View File

@ -792,6 +792,37 @@ dependencies = [
"yansi",
]
[[package]]
name = "com"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6"
dependencies = [
"com_macros",
]
[[package]]
name = "com_macros"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5"
dependencies = [
"com_macros_support",
"proc-macro2",
"syn 1.0.109",
]
[[package]]
name = "com_macros_support"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "combine"
version = "4.6.6"
@ -1562,6 +1593,21 @@ dependencies = [
"new_debug_unreachable",
]
[[package]]
name = "futures"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.30"
@ -1569,6 +1615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@ -1651,6 +1698,7 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
@ -2961,8 +3009,12 @@ dependencies = [
name = "mid"
version = "2.0.0"
dependencies = [
"chrono",
"hex",
"hmac-sha256",
"serde",
"serde_derive",
"wmi",
]
[[package]]
@ -6296,6 +6348,12 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
[[package]]
name = "widestring"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311"
[[package]]
name = "winapi"
version = "0.3.9"
@ -6781,6 +6839,22 @@ dependencies = [
"wayland-protocols-wlr",
]
[[package]]
name = "wmi"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dcdf3cb61b91b8b306b2a9ceb7cb2cbce776bc310ef5b7ef909b15c97f46a41"
dependencies = [
"chrono",
"com",
"futures",
"log",
"serde",
"thiserror",
"widestring",
"winapi",
]
[[package]]
name = "wry"
version = "0.24.7"

View File

@ -14,5 +14,9 @@ categories = ["authentication", "config", "accessibility"]
doctest = false
[dependencies]
wmi = "0.11.0"
serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
chrono = "0.4"
hex = "0.4.3"
hmac-sha256 = "1.1.7"

View File

@ -22,9 +22,9 @@ use windows::get_mid_result;
#[derive(Debug)]
pub struct MidData {
pub key: String,
pub result: Vec<String>,
pub hash: String,
pub key: String,
pub result: Vec<String>,
pub hash: String,
}
/// Gets unique platform metrics and returns a `Result`, which can be a MID hash (SHA-256) or a `MIDError`.
@ -47,10 +47,10 @@ pub struct MidData {
/// }
/// ```
pub fn get(key: &str) -> Result<String, MIDError> {
match data(key) {
Ok(mid) => Ok(mid.hash),
Err(err) => Err(err),
}
match data(key) {
Ok(mid) => Ok(mid.hash),
Err(err) => Err(err),
}
}
/// Returns MID key/result/hash as [`MidData`]
@ -65,25 +65,25 @@ pub fn get(key: &str) -> Result<String, MIDError> {
/// let mid_data = mid::data("mySecretKey").unwrap();
/// ```
pub fn data(key: &str) -> Result<MidData, MIDError> {
if key.is_empty() {
return Err(MIDError::EmptyMidKey);
}
match get_mid_result() {
Ok(mid) => {
let mid_result: Vec<String> = mid.split('|').map(|s| s.to_string()).collect();
let hmac_result = HMAC::mac(mid.as_bytes(), key.as_bytes());
let mid_hash = hex::encode(hmac_result);
Ok(MidData {
key: String::from(key),
result: mid_result,
hash: mid_hash,
})
}
Err(err) => Err(err),
if key.is_empty() {
return Err(MIDError::EmptyMidKey);
}
match get_mid_result() {
Ok(mid) => {
let mid_result: Vec<String> = mid.split('|').map(|s| s.to_string()).collect();
let hmac_result = HMAC::mac(mid.as_bytes(), key.as_bytes());
let mid_hash = hex::encode(hmac_result);
Ok(MidData {
key: String::from(key),
result: mid_result,
hash: mid_hash,
})
}
Err(err) => Err(err),
}
}
/// Output the MID key/result/hash to the console in `debug_assertions` mode.
@ -100,27 +100,27 @@ pub fn data(key: &str) -> Result<MidData, MIDError> {
/// mid::print("mySecretKey");
/// ```
pub fn print(key: &str) {
match data(key) {
Ok(mid) => {
debug!("MID.print[key]: {}", mid.key);
debug!("MID.print[result]: {:?}", mid.result);
debug!("MID.print[hash]: {}", mid.hash);
}
Err(err) => debug!("MID.print[error]: {}", err),
match data(key) {
Ok(mid) => {
debug!("MID.print[key]: {}", mid.key);
debug!("MID.print[result]: {:?}", mid.result);
debug!("MID.print[hash]: {}", mid.hash);
}
Err(err) => debug!("MID.print[error]: {}", err),
}
}
#[test]
fn test_mid_operations() {
match get("mykey") {
Ok(mid) => debug!("MID.get: {}", mid),
Err(err) => debug!("MID.get[error]: {}", err),
}
match get("mykey") {
Ok(mid) => debug!("MID.get: {}", mid),
Err(err) => debug!("MID.get[error]: {}", err),
}
match data("mykey") {
Ok(log_data) => debug!("MID.data: {:?}", log_data),
Err(err) => debug!("MID.data[error]: {}", err),
}
match data("mykey") {
Ok(log_data) => debug!("MID.data: {:?}", log_data),
Err(err) => debug!("MID.data[error]: {}", err),
}
print("mykey");
print("mykey");
}

View File

@ -6,64 +6,22 @@ use std::process::{Command, Stdio};
#[cfg(target_os = "macos")]
pub(crate) fn get_mid_result() -> Result<String, MIDError> {
let combined_output = Command::new("sh")
let output = Command::new("sh")
.arg("-c")
.arg(r#"system_profiler SPHardwareDataType SPSecureElementDataType"#)
.arg("system_profiler SPHardwareDataType | awk '/Hardware UUID/ { print $3; }'")
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn();
.output()
.map_err(|_| MIDError::ResultMidError)?;
match combined_output {
Ok(output) => {
let output = output.wait_with_output().unwrap();
if !output.status.success() {
return Err(MIDError::ResultMidError);
}
let system_profiler_output = String::from_utf8_lossy(&output.stdout);
if system_profiler_output.is_empty() {
return Err(MIDError::ResultMidError);
}
let targets = [
"Model Number",
"Serial Number",
"Hardware UUID",
"Provisioning UDID",
"Platform ID",
"SEID",
];
let combined_string = process_output(&system_profiler_output, &targets);
if combined_string.is_empty() {
return Err(MIDError::ResultMidError);
}
Ok(combined_string)
}
Err(_e) => Err(MIDError::ResultMidError),
}
}
#[cfg(target_os = "macos")]
fn process_output(output_str: &str, targets: &[&str]) -> String {
let mut result = Vec::new();
for target in targets {
for line in output_str.to_lowercase().lines() {
if line.contains(&target.to_lowercase()) {
let parts: Vec<&str> = line.split(":").collect();
if parts.len() == 2 {
let value = parts[1].trim().to_string();
if !value.is_empty() {
result.push(value);
}
}
}
}
if !output.status.success() {
return Err(MIDError::ResultMidError);
}
result.join("|")
let uuid = String::from_utf8_lossy(&output.stdout).trim().to_string();
if uuid.is_empty() {
return Err(MIDError::ResultMidError);
}
Ok(uuid)
}

View File

@ -1,56 +1,32 @@
#[cfg(target_os = "windows")]
use wmi::{COMLibrary, WMIConnection};
#[cfg(target_os = "windows")]
use serde::Deserialize;
#[cfg(target_os = "windows")]
use crate::errors::MIDError;
#[cfg(target_os = "windows")]
use std::os::windows::process::CommandExt;
#[derive(Deserialize)]
#[allow(non_snake_case)]
struct UUIDGeneric {
UUID: String,
}
#[cfg(target_os = "windows")]
use std::process::Command;
use std::process::Stdio;
pub fn get_mid_result() -> Result<String, MIDError> {
let com_connection = unsafe { COMLibrary::assume_initialized() };
let wmi_connection =
WMIConnection::new(com_connection.into()).map_err(|_| MIDError::ResultMidError)?;
const CREATE_NO_WINDOW: u32 = 0x08000000;
let computer_uuid_base: Vec<UUIDGeneric> = wmi_connection
.raw_query("SELECT UUID from Win32_ComputerSystemProduct WHERE UUID IS NOT NULL")
.map_err(|_| MIDError::ResultMidError)?;
#[cfg(target_os = "windows")]
pub(crate) fn get_mid_result() -> Result<String, MIDError> {
let combined_output = Command::new("powershell")
.args([
"-WindowStyle",
"Hidden",
"-command",
r#"
$csproduct = Get-WmiObject Win32_ComputerSystemProduct | Select-Object -ExpandProperty UUID;
$bios = Get-WmiObject Win32_BIOS | Select-Object -ExpandProperty SerialNumber;
$baseboard = Get-WmiObject Win32_BaseBoard | Select-Object -ExpandProperty SerialNumber;
$cpu = Get-WmiObject Win32_Processor | Select-Object -ExpandProperty ProcessorId;
"$csproduct|$bios|$baseboard|$cpu"
"#,
])
.creation_flags(CREATE_NO_WINDOW)
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn();
match combined_output {
Ok(output) => {
let output = output.wait_with_output().unwrap();
if !output.status.success() {
return Err(MIDError::ResultMidError);
}
let combined_output = String::from_utf8_lossy(&output.stdout);
if combined_output.is_empty() {
return Err(MIDError::ResultMidError);
}
println!("Device ID: {}", combined_output.trim());
Ok(
combined_output
.trim()
.trim_start_matches('|')
.trim_end_matches('|')
.to_lowercase(),
)
}
Err(_e) => Err(MIDError::ResultMidError),
if let Some(uuid_entry) = computer_uuid_base.first() {
Ok(uuid_entry.UUID.to_string())
} else {
Err(MIDError::ResultMidError)
}
}