File Coverage

blib/lib/Vayne/SSH/Tunnel.pm
Criterion Covered Total %
statement 26 72 36.1
branch 0 20 0.0
condition 0 16 0.0
subroutine 9 13 69.2
pod 0 1 0.0
total 35 122 28.6


line stmt bran cond sub pod time code
1             package Vayne::SSH::Tunnel;
2              
3 1     1   12586 use strict;
  1         2  
  1         20  
4 1     1   15 use 5.008_005;
  1         2  
5              
6             our $VERSION = '0.01';
7              
8 1     1   422 use POSIX;
  1         4581  
  1         4  
9 1     1   2176 use YAML::XS;
  1         1773  
  1         40  
10 1     1   5 use File::Spec;
  1         0  
  1         14  
11 1     1   380 use Sys::Hostname;
  1         737  
  1         41  
12 1     1   494 use FindBin qw($Bin);
  1         668  
  1         77  
13 1     1   4 use Fcntl qw( :flock );
  1         1  
  1         76  
14 1     1   393 use Net::EmptyPort qw(empty_port);
  1         22439  
  1         530  
15              
16             sub Run
17             {
18 0     0 0   my(%option, $cmd, $lport) = @_;
19              
20 0           $lport = empty_port();
21 0           $cmd = _fmt_ssh(%option, lport => $lport );
22              
23 0 0         die "can not find user $option{user}" unless my(undef, undef, $uid, $gid) = getpwnam $option{user};
24              
25 0           POSIX::setgid($gid);
26 0           POSIX::setuid($uid);
27 0           print $cmd, "\n";
28              
29             #fork
30 0           setpgrp(0,0);
31 0     0     $SIG{TERM} = $SIG{HUP} = sub{ print "Sig recv, killed!\n"; kill 'KILL', -$$};
  0            
  0            
32 0     0     $SIG{ALRM} = sub{ print "Alarm timeout, killed!\n"; kill 'KILL', -$$};
  0            
  0            
33              
34 0 0         my($pid, %grep, $lock_fh) = open my $fh, "$cmd|" or die "can't fork cmd $cmd";
35              
36 0 0         alarm $option{timeout} if $option{timeout};
37              
38             #read
39 0           $|++;
40            
41 0           READ: while(my $line = <$fh>)
42             {
43 0           alarm 0;
44 0           print $line;
45              
46             #write conf
47 0 0 0       if( $line =~ /Entering interactive session/ and $option{confdir} )
48             {
49 0           my $path = File::Spec->join($option{confdir}, $option{name}. ".". $$);
50              
51 0 0 0       unless (
      0        
52             not defined $lock_fh
53             and open $lock_fh, '>', $path
54             and flock $lock_fh, LOCK_EX | LOCK_NB
55             )
56             {
57 0           warn "can not open $path";
58 0           last READ;
59             }
60              
61 0           print $lock_fh YAML::XS::Dump { $option{title} => "127.0.0.1:$lport" };
62 0           $lock_fh->flush;
63            
64            
65             }
66              
67 0 0 0       print "channel open reach $option{max_channel}!\n" and last if $line =~ /channel (\d+):/ && $1 >= $option{max_channel};
      0        
68              
69 0           while(my($word, $times) = each %{ $option{grep_word} })
  0            
70             {
71 0 0         next unless $line =~ /$word/;
72 0           $grep{$word} += 1;
73 0 0 0       print "match '$word' reach $times!\n" and last READ if $grep{$word} >= $times;
74             }
75              
76 0 0         alarm $option{timeout} if $option{timeout};
77             }
78              
79 0           kill 'KILL', -$$;
80             }
81              
82              
83             #ssh -tt -L 127.0.0.1:7920:127.0.0.1:7920 foo@ser1.net ssh -v -o 'ServerAliveInterval=10' -o 'ServerAliveCountMax=3' -tt -L localhost:7920:127.0.0.1:7920 ser2.net ssh -v -o 'ServerAliveInterval=10' -o 'ServerAliveCountMax=1' -N -L localhost:7920:127.0.0.1:1080 foo@ser3.net 2>&1
84             sub _fmt_ssh
85             {
86 0     0     my(%opt, @way, $option, $cmd, $hostname) = @_;
87 0           @way = @{ $opt{way} };
  0            
88 0           $option = join ' ', map{ "-o '$_'" }@{$opt{ option }};
  0            
  0            
89              
90 0           $hostname = hostname;
91 0 0         shift @way if $way[0] =~ /\@$hostname$/;
92              
93 0           for(splice @way, 0, -1)
94             {
95 0           $cmd .= sprintf "ssh -tt %s -L 127.0.0.1:%s:127.0.0.1:%s %s ", $option, $opt{lport}, $opt{lport}, $_;
96             }
97              
98 0           $cmd .= sprintf "ssh -v %s -N -L 127.0.0.1:%s:127.0.0.1:%s %s 2>&1", $option, $opt{lport}, $opt{dport}, $way[-1];
99             }
100              
101             1;
102             __END__