refactor(host/W6.1): extract secret/config-dir helpers into the pf-paths leaf crate
Second de-coupling for the host crate carve (plan §W6.1 leaf). config_dir / create_private_dir / write_secret_file (+ the Windows DACL helpers) were pub(crate) in the gamestream junk drawer, yet consumed by vdisplay, stats, gpu, library, mgmt_token, native_pairing and the Windows service — many of which become pf-media / pf-vdisplay, for which crate::gamestream would be an illegal upward edge. New leaf crate pf-paths (pure std + tracing) owns them; ~40 call sites across 14 files repoint to pf_paths::. gamestream keeps only its own concerns. Verified: Linux (home-worker-5) clippy -p pf-paths -p punktfunk-host --all-targets -D warnings + tests (347 pass, incl. secrets_are_written_owner_only); Windows (192.168.1.158) clippy --features nvenc,amf-qsv --all-targets green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -382,7 +382,7 @@ fn web_setup(args: &[String]) -> Result<()> {
|
||||
let app_dir =
|
||||
PathBuf::from(flag_val(args, "--app-dir").context("web setup: --app-dir <app> required")?);
|
||||
let pw_file = flag_val(args, "--password-file");
|
||||
let data_dir = crate::gamestream::config_dir();
|
||||
let data_dir = pf_paths::config_dir();
|
||||
std::fs::create_dir_all(&data_dir).ok();
|
||||
let pw_path = data_dir.join("web-password");
|
||||
let token_path = data_dir.join("mgmt-token");
|
||||
|
||||
@@ -36,7 +36,7 @@ use windows::Win32::Foundation::LUID;
|
||||
|
||||
/// The crash-recovery journal: PnP instance ids we disabled and have not yet re-enabled.
|
||||
fn journal_path() -> std::path::PathBuf {
|
||||
crate::gamestream::config_dir().join("pnp-disabled-monitors.json")
|
||||
pf_paths::config_dir().join("pnp-disabled-monitors.json")
|
||||
}
|
||||
|
||||
fn read_journal() -> Vec<String> {
|
||||
@@ -55,7 +55,7 @@ fn write_journal(ids: &[String]) {
|
||||
return;
|
||||
}
|
||||
if let Some(dir) = path.parent() {
|
||||
let _ = crate::gamestream::create_private_dir(dir);
|
||||
let _ = pf_paths::create_private_dir(dir);
|
||||
}
|
||||
if let Err(e) = std::fs::write(&path, serde_json::to_vec_pretty(&ids).unwrap_or_default()) {
|
||||
tracing::warn!(error = %e, "PnP-disable: could not write the crash-recovery journal");
|
||||
|
||||
@@ -117,16 +117,16 @@ pub fn main(args: &[String]) -> Result<()> {
|
||||
/// `%ProgramData%\punktfunk\logs\service.log` — the service's own (supervision) log. The host child's
|
||||
/// stdout/stderr are redirected to `host.log` in the same dir.
|
||||
pub fn service_log_path() -> PathBuf {
|
||||
let dir = crate::gamestream::config_dir().join("logs");
|
||||
let dir = pf_paths::config_dir().join("logs");
|
||||
// DACL-locked (Users read-only, no create) so a local user can't pre-plant SYSTEM log files as
|
||||
// reparse points / hardlinks to redirect the SYSTEM service's writes (security-review #11).
|
||||
let _ = crate::gamestream::create_private_dir(&dir);
|
||||
let _ = pf_paths::create_private_dir(&dir);
|
||||
dir.join("service.log")
|
||||
}
|
||||
|
||||
fn host_log_path() -> PathBuf {
|
||||
let dir = crate::gamestream::config_dir().join("logs");
|
||||
let _ = crate::gamestream::create_private_dir(&dir);
|
||||
let dir = pf_paths::config_dir().join("logs");
|
||||
let _ = pf_paths::create_private_dir(&dir);
|
||||
dir.join("host.log")
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ pub fn init_file_logging(filter: tracing_subscriber::EnvFilter) {
|
||||
// ── host.env config ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
fn host_env_path() -> PathBuf {
|
||||
crate::gamestream::config_dir().join("host.env")
|
||||
pf_paths::config_dir().join("host.env")
|
||||
}
|
||||
|
||||
/// Load `%ProgramData%\punktfunk\host.env` (KEY=VALUE lines, `#` comments) into this process's
|
||||
@@ -728,7 +728,7 @@ fn install(args: &[String]) -> Result<()> {
|
||||
println!(
|
||||
"\nInstalled. Config: {}\nLogs: {}\n\nStart now with: punktfunk-host service start",
|
||||
host_env_path().display(),
|
||||
crate::gamestream::config_dir().join("logs").display()
|
||||
pf_paths::config_dir().join("logs").display()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
@@ -793,7 +793,7 @@ fn ensure_default_host_env() -> Result<()> {
|
||||
if let Some(dir) = path.parent() {
|
||||
// DACL-lock the config dir on creation so a local user can't pre-create it and plant a
|
||||
// host.env (which feeds the SYSTEM service's env + command line) — security-review #3.
|
||||
crate::gamestream::create_private_dir(dir).ok();
|
||||
pf_paths::create_private_dir(dir).ok();
|
||||
}
|
||||
let default = "# punktfunk host configuration (read by the Windows service).\n\
|
||||
# KEY=VALUE per line; '#' comments. Restart the service after editing:\n\
|
||||
@@ -818,7 +818,7 @@ fn ensure_default_host_env() -> Result<()> {
|
||||
// Write host.env DACL-locked to SYSTEM/Administrators: it controls the SYSTEM service's
|
||||
// environment + launched command line, so a local user must not be able to read or tamper with
|
||||
// it (security-review 2026-06-28 #3).
|
||||
crate::gamestream::write_secret_file(&path, default.as_bytes())
|
||||
pf_paths::write_secret_file(&path, default.as_bytes())
|
||||
.with_context(|| format!("write {}", path.display()))?;
|
||||
println!("Wrote default config: {}", path.display());
|
||||
Ok(())
|
||||
@@ -866,7 +866,7 @@ fn apply_gamestream_choice(enable: bool) {
|
||||
let mut out = lines.join("\n");
|
||||
out.push('\n');
|
||||
// Rewrite through write_secret_file so the SYSTEM/Administrators DACL is re-asserted.
|
||||
if let Err(e) = crate::gamestream::write_secret_file(&path, out.as_bytes()) {
|
||||
if let Err(e) = pf_paths::write_secret_file(&path, out.as_bytes()) {
|
||||
eprintln!("warning: could not write {}: {e}", path.display());
|
||||
return;
|
||||
}
|
||||
@@ -962,7 +962,7 @@ fn remove_firewall_rules() {
|
||||
/// (`--allow-public-network`). Its presence suppresses the startup Public-network warning (they made
|
||||
/// an informed choice); absence = the secure default.
|
||||
fn fw_public_marker() -> std::path::PathBuf {
|
||||
crate::gamestream::config_dir().join("fw-allow-public")
|
||||
pf_paths::config_dir().join("fw-allow-public")
|
||||
}
|
||||
|
||||
/// Record (or clear) the Public-firewall opt-in marker to match this install's choice.
|
||||
|
||||
Reference in New Issue
Block a user