CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
SFTP

 



ogit2
Novice

Mar 7, 2018, 9:28 AM

Post #1 of 7 (4793 views)
SFTP Can't Post

Hi

We use Net::FTPSSL the following code because Net::SFTP is not available on a Windows Install (using ActiveState Perl). Dependencies have no easy Windows equivalents.

We now have been asked by our customer to use public/private keys. We simply don't have a choice and are really not experts on Perl syntax, etc. Is someone able to modify the code below or direct us with really easy instructions on how to do this.



Code
#!C:\Perl\bin\perl.exe 
use Net::FTPSSL;

my $ftp_site = 'ftp.securecustomer.net';
my $ftp_dir = '';
my $ftp_user = '<user id>';
my $ftp_password = '<password>';

my $ftps = Net::FTPSSL->new($ftp_site, Port => 21, Encryption => EXP_CRYPT, Croak => 1, Trace => 1, OverridePASV => "<your IP address>", Debug => 2) or die "Can't open [SERVERNAME]\n$Net::FTPSSL::ERRSTR";
$ftps->login($ftp_user, $ftp_password) or die "Can't login: ";

$ftps->cwd("/PWImages/InReq") or die "Can't change directory: ";
$ftps->quot("PASV");
$ftps->binary() or die "Can't change directory: ";
$ftps->put("test.tif") or die "Can't get file: ";
#$ftps->get("anyfile.txt") or die "Can't get file: " . $ftps->last_message();

$ftps->quit();



FishMonger
Veteran / Moderator

Mar 7, 2018, 1:57 PM

Post #2 of 7 (4781 views)
Re: [ogit2] SFTP [In reply to] Can't Post

My recommendation would be to first install MinGW which will give you the required C compiler you need to build modules, then install Net::SFTP::Foreign (or if you prefer Net::SFTP).

https://sourceforge.net/projects/mingw/
http://search.cpan.org/~salva/Net-SFTP-Foreign-1.89/lib/Net/SFTP/Foreign.pm


(This post was edited by FishMonger on Mar 7, 2018, 1:58 PM)


ogit2
Novice

Mar 16, 2018, 3:22 AM

Post #3 of 7 (4630 views)
Re: [ogit2] SFTP [In reply to] Can't Post

Hi this is a tricky one as Net::SFTP::Foreign will install on Active Perl Windows but then errors as it requires Net::SFTP installed. It requests backend Net_SSH2 module which is the Net::SFTP module which cannot be installed on Windows. I cannot locate a version that will compile (including dependencies).

However, I have a workaround for all Windows users that works!! The purists will not like it, but it works in Perl!

I will post shortly.


Code
use Net::SFTP::Foreign; 
my $sftp = Net::SFTP::Foreign-> new(host => $host, backend => 'Net_SSH2', user => $user, key_path => $privateKey, passphrase => $passphrase,);



(This post was edited by ogit2 on Mar 16, 2018, 3:23 AM)


ogit2
Novice

Mar 16, 2018, 3:42 AM

Post #4 of 7 (4628 views)
Re: [ogit2] SFTP [In reply to] Can't Post

SFTP in Perl workaround. Please note that this IS a workaround (DRAFT version) but it works! (Step 4). Also note that for public/private keys we used Putty to generate.

STEP1. Install WINSCP https://winscp.net/eng/index.php

STEP2. Register the COM components as they may not register.


Code
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb:WinSCPnet32.tlb 
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe WinSCPnet.dll /codebase /tlb:WinSCPnet64.tlb



STEP 3. Run WinSCP, set up SFTP account and test. Make sure it works. Once it works, click on manage and generate session/url code. The data here will be required in Perl. This is important if you are a basic user.

STEP 4. See example Perl code below. Feel free if you are clever to modify and make it better for other users.



Code
#!C:\Perl\bin\perl.exe 
use File::Copy;
use Time::Local;
use Win32::OLE;
use Win32::OLE::Const;
use Win32::OLE::Variant;


Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE);
my $session = Win32::OLE->new('WinSCP.Session');
my $consts = Win32::OLE::Const->Load($session);
my $sessionOptions = Win32::OLE->new('WinSCP.SessionOptions');


my $host = 'FTPSITE';
my $user = 'FTPUSER';
my $privateKey = "PATH_AND_PRIVATE_KEY_NAME";
my $file = "test.txt";
my $passphrase = "";
my $put = 0;
my $get = 1;
my $proc = $$;

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon = $mon + 1;
$mon = trim0($mon);
$mday = trim0($mday);
$hour = trim0($hour);
$min = trim0($min);
$sec = trim0($sec);
my $todaydate = "$year$mon$mday\_$hour$min$sec_";


$sessionOptions->{'Protocol'} = $consts->{'Protocol_Sftp'};
$sessionOptions->{'HostName'} = $host;
$sessionOptions->{'UserName'} = $user;
$sessionOptions->{'SshPrivateKeyPath'} = $privateKey;

