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 )