Bug 3314 - RP_ALLOW_STDIN flag to read_passphrase() not working as documented
Summary: RP_ALLOW_STDIN flag to read_passphrase() not working as documented
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 8.6p1
Hardware: Other Linux
: P5 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks: V_8_7
  Show dependency treegraph
 
Reported: 2021-05-28 19:27 AEST by Allison Karlitskaya
Modified: 2022-02-25 13:57 AEDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Allison Karlitskaya 2021-05-28 19:27:56 AEST
This bug was originally filed against Fedora:

  https://bugzilla.redhat.com/show_bug.cgi?id=1949436

The maintainers there have asked me to also open a bug here.

The problem is that the read_passphrase() function accepts a flag called RP_ALLOW_STDIN, which is documented as part of the comment that appears above that function:

/*
 * Reads a passphrase from /dev/tty with echo turned off/on.  Returns the
 * passphrase (allocated with xmalloc).  Exits if EOF is encountered. If
 * RP_ALLOW_STDIN is set, the passphrase will be read from stdin if no
 * tty is available
 */

The problem is with the word "ALLOW" and the text "...if no tty is available".  The way this flag is currently implemented, if it is given, it *requires* the passphrase to be read from stdin, even if /dev/tty *is* available.  Additionally, stdin must, itself, be a reference to a tty.  Otherwise, you fall back to askpass, unless some heuristic conditions are met, in which case you get to use the tty afterall.

The logic in the function is pretty complex...  The offending segment for this particular problem is here, though:

        else if (flags & RP_ALLOW_STDIN) {
                if (!isatty(STDIN_FILENO)) {
                        debug("read_passphrase: stdin is not a tty");
                        use_askpass = 1;
                }

In any case, this issue is causing problems with tools like git and scp which pass their own (non-tty) stdin.  In particular, Fedora carries a patch which introduces the use of this flag with PKCS11 passphrases.

The result is that the askpass program is called, even if it's not installed, and even if a controlling terminal is available.

Some workarounds are available: setting SSH_ASKPASS_REQUIRE=never, or unsetting DISPLAY or setting it to the empty string all work (by triggering changes in some of the heuristics code in this function).

From what I understand, Fedora is considering dropping or reworking their patch, so a valid fix to this bug may be simply changing the comment to more accurately describe the current behaviour (and probably renaming the flag).

I guess, however, that the current behaviour of this code is not what was intended, so hopefully it can be fixed.

Thanks very much for your consideration!
Comment 1 Damien Miller 2021-07-23 15:57:42 AEST
I have just adjusted the comment to read:

>   * Reads a passphrase from /dev/tty with echo turned off/on.  Returns the
>   * passphrase (allocated with xmalloc).  Exits if EOF is encountered. If
>   * RP_ALLOW_STDIN is set, the passphrase will be read from stdin if no
> - * tty is available
> + * tty is or askpass program is available
Comment 2 Damien Miller 2022-02-25 13:57:57 AEDT
closing bugs resolved before openssh-8.9