Net-SSH-Perl
view release on metacpan or search on metacpan
lib/Net/SSH/Perl/Auth/Rhosts_RSA.pm view on Meta::CPAN
package Net::SSH::Perl::Auth::Rhosts_RSA;
use strict;
use warnings;
use Net::SSH::Perl::Constants qw(
SSH_SMSG_FAILURE
SSH_SMSG_SUCCESS
SSH_CMSG_AUTH_RHOSTS_RSA
SSH_SMSG_AUTH_RSA_CHALLENGE
SSH_CMSG_AUTH_RSA_RESPONSE );
use Net::SSH::Perl::Util qw( :rsa _load_private_key );
use Net::SSH::Perl::Packet;
use Net::SSH::Perl::Auth;
use base qw( Net::SSH::Perl::Auth );
use Scalar::Util qw(weaken);
use File::Spec::Functions qw( catfile );
sub new {
my $class = shift;
my $ssh = shift;
my $auth = bless { ssh => $ssh }, $class;
weaken $auth->{ssh};
$auth;
}
sub authenticate {
my $auth = shift;
my($packet);
my $ssh = $auth->{ssh};
$ssh->debug("Rhosts-RSA authentication is disabled by the client."), return
unless $ssh->config->get('auth_rhosts_rsa');
$ssh->debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
my $private_key;
eval {
my $ssh_host_key = $^O eq 'MSWin32'
? catfile($ENV{WINDIR}, 'ssh_host_key')
: '/etc/ssh_host_key';
$private_key = _load_private_key($ssh_host_key);
};
$ssh->debug("Rhosts with RSA authentication failed: Can't load private host key."),
return 0 if $@;
my $user = $ssh->config->get('user');
$packet = $ssh->packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
$packet->put_str($user);
$packet->put_int32($private_key->{rsa}{bits});
$packet->put_mp_int($private_key->{rsa}{e});
$packet->put_mp_int($private_key->{rsa}{n});
$packet->send;
$packet = Net::SSH::Perl::Packet->read($ssh);
my $type = $packet->type;
if ($type == SSH_SMSG_FAILURE) {
$ssh->debug("Server refused our rhosts authentication or host key.");
return 0;
}
if ($type != SSH_SMSG_AUTH_RSA_CHALLENGE) {
$ssh->fatal_disconnect("Protocol error during RSA authentication: $type");
}
my $challenge = $packet->get_mp_int;
$ssh->debug("Received RSA challenge for host key from server.");
_respond_to_rsa_challenge($ssh, $challenge, $private_key);
$packet = Net::SSH::Perl::Packet->read($ssh);
$type = $packet->type;
if ($type == SSH_SMSG_SUCCESS) {
$ssh->debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
return 1;
}
elsif ($type != SSH_SMSG_FAILURE) {
$ssh->fatal_disconnect("Protocol error waiting RSA auth response: $type");
}
$ssh->debug("Rhosts or /hosts.equiv with RSA host authentication refused.");
return 0;
}
1;
__END__
=head1 NAME
Net::SSH::Perl::Auth::Rhosts_RSA - Perform Rhosts-RSA authentication
=head1 SYNOPSIS
use Net::SSH::Perl::Auth;
my $auth = Net::SSH::Perl::Auth->new('Rhosts_RSA', $ssh);
print "Valid auth" if $auth->authenticate;
=head1 DESCRIPTION
I<Net::SSH::Perl::Auth::Rhosts_RSA> performs Rhosts with RSA
authentication with a remote sshd server. This is standard
Rhosts authentication, plus a challenge-response phase where
the server RSA-authenticates the client based on its host
key. When you create a new Rhosts_RSA auth object, you give
it an I<$ssh> object, which should contain an open connection
to an ssh daemon, as well as any data that the authentication
module needs to proceed. In this case, the I<$ssh> object
must contain the name of the user trying to open the connection.
Note that the sshd server will require two things from your
client:
=over 4
=item 1. Privileged Port
sshd will require your client to be running on a privileged port
(below 1024); this will, in turn, likely require your client to be
running as root. If your client is not running on a privileged port,
the Rhosts-RSA authentication request will be denied.
If you're running as root, I<Net::SSH::Perl> should
automatically detect that and try to start up on a privileged
port. If for some reason that isn't happening, take a look at
the I<Net::SSH::Perl> docs.
=item 2. Private Host Key
In order to do RSA-authentication on your host key, your client
( run in 1.507 second using v1.01-cache-2.11-cpan-39bf76dae61 )