Permalink
Browse files

Rewrite getpass as safe Rust code

  • Loading branch information...
palfrey committed Nov 25, 2018
1 parent fd97486 commit ff737f0184b0177ada323a3b54d38909886e2d3f
Showing with 123 additions and 85 deletions.
  1. +102 −0 Cargo.lock
  2. +1 −0 Cargo.toml
  3. +3 −6 src/ashuffle.rs
  4. +15 −78 src/getpass.rs
  5. +2 −0 src/main.rs
  6. +0 −1 src/streams.rs

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -8,6 +8,7 @@ name = "ashuffle"
[dependencies]
libc = { git = "https://github.com/palfrey/libc.git", branch="strcase-various"}
easycurses = "0.12"
[build-dependencies]
cc = "1"
@@ -2,7 +2,6 @@ use libc;
use args;
use mpd;
use list;
use streams;
use std::process;
use shuffle;
use rule;
@@ -307,12 +306,10 @@ pub unsafe fn shuffle_idle(
pub unsafe fn get_mpd_password(mpd: *mut mpd::mpd_connection) {
/* keep looping till we get a bad error, or we get a good password. */
loop {
let pass: *mut libc::c_char = getpass::as_getpass(
streams::stdin_file(),
streams::stdout_file(),
b"mpd password: \x00" as *const u8 as *const libc::c_char,
let pass = getpass::as_getpass(
"mpd password: "
);
mpd::mpd_run_password(mpd, pass);
mpd::mpd_run_password(mpd, pass.as_ptr() as *const libc::c_char);
let err = mpd::mpd_connection_get_error(mpd);
if err as libc::c_uint == mpd::MPD_ERROR_SUCCESS as libc::c_int as libc::c_uint {
return;
@@ -1,83 +1,20 @@
use libc;
pub type __off_t = libc::c_long;
pub type __off64_t = libc::c_long;
pub type __ssize_t = libc::c_long;
use std::io;
use easycurses::EasyCurses;
pub unsafe fn as_getpass(
in_stream: *mut libc::FILE,
out_stream: *mut libc::FILE,
prompt: *const libc::c_char,
) -> *mut libc::c_char {
if libc::fwrite(
prompt as *const libc::c_void,
libc::strlen(prompt),
1i32 as libc::size_t,
out_stream,
) != 1
{
libc::perror(b"getpass (fwrite)\x00" as *const u8 as *const libc::c_char);
::std::process::exit(1i32);
} else {
set_echo(out_stream, false, true);
let mut result = 0 as *mut libc::c_char;
let mut result_size = 0i32 as libc::size_t;
let result_len: libc::ssize_t = libc::getline(&mut result, &mut result_size, in_stream);
if result_len < 0 {
libc::perror(b"getline (getpass)\x00" as *const u8 as *const libc::c_char);
pub fn as_getpass(
prompt: &str,
) -> String {
print!("{}", prompt);
let mut curses = EasyCurses::initialize_system().unwrap();
curses.set_echo(false);
let mut result = String::new();
match io::stdin().read_line(&mut result) {
Err(error) => {
println!("read_line issue: {}", error);
::std::process::exit(1i32);
} else {
set_echo(out_stream, true, true);
return result;
}
};
}
unsafe fn set_echo(
stream: *mut libc::FILE,
echo_state: bool,
echo_nl_state: bool,
) {
#[cfg(target_os = "macos")]
let mut flags = libc::termios {
c_iflag: 0,
c_oflag: 0,
c_cflag: 0,
c_lflag: 0,
c_cc: [0; libc::NCCS],
c_ispeed: 0,
c_ospeed: 0,
};
#[cfg(not(target_os = "macos"))]
let mut flags = libc::termios {
c_iflag: 0,
c_oflag: 0,
c_cflag: 0,
c_lflag: 0,
c_line: 0,
c_cc: [0; libc::NCCS],
c_ispeed: 0,
c_ospeed: 0,
};
let mut res: libc::c_int = libc::tcgetattr(libc::fileno(stream), &mut flags);
if res != 0i32 {
libc::perror(b"set_echo (tcgetattr)\x00" as *const u8 as *const libc::c_char);
::std::process::exit(1i32);
} else {
if echo_state {
flags.c_lflag |= libc::ECHO
} else {
flags.c_lflag &= libc::ECHO
}
if echo_nl_state {
flags.c_lflag |= libc::ECHONL
} else {
flags.c_lflag &= !libc::ECHONL
}
res = libc::tcsetattr(libc::fileno(stream), 0i32, &mut flags);
if res != 0i32 {
libc::perror(b"set_echo (tcsetattr)\x00" as *const u8 as *const libc::c_char);
::std::process::exit(1i32);
} else {
return;
Ok(_) => {
return result;
}
};
}
}
@@ -2,6 +2,8 @@
#![allow(non_camel_case_types)]
extern crate libc;
extern crate easycurses;
mod args;
mod ashuffle;
mod getpass;
@@ -2,6 +2,5 @@ use libc;
extern {
pub fn stdin_file() -> *mut libc::FILE;
pub fn stdout_file() -> *mut libc::FILE;
pub fn errno_val() -> libc::c_int;
}

0 comments on commit ff737f0

Please sign in to comment.