1use strict; 2use warnings; 3 4use Test::More; 5use File::Spec; 6use Socket qw(AF_UNIX SOCK_STREAM PF_UNSPEC); 7 8sub sshd_cmd { 9 my $sc_name = 'sshd'; 10 11 my @paths = qw( /usr 12 /usr/local 13 /usr/local/openssh 14 /opt/ssh 15 /opt/openssh ); 16 17 @paths = map { ("$_/sbin/sshd", "$_/bin/sshd") } @paths; 18 19 for my $sshd (@paths) { 20 return $sshd if -x $sshd; 21 } 22} 23 24sub find_cmd { 25 my @path = qw(/usr/bin /bin 26 /usr/local/bin 27 /usr/sbin /sbin 28 /opt/bin ); 29 30 for my $cmd (@_) { 31 for my $path (@path) { 32 my $r = "$path/$cmd"; 33 return $r if -x $r; 34 } 35 } 36 undef; 37} 38 39sub shell_is_clean { 40 my $shell = (getpwuid($>))[8]; 41 42 socketpair my $up, my $down, AF_UNIX, SOCK_STREAM, PF_UNSPEC or return; 43 my $pid = fork; 44 unless ($pid) { 45 unless (defined $pid) { 46 diag "fork failed: $!"; 47 return; 48 } 49 open STDIN, '<&', $down; 50 open STDOUT, '>>&', $down; 51 open STDERR, '>>&', $down; 52 53 my $pid2 = fork; 54 if (defined $pid2 and not $pid2) { 55 setpgrp(0, 0); 56 # make bash read .bashrc on Debian systems: 57 delete $ENV{SHLVL}; 58 $ENV{SSH_CLIENT} = "::1 12345 22"; 59 do { exec $shell, '-c', 'echo ok' }; 60 } 61 exit 0; 62 } 63 close $down; 64 65 my $out = do { local $/; <$up> }; 66 if (!close($up) or $out ne "ok\n") { 67 diag "shell is not clean: \$?=$?, output...\n$out"; 68 return; 69 } 70 1 71} 72 73my @last_open_fds; 74 75sub count_open_fds { 76 @last_open_fds = (); 77 if ($^O eq 'linux') { 78 if (opendir my $dh, "/proc/$$/fd") { 79 my $count = 0; 80 while (defined(my $fd = readdir $dh)) { 81 push @last_open_fds, $fd if $fd =~ /^\d+$/; 82 } 83 return scalar @last_open_fds; 84 } 85 } 86 () 87} 88 89sub dump_open_fds { 90 my @ls = map { `ls -l /proc/$$/fd/$_ 2>&1` } @last_open_fds; 91 join('', "Currently open flle descriptors:\n", @ls); 92} 93 941; 95