nuts_tool/cli/
password.rs1use lazy_static::lazy_static;
24use rpassword::prompt_password;
25use std::fs::File;
26use std::io::{self, BufRead, BufReader};
27use std::os::fd::FromRawFd;
28
29use crate::cli::global::{PasswordSource, GLOBALS};
30
31fn ask_for_password() -> Result<Vec<u8>, String> {
32 lazy_static! {
33 static ref RESULT: Result<String, String> =
34 prompt_password("Enter a password: ").map_err(|err| err.to_string());
35 }
36
37 match RESULT.as_ref() {
38 Ok(s) => Ok(s.as_bytes().to_vec()),
39 Err(s) => Err(s.clone()),
40 }
41}
42
43fn ask_for_password_twice(prompt: &str) -> Result<Vec<u8>, String> {
44 let pass1 = prompt_password(format!("{}: ", prompt)).map_err(|err| err.to_string())?;
45 let pass2 = prompt_password(format!("{} (repeat): ", prompt)).map_err(|err| err.to_string())?;
46
47 if pass1 == pass2 {
48 Ok(pass1.as_bytes().to_vec())
49 } else {
50 Err("The passwords do not match".to_string())
51 }
52}
53
54fn password_from_file(file: File) -> io::Result<Vec<u8>> {
55 let mut reader = BufReader::new(file);
56 let mut buf = vec![];
57
58 reader.read_until(0x0a, &mut buf)?;
59
60 if let Some(n) = buf.last() {
61 if *n == 0x0a {
62 buf.pop();
63 }
64 }
65
66 Ok(buf)
67}
68
69fn password_from_source_or<F: FnOnce() -> Result<Vec<u8>, String>>(
70 source: &PasswordSource,
71 f: F,
72) -> Result<Vec<u8>, String> {
73 let file = match source {
74 PasswordSource::Fd(fd) => unsafe { Some(Ok(File::from_raw_fd(*fd))) },
75 PasswordSource::Path(path) => Some(File::open(path)),
76 PasswordSource::Console => None,
77 };
78
79 match file {
80 Some(Ok(f)) => password_from_file(f).map_err(|err| err.to_string()),
81 Some(Err(err)) => Err(err.to_string()),
82 None => f(),
83 }
84}
85
86pub fn password_from_source() -> Result<Vec<u8>, String> {
87 GLOBALS.with_borrow(|g| password_from_source_or(&g.password_source, ask_for_password))
88}
89
90pub fn password_from_source_twice(
91 source: &PasswordSource,
92 prompt: &str,
93) -> Result<Vec<u8>, String> {
94 password_from_source_or(source, || ask_for_password_twice(prompt))
95}