File Coverage

blib/lib/Net/Prober/ssh.pm
Criterion Covered Total %
statement 34 40 85.0
branch 4 10 40.0
condition 1 3 33.3
subroutine 8 8 100.0
pod 0 2 0.0
total 47 63 74.6


line stmt bran cond sub pod time code
1             package Net::Prober::ssh;
2             {
3             $Net::Prober::ssh::VERSION = '0.15';
4             }
5              
6 1     1   4 use strict;
  1         1  
  1         26  
7 1     1   4 use warnings;
  1         1  
  1         27  
8 1     1   4 use base 'Net::Prober::Probe::TCP';
  1         1  
  1         342  
9              
10 1     1   4 use Carp ();
  1         1  
  1         342  
11              
12             sub defaults {
13 2     2 0 2 my ($self) = @_;
14              
15 2         4 my $defaults = $self->SUPER::defaults();
16 2         3 $defaults->{port} = 22;
17              
18 2         3 return $defaults;
19             }
20              
21             sub probe {
22 1     1 0 1 my ($self, $args) = @_;
23              
24 1         5 my ($host, $port, $timeout, $username, $password) =
25             $self->parse_args($args, qw(host port timeout username password));
26              
27 1         5 my $t0 = $self->time_now();
28              
29 1         4 my $sock = $self->open_socket($args);
30 1 50       328355 if (! $sock) {
31 0         0 return $self->probe_failed(
32             reason => qq{Couldn't connect to SSH server $host:$port},
33             );
34             }
35              
36 1         5 chomp (my $ssh_banner = $self->_get_reply($sock));
37              
38 1 50       19 if (! $ssh_banner) {
39 0         0 return $self->probe_failed(
40             reason => qq{Couldn't get SSH banner from $host:$port}
41             );
42             }
43              
44             # SSH-protoversion-softwareversion SP comments CR LF
45 1 50       33 if ($ssh_banner !~ qr{^SSH-
46             (? [^\-]+) -
47             (? [^\s]+) \s?
48             (? .*)? $}x) {
49 0         0 return $self->probe_failed(
50             reason => qq{Non-RFC compliant SSH banner from $host:$port? ($ssh_banner)},
51             );
52             }
53              
54             my %ssh_info = (
55             protoversion => $+{protoversion},
56             softwareversion => $+{softwareversion},
57             comments => $+{comments},
58 1         41 banner => $ssh_banner,
59             );
60              
61             # We can't try to login if we haven't got credentials
62 1 50 33     16 if ($username && $password) {
63 0         0 $self->_send_command($sock, $username . "\n" . $password . "\n");
64 0 0       0 if (! $self->_get_reply($sock)) {
65 0         0 return $self->probe_failed(
66             reason => qq{Couldn't login to ssh $host:$port with user $username},
67             );
68             }
69             }
70              
71             # Say goodbye
72 1         16 $self->_send_command($sock, 'exit');
73              
74 1         145 return $self->probe_ok(%ssh_info);
75             }
76              
77             sub _send_command {
78 1     1   4 my ($self, $sock, $text_input) = @_;
79 1         19 return $sock->send($text_input);
80             }
81              
82             sub _get_reply {
83 1     1   2 my ($self, $sock) = @_;
84 1         21 $sock->recv(my $reply, 1024);
85 1         156886 $reply =~ s{\s+$}{};
86 1         10 return $reply;
87             }
88              
89             1;
90              
91             __END__