line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# (c) Jan Gehring |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Rex::Helper::SSH2; |
6
|
|
|
|
|
|
|
|
7
|
83
|
|
|
83
|
|
1163
|
use v5.12.5; |
|
83
|
|
|
|
|
303
|
|
8
|
83
|
|
|
83
|
|
423
|
use warnings; |
|
83
|
|
|
|
|
191
|
|
|
83
|
|
|
|
|
4152
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '1.14.2.3'; # TRIAL VERSION |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
require Exporter; |
13
|
83
|
|
|
83
|
|
516
|
use Data::Dumper; |
|
83
|
|
|
|
|
215
|
|
|
83
|
|
|
|
|
5165
|
|
14
|
|
|
|
|
|
|
require Rex::Commands; |
15
|
83
|
|
|
83
|
|
2214
|
use Time::HiRes qw(sleep); |
|
83
|
|
|
|
|
17155
|
|
|
83
|
|
|
|
|
703
|
|
16
|
|
|
|
|
|
|
|
17
|
83
|
|
|
83
|
|
11859
|
use base qw(Exporter); |
|
83
|
|
|
|
|
192
|
|
|
83
|
|
|
|
|
7454
|
|
18
|
|
|
|
|
|
|
|
19
|
83
|
|
|
83
|
|
621
|
use vars qw(@EXPORT); |
|
83
|
|
|
|
|
190
|
|
|
83
|
|
|
|
|
69811
|
|
20
|
|
|
|
|
|
|
@EXPORT = qw(net_ssh2_exec net_ssh2_exec_output net_ssh2_shell_exec); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
our $READ_STDERR = 1; |
23
|
|
|
|
|
|
|
our $EXEC_AND_SLEEP = 0; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub net_ssh2_exec { |
26
|
0
|
|
|
0
|
0
|
|
my ( $ssh, $cmd, $base, $option ) = @_; |
27
|
|
|
|
|
|
|
|
28
|
0
|
|
|
|
|
|
my $chan = $ssh->channel; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# REQUIRE_TTY can be turned off by feature no_tty |
31
|
0
|
0
|
|
|
|
|
if ( !Rex::Config->get_no_tty ) { |
32
|
0
|
|
|
|
|
|
$chan->pty("xterm"); # set to xterm, due to problems with vt100. |
33
|
|
|
|
|
|
|
# if vt100 sometimes the restart of services doesn't work and need a sleep .000001 after the command... |
34
|
|
|
|
|
|
|
# strange bug... |
35
|
0
|
|
|
|
|
|
$chan->pty_size( 4000, 80 ); |
36
|
|
|
|
|
|
|
} |
37
|
0
|
|
|
|
|
|
$chan->blocking(1); |
38
|
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
$chan->exec($cmd); |
40
|
|
|
|
|
|
|
|
41
|
0
|
|
|
|
|
|
my $in; |
42
|
0
|
|
|
|
|
|
my $in_err = ""; |
43
|
|
|
|
|
|
|
|
44
|
0
|
|
0
|
|
|
|
my $rex_int_conf = Rex::Commands::get("rex_internals") || {}; |
45
|
0
|
|
|
|
|
|
my $buffer_size = 1024; |
46
|
0
|
0
|
|
|
|
|
if ( exists $rex_int_conf->{read_buffer_size} ) { |
47
|
0
|
|
|
|
|
|
$buffer_size = $rex_int_conf->{read_buffer_size}; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
0
|
|
|
|
|
|
my @lines; |
51
|
|
|
|
|
|
|
my $last_line; |
52
|
0
|
|
|
|
|
|
my $current_line = ""; |
53
|
0
|
|
|
|
|
|
while ( my $len = $chan->read( my $buf, $buffer_size ) ) { |
54
|
0
|
|
|
|
|
|
$in .= $buf; |
55
|
0
|
|
|
|
|
|
$current_line .= $buf; |
56
|
|
|
|
|
|
|
|
57
|
0
|
0
|
|
|
|
|
if ( $buf =~ m/\n/ms ) { |
58
|
0
|
|
|
|
|
|
@lines = split( /\n/, $current_line ); |
59
|
0
|
0
|
|
|
|
|
unshift @lines, $last_line if ($last_line); |
60
|
0
|
|
|
|
|
|
$last_line = pop @lines; |
61
|
|
|
|
|
|
|
|
62
|
0
|
|
|
|
|
|
for my $line (@lines) { |
63
|
0
|
|
|
|
|
|
$line =~ s/[\r\n]//gms; |
64
|
0
|
|
|
|
|
|
$line .= "\n"; |
65
|
0
|
0
|
|
|
|
|
$base->execute_line_based_operation( $line, $option ) && goto END_READ; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
0
|
|
|
|
|
|
$current_line = ""; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
0
|
|
|
|
|
|
my @lines_err; |
74
|
0
|
|
|
|
|
|
my $last_line_err = ""; |
75
|
0
|
|
|
|
|
|
while ( my $len = $chan->read( my $buf_err, $buffer_size, 1 ) ) { |
76
|
0
|
|
|
|
|
|
$in_err .= $buf_err; |
77
|
0
|
|
|
|
|
|
@lines_err = split( /\n/, $buf_err ); |
78
|
0
|
0
|
|
|
|
|
unshift @lines_err, $last_line_err if ($last_line_err); |
79
|
0
|
|
|
|
|
|
$last_line_err = pop @lines_err; |
80
|
|
|
|
|
|
|
|
81
|
0
|
|
|
|
|
|
for my $line (@lines_err) { |
82
|
0
|
|
|
|
|
|
$line =~ s/[\r\n]//gms; |
83
|
0
|
|
|
|
|
|
$line .= "\n"; |
84
|
0
|
0
|
|
|
|
|
$base->execute_line_based_operation( $line, $option ) && goto END_READ; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
#select undef, undef, undef, 0.002; # wait a little before closing the channel |
89
|
|
|
|
|
|
|
#sleep 1; |
90
|
|
|
|
|
|
|
END_READ: |
91
|
0
|
|
|
|
|
|
$chan->send_eof; |
92
|
|
|
|
|
|
|
|
93
|
0
|
|
|
|
|
|
my $wait_c = 0; |
94
|
0
|
|
0
|
|
|
|
my $wait_max = $rex_int_conf->{ssh2_channel_closewait_max} || 500; |
95
|
0
|
|
|
|
|
|
while ( !$chan->eof ) { |
96
|
0
|
|
|
|
|
|
Rex::Logger::debug("Waiting for eof on ssh channel."); |
97
|
0
|
|
|
|
|
|
sleep 0.002; # wait a little for retry |
98
|
0
|
|
|
|
|
|
$wait_c++; |
99
|
0
|
0
|
|
|
|
|
if ( $wait_c >= $wait_max ) { |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# channel will be force closed. |
102
|
0
|
|
|
|
|
|
Rex::Logger::debug( |
103
|
|
|
|
|
|
|
"Rex::Helper::SSH2::net_ssh2_exec: force closing channel for command: $cmd" |
104
|
|
|
|
|
|
|
); |
105
|
0
|
|
|
|
|
|
last; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
0
|
|
|
|
|
|
$chan->wait_closed; |
110
|
0
|
|
|
|
|
|
$? = $chan->exit_status; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# if used with $chan->pty() we have to remove \r |
113
|
0
|
0
|
|
|
|
|
if ( !Rex::Config->get_no_tty ) { |
114
|
0
|
0
|
|
|
|
|
$in =~ s/\r//g if $in; |
115
|
0
|
0
|
|
|
|
|
$in_err =~ s/\r//g if $in_err; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
0
|
0
|
|
|
|
|
if (wantarray) { |
119
|
0
|
|
|
|
|
|
return ( $in, $in_err ); |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
0
|
|
|
|
|
|
return $in; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub net_ssh2_exec_output { |
126
|
0
|
|
|
0
|
0
|
|
my ( $ssh, $cmd, $callback ) = @_; |
127
|
|
|
|
|
|
|
|
128
|
0
|
|
|
|
|
|
my $chan = $ssh->channel; |
129
|
0
|
|
|
|
|
|
$chan->blocking(1); |
130
|
|
|
|
|
|
|
|
131
|
0
|
|
|
|
|
|
$chan->exec($cmd); |
132
|
|
|
|
|
|
|
|
133
|
0
|
|
|
|
|
|
while (1) { |
134
|
0
|
|
|
|
|
|
my $buf; |
135
|
|
|
|
|
|
|
my $buf_err; |
136
|
0
|
|
|
|
|
|
$chan->read( $buf, 15 ); |
137
|
0
|
|
|
|
|
|
$chan->read( $buf_err, 15 ); |
138
|
|
|
|
|
|
|
|
139
|
0
|
0
|
|
|
|
|
if ($callback) { |
140
|
0
|
|
|
|
|
|
&$callback( $buf, $buf_err ); |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
else { |
143
|
0
|
|
|
|
|
|
print $buf; |
144
|
0
|
|
|
|
|
|
print $buf_err; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
0
|
0
|
|
|
|
|
last unless $buf; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
0
|
|
|
|
|
|
$chan->close; |
151
|
0
|
|
|
|
|
|
$? = $chan->exit_status; |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
1; |