public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Peter via pve-devel <pve-devel@lists.proxmox.com>
To: pve-devel@lists.proxmox.com
Cc: Peter <pjcreath+proxmox@gmail.com>
Subject: [pve-devel] [PATCH installer v3 1/1] assistant: validate: add verify-root-password option
Date: Wed, 10 Sep 2025 15:47:18 -0400	[thread overview]
Message-ID: <mailman.433.1757533685.418.pve-devel@lists.proxmox.com> (raw)

[-- Attachment #1: Type: message/rfc822, Size: 10267 bytes --]

From: Peter <pjcreath+proxmox@gmail.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH installer v3 1/1] assistant: validate: add verify-root-password option
Date: Wed, 10 Sep 2025 15:47:18 -0400
Message-ID: <20250910194718.66959-1-pjcreath+proxmox@gmail.com>

Adds an option to interactively verify the hashed root password in
the answer file, so that mistakes can be caught before installation.

Signed-off-by: Peter <pjcreath+proxmox@gmail.com>
---

 changes since v2:
 * updated debian/control for new dependency
 * cleaned up the proxmox_sys use statements
 * cleaned up messages and usage description as requested

 debian/control                             |  1 +
 proxmox-auto-install-assistant/Cargo.toml  |  1 +
 proxmox-auto-install-assistant/src/main.rs | 37 +++++++++++++++++++---
 3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/debian/control b/debian/control
index 5a6a8cf..9659924 100644
--- a/debian/control
+++ b/debian/control
@@ -18,6 +18,7 @@ Build-Depends: cargo:native,
                librust-native-tls-dev,
                librust-pico-args-0.5-dev,
                librust-pretty-assertions-1.4-dev,
+               librust-proxmox-sys+crypt-dev,
                librust-regex-1+default-dev (>= 1.7~~),
                librust-rustls-0.23-dev,
                librust-rustls-native-certs-dev,
diff --git a/proxmox-auto-install-assistant/Cargo.toml b/proxmox-auto-install-assistant/Cargo.toml
index 9b4a9c4..eeba42f 100644
--- a/proxmox-auto-install-assistant/Cargo.toml
+++ b/proxmox-auto-install-assistant/Cargo.toml
@@ -17,4 +17,5 @@ proxmox-installer-common = { workspace = true, features = [ "cli" ] }
 serde_json.workspace = true
 toml.workspace = true
 
+proxmox-sys = { version = "1.0.0", features = [ "crypt" ] }
 glob = "0.3"
diff --git a/proxmox-auto-install-assistant/src/main.rs b/proxmox-auto-install-assistant/src/main.rs
index 5d6c1d5..c0d932c 100644
--- a/proxmox-auto-install-assistant/src/main.rs
+++ b/proxmox-auto-install-assistant/src/main.rs
@@ -6,10 +6,11 @@
 
 use anyhow::{Context, Result, bail, format_err};
 use glob::Pattern;
+use proxmox_sys::{crypt::verify_crypt_pw, linux::tty::read_password};
 use std::{
     collections::BTreeMap,
     fmt, fs,
-    io::{self, Read},
+    io::{self, IsTerminal, Read},
     path::{Path, PathBuf},
     process::{self, Command, Stdio},
     str::FromStr,
@@ -153,12 +154,15 @@ struct CommandValidateAnswerArgs {
     path: PathBuf,
     /// Whether to also show the full answer as parsed.
     debug: bool,
+    /// Interactively verify the hashed root password.
+    verify_password: bool,
 }
 
 impl cli::Subcommand for CommandValidateAnswerArgs {
     fn parse(args: &mut cli::Arguments) -> Result<Self> {
         Ok(Self {
             debug: args.contains(["-d", "--debug"]),
+            verify_password: args.contains("--verify-root-password"),
             // Needs to be last
             path: args.free_from_str()?,
         })
@@ -175,15 +179,20 @@ ARGUMENTS:
   <PATH>  Path to the answer file.
 
 OPTIONS:
-  -d, --debug        Also show the full answer as parsed.
-  -h, --help         Print this help
-  -V, --version      Print version
+  -d, --debug                 Also show the full answer as parsed.
+      --verify-root-password  Interactively verify the hashed root password.
+  -h, --help                  Print this help
+  -V, --version               Print version
     "#,
             env!("CARGO_PKG_NAME")
         );
     }
 
     fn run(&self) -> Result<()> {
+        if self.verify_password && !std::io::stdin().is_terminal() {
+            Self::print_usage();
+            bail!("Verifying the root password requires an interactive terminal.");
+        }
         validate_answer(self)
     }
 }
@@ -545,6 +554,20 @@ fn validate_answer_file_keys(path: impl AsRef<Path> + fmt::Debug) -> Result<bool
     }
 }
 
+fn verify_hashed_password_interactive(answer: &Answer) -> Result<()> {
+    if let Some(hashed) = &answer.global.root_password_hashed {
+        println!("Verifying hashed root password.");
+
+        let password = String::from_utf8(read_password("Enter root password to verify: ")?)?;
+        verify_crypt_pw(&password, hashed).context("Failed to verify hashed root password")?;
+
+        println!("Password matches hashed root password.");
+        Ok(())
+    } else {
+        bail!("'root-password-hashed' not set in answer file, cannot verify.");
+    }
+}
+
 fn validate_answer(args: &CommandValidateAnswerArgs) -> Result<()> {
     let mut valid = validate_answer_file_keys(&args.path)?;
 
@@ -553,6 +576,12 @@ fn validate_answer(args: &CommandValidateAnswerArgs) -> Result<()> {
             if args.debug {
                 println!("Parsed data from answer file:\n{:#?}", answer);
             }
+            if args.verify_password {
+                if let Err(err) = verify_hashed_password_interactive(&answer) {
+                    eprintln!("{err:#}");
+                    valid = false;
+                }
+            }
         }
         Err(err) => {
             eprintln!("{err:#}");
-- 
2.47.2



[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

                 reply	other threads:[~2025-09-10 19:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mailman.433.1757533685.418.pve-devel@lists.proxmox.com \
    --to=pve-devel@lists.proxmox.com \
    --cc=pjcreath+proxmox@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal