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
>
|