conradkleinespel / rpassword

Cross platform Rust library to read a password in the terminal (Linux, BSD, OSX, Windows, WASM).
Apache License 2.0
244 stars 38 forks source link

[BUG?] "No such device or address" on hardened system #93

Closed Arthurdw closed 9 months ago

Arthurdw commented 9 months ago

The issue

Hello, first of all; thank you for maintaining this crate!

I encountered an error when executing prompt_password on a securely configured system using devsec.os_hardening. The error message is as follows:

Os { code: 6, kind: Uncategorized, message: "No such device or address" }

Do you have any insights into why this might be happening?

System info

/etc/os-release

PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

uname -a

Linux <host> 6.1.0-9-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.27-1 (2023-05-08) x86_64 GNU/Linux
conradkleinespel commented 9 months ago

Hello @Arthurdw ! You're welcome, I appreciate your kind words.

By default, prompt_password prompts and reads from /dev/tty (see here). And I see the playbook you're referring to seems to do things on TTYs.

You may need a specific TTY configuration or read from stdin, instead of TTY, using this version of prompt_password: https://docs.rs/rpassword/latest/rpassword/fn.prompt_password_from_bufread.html

The documentation says "Prompts on the TTY ..." but it's outdated, you can prompt from anything that implements Write as the function signature suggests.

Let me know what works for you, I will update the documentation accordingly.

Cheers

Arthurdw commented 9 months ago

Thank you so much!

This is the solution that we are going to use to this issue. This might not be the most optimal solution as the stdin shows the input. But in our use case this will not form a issue. It does however come at the cost that if the reason would not be a tty issue it will still attempt again with stdin.

let prompt_password = |prompt: &str| {
    rpassword::prompt_password(prompt).or_else(|_| {
        println!("Cannot use TTY, falling back to stdin/stdout");
        println!("WARNING: Password will be visible on the screen");

        rpassword::prompt_password_from_bufread(
            &mut std::io::BufReader::new(std::io::stdin()),
            &mut std::io::stdout(),
            prompt,
        )
    })
};

Once again, thank you for maintaining this project; and thank you for the detailed support!

conradkleinespel commented 9 months ago

You're welcome !

conradkleinespel commented 9 months ago

And thanks for your feedback, sounds good !