From 0c6ce108a47e05006e276b0bfddddb7af6b39df9 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Wed, 20 May 2026 11:34:39 +0200 Subject: [PATCH 1/3] report number of days --- src-tauri/proto | 2 +- src-tauri/src/enterprise/inspector/mod.rs | 23 ++++++++++++---- .../src/enterprise/inspector/tests/windows.rs | 6 ++--- src-tauri/src/enterprise/inspector/windows.rs | 26 +++++++------------ 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src-tauri/proto b/src-tauri/proto index 84a2bf71..a01cdc15 160000 --- a/src-tauri/proto +++ b/src-tauri/proto @@ -1 +1 @@ -Subproject commit 84a2bf71b1435d956cae2f7933ab9b7e880292b6 +Subproject commit a01cdc15497feceb0266aa6843122ce3f380e273 diff --git a/src-tauri/src/enterprise/inspector/mod.rs b/src-tauri/src/enterprise/inspector/mod.rs index bbf64195..753d5f50 100644 --- a/src-tauri/src/enterprise/inspector/mod.rs +++ b/src-tauri/src/enterprise/inspector/mod.rs @@ -13,7 +13,8 @@ use sysinfo::System; use crate::{ proto::defguard::enterprise::posture::v2::{ - bool_check, string_check, BoolCheck, DevicePostureData, StringCheck, UnavailableReason, + bool_check, int32_check, string_check, BoolCheck, DevicePostureData, Int32Check, + StringCheck, UnavailableReason, }, VERSION, }; @@ -109,11 +110,11 @@ fn device_integrity() -> Result { Err(UnavailableReason::NotApplicable) } -/// Returns the security update status. -fn security_update_status() -> Result { +/// Returns the number of days since the last installed Windows security update. +fn security_update_age_days() -> Result { #[cfg(windows)] { - windows::security_update_status() + windows::security_update_age_days() } #[cfg(not(windows))] @@ -134,6 +135,18 @@ impl From> for BoolCheck { } } +/// Convert `Result` to `Int32Check`. +impl From> for Int32Check { + fn from(value: Result) -> Self { + Self { + result: Some(match value { + Ok(inner) => int32_check::Result::Value(inner), + Err(err) => int32_check::Result::Unavailable(err as i32), + }), + } + } +} + /// Convert `Result` to `StringCheck`. impl From> for StringCheck { fn from(value: Result) -> Self { @@ -159,7 +172,7 @@ impl DevicePostureData { disk_encryption: Some(BoolCheck::from(disk_encryption_status())), antivirus_present: Some(BoolCheck::from(anti_virus_status())), windows_ad_domain_joined: Some(BoolCheck::from(part_of_domain())), - windows_security_update_current: Some(BoolCheck::from(security_update_status())), + windows_security_update_age_days: Some(Int32Check::from(security_update_age_days())), linux_kernel_version: Some(StringCheck::from(linux_kernel_version())), device_integrity: Some(BoolCheck::from(device_integrity())), } diff --git a/src-tauri/src/enterprise/inspector/tests/windows.rs b/src-tauri/src/enterprise/inspector/tests/windows.rs index d1bfaf24..8c743fa0 100644 --- a/src-tauri/src/enterprise/inspector/tests/windows.rs +++ b/src-tauri/src/enterprise/inspector/tests/windows.rs @@ -1,6 +1,6 @@ use super::super::{ anti_virus_status, disk_encryption_status, os_name, os_version, part_of_domain, - security_update_status, + security_update_age_days, }; #[test] @@ -33,6 +33,6 @@ fn test_part_of_domain() { #[test] #[ignore = "development machine only"] -fn test_security_update_status() { - assert!(security_update_status().unwrap()); +fn test_security_update_age_days() { + assert!(security_update_age_days().unwrap() >= 0); } diff --git a/src-tauri/src/enterprise/inspector/windows.rs b/src-tauri/src/enterprise/inspector/windows.rs index 7351e043..82e66dbd 100644 --- a/src-tauri/src/enterprise/inspector/windows.rs +++ b/src-tauri/src/enterprise/inspector/windows.rs @@ -7,8 +7,6 @@ use wmi::{AuthLevel, WMIConnection, WMIError}; use super::UnavailableReason; -const MAX_QUICKFIX_DAYS: i64 = 60; - #[derive(Deserialize)] #[serde(rename = "Win32_EncryptableVolume")] #[serde(rename_all = "PascalCase")] @@ -137,28 +135,24 @@ pub(super) fn part_of_domain() -> Result { Ok(system.part_of_domain) } -/// Find the latest security patch. +/// Number of days since the most recently installed security patch. /// /// Check manually in PowerShell: /// `Get-CimInstance -ClassName Win32_QuickFixEngineering` /// /// Equivalent to PowerShell command: /// `Get-WmiObject -query "SELECT * FROM Win32_QuickFixEngineering"` -pub(super) fn security_update_status() -> Result { +pub(super) fn security_update_age_days() -> Result { let conn = WMIConnection::new()?; let fixes: Vec = conn.query()?; - // Days from today let today = OffsetDateTime::now_utc().date(); - let mut max_days = i64::MAX; - for fix in fixes { - if let Some(installed_on) = fix.installed_on { - let days = (today - installed_on).whole_days(); - if days < max_days { - max_days = days; - } - } - } - - Ok(max_days <= MAX_QUICKFIX_DAYS) + let min_days = fixes + .into_iter() + .filter_map(|fix| fix.installed_on) + .map(|installed_on| (today - installed_on).whole_days()) + .min() + .ok_or(UnavailableReason::DetectionFailed)?; + + i32::try_from(min_days).map_err(|_| UnavailableReason::DetectionFailed) } From a6175d2cf4a52ef2ac0f8293cb65f7d6c45cbfd4 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Wed, 20 May 2026 11:34:47 +0200 Subject: [PATCH 2/3] format --- src-tauri/src/enterprise/inspector/windows.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src-tauri/src/enterprise/inspector/windows.rs b/src-tauri/src/enterprise/inspector/windows.rs index 82e66dbd..d5c56a04 100644 --- a/src-tauri/src/enterprise/inspector/windows.rs +++ b/src-tauri/src/enterprise/inspector/windows.rs @@ -2,7 +2,6 @@ use serde::Deserialize; use time::{Date, OffsetDateTime}; - use wmi::{AuthLevel, WMIConnection, WMIError}; use super::UnavailableReason; From d5ecc18bbf5d63e2b5501a696b08b4901fe636e6 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Wed, 20 May 2026 12:21:25 +0200 Subject: [PATCH 3/3] proto --- src-tauri/proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-tauri/proto b/src-tauri/proto index a01cdc15..07397d4e 160000 --- a/src-tauri/proto +++ b/src-tauri/proto @@ -1 +1 @@ -Subproject commit a01cdc15497feceb0266aa6843122ce3f380e273 +Subproject commit 07397d4e8712fd89804c49af3e41ddcaeb824cbf