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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.