Subject: | Change to improve response handling. |
I have attached a patch that is intended to improve the way that the
FTPSSL module handles multi-line responses from the server. We recently
turned on a multi-line login banner on our FTPS servers, which causes
breakage in Net::FTPSSL (the login banner gets read as output for
subsequent commands).
The problem appears to be (I am not an expert) that the sysread call
only gets a single line of text each time it is called. My solution is
to continue calling sysread until we receive a line that is formatted as
we expect, giving up after 10 lines.
My solution works for our situation, but it could definitely be improved
(read until no data returned or match found?). I have not seen any
regression issues, but we use this module in a very limited scope
(nagios connectivity check to our FTPS servers).
The attached diff includes my changes to the module. There are some
irrelevant versioning changes because I am tracking my changes in our
local subversion.
Distribution: Net-FTPSSL-0.04
Perl: v5.10.1
OS: FreeBSD 8.0-RELEASE-p2 FreeBSD 8.0-RELEASE-p2 #2
Subject: | ftpssl.diff |
--- Net-FTPSSL-0.04/FTPSSL.pm 2005-10-23 09:37:12.000000000 -0500
+++ FTPSSL.pm 2010-11-08 09:55:16.000000000 -0600
@@ -2,7 +2,7 @@
# Author : kral <kral at paranici dot org>
# Created : 01 March 2005
# Version : 0.04
-# Revision: $Id: FTPSSL.pm,v 1.24 2005/10/23 14:37:12 kral Exp $
+# Revision: $Id: FTPSSL.pm 268 2010-11-01 17:56:35Z tom $
package Net::FTPSSL;
@@ -15,7 +15,7 @@
use Carp qw( carp croak );
use Errno qw/ EINTR /;
-$VERSION = "0.04";
+$VERSION = "0.05";
@EXPORT = qw( IMP_CRYPT EXP_CRYPT );
use constant IMP_CRYPT => "I";
@@ -654,36 +654,31 @@
}
sub response {
- my $self = shift;
- my ( $data, $code );
-
- my $read = sysread( $self, $data, 4096);
- unless( defined $read ) {
- croak "Can't read on socket: $!";
+ my $self = shift;
+ my ( $data, $code );
+ my $ctr = 0;
+ while ( $ctr < 10 ) {
+ my $read = sysread( $self, $data, 8192);
+ unless( defined $read ) {
+ croak "Can't read on socket: $!";
+ }
+ my @lines = split( "\015\012", $data );
+ foreach my $line ( @lines ) {
+ $line =~ m/^(\d+)(\-?)(.*)$/s;
+ $code = $1;
+ print STDERR "<<< " . $line ."\n" if ref($self) eq "Net::FTPSSL" && ${*$self}{'debug'};
+
+ if ( ref($self) eq "Net::FTPSSL" ) {
+ ${*$self}{'last_ftp_msg'} = $line;
+ }
+
+ if ( $2 ne '-') {
+ return substr( $code, 0, 1 );
+ }
+ }
+ $ctr++;
}
-
- my @lines = split( "\015\012", $data );
-
- foreach my $line ( @lines ) {
-
-# $data = $self->getline();
-# $data =~ m/^(\d+)(\-?)(.*)$/s;
- $line =~ m/^(\d+)(\-?)(.*)$/s;
-
- $code = $1;
- print STDERR "<<< " . $line ."\n"
- if ref($self) eq "Net::FTPSSL" && ${*$self}{'debug'};
-
- if ( ref($self) eq "Net::FTPSSL" ) {
- ${*$self}{'last_ftp_msg'} = $line;
- }
-
- last if $2 ne '-';
-
- }
-
- return substr( $code, 0, 1 );
-
+ croak "FAIL: Never found a valid FTP response.\n";
}
sub last_message {
@@ -699,7 +694,7 @@
Net::FTPSSL - A FTP over SSL/TLS class
-=head1 VERSION 0.04
+=head1 VERSION 0.05
=head1 SYNOPSIS