diff --git a/Cargo.lock b/Cargo.lock index 3a0486e23..29a193013 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -456,9 +456,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.5" +version = "4.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2686c4115cb0810d9a984776e197823d08ec94f176549a89a9efded477c456dc" +checksum = "d9394150f5b4273a1763355bd1c2ec54cc5a2593f790587bcd6b2c947cfa9211" dependencies = [ "clap_builder", "clap_derive", @@ -467,9 +467,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.5" +version = "4.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e53afce1efce6ed1f633cf0e57612fe51db54a1ee4fd8f8503d078fe02d69ae" +checksum = "9a78fbdd3cc2914ddf37ba444114bc7765bbdcb55ec9cbe6fa054f0137400717" dependencies = [ "anstream", "anstyle", @@ -2232,17 +2232,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rpassword" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" -dependencies = [ - "libc", - "rtoolbox", - "winapi", -] - [[package]] name = "rstest" version = "0.17.0" @@ -2269,16 +2258,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "rtoolbox" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "rustc-demangle" version = "0.1.23" @@ -2335,6 +2314,7 @@ dependencies = [ "crossbeam-channel", "derivative", "derive_more", + "dialoguer", "dircmp", "directories", "dirs", @@ -2361,7 +2341,6 @@ dependencies = [ "rand", "rayon", "rhai", - "rpassword", "rustic_core", "rustic_testing", "scrypt", @@ -2402,6 +2381,7 @@ dependencies = [ "crossbeam-channel", "derivative", "derive_more", + "dialoguer", "directories", "dirs", "displaydoc", @@ -2429,7 +2409,6 @@ dependencies = [ "rand", "rayon", "reqwest", - "rpassword", "rstest", "rustdoc-json", "rustup-toolchain", diff --git a/Cargo.toml b/Cargo.toml index 37192f855..36ba09647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -108,7 +108,7 @@ merge = { workspace = true } directories = { workspace = true } nom = { workspace = true } -rpassword = { workspace = true } +dialoguer = "0.10.4" bytesize = { workspace = true } indicatif = { workspace = true } path-dedot = { workspace = true } @@ -232,7 +232,6 @@ cachedir = "0.3" # commands merge = "0.1" -rpassword = "7" directories = "5" nom = "7" indicatif = "0.17" diff --git a/changelog/new.txt b/changelog/new.txt index 30ea692c1..78ec6d27d 100644 --- a/changelog/new.txt +++ b/changelog/new.txt @@ -11,3 +11,4 @@ New features: - restore: Files are now allocated just before being first processed. This allows easier resumed restores. - New option: `no-require-git` for backup - if enabled, a git repository is not required to apply `git-ignore` rule. - fix: wait for password-command to successfully exit, allowing to input something into the command, and read password from stdout. +- Creation of new keys now enforces confirmation of entered key. This helps to prevent mistype of passwords during the initial entry diff --git a/crates/rustic_core/Cargo.lock b/crates/rustic_core/Cargo.lock index d06f26f1d..ca80f44f0 100644 --- a/crates/rustic_core/Cargo.lock +++ b/crates/rustic_core/Cargo.lock @@ -2060,7 +2060,7 @@ dependencies = [ "rayon", "reqwest", "rhai", - "rpassword", + "dialoguer", "rstest", "rustdoc-json", "rustup-toolchain", diff --git a/crates/rustic_core/Cargo.toml b/crates/rustic_core/Cargo.toml index ca64b6fc1..7305c3b5c 100644 --- a/crates/rustic_core/Cargo.toml +++ b/crates/rustic_core/Cargo.toml @@ -94,7 +94,7 @@ clap = { workspace = true, optional = true } clap_complete = { workspace = true, optional = true } merge = { workspace = true, optional = true } -rpassword = { workspace = true } +dialoguer = "0.10.4" directories = { workspace = true } nom = { workspace = true } path-dedot = { workspace = true } diff --git a/crates/rustic_core/src/lib.rs b/crates/rustic_core/src/lib.rs index d4f082c70..1ec76f8fe 100644 --- a/crates/rustic_core/src/lib.rs +++ b/crates/rustic_core/src/lib.rs @@ -142,5 +142,5 @@ pub use crate::{ }, RepoFile, }, - repository::{parse_command, OpenRepository, RepoInfo, Repository, RepositoryOptions}, + repository::{parse_command, read_password_from_reader, OpenRepository, RepoInfo, Repository, RepositoryOptions}, }; diff --git a/crates/rustic_core/src/repository.rs b/crates/rustic_core/src/repository.rs index aab3e2af2..89041880a 100644 --- a/crates/rustic_core/src/repository.rs +++ b/crates/rustic_core/src/repository.rs @@ -19,7 +19,7 @@ use nom::{ sequence::delimited, IResult, }; -use rpassword::prompt_password; +use dialoguer::Password; use serde_with::{serde_as, DisplayFromStr}; @@ -176,7 +176,7 @@ pub fn parse_command<'a, E: ParseError<&'a str>>( )(input) } -pub(crate) fn read_password_from_reader(file: &mut impl BufRead) -> RusticResult { +pub fn read_password_from_reader(file: &mut impl BufRead) -> RusticResult { let mut password = String::new(); _ = file .read_line(&mut password) @@ -365,7 +365,10 @@ pub(crate) fn get_key(be: &impl ReadBackend, password: Option) -> Rustic // TODO: Differentiate between wrong password and other error! if let Ok(key) = find_key_in_backend( be, - &prompt_password("enter repository password: ") + &Password::new() + .with_prompt("enter repository password") + .allow_empty_password(true) + .interact() .map_err(RepositoryErrorKind::ReadingPasswordFromPromptFailed)?, None, ) { diff --git a/src/commands/init.rs b/src/commands/init.rs index bb7264dd1..350637dec 100644 --- a/src/commands/init.rs +++ b/src/commands/init.rs @@ -8,7 +8,7 @@ use anyhow::{bail, Result}; use crate::{commands::get_repository, Application, RUSTIC_APP}; use bytes::Bytes; -use rpassword::prompt_password; +use dialoguer::Password; use rustic_core::{ hash, random_poly, ConfigFile, DecryptBackend, DecryptWriteBackend, FileType, Id, Key, KeyFile, @@ -80,7 +80,11 @@ pub(crate) fn save_config( let key = Key::new(); let pass = password.map_or_else( - || match prompt_password("enter password for new key: ") { + || match Password::new().with_prompt("enter password for new key") + .allow_empty_password(true) + .with_confirmation("confirm password", "passwords do not match") + .interact() + { Ok(it) => it, Err(err) => { status_err!("{}", err); diff --git a/src/commands/key.rs b/src/commands/key.rs index b467cd96a..a544735b1 100644 --- a/src/commands/key.rs +++ b/src/commands/key.rs @@ -12,9 +12,9 @@ use anyhow::Result; use std::{fs::File, io::BufReader}; -use rpassword::{prompt_password, read_password_from_bufread}; +use dialoguer::Password; -use rustic_core::{hash, FileType, KeyFile, WriteBackend}; +use rustic_core::{hash, read_password_from_reader, FileType, KeyFile, WriteBackend}; /// `key` subcommand #[derive(clap::Parser, Command, Debug)] @@ -79,7 +79,11 @@ impl AddCmd { let key = repo.key; let pass = self.new_password_file.as_ref().map_or_else( - || match prompt_password("enter password for new key: ") { + || match Password::new().with_prompt("enter password for new key") + .allow_empty_password(true) + .with_confirmation("confirm password", "passwords do not match") + .interact() + { Ok(it) => it, Err(err) => { status_err!("{}", err); @@ -94,7 +98,7 @@ impl AddCmd { RUSTIC_APP.shutdown(Shutdown::Crash); } }); - match read_password_from_bufread(&mut file) { + match read_password_from_reader(&mut file) { Ok(it) => it, Err(err) => { status_err!("{}", err);