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.002';
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 );

    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 => 0 );

    unless ( $ssh->connect ) {
        Rex::Logger::info( "LibSSH: can't connect to $server: " . ( $ssh->error // '' ), 'warn' );
        $self->{connected} = 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 {
        # auto: agent first, then key file, then password
        $authed = $ssh->auth_agent;
        $authed ||= $ssh->auth_publickey($privkey) if !$authed && $privkey;
        $authed ||= $ssh->auth_password($password) if !$authed && $password;
    }

    unless ($authed) {
        Rex::Logger::info( "LibSSH: authentication failed for $user\@$server: "
              . ( $ssh->error // '' ), 'warn' );
        $self->{auth_ret} = 0;
        return;
    }

    Rex::Logger::debug("LibSSH: authenticated $user\@$server");
    $self->{ssh}      = $ssh;
    $self->{auth_ret} = 1;
}

sub reconnect {



( run in 1.377 second using v1.01-cache-2.11-cpan-39bf76dae61 )