MOON
Server: Apache/2.2.31 (Unix) mod_ssl/2.2.31 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4
System: Linux csr818.wilogic.com 2.6.18-419.el5xen #1 SMP Fri Feb 24 22:50:37 UTC 2017 x86_64
User: digitals (531)
PHP: 5.4.45
Disabled: NONE
Upload Files
File: //scripts.20110531.215904.25158/sshcontrol
#!/usr/bin/perl
# cpanel - sshcontrol                             Copyright(c) 2010 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

package Script::SSHControl;

BEGIN { unshift @INC, '/usr/local/cpanel'; }

use Cpanel::CleanupStub ();
use strict;

$| = 1;

$ENV{'TERM'} = 'dumb';

my $hasexp = 0;
eval {
    require IO::Tty;
    require Expect;
    $hasexp = 1;
};

if ( !$hasexp ) {
    print "Broken Expect.pm, please reinstall the Expect perl module.\n";
    die;
}

__PACKAGE__->script(@ARGV) unless caller();

sub script {
    my ($class, @argv) = @_;
    #%ARGS
    #{ctl}      = (ssh|scp)
    #{host}     = (host*)
    #{user}     = (user*)
    #{hash}     = (security hash)
    #{sumethod} = (usesu)
    #{srcfile}  = (*)
    #{destfile} = (*)

    Cpanel::CleanupStub::closefds();

    my $sshkey = 'perl -e \'print "\t==sshcontroloutput==\n"\'';

    my (%ARGS) = parseargv(@argv);

    my $line = <STDIN>;
    chomp($line);

    my $rpass = $line;
    my $upass;
    my $rpassforsudo = 0;
    if ( $ARGS{'authmethod'} ne 'root' ) {
        if ( $ARGS{'escmethod'} eq 'su' )   { $ARGS{sumethod}   = 1; }
        if ( $ARGS{'escmethod'} eq 'sudo' ) { $ARGS{sudomethod} = 1; }
        if ( $ARGS{sumethod} ) {
            ( $upass, $rpass ) = split( / /, $line );
        }
        elsif ( $ARGS{sudomethod} ) {
            if ( $ARGS{authtype} eq 'publickey' ) {
                ( $upass, $rpass ) = split( / /, $line );
                $rpassforsudo = 1;
            }
            else {
                $upass = $line;
            }
        }
        else {
            $upass = $line;
        }
    }

    my ( $prog, $cmdargs ) = ssh_options( \%ARGS );

    my $cmd;
    if ( $prog eq 'ssh' ) {
        $cmd = <STDIN>;
        chomp($cmd);

        if ( $cmd eq "" ) {
            print "Sorry, you cannot execute an empty command!\n";
            exit();
        }

        if ( !$ARGS{sumethod} && !$ARGS{sudomethod} ) {
            push( @{$cmdargs}, ${cmd} );
        }
    }

    my $exp = Expect->spawn( $prog, @{$cmdargs} ) or die "Cannot spawn $prog $!\n";

    my $pid = $exp->pid();

    my $iauth = 1;
    if ( $ARGS{sumethod} || $ARGS{sudomethod} ) {
        if ( !$upass ) { $iauth = 0; }
    }
    else {
        if ( !$rpass ) { $iauth = 0; }
    }

    if ($iauth) {

        #password auth or public/priv key with a passphrase
        my $eof = 0;
        $exp->expect(
            90,
            [ 'eof', sub { $eof = 1; } ],
            [ '-re', 'No such file or directory',  sub { print "\nsshfileprob\n";          exit(); } ],
            [ '-re', 'REMOTE HOST IDENTIFICATION', sub { print "\nsshhostproblem\n";       exit(); } ],
            [ '-re', 'Name or service not known',  sub { print "\nsshhostnotfound\n";      exit(); } ],
            [ '-re', 'Connection timed out',       sub { print "\nsshconnecttimeout\n";    exit(); } ],
            [ '-re', 'Connection closed',          sub { print "\nsshdisconnectproblem\n"; exit(); } ],
            [ '-re', 'No route to host',           sub { print "\nsshdisconnectproblem\n"; exit(); } ],
            [ '-re', 'Connection refused',         sub { print "\nsshdisconnectproblem\n"; exit(); } ],
            [ '-re', 'timeout',                    sub { print "\nsshconnectproblem\n";    exit(); } ],
            [ '-re', 'Permission denied',          sub { print "\nsshcmdpermissiondeny";   exit(); } ],
            '-re',
            'Enter passphrase',
            '-re',
            'assword:'
        );
        if ($eof) {
            print "\nsshcmdpermissiondeny";
            exit();
        }
    }

    if ( $ARGS{ctl} eq "ssh" ) {
        if ( $ARGS{sumethod} || $ARGS{sudomethod} ) {
            my $skipp = 0;
            $exp->send("$upass\r");
            $exp->expect( 30, [ '-re', 'Permission denied', sub { print "\nsshcmdpermissiondeny"; exit(); } ], [ '-re', 'assword:', sub { print "\nsshcmdpermissiondeny"; exit(); } ], [ '-re', 'Enter passphrase', sub { print "\nsshcmdpermissiondeny"; exit(); } ], '-re', '\]$', '-re', '\$$', '-re', '\#$', '-re', '\] ', '-re', '\$ ', '-re', '\# ' );
            $exp->send("export LANG=C ; setenv LANG C ; echo \${LANG}_SSH_CLIENT=\${SSH_CLIENT}\r");
            my $sshclient = '';
            $exp->expect( 15, [ 'C_SSH_CLIENT=\S+', sub { my $self = shift; my $string = $self->exp_match(); $sshclient = $string; } ], [ 'default', sub { $skipp = 1; } ] );

            if ( !$skipp ) {
                $exp->expect( 10, [ '-re', '\] ', sub { $skipp = 1; } ], [ '-re', '\$ ', sub { $skipp = 1; } ], [ '-re', '\# ', sub { $skipp = 1; } ], [ '-re', '\]$', sub { $skipp = 1; } ], [ '-re', '\$$', sub { $skipp = 1; } ], [ '-re', '\#$', sub { $skipp = 1; } ] );
            }
            else {
                print STDERR "Unable to set C_SSH_CLIENT!\n";
            }

            my $skippass = 0;
            if ( $ARGS{sudomethod} ) {
                $exp->send("sudo su\r");
                $exp->expect(
                    30, 'assword:',
                    [ '-re', 'denied',             sub { print "\nsshcmdpermissiondeny\n"; exit(); } ],
                    [ '-re', 'not in the sudoers', sub { print "\nsshcmdpermissiondeny\n"; exit(); } ],
                    [ '-re', '\] ', sub { $skippass = 1; } ],
                    [ '-re', '\$ ', sub { $skippass = 1; } ],
                    [ '-re', '\# ', sub { $skippass = 1; } ],
                    [ '-re', '\]$', sub { $skippass = 1; } ],
                    [ '-re', '\$$', sub { $skippass = 1; } ],
                    [ '-re', '\#$', sub { $skippass = 1; } ],
                );
                if ( !$skippass ) {
                    if ($rpassforsudo) {
                        $exp->send("$rpass\r");
                    }
                    else {
                        $exp->send("$upass\r");
                    }
                }
                if ($skippass) { print STDERR "sudo is cached!\n"; }
            }
            else {
                $exp->send("su\r");

                my $waitforprompt = 0;
                $exp->expect( 10, '-re', 'assword:', [ 'denied', sub { print "\nsshcmdpermissiondeny\n"; exit(); } ], [ 'timeout', sub { $waitforprompt = 1; } ] );

                if ($waitforprompt) {
                    $exp->expect( 10, '-re', 'assword:', [ '-re', '\] ', sub { $skippass = 1; } ], [ '-re', '\$ ', sub { $skippass = 1; } ], [ '-re', '\# ', sub { $skippass = 1; } ], [ '-re', '\]$', sub { $skippass = 1; } ], [ '-re', '\$$', sub { $skippass = 1; } ], [ '-re', '\#$', sub { $skippass = 1; } ] );
                }
                $exp->send("$rpass\r");
            }
            if ($skippass) { print STDERR "su is cached!\n"; }
            if ( !$skippass ) {
                $exp->expect( 30, [ '-re', 'incorrect', sub { print "\nsshcmdpermissiondeny\n"; exit(); } ], [ '-re', 'Sorry', sub { print "\nsshcmdpermissiondeny\n"; exit(); } ], [ '-re', 'assword:', sub { print "\nsshcmdpermissiondeny\n"; exit(); } ], '-re', '\] ', '-re', '\$ ', '-re', '\# ', '-re', '\]$', '-re', '\$$', '-re', '\#$' );
            }
            if ( $ARGS{hash} ne "" ) {    #alabanz kludge
                $exp->send("export DONOTSTEALME=$ARGS{hash}\r");
                $exp->expect( 30, '-re', '\] ', '-re', '\$ ', '-re', '\# ', '-re', '\]$', '-re', '\$$', '-re', '\#$' );
            }
            if ( $sshclient ne '' ) {
                chomp($sshclient);
                my ( $var, $value ) = split( /=/, $sshclient );
                $exp->send("setenv SSH_CLIENT $value ; export SSH_CLIENT=$value\r");
                $exp->expect( 30, '-re', '\] ', '-re', '\$ ', '-re', '\# ', '-re', '\]$', '-re', '\$$', '-re', '\#$' );

                print STDERR "Carries SSH_CLIENT\n";
            }

            $exp->send("set TERM dumb ; export TERM=dumb\r");

            $exp->expect( 30, '-re', '\] ', '-re', '\$ ', '-re', '\# ', '-re', '\]$', '-re', '\$$', '-re', '\#$' );

            $exp->send("stty columns 80\r");

            $exp->expect( 30, '-re', '\] ', '-re', '\$ ', '-re', '\# ', '-re', '\]$', '-re', '\$$', '-re', '\#$' );

            $exp->send("stty columns 80\r");

            $exp->expect( 30, '-re', '\] ', '-re', '\$ ', '-re', '\# ', '-re', '\]$', '-re', '\$$', '-re', '\#$' );

            $exp->send( $sshkey . ';' . $cmd . ';echo;' . $sshkey . "\r" );
            $exp->expect( 20,    "\t==sshcontroloutput==" );
            $exp->expect( 15000, "\t==sshcontroloutput==" );

            my $dl = 0;
            for ( my $i = 0; $i < 6; $i++ ) {
                if ( $i % 2 == 0 ) {
                    $exp->send("exit\r");
                }
                else {
                    $exp->send("logout\r");
                }
                $exp->expect( 10, [ 'eof', sub { $dl = 1; } ], [ '-re', 'closed', sub { $dl = 1; } ], 'default', '-re', "not found", '-re', '\] ', '-re', '\$ ', '-re', '\# ', '-re', '\]$', '-re', '\$$', '-re', '\#$' );
                last if ($dl);
            }
            if ( !$dl ) {
                $exp->expect( 15000, 'eof' );
            }
            $exp->soft_close();
            waitpid( $pid, 0 );

        }
        else {
            if ( $rpass eq '' ) {
                $exp->send("$upass\r");
            }
            else {
                $exp->send("$rpass\r");
            }
            print "\t==sshcontroloutput==";
            $exp->expect( 15000, [ 'Permission denied', sub { print "\nsshcmdpermissiondeny\n"; } ], [ qr/assword:\s*$/i, sub { print "\nsshcmdpermissiondeny\n"; } ], [ '-re', 'Enter passphrase', sub { print "\nsshcmdpermissiondeny\n"; } ], 'eof' );
            $exp->soft_close();
            waitpid( $pid, 0 );
            print "\t==sshcontroloutput==\n";
        }
    }
    elsif ( $ARGS{ctl} eq "scp" ) {
        $exp->send("$rpass\r");
        $exp->expect( 15000, [ '/scp: ', sub { print "\nsshscpdisabled\n"; exit(); } ], [ '-re', 'Enter passphrase', sub { print "\nsshcmdpermissiondeny"; exit(); } ], [ 'Permission denied', sub { print "\nsshcmdpermissiondeny\n"; exit(); } ], [ qr/assword:\s*$/i, sub { print "\nsshcmdpermissiondeny\n"; exit(); } ], 'eof' );
        $exp->soft_close();
        waitpid( $pid, 0 );
    }
}

sub parseargv {
    my @argv = @_;

    my (%args);
    while ( $#argv != -1 ) {
        $_ = $argv[0];
        if (/^\-\-/) {
            my $arg = shift(@argv);
            $arg =~ s/^\-\-//g;
            $arg =~ tr/[A-Z]/[a-z]/;
            my $value = shift(@argv);
            $args{$arg} = $value;
        }
        else {
            last;
        }
    }
    return (%args);
}

sub ssh_options {
    my $args = shift;

    my %ARGS = ();
    foreach my $key ( %{$args} ) {
        $ARGS{$key} = $args->{$key};
    }

    my (@CMDARGS) = ( "-o", "UserKnownHostsFile /dev/null", "-o", "StrictHostKeyChecking no" );
    if ( $ARGS{ctl} eq 'ssh' ) { push( @CMDARGS, "-q" ); }

    # using -q hides perm denied errors, but makes this work
    #
    if ( $ARGS{port} ne "" ) {
        if ( $ARGS{ctl} eq "ssh" ) {
            push( @CMDARGS, "-p" );
        }
        else {
            push( @CMDARGS, "-P" );
        }
        push( @CMDARGS, $ARGS{port} );
    }

    if ( $ARGS{authtype} eq 'publickey' ) {
        push( @CMDARGS, "-o", 'PasswordAuthentication no' );
        push( @CMDARGS, "-o", 'PubkeyAuthentication yes' );
    }
    else {
        push( @CMDARGS, "-o", 'PasswordAuthentication yes' );
        push( @CMDARGS, "-o", 'PubkeyAuthentication no' );
    }

    if ( $ARGS{authtype} eq 'publickey' && $ARGS{sshkey} ) {
        $ARGS{sshkey} =~ s/\.\.//g;
        $ARGS{sshkey} =~ s/\///g;
        push( @CMDARGS, "-i", ( getpwuid($>) )[7] . "/.ssh/" . $ARGS{sshkey} );
    }

    if ( $ARGS{authmethod} ne '' ) {
        if ( $ARGS{authmethod} eq 'root' ) { $ARGS{user} = 'root'; }
        if ( $ARGS{authmethod} eq 'user' ) { $ARGS{user} = $ARGS{authuser}; }
    }

    
    if ( $ARGS{user} eq "" ) {
        print "Sorry, you must specify a user to login to the remote server as.";
        exit();
    }
    if ( $ARGS{host} eq "" ) {
        print "Sorry, you must specify a remote server.";
        exit();
    }

    if ( $ARGS{ctl} eq "ssh" ) {
        push( @CMDARGS, $ARGS{user} . '@' . $ARGS{host} );

        return ( 'ssh', \@CMDARGS );
    }
    elsif ( $ARGS{ctl} eq "scp" ) {
        if ( $ARGS{srcfile} eq "" ) {
            print "Sorry you must specify a source file.\n";
            exit();
        }
        if ( $ARGS{destfile} eq "" ) {
            print "Sorry you must specify a destfile file.\n";
            exit();
        }
        if ( $ARGS{direction} eq "" ) {
            print "Sorry you must specify a direction file.\n";
            exit();
        }

        if ( $ARGS{direction} eq "download" ) {
            push( @CMDARGS, $ARGS{user} . '@' . $ARGS{host} . ':' . $ARGS{srcfile} );
            push( @CMDARGS, $ARGS{destfile} );
        }
        else {
            push( @CMDARGS, $ARGS{srcfile} );
            push( @CMDARGS, $ARGS{user} . '@' . $ARGS{host} . ':' . $ARGS{destfile} );
        }

        return ( 'scp', \@CMDARGS );
    }
    else {
        print "Sorry, no app to control was specified!\n";
        die;
    }
}

1;