On Sun, 13 Jul 2025, Ellie wrote:

I often use touch screen devices, too. It's a challenge on any touch screen to be certain about what you're typing.

sudo has this feature called "pwfeedback". I realize sudo is notorious having questionable many features. However, showing asterisks is a god-sent as an accessibility tool for anybody who may have trouble typing, whether caused by a touch screen or not.

For various technical reasons, I rely on su instead of sudo or doas.

Since "su" seems to be a busybox plugin, is there a way to do something like "pwfeedback" with it? Might it be possibly considered as a new feature? An option would do the job just fine, e.g.: su --pwfeedback

Some existing things outside of busybox might be available to help.
Your touch screen device's keyboard software may have a haptic feedback
option, where the surface might vibrate slightly on registered keypresses.
You have probably explored this already, but I thought I'd mention it.

libc's getpass() is probably not the best place for implementing asterisk
feedback, because it is a legacy interface (removed in POSIX.1-2001).
Even glibc recommends OpenBSD's readpassphrase() instead.  Neither have
an asterisk capability. This probably explains why busybox's libbb
implements its own (see below). I notice similar activity around python's
getpass.

Another non-busybox place is the termios interface, which is mostly implemented
in the kernel. POSIX defines ECHO flags et al. for c_lflag which are normally
cleared by getpass() and friends so that passwords are not revealed
when typed. There seems no existing standard way in this interface for setting
an obfuscating character like asterisk.

[As an aside, and something you may want to advocate, is the following
extension to termios's c_oflag:

        OOBFUSC   output an obfuscating character in lieu of visible chars

accompanied by this c_cc[] member:

        VOBFUSC   character to output when OOBFUSC is enabled, 0 means none.

With this, the convention for getpass()-like setup code would change from

        tio.c_lflag &= ~(ECHO|ECHOE|...)

to

        #ifdef VOBFUSC
                tio.c_oflag |= OOBFUSC;
        #else
                tio.c_lflag &= ~(ECHO|ECHOE|...);
        #endif

The asterisk-wanting user would then use  stty obfusc '*'  to set up their
terminal for asterisk feedback. This seems cleaner to me than using environment
variables or dotfiles or special options to utilities. And the adoption path
also seems clear. There is going to be a niggle with how newlines are printed
after a password is entered, but that's not unassailable.]


Returning to busybox, here is my quick survey of how busybox applets
perform password prompting:

  cryptpw: bb_ask_noecho_stdin("Password: ")
  passwd:  bb_ask_noecho_stdin("Old password: ")
  passwd:  bb_ask_noecho_stdin("New password: ")
  passwd:  bb_ask_noecho_stdin("Retype password: ")
  mail:    bb_ask_noecho(fd, /* timeout: */ 0, "User: ");    /* why noecho? */
  mail:    bb_ask_noecho(fd, /* timeout: */ 0, "Password: ");
  login:   ask_and_check_password(pw)
  su:      ask_and_check_password(pw)
  sulogin: ask_and_check_password_extended(pwd, timeout, "Give root password for 
maintenance\n"
  vlock:   ask_and_check_password(pw)

These flow into libbb's helper functions:

  ask_and_check_password(struct passwd *)
   -> ask_and_check_password_extended(struct passwd *, int timeout,
                                      char *prompt)
      -> bb_ask_noecho(int fd, int timeout, char *prompt)

Therefore, the easy part of implementing asterisks is this patch:

    --- a/libbb/bb_askpass.c
    +++ b/libbb/bb_askpass.c
    @@ -82,6 +82,10 @@ char* FAST_FUNC bb_ask_noecho(int fd, int timeout, const 
char *prompt)
                            ret[i] = '\0';
                            break;
                    }
    +               if (noecho_wants_asterisks()) {
    +                   bb_putchar('*');
    +                   fflush(stdout);
    +               }
            }

            if (timeout) {

But the hard part is answering what noecho_wants_asterisks() should do?
Should it check a global var? An envvar? Expand to the constant 0 or 1
depending on FEATURE_NOECHO_ASTERISKS? I don't have an answer.
(I like the termios solution myself, but that's way beyond busybox.)
_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox

Reply via email to