$sessionOptions->{'PrivateKeyPassphrase'} = 'PRIVATEKEY';
$sessionOptions->{'SshHostKeyFingerprint'} = 'FINGERPRINT';

# Connect
$session->Open($sessionOptions);

# Upload files
my $transferOptions = Win32::OLE->new('WinSCP.TransferOptions');

$transferOptions->{'TransferMode'} = $consts->{'TransferMode_Ascii'};

my $cfiledir="WORKDIRECTORY";
print "$cfiledir \n";
chdir($cfiledir) or die "Cant chdir to $path $!";

#START: PUT FILES
if ($put == 1)
{
my $transferResult = $session->PutFiles('test.txt', '/Test/Out/', FALSE, $transferOptions);

# Throw on any error
$transferResult->Check();

# Print results
my $items = Win32::OLE::Enum->new($transferResult->{'Transfers'});
my $item;
while (defined($item = $items->Next))
{
print $item->{'FileName'} . "\n";
}
}
#END: PUT FILES

#START: GET FILES
print "Start: Getting Files from SFTP \n";
if ($get == 1)
{

#my $transferResult = $session->FileExists(string path);

my $transferResult = $session->GetFiles('/Test/Out/',$cfiledir, FALSE, $transferOptions);

# Throw on any error
$transferResult->Check();

# Print results
my $items = Win32::OLE::Enum->new($transferResult->{'Transfers'});
my $item;
while (defined($item = $items->Next))
{
my $filename = $item->{'FileName'};
print "File Received: " . $filename . "\n";
# START: Change received filename with datestamp
my $filename2 = $filename;
$filename2 =~s/.*\///;
my $filename3 = $todaydate . "_" . $filename2;
move($filename2,$filename3);
# END : Change received filename with datestamp
my $removalResult = $session->RemoveFiles($filename);
}

}
print "End: Getting Files from SFTP \n";
#END: GET FILES

exit;

sub trim0
{
my ($trims) = @_;

$trims =~ s/^\s+//;
$trims =~ s/\s+$//;
$myLength = length($trims);
if ($myLength == 1)
{
$trims = "0$trims";
}
return $trims;
}



(This post was edited by ogit2 on Mar 16, 2018, 5:01 AM)


FishMonger
Veteran / Moderator

Mar 16, 2018, 7:12 AM

Post #5 of 7 (4619 views)
Re: [ogit2] SFTP [In reply to] Can't Post


Quote
Hi this is a tricky one as Net::SFTP::Foreign will install on Active Perl Windows but then errors as it requires Net::SFTP installed. It requests backend Net_SSH2 module which is the Net::SFTP module which cannot be installed on Windows.

You are mistaken. Net::SFTP::Foreign AND Net::SFTP can be installed on Windows.


Code
c:\test>perl -MNet::SFTP -e 1 

c:\test>perl -MNet::SFTP::Foreign -e 1

c:\test>

I installed them using cpan and did not have any proplems.


Using Win32::OLE and winscp is not the choice I'd make, but if you want a Windows only solution then go ahead and use it.

I would, however, strongly recommend changing the way you build your $todaydate string. That is perl 4 coding style and is very messy/ugly. Instead, use the strftime function from the POSIX module.


Code
use POSIX qw( strftime ); 

my $todaydate = strftime("%Y%m%d_%H%M%S\n", localtime);


This is perl not php. That trim sub could be replaced with a single call to the sprintf() function, but even that is not needed if you use the strftime function like I showed.

Also, ALWAYS use the warnings and strict pragmas in your scripts. They will point out lots of your coding mistakes.


(This post was edited by FishMonger on Mar 16, 2018, 7:16 AM)


ogit2
Novice

Mar 16, 2018, 7:43 AM

Post #6 of 7 (4612 views)
Re: [ogit2] SFTP [In reply to] Can't Post

Hi

Thank you for the pointer on date. Appreciated.

When we have time, we will have to load up a clean install of Strawberry Perl, and try again. We have tried Net::SSH2, Net::SFTP but failed and tried various web advice but not made headway. ppm and cpan dependencies fail every time. WINscp would not have been our first choice either but it works and gets us past requirements for customer.

If we get time and make it past this we will post.


ogit2
Novice

Mar 21, 2018, 4:41 AM

Post #7 of 7 (4475 views)
Re: [ogit2] SFTP [In reply to] Can't Post

Hi

An update to using WINSCP. the following line is not required as in the current version of WINSCP, it is ignored.


Code
#$sessionOptions->{'PrivateKeyPassphrase'} = 'PRIVATEKEY';


It seems they do not want any text based security to be present which is clever thinking but a pain! Instead you must run the software pageant on the server and enter the private key path and keyphrase, which then remains encrypted in memory. The Perl code then works.

The software pageant comes within the installation and can be run from within WINSCP or downloaded as a stand alone exe from the WINSCP site.

The drawback is that this keyphrase has to be re-entered every time server reboots. there probably is a work around for that also. Not found it yet.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives