From ea0cd87b3b117ceb5d1d330d204d299d40de1a1e Mon Sep 17 00:00:00 2001 From: archipelago Date: Fri, 17 Jul 2026 11:31:27 -0400 Subject: [PATCH] fix(auth): sync OS login password when the UI password is set at install (#97) auth.setup only wrote the web password hash to user.json, so the archipelago system user kept the image default password ("archipelago") on console/SSH even after the user picked a real password during onboarding. Reuse the existing usermod-based sync (already used by auth.changePassword's alsoChangeSsh path) at setup time, best-effort so a failure can never break onboarding. Co-Authored-By: Claude Fable 5 --- core/archipelago/src/api/rpc/auth.rs | 9 +++++++++ core/archipelago/src/auth.rs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/core/archipelago/src/api/rpc/auth.rs b/core/archipelago/src/api/rpc/auth.rs index b68519f2..a01c362e 100644 --- a/core/archipelago/src/api/rpc/auth.rs +++ b/core/archipelago/src/api/rpc/auth.rs @@ -147,6 +147,15 @@ impl RpcHandler { self.auth_manager.setup_user(password).await?; tracing::info!("[onboarding] user setup complete"); + // The install-time password must also become the OS login for the + // archipelago user — otherwise the console/SSH keeps the image default + // ("archipelago") after the user has picked a real password (#97). + // Best-effort: a failure here must not break onboarding. + match crate::auth::change_ssh_password(password).await { + Ok(()) => tracing::info!("[onboarding] system login password synced"), + Err(e) => tracing::warn!("[onboarding] system login password sync failed: {e}"), + } + // Persist the pending onboarding seed as the encrypted backup now that // a passphrase (the login password) finally exists — otherwise "Reveal // recovery phrase" has nothing to decrypt on this node, ever. diff --git a/core/archipelago/src/auth.rs b/core/archipelago/src/auth.rs index ce7f51cc..cdd40e20 100644 --- a/core/archipelago/src/auth.rs +++ b/core/archipelago/src/auth.rs @@ -360,7 +360,7 @@ fn validate_password_strength(password: &str) -> Result<()> { /// Change the archipelago user's SSH/login password. /// Uses usermod + openssl to bypass PAM (avoids "Authentication token manipulation" errors). /// Uses absolute paths (/usr/bin/openssl, /usr/sbin/usermod) for systemd's minimal PATH. -async fn change_ssh_password(new_password: &str) -> Result<()> { +pub(crate) async fn change_ssh_password(new_password: &str) -> Result<()> { let ssh_user = std::env::var("ARCHIPELAGO_SSH_USER").unwrap_or_else(|_| "archipelago".to_string());