File Coverage

blib/lib/Net/SSH/Perl/WithSocks.pm
Criterion Covered Total %
statement 18 38 47.3
branch 0 12 0.0
condition 0 4 0.0
subroutine 6 8 75.0
pod n/a
total 24 62 38.7


line stmt bran cond sub pod time code
1             package Net::SSH::Perl::WithSocks;
2 2     2   9821 use strict;
  2         7  
  2         80  
3 2     2   18 use warnings;
  2         6  
  2         96  
4 2     2   770 use parent qw(Net::SSH::Perl);
  2         730  
  2         16  
5 2     2   159063 use vars qw($VERSION);
  2         22  
  2         308  
6              
7             require v5.10; # Dependency Math-GMP-2.15 requires 5.10
8             # Todo investigate if the module is required
9             # and if we could use older or change module
10              
11             $VERSION = '0.021_04';
12              
13             =encoding utf8
14              
15             =head1 NAME
16              
17             Net::SSH::Perl::WithSocks - connect to an SSH host through a TCP proxy
18              
19             =head1 SYNOPSIS
20              
21             my $ssh = Net::SSH::Perl::WithSocks->new( 'motherbrain.nanabox.net',
22             with_socks => {
23             socks_host => 'motherbrain.nanabox.net',
24             socks_port => 9000,
25             }
26             );
27              
28             $ssh->login(); # Use it just like a regular Net::SSH object
29              
30             =head1 DESCRIPTION
31              
32             This is a utility to make simple the process of connecting to an SSH
33             host by way of a TCP proxy, such as those provided by OpenSSH servers
34             for tunneling. It is based off of C so that it can work
35             in Windows as well, though the basic idea could be expounded upon to
36             support C as well.
37              
38             =cut
39              
40 2     2   28 use Carp;
  2         5  
  2         234  
41 2     2   1448 use IO::Socket::Socks;
  2         44000  
  2         749  
42              
43             sub _init {
44 0     0     my( $self, %params ) = @_;
45 0 0         if( $params{SocksHost} ) {
46             $self->{WithSocks} = {
47             ProxyAddr => $params{SocksHost},
48             ProxyPort => $params{SocksPort},
49 0           };
50             }
51 0           $self->SUPER::_init(%params);
52             }
53              
54             sub _connect {
55 0     0     my $ssh = shift;
56 0 0         return $ssh->SUPER::_connect(@_) unless $ssh->{WithSocks};
57              
58 0           my $raddr = inet_aton($ssh->{host});
59 0 0         croak "Net::SSH::Perl::WithSocks: Bad Hostname: $ssh->{host}"
60             unless defined $raddr;
61 0   0       my $rport = $ssh->{config}->get('port') || 'ssh';
62 0 0         if( $rport =~ /\D/ ) {
63 0           my @serv = getservbyname(my $serv = $rport, 'tcp');
64 0   0       $rport = $serv[2] || 22;
65             }
66 0           $ssh->debug("Connecting to $ssh->{host}:$rport");
67             my $sock = IO::Socket::Socks->new(
68             ConnectAddr => $raddr,
69             ConnectPort => $rport,
70 0 0         %{$ssh->{WithSocks}}
  0            
71             ) or die "Can't connect to $ssh->{host}:$rport : $!";
72              
73 0           select((select($sock), $|=1)[0]);
74              
75 0           $ssh->{session}{sock} = $sock;
76 0           $ssh->_exchange_identification;
77              
78 0 0         defined( $sock->blocking(0) ) or die "Can't set non-blocking: $!";
79 0           $ssh->debug("Connection established.");
80             }
81              
82             1;
83              
84             __END__