Rex-LibSSH

 view release on metacpan or  search on metacpan

lib/Rex/Interface/Connection/LibSSH.pm  view on Meta::CPAN

# ABSTRACT: Rex SSH connection via Net::LibSSH (no SFTP required)

package Rex::Interface::Connection::LibSSH;
our $VERSION = '0.004';
use strict;
use warnings;

use Net::LibSSH;
use Rex::Logger;
use Rex::Config;
use Rex::Helper::IP;
use Rex::Interface::Connection::Base;
use base qw(Rex::Interface::Connection::Base);

sub new {
    my ( $that, %args ) = @_;
    my $self = $that->SUPER::new(%args);
    return $self;
}

sub connect {
    my ( $self, %opt ) = @_;

    my $server   = $opt{server};
    my $port     = $opt{port}     || Rex::Config->get_port( server => $server )    || 22;
    my $timeout  = $opt{timeout}  || Rex::Config->get_timeout( server => $server ) || 10;
    my $user     = $opt{user};
    my $password = $opt{password};
    my $privkey  = $opt{private_key};
    my $auth     = $opt{auth_type} // 'key';

    $self->{server}        = $server;
    $self->{is_sudo}       = $opt{sudo};
    $self->{__auth_info__} = \%opt;

    ( $server, $port ) = Rex::Helper::IP::get_server_and_port( $server, $port );

    # Host key verification: a per-connect option wins, otherwise the same
    # openssh_opt knobs the OpenSSH backend honours -- StrictHostKeyChecking
    # (what -feature => ['disable_strict_host_key_checking'] sets to "no")
    # and UserKnownHostsFile. Strict unless explicitly turned off.
    my %openssh_opt = Rex::Config->get_openssh_opt();
    my $strict      = $opt{strict_hostkeycheck};
    unless ( defined $strict ) {
        my $shkc = $openssh_opt{StrictHostKeyChecking} // '';
        $strict = $shkc =~ /^(?:no|off)$/i ? 0 : 1;
    }
    my $knownhosts = $opt{knownhosts} // $openssh_opt{UserKnownHostsFile};

    Rex::Logger::debug("LibSSH: connecting to $server:$port as $user");

    my $ssh = Net::LibSSH->new;
    $ssh->option( host    => "$server" );
    $ssh->option( port    => $port     );
    $ssh->option( user    => $user     ) if defined $user;
    $ssh->option( timeout => $timeout  );
    $ssh->option( strict_hostkeycheck => $strict ? 1 : 0 );
    $ssh->option( knownhosts => $knownhosts ) if defined $knownhosts;

    unless ( $ssh->connect ) {
        Rex::Logger::info( "LibSSH: can't connect to $server: " . ( $ssh->error // '' )
              . ( $strict
                ? " -- host key checking is on: add the host to known_hosts (ssh-keyscan)"
                  . " or opt out with strict_hostkeycheck => 0 / use Rex -feature => ['disable_strict_host_key_checking']"
                : '' ), 'warn' );
        $self->{error}     = $ssh->error;
        $self->{connected} = 0;
        $self->{auth_ret}  = 0;
        return;
    }

    # Reset timeout to 0 (infinite) after connect — the connect timeout must
    # be short so unreachable hosts fail fast, but channel reads (e.g. apt-get
    # with DKMS build) must not time out. libssh's timeout option affects both.
    $ssh->option( timeout => 0 );

    $self->{connected} = 1;

    # Try authentication in order
    my $authed = 0;

    if ( $auth eq 'pass' && defined $password ) {
        $authed = $ssh->auth_password($password);
    }
    elsif ( $auth eq 'key' && defined $privkey ) {
        $authed = $ssh->auth_publickey($privkey);
        $authed ||= $ssh->auth_agent if !$authed;
    }
    else {



( run in 1.012 second using v1.01-cache-2.11-cpan-036bef1c656 )