#!/usr/bin/perl -U # $version = "2.6"; # written by Herb Rubin herbr@pfinders.com 09/04/2014 # www.pfinders.com # # Purpose: #---------- # Securely send (upload) a file using sftp (over ssh) # # It works with a password or preshared keys. # If password is blank then it assumes preshared keys. # # Use it like this: sftppush -f /path/to/file # Requires: /usr/bin/expect to be installed # $progname = $0; use Getopt::Std; # # Begin User Defined Section #---------------------------- my $tempscript = "/tmp/sftp_script"; my $host = "ftp.domain.com"; my $port = "22"; my $user = "bob"; my $password = "flaDfld3d"; # if blank then assume preshared keys my $remote = ""; # remote directory to upload to, blank is ok # End User Defined Section #---------------------------- $pid = $$; $progname = $1 if ($progname =~ /\/(\w+)$/); $ENV{'PATH'} = '/usr/bin:/usr/bin/X11:/sbin:.'; &getopts("ahf:u:p:s:r:vo:",\%Options); if (! -e "/usr/bin/expect") { print "Error: The requisite /usr/bin/expect not found\n"; exit; } &usage if ($Options{'h'}); if ($Options{'u'} ne "") { $user = "$Options{'u'}"; } if ($user eq "") { print "$progname: User id missing, try -u user\n"; } if ($Options{'p'} ne "") { $password = "$Options{'p'}"; } if ($Options{'o'} ne "") { $port = "$Options{'o'}"; } if ($Options{'s'} ne "") { $host = "$Options{'s'}"; } if (host eq "") { print "$progname: FTP Server missing, try -s server\n"; } if ($Options{'r'} ne "") { $remote = "$Options{'r'}"; } $filename = "$Options{'f'}"; if (-e "$filename") { ############################################ # There is some data to upload, so send it # ############################################ $results = &send_file; print $results if ($Options{'v'}); } else { if ($filename eq "") { print "filename to push was not provided, use -f file\n"; } else { print "$progname: $filename does not exist, nothing uploaded via FTP\n"; } } exit; sub usage { print <<EOF; $progname usage: $progname [-hvV] -s ftp.server.com -u user -p password -f /path/to/file Upload a file to an sftp server (ssh) Where: -f filename file to upload -s ftp.server.name hostname of ftp server -u userid login with userid to ftp server -p password login with password not preshared keys -o port sftp port, default 22 -a send in ascii mode, defaults to binary -r remotedirectory change to this directory on ftp server -v verbose mode -V show version (currently $version) If password is not specified then it requires preshared keys ssh-keygen -t dsa on remote machine: cat identity.pub >> ~/.ssh/authorized_keys Note: If password is specified on the command line and includes symbols, surround it with single quotes. Examples: $progname -f /tmp/data.txt $progname -p 2222 -f /tmp/data.txt EOF exit; } sub send_file { my $cmd; my $sftpscript = "/tmp/sftpscript$pid"; my $tempscript = "/tmp/tempscript$pid"; if ($host eq "") { print "$progname: remote hostname missing, nothing sent\n"; return; } if ($user eq "") { print "$progname: user missing, nothing sent\n"; return; } print "Connecting to sftp site $host\n" if ($Options{'v'}); if (open PFILE, ">$sftpscript") { if ($remote ne "") { print PFILE "cd $remote\n"; } print PFILE "put $filename\n"; print PFILE "quit\n"; close PFILE; } else { print "$progname: failed to create sftp script $sftpscript\n"; } chmod 0660, $sftpscript; if ($port ne "22") { $cmd = "sftp -o batchmode=no -o Port=$port -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -b $sftpscript $user\@$host"; } else { $cmd = "sftp -o batchmode=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -b $sftpscript $user\@$host"; } my $results = ""; if ($password ne "") { ############################################### # use expect to force feed a password to sftp # ############################################### if (open PFILE, ">$tempscript") { print PFILE <<EOF; #!/usr/bin/expect spawn $cmd for {} 1 {} { expect { assword: { sleep 1; set send_human {.1 .3 1 .07 .1 .3 .1} ; send -h \"$password\\r\" } failed: { exit } eof exit } } EOF close PFILE; chmod 0700, $tempscript; $results = `$tempscript`; $results =~ s/\r//g; # remove CRs unlink $tempscript unless ($Options{'v'}); unlink $sftpscript unless ($Options{'v'}); } else { print "$progname: Cannot write to $tempscript, sftp session aborted\n"; } } else { $results = `$cmd`; unlink $sftpscript unless ($Options{'v'}); } if ($results =~ /closed by remote host/) { print "$progname: failed to login to $host, firewall issue?\n"; } if ($results =~ /Host not found/) { print "$progname: failed to login to $host, DNS failure?\n"; } if ($results =~ /ermission denied/) { print "$progname: failed to login to $host, password incorrect?\n"; } return $results; }