[FIX] race condition with SSHv2 (RT #48338)
[FIX] race condition in KEXINIT (RT #55195)
enable PTY support in SSH2 (RT #64517)

Currently, the use_pty support for SSH2 is disabled. I tried enabling it
but found that programs that read from STDIN often hang attempting to
read after consuming all input. I've put some work into fixing that.

My investigation indicates that the issue is due to the way that PTYs
are handled on the server side. The child process on the server side
never sees an EOF condition. When there is no PTY, the SSH server closes
the STDIN file descriptor, which causes EOF to return. Since STDIN and
STDOUT share a file descriptor when a PTY is allocated, the file handle
cannot be closed and the read blocks.

I believe that appending an 0x04 or two is actually the right thing to
do, based on _Advanced UNIX Programming_, section 4.2 (page 204):

=================================
The user can end a line in one of two ways. Most often, a newline
character is the terminator. The return key is pressed, but the device
driver translates the return (octal 15) to a newline (octal 12).
Alternatively, the user can generate an end-offile (EOF) character by
pressing Ctrl-d. In this case the line is made available to read as is,
without a newline terminator. One special case is important: If the user
generates an EOF at the start of the line, read will return with a zero
count, since the line that the EOF terminated is empty. This looks like
an end-of-file, and that’s why Ctrl-d can be thought of as an
end-of-file "character"
=================================

My testing indicates this is a workable solution. In addition, although
it *should* be the default behavior, I have set the "terminal modes"
string in the pty_req channel request to set VEOF (the character to be
treated as EOF) to 0x04, and provided a method to configure this value.
Replacement for KeyboardInt.pm (RT #23947)

I've written a replacement for KeyboardInt.pm that both
facilitates what it is you want to do (try the password in
$ssh->config->get('pass')) but doesn't get in they way of
compliance with RFC 4256, or impose any limitations on any other
users of this package that may not enjoy a change in existing
behavior.  What I haven't written is any documentation for
it (yet).  If there's a chance that my replacement could just
become the default keyboard-interactive authentication method
implementation for Net::SSH::Perl, then I'd happily write up some
pod too, but here's the basic feature list and how it differs
from KeyboardInt.pm:

1) isn't limited to interactive mode

Incidentally, despite the name "keyboard-interactive", a
completely legitimate userauth info request may include a request
with empty strings for the name, and instruction fields and 0
num-prompts, the correct response for which is handled entirely
without any user interaction.  Given that the SSH authentication
protocol allows for multi-method authentication sequences, it's
completely possible for such a request to be part of a such a
sequence, and it would be silly to not support it just because
the client hadn't been configured as "interactive."  I consider
the current package to be buggy in this regard.

2) includes debugging

Figuring out where and why authentication is failing can be
tricky.  I just used the existing debugging framework and added
some appropriate debug calls.

3) implements control character filtering

Client's shouldn't blindly trust the text servers give them to be
safe for display, so I rip out any control characters per RFC
4251 section 9.2.

4) includes the ability to register info request handlers

Want to introspect the userauth info request and send an
automated reply to it if the request matches some set of
heuristics?  This the feature that lets you do that.  If you
don't register any handlers, this module acts pretty much the
same as KeyboardInt.pm acts now (modulo the above 3 features
anyway).

As an example of how you might use it to go about installing a
one-shot automatic password handler that will only be triggered
if the name and instruction strings in the userauth info request
message are empty, num-prompts is 1, the prompt looks like the
word "password" and we have a stored password for the current
user...

use Net::SSH::Perl;
use Net::SSH::Perl::Auth::KeyboardInteractive qw(add_kbdint_handler);
my $ssh = new Net::SSH::Perl->new($host, 'protocol' => 2);
add_kbdint_handler($ssh,
    sub {
        my ($auth, $name, $instruction, $lang, $prompts) = @_;
        return defined($auth->{'ssh'}->config->get('pass')) &&
               $name eq '' && $instruction eq '' &&
               @$prompts == 1 &&
               $prompts->[0]->[0] =~ /\Apassword\W*\z/i;
    },
    sub {
        my ($auth, $name, $instruction, $lang, $prompt, $echo) = @_;
        $auth->del_handler;
        return $auth->{'ssh'}->config->get('pass');
    }
);
$ssh-login(...
[FIX] test '03-packet.t' hangs forever (RT #67586)

...on BSD based systems. See

  https://rt.cpan.org/Public/Bug/Display.html?id=67586

for discussion.
Merge branches 'rt64517-pty-support', 'rt55195-race-condition-in-kexinit', 'rt48338-race-condition-ssh2', 'rt23947-keyboard-interactive' and 'rt67586-test-hangs'
changelog
version++
MANIFEST
SIGNATURE