Crate readpassphrase_3

Crate readpassphrase_3 

Source
Expand description

Lightweight, easy-to-use wrapper around the C readpassphrase(3) function.

From the man page:

The readpassphrase() function displays a prompt to, and reads in a passphrase from, /dev/tty. If this file is inaccessible and the RPP_REQUIRE_TTY flag is not set, readpassphrase() displays the prompt on the standard error output and reads from the standard input.

§Usage

For the simplest of cases, where you would just like to read a password from the console into a String to use elsewhere, you can use getpass:

use readpassphrase_3::getpass;
let _ = getpass(c"Enter your password: ").expect("failed reading password");

If you need to pass Flags or to control the buffer size, then you can use readpassphrase or readpassphrase_into depending on your ownership requirements:

let mut buf = vec![0u8; 256];
use readpassphrase_3::{Flags, readpassphrase};
let pass: &str = readpassphrase(c"Password: ", &mut buf, Flags::default()).unwrap();

use readpassphrase_3::readpassphrase_into;
let pass: String = readpassphrase_into(c"Pass: ", buf, Flags::FORCELOWER).unwrap();

§Security

The readpassphrase(3) man page says:

The calling process should zero the passphrase as soon as possible to avoid leaving the cleartext passphrase visible in the process’s address space.

It is your job to ensure that this is done with the data you own, i.e. any Vec passed to readpassphrase or any String received from getpass or readpassphrase_into.

This crate ships with a minimal Zeroize trait that may be used for this purpose:

use readpassphrase_3::Zeroize;
let mut pass = getpass(c"password: ").unwrap();
// do_something_with(&pass);
pass.zeroize();

let mut buf = vec![0u8; 256];
let res = readpassphrase(c"password: ", &mut buf, Flags::empty());
// match_something_on(res);
buf.zeroize();

let mut pass = readpassphrase_into(c"password: ", buf, Flags::empty()).unwrap();
// do_something_with(&pass);
pass.zeroize();

§Zeroizing memory

This crate works well with the zeroize crate. For example, zeroize::Zeroizing may be used to zero buffer contents regardless of a function’s control flow:

use zeroize::Zeroizing;
let mut buf = Zeroizing::new(vec![0u8; PASSWORD_LEN]);
let pass = readpassphrase(c"pass: ", &mut buf, Flags::REQUIRE_TTY)?;
// do_something_that_can_fail_with(pass)?;

// Or alternatively:
let pass = Zeroizing::new(getpass(c"pass: ")?);
// do_something_that_can_fail_with(&pass)?;

If this crate’s zeroize feature is enabled, then its Zeroize will be replaced by a re-export of the upstream zeroize::Zeroize.

§“Mismatched types” errors

The prompt strings in this API are &CStr, not &str. This is because the underlying C function assumes that the prompt is a NUL-terminated string; were we to take &str instead of &CStr, we would need to make a copy of the prompt on every call.

Most of the time, your prompts will be string literals; you can ask Rust to give you a &CStr literal by simply prepending c to the string:

let _ = getpass(c"pass: ")?;
//              ^
//              |
//              like this

If you need a dynamic prompt, look at CString.

§Windows Limitations

The Windows implementation of readpassphrase(3) that we are using does not yet support UTF-8 in prompts; they must be ASCII. It also does not yet support flags, and always behaves as though called with Flags::empty().

Structs§

Flags
Flags for controlling readpassphrase.
IntoError
An Error from readpassphrase_into containing the passed buffer.

Enums§

Error
Errors that can occur in readpassphrase.

Constants§

MAX_CAPACITY
Maximum capacity to use with readpassphrase_into.
PASSWORD_LEN
Size of buffer used in getpass.

Traits§

Zeroize
A minimal in-crate implementation of a subset of zeroize::Zeroize.

Functions§

getpass
Reads a passphrase using readpassphrase(3), returning a String.
readpassphrase
Reads a passphrase using readpassphrase(3).
readpassphrase_into
Reads a passphrase using readpassphrase(3), returning buf as a String.