netftpserver-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Net::FTPServer] Grotesque passive-mode hack


From: Richard Jones
Subject: [Net::FTPServer] Grotesque passive-mode hack
Date: Fri, 8 Sep 2006 17:35:13 +0100
User-agent: Mutt/1.5.9i

I'd like to share this grotesque hack that I just created to get
passive mode working correctly behind a complex firewall.

The situation is that the FTP server is on a machine behind the
firewall.  It has a private IP address, say, 10.1.2.3.  The firewall
has a public address, say, 180.4.5.6.

The firewall is redirecting public facing ports 21 and 49991-49998
through to the FTP server.

The problem is that when the client requests passive mode,
Net::FTPServer advertises its own address as 10.1.2.3, saying
something like:

  227 Entering Passive Mode (10,1,2,3,195,75)

The hack changes this to display the public IP address, ie:

  227 Entering Passive Mode (180,4,5,6,195,75)

This really needs to be turned into a configuration file setting, if
someone wants to step up to do that.

Anyhow, without any further ado, here is the hack:

----------------------------------------------------------------------
<Perl>
sub my_PASV_command {
  my $self = shift;

  $self->{_passive_next_port} = 49991
    if !defined $self->{_passive_next_port};
  my $port = $self->{_passive_next_port};
  $self->{_passive_next_port}++;
  $self->{_passive_next_port} = 49991 if $self->{_passive_next_port} == 49999;

  print STDERR "custom passive port = $port\n";

  "0" =~ /(0)/; # Perl 5.7 / IO::Socket::INET bug workaround.
  my $sock = IO::Socket::INET->new
              (Listen => 1,
               LocalAddr => $self->{sockaddrstring},
               LocalPort => $port,
               Reuse => 1,
               Proto => "tcp",
               Type => SOCK_STREAM);

  unless ($sock)
      {
        # Return a code 550 here, even though this is not in the RFC. XXX
        $self->reply (550, "Can't open a listening socket: $!");
        return;
      }

  $self->{_passive} = 1;
  $self->{_passive_sock} = $sock;

  # Get our port number.
  my $sockport = $sock->sockport;

  # Split the port number into high and low components.
  my $p1 = int ($sockport / 256);
  my $p2 = $sockport % 256;

  # Be very precise about this error message, since most clients
  # will have to parse the whole of it.
  $self->reply (227, "Entering Passive Mode (180,4,5,6,$p1,$p2)");
}
$self->{command_table}{PASV} = \&my_PASV_command;
</Perl>
----------------------------------------------------------------------

Rich.

-- 
Richard Jones, CTO Merjis Ltd.
Merjis - web marketing and technology - http://merjis.com
Team Notepad - intranets and extranets for business - http://team-notepad.com




reply via email to

[Prev in Thread] Current Thread [Next in Thread]