fix(agent): SPEC-018 review fixes — agent_id persistence, managed fallback, HKEY typing
Some checks failed
Build and Test / Build Server (Linux) (pull_request) Failing after 7m12s
Build and Test / Build Agent (Windows) (pull_request) Successful in 14m56s
Build and Test / Security Audit (pull_request) Successful in 7m57s
Build and Test / Build Summary (pull_request) Has been skipped
Some checks failed
Build and Test / Build Server (Linux) (pull_request) Failing after 7m12s
Build and Test / Build Agent (Windows) (pull_request) Successful in 14m56s
Build and Test / Security Audit (pull_request) Successful in 7m57s
Build and Test / Build Summary (pull_request) Has been skipped
Address the SPEC-018 Phase 1 code review (reports/2026-06-03-spec018-review.md): - Bug 2 (config.rs): stop agent_id churn on every restart. The embedded-config path always wins in Config::load, so the saved agent_id was never read back. Add Config::persisted_agent_id() and reuse a prior id from the TOML; only mint a new UUID when none exists. - Bug 1 (main.rs): remove the non-functional in-process fallback in run_permanent_agent_managed. A managed agent's cak_ store is SYSTEM-only ACL'd, so a non-elevated in-process run cannot authenticate (load_cak permission-denied, or enroll C1 read-back failure). Return an actionable "install elevated" error instead of pretending to provide an agent; update the misleading comments. - Issue 6 (startup.rs): replace the fragile transmute::<HANDLE, HKEY> with the windows crate's typed HKEY out-param; add SAFETY comments. cargo check -p guruconnect --target x86_64-pc-windows-msvc passes clean. Deferred lower-severity items tracked in #8. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ use tracing::{info, warn};
|
||||
use windows::core::PCWSTR;
|
||||
#[cfg(windows)]
|
||||
use windows::Win32::System::Registry::{
|
||||
RegCloseKey, RegDeleteValueW, RegOpenKeyExW, RegSetValueExW, HKEY_CURRENT_USER, KEY_WRITE,
|
||||
RegCloseKey, RegDeleteValueW, RegOpenKeyExW, RegSetValueExW, HKEY, HKEY_CURRENT_USER, KEY_WRITE,
|
||||
REG_SZ,
|
||||
};
|
||||
|
||||
@@ -42,40 +42,39 @@ pub fn add_to_startup() -> Result<()> {
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
|
||||
// SAFETY: FFI into the Win32 registry API. `key_path`/`value_name`/`value_data`
|
||||
// are NUL-terminated wide strings that outlive the calls. `RegOpenKeyExW`
|
||||
// writes the opened key into `hkey`; we only use it after confirming success,
|
||||
// and always pair it with `RegCloseKey`.
|
||||
unsafe {
|
||||
let mut hkey = windows::Win32::Foundation::HANDLE::default();
|
||||
let mut hkey = HKEY::default();
|
||||
|
||||
// Open the Run key
|
||||
// Open the Run key. RegOpenKeyExW takes a `*mut HKEY` out-param.
|
||||
let result = RegOpenKeyExW(
|
||||
HKEY_CURRENT_USER,
|
||||
PCWSTR(key_path.as_ptr()),
|
||||
0,
|
||||
KEY_WRITE,
|
||||
&mut hkey as *mut _ as *mut _,
|
||||
&mut hkey,
|
||||
);
|
||||
|
||||
if result.is_err() {
|
||||
anyhow::bail!("Failed to open registry key: {:?}", result);
|
||||
}
|
||||
|
||||
let hkey_raw = std::mem::transmute::<
|
||||
windows::Win32::Foundation::HANDLE,
|
||||
windows::Win32::System::Registry::HKEY,
|
||||
>(hkey);
|
||||
|
||||
// Set the value
|
||||
let data_bytes =
|
||||
std::slice::from_raw_parts(value_data.as_ptr() as *const u8, value_data.len() * 2);
|
||||
|
||||
let set_result = RegSetValueExW(
|
||||
hkey_raw,
|
||||
hkey,
|
||||
PCWSTR(value_name.as_ptr()),
|
||||
0,
|
||||
REG_SZ,
|
||||
Some(data_bytes),
|
||||
);
|
||||
|
||||
let _ = RegCloseKey(hkey_raw);
|
||||
let _ = RegCloseKey(hkey);
|
||||
|
||||
if set_result.is_err() {
|
||||
anyhow::bail!("Failed to set registry value: {:?}", set_result);
|
||||
@@ -103,15 +102,19 @@ pub fn remove_from_startup() -> Result<()> {
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
|
||||
// SAFETY: FFI into the Win32 registry API. `key_path`/`value_name` are
|
||||
// NUL-terminated wide strings that outlive the calls. `RegOpenKeyExW` writes
|
||||
// the opened key into `hkey`; we only use it after confirming success, and
|
||||
// always pair it with `RegCloseKey`.
|
||||
unsafe {
|
||||
let mut hkey = windows::Win32::Foundation::HANDLE::default();
|
||||
let mut hkey = HKEY::default();
|
||||
|
||||
let result = RegOpenKeyExW(
|
||||
HKEY_CURRENT_USER,
|
||||
PCWSTR(key_path.as_ptr()),
|
||||
0,
|
||||
KEY_WRITE,
|
||||
&mut hkey as *mut _ as *mut _,
|
||||
&mut hkey,
|
||||
);
|
||||
|
||||
if result.is_err() {
|
||||
@@ -119,14 +122,9 @@ pub fn remove_from_startup() -> Result<()> {
|
||||
return Ok(()); // Not an error if key doesn't exist
|
||||
}
|
||||
|
||||
let hkey_raw = std::mem::transmute::<
|
||||
windows::Win32::Foundation::HANDLE,
|
||||
windows::Win32::System::Registry::HKEY,
|
||||
>(hkey);
|
||||
let delete_result = RegDeleteValueW(hkey, PCWSTR(value_name.as_ptr()));
|
||||
|
||||
let delete_result = RegDeleteValueW(hkey_raw, PCWSTR(value_name.as_ptr()));
|
||||
|
||||
let _ = RegCloseKey(hkey_raw);
|
||||
let _ = RegCloseKey(hkey);
|
||||
|
||||
if delete_result.is_err() {
|
||||
warn!("Registry value may not exist: {:?}", delete_result);
|
||||
|
||||
Reference in New Issue
Block a user