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 )