From 8c9c211c249b9f2a4616b341e6378177129f3a4e Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Sat, 24 Feb 2018 15:21:18 +0100 Subject: Make password line invisible Instead of rendering the password string, hide it while allowing it to be copied. It is identified by the "p: " prefix, but nothing follows that. This allows you to run `passextract` without having to worry about others peering over your shoulder or about screen capture or recording hacks. I'll be adding a command line flag to force you to opt in to this feature, while keeping the old functionality the same. --- src/main.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 2a196d3..9b1fe59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -78,6 +78,17 @@ fn parse_options(filename: &str) -> Vec { options } +/// Checks whether the given line starts with "p: " +/// +/// # Examples +/// +/// ``` +/// assert_eq!(is_password_line("p: secret"), true); +/// ``` +fn is_password_line(line: &str) -> bool { + line.starts_with("p: ") +} + fn main() { let args: Vec = env::args().collect(); @@ -110,7 +121,11 @@ fn main() { term.printline_with_cell(selection.x, selection.y, "->", knockout_cell); for (i, s) in options.iter().enumerate() { - term.printline(5, i + 2, s) + if is_password_line(s) { + term.printline(5, i + 2, "p: ") + } else { + term.printline(5, i + 2, s) + } } let evt = term.get_event(Duration::from_millis(100)).unwrap(); -- cgit v1.2.3 From 43cf870c98c98d2c818178cc4b9d14810a3cc7a9 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Thu, 1 Mar 2018 01:32:32 +0100 Subject: Try to match `-i` argument Turn on a `hide_password` boolean variable if an `-i` argument is passed in (haven't tested this yet). This tells us whether the user wants us to hide the password in the selection interface. --- src/main.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 9b1fe59..ffe6329 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,6 +92,12 @@ fn is_password_line(line: &str) -> bool { fn main() { let args: Vec = env::args().collect(); + let hide_password = match args.first() { + Some(arg) if arg == "-i" => true, + Some(_) => false, + None => false, + }; + let input = if args.len() > 1 { &args[1] } else { -- cgit v1.2.3 From f43eafeab711ea4be4a71c732228b1244466e9b4 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Thu, 1 Mar 2018 22:10:25 +0100 Subject: Use `-i` argument to hide passwords Connect the `-i` argument flag to the renderer. If the arg was passed, hide passwords, otherwise show them. Change `args.first()` to `args.get(1)` because the actual first element is the command executable. Not happy with the condition I'm using here to grab the password file or the STDIN `-`. It doesn't read well at all. It all does work, but this part I want to rewrite to make it easier to read. --- src/main.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index ffe6329..69f7736 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,14 +92,15 @@ fn is_password_line(line: &str) -> bool { fn main() { let args: Vec = env::args().collect(); - let hide_password = match args.first() { + let hide_password = match args.get(1) { Some(arg) if arg == "-i" => true, Some(_) => false, None => false, }; - let input = if args.len() > 1 { - &args[1] + let input = if hide_password && args.len() > 2 || + !hide_password && args.len() > 1 { + &args[args.len() - 1] } else { "-" }; @@ -127,7 +128,7 @@ fn main() { term.printline_with_cell(selection.x, selection.y, "->", knockout_cell); for (i, s) in options.iter().enumerate() { - if is_password_line(s) { + if hide_password && is_password_line(s) { term.printline(5, i + 2, "p: ") } else { term.printline(5, i + 2, s) -- cgit v1.2.3 From 9faef460fa13857ca26b4447b9d627bb76e9bbd9 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Thu, 1 Mar 2018 23:58:25 +0100 Subject: Clean up condition for getting file path from argument Instead of the convoluted hard-to-read `hide_password &&` nonsense, give ourselves a way to express the condition in terms of the argument _not_ being one of our accepted options (only `-i`). This ensures that we either capture the filename in the last argument or use STDIN. --- src/main.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 69f7736..7411c1a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,15 +92,18 @@ fn is_password_line(line: &str) -> bool { fn main() { let args: Vec = env::args().collect(); + let options = ["-i"]; + let hide_password = match args.get(1) { Some(arg) if arg == "-i" => true, Some(_) => false, None => false, }; - let input = if hide_password && args.len() > 2 || - !hide_password && args.len() > 1 { - &args[args.len() - 1] + let last_arg = &args[args.len() - 1]; + let input = if args.len() > 1 && + !options.contains(&last_arg.as_ref()) { + last_arg } else { "-" }; -- cgit v1.2.3 From 99fa6cb2210328c8a7ba96e56971788aac5bce27 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Sat, 3 Mar 2018 17:33:23 +0100 Subject: When `-i`, replace password with '*'s Previously, when the "invisible" flag was activated, we wouldn't print anything except the "p: " prefix on a password line. This made it difficult to verify the password, and if you for some reason had multiple passwords, you wouldn't know which one to pick unless you knew the order. This at least gives you a visual cue about your password. --- src/main.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 7411c1a..28b0259 100644 --- a/src/main.rs +++ b/src/main.rs @@ -89,6 +89,20 @@ fn is_password_line(line: &str) -> bool { line.starts_with("p: ") } +/// Replaces the password on a password line with "*"s. +/// +/// # Examples +/// +/// ``` +/// assert_eq!(hide_password_line("p: secret"), "p: ******); +/// ``` +fn hide_password_line(line: &str) -> String { + const KEY_LENGTH: usize = 3; + let password_length = line.len() - KEY_LENGTH; + + format!("p: {}", "*".repeat(password_length)) +} + fn main() { let args: Vec = env::args().collect(); @@ -132,7 +146,7 @@ fn main() { for (i, s) in options.iter().enumerate() { if hide_password && is_password_line(s) { - term.printline(5, i + 2, "p: ") + term.printline(5, i + 2, &hide_password_line(s)) } else { term.printline(5, i + 2, s) } -- cgit v1.2.3