Skip to content

Commit 7da9b7e

Browse files
delegate read_password() to read_password_with_config()
1 parent a380f14 commit 7da9b7e

1 file changed

Lines changed: 5 additions & 137 deletions

File tree

src/lib.rs

Lines changed: 5 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ mod wasm {
204204

205205
#[cfg(target_family = "unix")]
206206
mod unix {
207-
use super::{Config, FeedbackState, PasswordFeedback, SafeString};
207+
use super::{Config, ConfigBuilder, FeedbackState};
208208
use libc::{c_int, tcsetattr, termios, ECHO, ECHONL, ICANON, ISIG, TCSANOW, VMIN, VTIME};
209-
use std::io::{self, BufRead, Write};
209+
use std::io::{self, Write};
210210
use std::mem;
211211
use std::os::unix::io::AsRawFd;
212212

@@ -217,41 +217,6 @@ mod unix {
217217
const CTRL_U: u8 = 0x15;
218218
const ESC: u8 = 0x1B;
219219

220-
struct HiddenInput {
221-
fd: i32,
222-
term_orig: termios,
223-
}
224-
225-
impl HiddenInput {
226-
fn new(fd: i32) -> io::Result<HiddenInput> {
227-
// Make two copies of the terminal settings. The first one will be modified
228-
// and the second one will act as a backup for when we want to set the
229-
// terminal back to its original state.
230-
let mut term = safe_tcgetattr(fd)?;
231-
let term_orig = safe_tcgetattr(fd)?;
232-
233-
// Hide the password. This is what makes this function useful.
234-
term.c_lflag &= !ECHO;
235-
236-
// But don't hide the NL character when the user hits ENTER.
237-
term.c_lflag |= ECHONL;
238-
239-
// Save the settings for now.
240-
io_result(unsafe { tcsetattr(fd, TCSANOW, &term) })?;
241-
242-
Ok(HiddenInput { fd, term_orig })
243-
}
244-
}
245-
246-
impl Drop for HiddenInput {
247-
fn drop(&mut self) {
248-
// Set the mode back to normal
249-
unsafe {
250-
tcsetattr(self.fd, TCSANOW, &self.term_orig);
251-
}
252-
}
253-
}
254-
255220
/// Turns a C function return into an IO Result
256221
fn io_result(ret: c_int) -> std::io::Result<()> {
257222
match ret {
@@ -268,27 +233,7 @@ mod unix {
268233

269234
/// Reads a password from the TTY
270235
pub fn read_password() -> std::io::Result<String> {
271-
let tty = std::fs::File::open("/dev/tty")?;
272-
let fd = tty.as_raw_fd();
273-
let mut reader = io::BufReader::new(tty);
274-
275-
read_password_from_fd_with_hidden_input(&mut reader, fd)
276-
}
277-
278-
/// Reads a password from a given file descriptor
279-
fn read_password_from_fd_with_hidden_input(
280-
reader: &mut impl BufRead,
281-
fd: i32,
282-
) -> std::io::Result<String> {
283-
let mut password = SafeString::new();
284-
285-
let hidden_input = HiddenInput::new(fd)?;
286-
287-
reader.read_line(&mut password)?;
288-
289-
std::mem::drop(hidden_input);
290-
291-
super::fix_line_issues(password.into_inner())
236+
read_password_with_config(ConfigBuilder::new().build())
292237
}
293238

294239
struct RawModeInput {
@@ -321,10 +266,6 @@ mod unix {
321266

322267
/// Reads a password from TTY using the given config
323268
pub fn read_password_with_config(config: Config) -> std::io::Result<String> {
324-
if config.feedback == PasswordFeedback::Hide {
325-
return read_password();
326-
}
327-
328269
let mut tty = std::fs::OpenOptions::new()
329270
.read(true)
330271
.write(true)
@@ -452,7 +393,7 @@ mod unix {
452393

453394
#[cfg(target_family = "windows")]
454395
mod windows {
455-
use super::{Config, FeedbackState, PasswordFeedback, SafeString};
396+
use super::{Config, ConfigBuilder, FeedbackState, PasswordFeedback, SafeString};
456397
use std::io::{self, BufRead, BufReader, Write};
457398
use std::os::windows::io::FromRawHandle;
458399
use windows_sys::core::PCSTR;
@@ -474,82 +415,9 @@ mod windows {
474415
const CTRL_U: char = '\x15';
475416
const ESC: char = '\x1B';
476417

477-
struct HiddenInput {
478-
mode: u32,
479-
handle: HANDLE,
480-
}
481-
482-
impl HiddenInput {
483-
fn new(handle: HANDLE) -> io::Result<HiddenInput> {
484-
let mut mode = 0;
485-
486-
// Get the old mode so we can reset back to it when we are done
487-
if unsafe { GetConsoleMode(handle, &mut mode as *mut CONSOLE_MODE) } == 0 {
488-
return Err(std::io::Error::last_os_error());
489-
}
490-
491-
// We want to be able to read line by line, and we still want backspace to work
492-
let new_mode_flags = ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
493-
if unsafe { SetConsoleMode(handle, new_mode_flags) } == 0 {
494-
return Err(std::io::Error::last_os_error());
495-
}
496-
497-
Ok(HiddenInput { mode, handle })
498-
}
499-
}
500-
501-
impl Drop for HiddenInput {
502-
fn drop(&mut self) {
503-
// Set the mode back to normal
504-
unsafe {
505-
SetConsoleMode(self.handle, self.mode);
506-
}
507-
}
508-
}
509-
510418
/// Reads a password from the TTY
511419
pub fn read_password() -> std::io::Result<String> {
512-
let handle = unsafe {
513-
CreateFileA(
514-
b"CONIN$\x00".as_ptr() as PCSTR,
515-
GENERIC_READ | GENERIC_WRITE,
516-
FILE_SHARE_READ | FILE_SHARE_WRITE,
517-
std::ptr::null(),
518-
OPEN_EXISTING,
519-
0,
520-
INVALID_HANDLE_VALUE,
521-
)
522-
};
523-
524-
if handle == INVALID_HANDLE_VALUE {
525-
return Err(std::io::Error::last_os_error());
526-
}
527-
528-
let mut stream = BufReader::new(unsafe { std::fs::File::from_raw_handle(handle as _) });
529-
read_password_from_handle_with_hidden_input(&mut stream, handle)
530-
}
531-
532-
/// Reads a password from a given file handle
533-
fn read_password_from_handle_with_hidden_input(
534-
reader: &mut impl BufRead,
535-
handle: HANDLE,
536-
) -> io::Result<String> {
537-
let mut password = SafeString::new();
538-
539-
let hidden_input = HiddenInput::new(handle)?;
540-
541-
let reader_return = reader.read_line(&mut password);
542-
543-
// Newline for windows which otherwise prints on the same line.
544-
println!();
545-
546-
if reader_return.is_err() {
547-
return Err(reader_return.unwrap_err());
548-
}
549-
550-
std::mem::drop(hidden_input);
551-
552-
super::fix_line_issues(password.into_inner())
420+
read_password_with_config(ConfigBuilder::new().build())
553421
}
554422

555423
struct RawModeInput {

0 commit comments

Comments
 (0)