readpassphrase(3bsd)

πŸ“¦
version 0.12.2 Β· 3 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, debian trixie, epel 10, epel 9, fedora 43, fedora 44, nixos 26.05, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– readpassphrase β€” get a passphrase from the user πŸ’–

okay so bestie, this one lives in section 3bsd of the manual, and it's a BSD utility function that Debian ships through libbsd. if you've ever typed a password into a terminal and watched absolutely nothing appear on screen, you've met this function's whole vibe. 🫢


πŸ“š LIBRARY

utility functions from BSD systems, aka libbsd</>, link it with -lbsd.


✨ SYNOPSIS ✨

#include <readpassphrase.h>
(See libbsd(7) for include usage.)

char *
readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags);

(if you're confused about how to include libbsd stuff, go read libbsd(7), she explains it πŸ’…)


🌸 DESCRIPTION 🌸

so like. readpassphrase() shows the user a prompt and reads a passphrase from them β€” and it does it through /dev/tty, which is the main character of this whole story. no cap.

but here's the plot twist πŸ‘€: if that file is inaccessible AND the RPP_REQUIRE_TTY flag is not set, then readpassphrase() gives up on /dev/tty and instead prints the prompt on the standard error output and reads from standard input. and in that case, it's generally not possible to turn off echo. so like, your typing might just be visible. awkward. 😭

it reads up to bufsiz - 1 characters into the buffer buf you hand it β€” the - 1 is because one spot is saved for the NUL. any extra characters beyond that, plus the terminating newline (or return) character, get discarded. bye bye. πŸ—‘οΈ

the flags argument is the bitwise OR</> of zero or more of these:

  • RPP_ECHO_OFF β€” turn off echo. this is the default behavior, it's giving classic password field.
  • RPP_ECHO_ON β€” leave echo on, so everything the user types is visible. bold choice, respect.
  • RPP_REQUIRE_TTY β€” fail if there is no tty. no tty, no deal, periodt.
  • RPP_FORCELOWER β€” force the input to lower case.
  • RPP_FORCEUPPER β€” force the input to upper case.
  • RPP_SEVENBIT β€” strip the high bit from the input.
  • RPP_STDIN β€” read the passphrase from stdin and ignore the prompt.
⚠️ and bestie, listen: the calling process should zero the passphrase as soon as possible so you don't leave the cleartext passphrase just vibing in the process's address space. that's a security thing. don't be messy. 🧼

πŸŽ€ RETURN VALUES πŸŽ€

slay success = readpassphrase() returns a pointer to the NUL-terminated passphrase. πŸ’…

if an error happens, the terminal state gets restored and a null pointer is returned. that's your cue to check for NULL, bestie.


πŸ“ FILES πŸ“

  • /dev/tty

🌈 EXAMPLES 🌈

this code fragment reads a passphrase from /dev/tty into the buffer passbuf. iconic behavior:

char passbuf[1024];

...

if (readpassphrase("Response: ", passbuf, sizeof(passbuf),
    RPP_REQUIRE_TTY) == NULL)
        errx(1, "unable to read passphrase");

if (compare(transform(passbuf), epass) != 0)
        errx(1, "bad passphrase");

...

explicit_bzero(passbuf, sizeof(passbuf));

see that explicit_bzero at the end? that's the clean-up queen. πŸ‘‘


πŸ’€ ERRORS πŸ’€

  • [EINTR] β€” readpassphrase() got interrupted by a signal.
  • [EINVAL] β€” the bufsiz argument was zero. not even one character, bestie??
  • [EIO] β€” the process is a member of a background process attempting to read from its controlling terminal, OR the process is ignoring or blocking the SIGTTIN signal, OR the process group is orphaned.
  • [EMFILE] β€” the process has already reached its limit for open file descriptors. too many tabs open, fr fr.
  • [ENFILE] β€” the system file table is full.
  • [ENOTTY] β€” there's no controlling terminal and the RPP_REQUIRE_TTY flag was specified. told you that flag was serious.

🚨 SIGNALS 🚨

readpassphrase() will catch these signals:

SIGALRM         SIGHUP          SIGINT
SIGPIPE         SIGQUIT         SIGTERM
SIGTSTP         SIGTTIN         SIGTTOU

when one of those gets intercepted, terminal echo gets restored if it had previously been turned off. so no, your terminal won't be stuck in ghost mode. 😌

if a signal handler was installed for the signal back when readpassphrase() was called, that handler then gets executed. if no handler was previously installed for the signal, then the default action is taken as per sigaction(2).

and now the special ones β€” the way that SIGTSTP, SIGTTIN and SIGTTOU get treated is different. these are the stop signals, generated from the keyboard or because of terminal I/O from a background process. when the process is resumed after it's been stopped, readpassphrase() will reprint the prompt and the user can then enter a passphrase. so thoughtful of her honestly. πŸ₯Ή


πŸ‘€ SEE ALSO πŸ‘€


πŸ“œ STANDARDS πŸ“œ

readpassphrase() is a BSD extension</> and should not be used if portability is what you want. iykyk. if you need to run everywhere, this ain't it bestie.


πŸ¦‹ HISTORY πŸ¦‹

readpassphrase() first appeared in OpenBSD 2.9</> and FreeBSD 4.6</>. a legend from the jump. ⭐


okay that's the whole page!! πŸ’– this Debian build of the page is dated March 6, 2014, so go hydrate, zero your buffers, and stay safe out there. mwah 🫢✨

πŸ“¦ where this page comes from