Re: [Ssh-sftp-perl-users] Handling Invalid Login Credentials
Brought to you by:
dbrobins
From: Russ B. <us...@gm...> - 2009-09-02 13:21:32
|
Leon, eval is generally the correct approach for retaining control when a failed login is encountered. Here is an example: # using PKI key pairs so no password is defined below eval { $sftp = Net::SFTP->new("$target_server", debug=>0) }; if ($@) { print "Log-in problem on server $target_server\n"; # jump to error handling subroutine of choice here # send email warning if desired here } else { print "Login succeeded to server $target server\n"; } The above code reliably traps login errors. However, there are some circumstances where eval alone can not trap the failure because $@ is not generated during the failure. An example is the SFTP "get" command, where $@ is generated when the "get" failure is on the local server but is not generated when the "get" failure is on the remote server. For example, if you try to get a file and pull it onto your local server and place it into a non-existent local directory then eval will generate $@ as expected. However, if you try to get a file from a directory that does not exist on a remote server, then $@ is not generated. (Note that SFTP 'get' has this peculiarity but SFTP 'put' does not). I too gave up on $SIG{__DIE__} because it reports other problems such as discrepancies not related to what I am trying to trap. So I turned to $SIG{__WARN__} as follows: $SIG{__WARN__} = \&alarm; sub alarm { print "While in subroutine $function\n"; print "Perl 'WARN' SIGNAL: @_\n"; $sig_warn_alarm = "true"; # used for Net::SFTP 'get' success analysis } Having defined the above when the script initiates, it is available for use when a subroutine needs it, such as: sub get_files_from_target_server { $sig_warn_alarm = "false"; eval { $sftp->get($remote_path_to_file, $local_path_for_file); }; if (($@ || ($sig_warn_alarm eq "true")) { # then the get failed -- but where is the problem? if ($@) { print "SFTP 'get' error on local server\n"; print "Get ERROR = $@\n"; } if ($sig_warn_alarm eq "true") { print "SFTP 'get' error caused by a problem on remote server\n"; # note the 'alarm' subroutine has its own print statements } } else { print "Detected no problems during SFTP 'get' command\n"; } # reset the $sig_warn_alarm variable so it is ready for the next get attempt # it does not reset automatically and neither does $SIG{__WARN__} $sig_warn_alarm = "false"; } # end of subroutine 'get_files_from_target_server The failed get will trigger $SIG{_WARN__} for both local and remote centered errors. But $@ is only generated for locally centered 'get' errors. Thus $@ is insufficient to prove no get error occurred. eval blocks are important beyond error trapping. For instance, the do_stat command has its own difficulties. A failed do_stat command will kill your script without notice of any kind unless protected in an eval block that also holds a 'die' statement. eval { $attrs = $sftp->do_stat($path_to_remote_file) or die "The do_stat failed: $!"; }; Related commands also require 'eval' protection to keep failures from silently killing your script: eval { $remote_file_size = $attrs->size; } Once the evals are in place, monitoring $@ can reliably be used to trap the results of do_stat related commands and the 'eval' prevents sudden silent script death when the command fails, such as would happen if the remote file did not exist. I hope this helps. I am so skittish about reliably detecting remote 'get' problems that I usually do a file size comparison between the local file and the remote file (stat for the local file and do_stat for the remote) to further prove there was no undetected 'get' failure. Russ On Tue, Sep 1, 2009 at 6:15 PM, Leon Kowalski <leo...@ya...>wrote: > I'm testing a script that uses Net::SFTP, and if I provide a bogus > password, the ssh->login kills my script with a "die": > > Permission denied at > /usr/local/pkg/perl/5.8.4/lib/site_perl/5.8.4/Net/SFTP.pm line 62 > > I am unable to find any way to handle this. I want to catch the error > (which is not very specific BTW) and call my own failure handler code to > exit the script on my terms. > > Is there a way to configure the call to Net::SFTP->new so that if it fails, > control returns back to my script? > > I tried using a warn handler, which had no effect. I also tried an ssh_args > containing "LogLevel QUIET" to no avail. If I use a $SIG{__DIE__}, it > catches all sorts of events prior to the "Permission denied" die signal. > > > > > > ------------------------------------------------------------------------------ > Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day > trial. Simplify your report design, integration and deployment - and focus > on > what you do best, core application coding. Discover what's new with > Crystal Reports now. http://p.sf.net/sfu/bobj-july > _______________________________________________ > Ssh-sftp-perl-users mailing list > Ssh...@li... > https://lists.sourceforge.net/lists/listinfo/ssh-sftp-perl-users > |