App-SimpleBackuper

 view release on metacpan or  search on metacpan

local/lib/perl5/Net/SFTP/Foreign/Backend/Unix.pm  view on Meta::CPAN


            my $port = delete $opts->{port};
	    my $ssh1 = delete $opts->{ssh1};

            my $more = delete $opts->{more};
            defined $more and !ref($more) and $more =~ /^-\w\s+\S/ and
                warnings::warnif("Net::SFTP::Foreign", "'more' argument looks like it should be split first");
            my @more = _ensure_list $more;

            my @preferred_authentications;
            if (defined $key_path) {
                push @preferred_authentications, 'publickey';
                push @open2_cmd, map { -i => $_ } _ensure_list $key_path;
            }

            if ($ssh_cmd_interface eq 'plink') {
                push @open2_cmd, -P => $port if defined $port;
                if (defined $pass and !$pass_is_passphrase) {
                    warnings::warnif("Net::SFTP::Foreign", "using insecure password authentication with plink");
                    push @open2_cmd, -pw => $pass;
                    undef $pass;
                }

            }
            elsif ($ssh_cmd_interface eq 'ssh') {
                push @open2_cmd, -p => $port if defined $port;
		if (defined $pass and !$pass_is_passphrase) {
		    push @open2_cmd, -o => 'NumberOfPasswordPrompts=1';
                    push @preferred_authentications, ('keyboard-interactive', 'password');
		}
                if (@preferred_authentications
                    and not grep { $more[$_] eq '-o' and
                                       $more[$_ + 1] =~ /^PreferredAuthentications\W/ } 0..$#more-1) {
                    push @open2_cmd, -o => 'PreferredAuthentications=' . join(',', @preferred_authentications);
                }
            }
            elsif ($ssh_cmd_interface eq 'tectia') {
            }
            else {
                die "Unsupported ssh_cmd_interface '$ssh_cmd_interface'";
            }

            push @open2_cmd, -l => $user if defined $user;
            push @open2_cmd, @more;
            push @open2_cmd, $host;
	    push @open2_cmd, ($ssh1 ? "/usr/lib/sftp-server" : -s => 'sftp');
        }

        my $redirect_stderr_to_tty = ( defined $pass and
                                       ( delete $opts->{redirect_stderr_to_tty} or $ssh_cmd_interface eq 'tectia' ) );

        $redirect_stderr_to_tty and ($stderr_discard or $stderr_fh)
            and croak "stderr_discard or stderr_fh can not be used together with password/passphrase "
                          . "authentication when Tectia client is used";

	$debug and $debug & 1 and _debug "ssh cmd: @open2_cmd\n";

	%$opts and return; # Net::SFTP::Foreign will find the
                           # unhandled options and croak

	if (${^TAINT} and Scalar::Util::tainted($ENV{PATH})) {
            _tcroak('Insecure $ENV{PATH}')
        }

	if ($stderr_discard) {
	    $stderr_fh = $backend->_open_dev_null($sftp) or return;
	}

        if (defined $pass) {
            # user has requested to use a password or a passphrase for
            # authentication we use IO::Pty to handle that

            eval { require IO::Pty; 1 }
                or croak "password authentication not available, IO::Pty is not installed or failed to load: $@";

            local ($ENV{SSH_ASKPASS}, $ENV{SSH_AUTH_SOCK}) if $pass_is_passphrase;

            my $name = $pass_is_passphrase ? 'Passphrase' : 'Password';

	    my $child;
            my $pty = IO::Pty->new;

            $redirect_stderr_to_tty and $stderr_fh = $pty->slave;

            $child = $backend->_open4($sftp, $sftp->{ssh_in}, $sftp->{ssh_out}, $stderr_fh, $pty, @open2_cmd);
            unless (defined $child) {
                $sftp->_conn_failed("Bad ssh command", $!);
                return;
            }
            $sftp->{pid} = $child;
            open my $pty_dup, '+>&', $pty; # store pty as a file handler instead of a object in
                                           # order to save it from being destroyed too early
                                           # during global destruction
            $sftp->{_pty} = $pty_dup;

            $debug and $debug & 65536 and _debug "starting password authentication";
            my $rv = '';
            vec($rv, fileno($pty), 1) = 1;
            my $buffer = '';
            my $at = 0;
            my $password_sent;
            my $start_time = time;
            while(1) {
                if (defined $sftp->{_timeout}) {
                    $debug and $debug & 65536 and _debug "checking timeout, max: $sftp->{_timeout}, ellapsed: " . (time - $start_time);
                    if (time - $start_time > $sftp->{_timeout}) {
                        $sftp->_conn_failed("login procedure timed out");
                        return;
                    }
                }

                if (waitpid($child, POSIX::WNOHANG()) > 0 or $! == Errno::ECHILD()) {
                    undef $sftp->{pid};
                    my $err = $? >> 8;
                    $sftp->_conn_failed("SSH slave exited unexpectedly with error code $err");
                    return;
                }

                $debug and $debug & 65536 and _debug "waiting for data from the pty to become available";

                my $rv1 = $rv;



( run in 0.880 second using v1.01-cache-2.11-cpan-39bf76dae61 )