Question: We are using HAProxy in front of ProFTPD, and
we see PROXY
protocol headers appended to our upload files. What
is wrong?
Answer: Usually this happens because of the specific
HAProxy configuration used -- and can be fixed by adjusting that HAProxy
configuration.
Let's assume your HAProxy configuration looks something like this:
listen ftp
bind 0.0.0.0:21,:60000-60250
mode tcp
balance source
server services-a 192.168.1.71 send-proxy-v2 check port 21
server services-b 192.168.1.72 send-proxy-v2 check port 21
This causes HAProxy to use the PROXY protocol (via send-proxy-v2
)
for control and data connections, which is probably not what you
intended.
The solution is to use separate HAProxy configurations for the FTP control
and FTP data addresses/ports, and to not use send-proxy-v2
(or send-proxy
) for the FTP data ports:
listen ftp
bind 0.0.0.0:21
mode tcp
balance source
server services-a 192.168.1.71 send-proxy-v2 check port 21
server services-b 192.168.1.72 send-proxy-v2 check port 21
listen ftp-data
bind :60000-60250
mode tcp
balance source
server services-a 192.168.1.71 check port 21
server services-b 192.168.1.72 check port 21
© Copyright 2013-2021 TJ Saunders
All Rights Reserved
proftpd-mod_proxy_protocol-0.6/t/ 0000775 0000000 0000000 00000000000 14336707071 0017247 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/config/ 0000775 0000000 0000000 00000000000 14336707071 0020514 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/config/maxhostsperuser.t 0000664 0000000 0000000 00000000272 14336707071 0024156 0 ustar 00root root 0000000 0000000 #!/usr/bin/env perl
use lib qw(t/lib);
use strict;
use Test::Unit::HarnessUnit;
$| = 1;
my $r = Test::Unit::HarnessUnit->new();
$r->start("ProFTPD::Tests::Config::MaxHostsPerUser");
proftpd-mod_proxy_protocol-0.6/t/lib/ 0000775 0000000 0000000 00000000000 14336707071 0020015 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/ 0000775 0000000 0000000 00000000000 14336707071 0021233 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/TestSuite/ 0000775 0000000 0000000 00000000000 14336707071 0023164 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/TestSuite/ProxiedFTP.pm 0000664 0000000 0000000 00000002161 14336707071 0025506 0 ustar 00root root 0000000 0000000 package ProFTPD::TestSuite::ProxiedFTP;
use strict;
use vars qw(@ISA);
use Carp;
use Net::FTP;
@ISA = qw(Net::FTP);
my $proxy_info = undef;
sub new {
my $class = shift;
my ($addr, $port, $proxy, $timeout) = @_;
$timeout = 5 unless defined($timeout);
my $debug = undef;
$proxy_info = $proxy;
if ($ENV{TEST_VERBOSE}) {
$debug = 10;
}
my $self = $class->SUPER::new($addr,
Port => $port,
Timeout => $timeout,
Debug => $debug,
);
unless ($self) {
croak($@);
}
return $self;
}
# Override response() from Net::Cmd to trigger sending the PROXY command
sub response {
my $self = shift;
if (defined($proxy_info)) {
if (ref($proxy_info)) {
my ($proto, $src_addr, $dst_addr, $src_port, $dst_port) = @$proxy_info;
$self->command("PROXY", $proto, $src_addr, $dst_addr, $src_port, $dst_port);
} else {
$self->rawdatasend($proxy_info);
}
$proxy_info = undef;
}
$self->SUPER::response();
}
sub login {
my $self = shift;
unless ($self->SUPER::login(@_)) {
croak("Failed to login: " . $self->code . " " . $self->message);
}
return 1;
}
1;
proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/ 0000775 0000000 0000000 00000000000 14336707071 0022335 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Config/ 0000775 0000000 0000000 00000000000 14336707071 0023542 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Config/MaxHostsPerUser.pm 0000664 0000000 0000000 00000012146 14336707071 0027160 0 ustar 00root root 0000000 0000000 package ProFTPD::Tests::Config::MaxHostsPerUser;
use lib qw(t/lib);
use base qw(ProFTPD::TestSuite::Child);
use strict;
use File::Spec;
use IO::Handle;
use ProFTPD::TestSuite::FTP;
use ProFTPD::TestSuite::ProxiedFTP;
use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
$| = 1;
my $order = 0;
my $TESTS = {
maxhostsperuser_one => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
maxhostsperuser_one_multi_conns => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
};
sub new {
return shift()->SUPER::new(@_);
}
sub list_tests {
return testsuite_get_runnable_tests($TESTS);
}
sub maxhostsperuser_one {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'config');
my $max_hosts = 1;
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
MaxHostsPerUser => $max_hosts,
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
my $proxy_info = ['TCP4', '1.1.1.1', '127.0.0.1', 111, $port];
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(1);
# First client should be able to connect and log in...
my $client1 = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '127.0.0.1', '127.0.0.1', 12345, $port]);
$client1->login($setup->{user}, $setup->{passwd});
# ...but the second client should be able to connect, but not login.
my $client2 = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
$proxy_info);
eval { $client2->login($setup->{user}, $setup->{passwd}) };
unless ($@) {
die("Login succeeded unexpectedly");
}
$client1->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub maxhostsperuser_one_multi_conns {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'config');
my $max_hosts = 1;
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
MaxHostsPerUser => $max_hosts,
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
my $proxy_info = ['TCP4', '1.1.1.1', '127.0.0.1', 111, $port];
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(1);
# First client should be able to connect and log in...
my $client1 = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '127.0.0.1', '127.0.0.1', 12345, $port]);
$client1->login($setup->{user}, $setup->{passwd});
# ...but the second client should be able to connect, but not login.
my $client2 = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
$proxy_info);
eval { $client2->login($setup->{user}, $setup->{passwd}) };
unless ($@) {
die("Login succeeded unexpectedly");
}
# Even though we can't log in, we should be able to connect quite
# a few more times
my $clients = [];
for (my $i = 0; $i < 10; $i++) {
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
$proxy_info);
push(@$clients, $client);
}
$client1->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
1;
proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Modules/ 0000775 0000000 0000000 00000000000 14336707071 0023745 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Modules/mod_proxy_protocol.pm 0000664 0000000 0000000 00000150077 14336707071 0030256 0 ustar 00root root 0000000 0000000 package ProFTPD::Tests::Modules::mod_proxy_protocol;
use lib qw(t/lib);
use base qw(ProFTPD::TestSuite::Child);
use strict;
use File::Path qw(mkpath);
use File::Spec;
use IO::Handle;
use Net::Cmd qw(CMD_OK);
use ProFTPD::TestSuite::FTP;
use ProFTPD::TestSuite::ProxiedFTP;
use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
$| = 1;
my $order = 0;
my $TESTS = {
proxy_protocol_login_with_proxy => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_login_without_proxy => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_config_denyclass => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_bad_start_of_line => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_bad_end_of_line => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_bad_proto => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_bad_src_addr => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_dns_src_addr => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_bad_dst_addr => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_dns_dst_addr => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_bad_src_port => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_bad_dst_port => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_too_large_src_port => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_too_large_dst_port => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_tcp4_with_ipv6_src_addr => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_tcp4_with_ipv6_dst_addr => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_tcp6_with_ipv4_src_addr => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_tcp6_with_ipv4_dst_addr => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_tcp6_with_useipv6_off => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_matching_src_dst_info => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_unknown_proto => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_active_transfer_with_proxy => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_passive_transfer_with_proxy => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_active_transfer_with_proxy_allowforeignaddress => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_passive_transfer_with_proxy_allowforeignaddress => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_login_using_proxied_server_address => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
proxy_protocol_login_no_matching_proxied_server_address => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol)],
},
};
sub new {
return shift()->SUPER::new(@_);
}
sub list_tests {
return testsuite_get_runnable_tests($TESTS);
}
sub proxy_protocol_login_with_proxy {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_login_without_proxy {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $proxy_timeout = 1;
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
ProxyProtocolTimeout => $proxy_timeout,
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port, 1, 1, 1);
$client->login($setup->{user}, $setup->{passwd});
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, $proxy_timeout + 5) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
if ($ex) {
$ex = undef;
} else {
$ex = "Connection succeeded unexpectedly";
}
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_config_denyclass {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
if (open(my $fh, ">> $setup->{config_file}")) {
print $fh <
From 1.1.1.1
DenyClass test
EOC
unless (close($fh)) {
die("Can't write $setup->{config_file}: $!");
}
} else {
die("Can't open $setup->{config_file}: $!");
}
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
eval { $client->login($setup->{user}, $setup->{passwd}) };
unless ($@) {
die("Login succeeded unexpectedly");
}
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_bad_start_of_line {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
"GET /index.html HTTP/1.1.1\r\n")
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_bad_end_of_line {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, '222 ' . 'A' x 128]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_bad_proto {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['IPV4', '1.1.1.1', '2.2.2.2', 111, '222']);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_bad_src_addr {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', 'foo', '2.2.2.2', 111, '222']);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_dns_src_addr {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', 'localhost', '2.2.2.2', 111, '222']);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_bad_dst_addr {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', 'bar', 111, '222']);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_dns_dst_addr {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', 'localhost', 111, '222']);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_bad_src_port {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 'baz', '222']);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_bad_dst_port {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 'quxx']);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_too_large_src_port {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 70000, 222]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_too_large_dst_port {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 70000]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_tcp4_with_ipv6_src_addr {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
UseIPv6 => 'on',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '::1', '2.2.2.2', 111, 222]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_tcp4_with_ipv6_dst_addr {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
UseIPv6 => 'on',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '::2', 111, 222]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_tcp6_with_ipv4_src_addr {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
UseIPv6 => 'on',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP6', '1.1.1.1', '::2', 111, 222]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_tcp6_with_ipv4_dst_addr {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
UseIPv6 => 'on',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP6', '::1', '2.2.2.2', 111, 222]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_tcp6_with_useipv6_off {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
UseIPv6 => 'off',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP6', '::1', '::2', 111, 222]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_matching_src_dst_info {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
eval {
ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '1.1.1.1', 111, 111]);
};
unless ($@) {
die("Connection succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_unknown_proto {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['UNKNOWN', '1.1.1.1', '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_active_transfer_with_proxy {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $test_file = File::Spec->rel2abs("$tmpdir/test.dat");
if (open(my $fh, "> $test_file")) {
print $fh "Hello, World!\n";
unless (close($fh)) {
die("Can't write $test_file: $!");
}
} else {
die("Can't open $test_file: $!");
}
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
# Note: If AllowForeignAddress is not allowed, then the PORT command
# will fail with the following e.g. error being logged:
#
# Refused PORT 127,0,0,1,218,225 (address mismatch)
#
AllowForeignAddress => 'off',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
$ENV{FTP_PASSIVE} = 0;
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
if ($client->get('test.dat', '/dev/null')) {
die("RETR test.dat succeeded unexpectedly");
}
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_passive_transfer_with_proxy {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $test_file = File::Spec->rel2abs("$tmpdir/test.dat");
if (open(my $fh, "> $test_file")) {
print $fh "Hello, World!\n";
unless (close($fh)) {
die("Can't write $test_file: $!");
}
} else {
die("Can't open $test_file: $!");
}
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
# Note: If AllowForeignAddress is not allowed, then the data transfer
# will fail with the following e.g. error being logged:
#
# SECURITY VIOLATION: Passive connection from 127.0.0.1 rejected.
#
AllowForeignAddress => 'off',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
$ENV{FTP_PASSIVE} = 1;
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
if ($client->get('test.dat', '/dev/null')) {
die("RETR test.dat succeeded unexpectedly");
}
# Note: we should send QUIT here, but because proftpd treated this as
# a security violation, it terminated the control connection as well.
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_active_transfer_with_proxy_allowforeignaddress {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $test_file = File::Spec->rel2abs("$tmpdir/test.dat");
if (open(my $fh, "> $test_file")) {
print $fh "Hello, World!\n";
unless (close($fh)) {
die("Can't write $test_file: $!");
}
} else {
die("Can't open $test_file: $!");
}
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
# Note: If AllowForeignAddress is not allowed, then the PORT command
# will fail with the following e.g. error being logged:
#
# Refused PORT 127,0,0,1,218,225 (address mismatch)
#
AllowForeignAddress => 'on',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
$ENV{FTP_PASSIVE} = 0;
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
unless ($client->get('test.dat', '/dev/null')) {
die("RETR test.dat failed: " . $client->code . " " . $client->message);
}
my $resp_code = $client->code;
my $expected = 226;
$self->assert($expected == $resp_code,
test_msg("Expected response code $expected, got $resp_code"));
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_passive_transfer_with_proxy_allowforeignaddress {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $test_file = File::Spec->rel2abs("$tmpdir/test.dat");
if (open(my $fh, "> $test_file")) {
print $fh "Hello, World!\n";
unless (close($fh)) {
die("Can't write $test_file: $!");
}
} else {
die("Can't open $test_file: $!");
}
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
# Note: If AllowForeignAddress is not allowed, then the data transfer
# will fail with the following e.g. error being logged:
#
# SECURITY VIOLATION: Passive connection from 127.0.0.1 rejected.
#
AllowForeignAddress => 'on',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
$ENV{FTP_PASSIVE} = 1;
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
unless ($client->get('test.dat', '/dev/null')) {
die("RETR test.dat failed: " . $client->code . " " . $client->message);
}
my $resp_code = $client->code;
my $expected = 226;
$self->assert($expected == $resp_code,
test_msg("Expected response code $expected, got $resp_code"));
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_login_using_proxied_server_address {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'proxy_protocol:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
ProxyProtocolOptions => 'UseProxiedServerAddress',
},
},
Limit => {
LOGIN => {
DenyUser => $setup->{user},
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
my $proxied_dst_addr = '127.0.0.1';
my $proxied_dst_port = ProFTPD::TestSuite::Utils::get_high_numbered_port();
$proxied_dst_port += 7;
if (open(my $fh, ">> $setup->{config_file}")) {
print $fh <
Port $proxied_dst_port
ServerName "Real Destination Server"
WtmpLog off
TransferLog none
AuthUserFile $setup->{auth_user_file}
AuthGroupFile $setup->{auth_group_file}
AuthOrder mod_auth_file.c
EOC
unless (close($fh)) {
die("Can't write $setup->{config_file}: $!");
}
} else {
die("Can't open $setup->{config_file}: $!");
}
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', $proxied_dst_addr, 111, $proxied_dst_port]);
$client->login($setup->{user}, $setup->{passwd});
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_login_no_matching_proxied_server_address {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'proxy_protocol:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
ProxyProtocolOptions => 'UseProxiedServerAddress',
},
},
Limit => {
LOGIN => {
DenyUser => $setup->{user},
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
my $proxied_dst_addr = '127.0.0.1';
my $proxied_dst_port = ProFTPD::TestSuite::Utils::get_high_numbered_port();
$proxied_dst_port += 7;
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', $proxied_dst_addr, 111, $proxied_dst_port]);
# Our requested server address doesn't exist, thus we expect this
# login to fail due to the DenyUser .
eval { $client->login($setup->{user}, $setup->{passwd}) };
unless ($@) {
die("Login for user '$setup->{user}' succeeded expectedly");
}
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
1;
proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Modules/mod_proxy_protocol/ 0000775 0000000 0000000 00000000000 14336707071 0027706 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Modules/mod_proxy_protocol/ifsession.pm 0000664 0000000 0000000 00000035124 14336707071 0032253 0 ustar 00root root 0000000 0000000 package ProFTPD::Tests::Modules::mod_proxy_protocol::ifsession;
use lib qw(t/lib);
use base qw(ProFTPD::TestSuite::Child);
use strict;
use File::Path qw(mkpath);
use File::Spec;
use IO::Handle;
use Net::Cmd qw(CMD_OK);
use ProFTPD::TestSuite::FTP;
use ProFTPD::TestSuite::ProxiedFTP;
use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
$| = 1;
my $order = 0;
my $TESTS = {
proxy_protocol_ifsess_matching_class => {
order => ++$order,
test_class => [qw(forking mod_ifsession mod_proxy_protocol)],
},
proxy_protocol_ifsess_mismatched_class => {
order => ++$order,
test_class => [qw(forking mod_ifsession mod_proxy_protocol)],
},
proxy_protocol_ifsess_matching_user => {
order => ++$order,
test_class => [qw(forking mod_ifsession mod_proxy_protocol)],
},
proxy_protocol_ifsess_mismatched_user => {
order => ++$order,
test_class => [qw(forking mod_ifsession mod_proxy_protocol)],
},
proxy_protocol_config_ignore_ifsess_matching_class_issue2 => {
order => ++$order,
test_class => [qw(forking mod_ifsession mod_proxy_protocol)],
},
proxy_protocol_config_ignore_ifsess_mismatched_class_issue2 => {
order => ++$order,
test_class => [qw(forking mod_ifsession mod_proxy_protocol)],
},
};
sub new {
return shift()->SUPER::new(@_);
}
sub list_tests {
return testsuite_get_runnable_tests($TESTS);
}
sub proxy_protocol_ifsess_matching_class {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'ifsess');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
if (open(my $fh, ">> $setup->{config_file}")) {
print $fh <
From 127.0.0.1
ProxyProtocolEngine on
EOC
unless (close($fh)) {
die("Can't write $setup->{config_file}: $!");
}
} else {
die("Can't open $setup->{config_file}: $!");
}
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_ifsess_mismatched_class {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'ifsess');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
if (open(my $fh, ">> $setup->{config_file}")) {
print $fh <
From !127.0.0.1
ProxyProtocolEngine on
EOC
unless (close($fh)) {
die("Can't write $setup->{config_file}: $!");
}
} else {
die("Can't open $setup->{config_file}: $!");
}
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
eval { $client->user($setup->{user}) };
unless ($@) {
die('USER command succeeded unexpectedly');
}
my $resp_code = $client->response();
my $expected = 5;
$self->assert($resp_code == $expected,
test_msg("Expected response code $expected, got $resp_code"));
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_ifsess_matching_user {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'ifsess');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
if (open(my $fh, ">> $setup->{config_file}")) {
print $fh <
ProxyProtocolEngine on
{user}>
Deny from 1.1.1.1
EOC
unless (close($fh)) {
die("Can't write $setup->{config_file}: $!");
}
} else {
die("Can't open $setup->{config_file}: $!");
}
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
eval { $client->login($setup->{user}, $setup->{passwd}); };
unless ($@) {
die("Login succeeded unexpectedly");
}
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_ifsess_mismatched_user {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'ifsess');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
if (open(my $fh, ">> $setup->{config_file}")) {
print $fh <
ProxyProtocolEngine on
Deny from 1.1.1.1
EOC
unless (close($fh)) {
die("Can't write $setup->{config_file}: $!");
}
} else {
die("Can't open $setup->{config_file}: $!");
}
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_config_ignore_ifsess_matching_class_issue2 {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'ifsess');
my $proxied_src_addr = '1.1.1.1';
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'proxy_protocol:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
if (open(my $fh, ">> $setup->{config_file}")) {
print $fh <
From 127.0.0.1
ProxyProtocolEngine on
ProxyProtocolIgnore off
EOC
unless (close($fh)) {
die("Can't write $setup->{config_file}: $!");
}
} else {
die("Can't open $setup->{config_file}: $!");
}
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', $proxied_src_addr, '2.2.2.2', 111, 222]);
$client->login($setup->{user}, $setup->{passwd});
$client->quit();
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
eval {
if (open(my $fh, "< $setup->{log_file}")) {
my $ok = 0;
while (my $line = <$fh>) {
chomp($line);
if ($ENV{TEST_VERBOSE}) {
print STDERR "# $line\n";
}
if ($line =~ /using proxied source address: /) {
$ok = 1;
last;
}
}
close($fh);
$self->assert($ok, test_msg("Did not see expected debug log messages"));
} else {
die("Can't read $setup->{log_file}: $!");
}
};
if ($@) {
$ex = $@;
}
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_config_ignore_ifsess_mismatched_class_issue2 {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'ifsess');
my $proxied_src_addr = '1.1.1.1';
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
if (open(my $fh, ">> $setup->{config_file}")) {
print $fh <
From 127.0.0.1
ProxyProtocolEngine on
ProxyProtocolIgnore on
EOC
unless (close($fh)) {
die("Can't write $setup->{config_file}: $!");
}
} else {
die("Can't open $setup->{config_file}: $!");
}
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', $proxied_src_addr, '2.2.2.2', 111, 222]);
eval { $client->user($setup->{user}) };
unless ($@) {
die('USER command succeeded unexpectedly');
}
my $resp_code = $client->response();
my $expected = 5;
$self->assert($resp_code == $expected,
test_msg("Expected response code $expected, got $resp_code"));
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
eval {
if (open(my $fh, "< $setup->{log_file}")) {
my $ok = 1;
while (my $line = <$fh>) {
chomp($line);
if ($ENV{TEST_VERBOSE}) {
print STDERR "# $line\n";
}
if ($line =~ /using proxied source address: /) {
$ok = 0;
last;
}
}
close($fh);
$self->assert($ok, test_msg("Saw unexpected debug log messages"));
} else {
die("Can't read $setup->{log_file}: $!");
}
};
if ($@) {
$ex = $@;
}
test_cleanup($setup->{log_file}, $ex);
}
1;
proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Modules/mod_proxy_protocol/sftp.pm 0000664 0000000 0000000 00000006726 14336707071 0031233 0 ustar 00root root 0000000 0000000 package ProFTPD::Tests::Modules::mod_proxy_protocol::sftp;
use lib qw(t/lib);
use base qw(ProFTPD::TestSuite::Child);
use strict;
use File::Path qw(mkpath);
use File::Spec;
use IO::Handle;
use ProFTPD::TestSuite::ProxiedFTP;
use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
$| = 1;
my $order = 0;
my $TESTS = {
proxy_protocol_sftp_with_proxy => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol mod_sftp)],
},
proxy_protocol_sftp_without_proxy => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol mod_sftp)],
},
};
sub new {
return shift()->SUPER::new(@_);
}
sub list_tests {
# return testsuite_get_runnable_tests($TESTS);
return qw(
proxy_protocol_sftp_with_proxy
);
}
sub set_up {
my $self = shift;
$self->SUPER::set_up(@_);
# Make sure that mod_sftp does not complain about permissions on the hostkey
# files.
my $rsa_host_key = File::Spec->rel2abs("$ENV{PROFTPD_TEST_DIR}/t/etc/modules/mod_sftp/ssh_host_rsa_key");
my $dsa_host_key = File::Spec->rel2abs("$ENV{PROFTPD_TEST_DIR}/t/etc/modules/mod_sftp/ssh_host_dsa_key");
unless (chmod(0400, $rsa_host_key, $dsa_host_key)) {
die("Can't set perms on $rsa_host_key, $dsa_host_key: $!");
}
}
sub proxy_protocol_sftp_with_proxy {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $rsa_host_key = File::Spec->rel2abs("$ENV{PROFTPD_TEST_DIR}/t/etc/modules/mod_sftp/ssh_host_rsa_key");
my $dsa_host_key = File::Spec->rel2abs("$ENV{PROFTPD_TEST_DIR}/t/etc/modules/mod_sftp/ssh_host_dsa_key");
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'ssh2:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
'mod_sftp.c' => [
"SFTPEngine on",
"SFTPLog $setup->{log_file}",
"SFTPHostKey $rsa_host_key",
"SFTPHostKey $dsa_host_key",
],
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port);
$client->send_proxy_raw('1.1.1.1', '2.2.2.2', 111, 222);
my $banner = $client->getline();
chomp($banner);
unless ($banner =~ /^SSH\-2\.0\-mod_sftp/) {
die("Received unexpected banner from mod_sftp: '$banner'");
}
print $client "SSH-2.0-ProFTPD_mod_proxy_protocol_sftp_Test\r\n";
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
1;
proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Modules/mod_proxy_protocol/tls.pm 0000664 0000000 0000000 00000036530 14336707071 0031055 0 ustar 00root root 0000000 0000000 package ProFTPD::Tests::Modules::mod_proxy_protocol::tls;
use lib qw(t/lib);
use base qw(ProFTPD::TestSuite::Child);
use strict;
use File::Path qw(mkpath);
use File::Spec;
use IO::Handle;
use Net::Cmd qw(CMD_OK CMD_MORE);
use ProFTPD::TestSuite::ProxiedFTP;
use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
$| = 1;
my $order = 0;
my $TESTS = {
proxy_protocol_tls_login_with_proxy => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol mod_tls)],
},
# NOTE: Beware of module load order; this requires that mod_proxy_protocol
# be loaded AFTER mod_tls, so that the mod_proxy_protocol init handlers
# run BEFORE mod_tls.
proxy_protocol_tls_login_with_proxy_useimplicitssl => {
order => ++$order,
test_class => [qw(forking inprogress mod_proxy_protocol mod_tls)],
},
proxy_protocol_tls_without_proxy_v1_bytes => {
order => ++$order,
test_class => [qw(bug forking mod_proxy_protocol)],
},
proxy_protocol_tls_without_proxy_v2_bytes => {
order => ++$order,
test_class => [qw(bug forking mod_proxy_protocol)],
},
proxy_protocol_starttls_without_proxy_v1_bytes => {
order => ++$order,
test_class => [qw(bug forking mod_proxy_protocol)],
},
proxy_protocol_starttls_without_proxy_v2_bytes => {
order => ++$order,
test_class => [qw(bug forking mod_proxy_protocol)],
},
};
sub new {
return shift()->SUPER::new(@_);
}
sub list_tests {
# Check for the required Perl modules:
#
# Net-SSLeay
# IO-Socket-SSL
my $required = [qw(
Net::SSLeay
IO::Socket::SSL
)];
foreach my $req (@$required) {
eval "use $req";
if ($@) {
print STDERR "\nWARNING:\n + Module '$req' not found, skipping all tests\n";
if ($ENV{TEST_VERBOSE}) {
print STDERR "Unable to load $req: $@\n";
}
return qw(testsuite_empty_test);
}
}
return testsuite_get_runnable_tests($TESTS);
}
sub proxy_protocol_tls_login_with_proxy {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $server_cert_file = File::Spec->rel2abs("$ENV{PROFTPD_TEST_DIR}/t/etc/modules/mod_tls/server-cert.pem");
my $ca_file = File::Spec->rel2abs("$ENV{PROFTPD_TEST_DIR}/t/etc/modules/mod_tls/ca-cert.pem");
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'netio:10 proxy_protocol:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
AuthOrder => 'mod_auth_file.c',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
'mod_tls.c' => {
TLSEngine => 'on',
TLSLog => $setup->{log_file},
TLSProtocol => 'SSLv3 TLSv1',
TLSRequired => 'on',
TLSRSACertificateFile => $server_cert_file,
TLSCACertificateFile => $ca_file,
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
require IO::Socket::SSL;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
my $ok = $client->command("AUTH", "TLS")->response();
unless ($ok == CMD_OK || $ok == CMD_MORE) {
die($client->message);
}
my $ssl_opts = {
SSL_version => 'SSLv23',
SSL_ca_file => $ca_file,
};
if ($ENV{TEST_VERBOSE}) {
$ssl_opts->{Debug} = 2;
}
my $ssl_client = IO::Socket::SSL->start_SSL($client, %$ssl_opts);
unless ($ssl_client) {
die("TLS handshake failed: " . IO::Socket::SSL::errstr());
}
push(@IO::Socket::SSL::ISA, 'Net::Cmd');
$ok = $ssl_client->command("USER", $setup->{user})->response();
unless ($ok == CMD_OK || $ok == CMD_MORE) {
die($client->message);
}
$ok = $ssl_client->command("PASS", $setup->{passwd})->response();
unless ($ok == CMD_OK || $ok == CMD_MORE) {
die($client->message);
}
$ok = $ssl_client->command("QUIT")->response();
unless ($ok == CMD_OK) {
die($client->message);
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_tls_login_with_proxy_useimplicitssl {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $server_cert_file = File::Spec->rel2abs("$ENV{PROFTPD_TEST_DIR}/t/etc/modules/mod_tls/server-cert.pem");
my $ca_file = File::Spec->rel2abs("$ENV{PROFTPD_TEST_DIR}/t/etc/modules/mod_tls/ca-cert.pem");
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'proxy_protocol:20 tls:30',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
AuthOrder => 'mod_auth_file.c',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
'mod_tls.c' => {
TLSEngine => 'on',
TLSLog => $setup->{log_file},
TLSRequired => 'on',
TLSRSACertificateFile => $server_cert_file,
TLSCACertificateFile => $ca_file,
TLSOptions => 'UseImplicitSSL EnableDiags',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
require IO::Socket::SSL;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port,
['TCP4', '1.1.1.1', '2.2.2.2', 111, 222]);
my $ssl_opts = {
SSL_version => 'SSLv23',
SSL_ca_file => $ca_file,
};
if ($ENV{TEST_VERBOSE}) {
$ssl_opts->{Debug} = 2;
}
my $ssl_client = IO::Socket::SSL->start_SSL($client, %$ssl_opts);
unless ($ssl_client) {
die("TLS handshake failed: " . IO::Socket::SSL::errstr());
}
push(@IO::Socket::SSL::ISA, 'Net::Cmd');
my $ok = $ssl_client->response();
unless ($ok == CMD_OK || $ok == CMD_MORE) {
die($client->message);
}
$ok = $ssl_client->command("USER", $setup->{user})->response();
unless ($ok == CMD_OK || $ok == CMD_MORE) {
die($client->message);
}
$ok = $ssl_client->command("PASS", $setup->{passwd})->response();
unless ($ok == CMD_OK || $ok == CMD_MORE) {
die($client->message);
}
$ok = $ssl_client->command("QUIT")->response();
unless ($ok == CMD_OK) {
die($client->message);
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_tls_without_proxy_v1_bytes {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'proxy_protocol:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
AuthOrder => 'mod_auth_file.c',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
ProxyProtocolVersion => 'haproxyV1',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
require IO::Socket::SSL;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $ssl_client = IO::Socket::SSL->new(
PeerHost => '127.0.0.1',
PeerPort => $port,
);
if ($ssl_client) {
die("TLS handshake succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_tls_without_proxy_v2_bytes {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'proxy_protocol:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
AuthOrder => 'mod_auth_file.c',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
ProxyProtocolVersion => 'haproxyV2',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
require IO::Socket::SSL;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $ssl_client = IO::Socket::SSL->new(
PeerHost => '127.0.0.1',
PeerPort => $port,
);
if ($ssl_client) {
die("TLS handshake succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_starttls_without_proxy_v1_bytes {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'proxy_protocol:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
AuthOrder => 'mod_auth_file.c',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
ProxyProtocolVersion => 'haproxyV1',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
require Net::FTPSSL;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $ssl_opts = {
Encryption => 'E',
Port => $port,
};
if ($ENV{TEST_VERBOSE}) {
$ssl_opts->{Debug} = 2;
}
my $client = Net::FTPSSL->new('127.0.0.1', %$ssl_opts);
if ($client) {
die("STARTTLS FTP handshake succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
sub proxy_protocol_starttls_without_proxy_v2_bytes {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
TraceLog => $setup->{log_file},
Trace => 'proxy_protocol:20',
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
AuthOrder => 'mod_auth_file.c',
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
ProxyProtocolVersion => 'haproxyV2',
},
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
require Net::FTPSSL;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $ssl_opts = {
Encryption => 'E',
Port => $port,
};
if ($ENV{TEST_VERBOSE}) {
$ssl_opts->{Debug} = 2;
}
my $client = Net::FTPSSL->new('127.0.0.1', %$ssl_opts);
if ($client) {
die("STARTTLS FTP handshake succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
1;
proftpd-mod_proxy_protocol-0.6/t/lib/ProFTPD/Tests/Modules/mod_proxy_protocol/wrap2.pm 0000664 0000000 0000000 00000005575 14336707071 0031313 0 ustar 00root root 0000000 0000000 package ProFTPD::Tests::Modules::mod_proxy_protocol::wrap2;
use lib qw(t/lib);
use base qw(ProFTPD::TestSuite::Child);
use strict;
use File::Path qw(mkpath);
use File::Spec;
use IO::Handle;
use ProFTPD::TestSuite::ProxiedFTP;
use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
$| = 1;
my $order = 0;
my $TESTS = {
proxy_protocol_wrap2_config_deny => {
order => ++$order,
test_class => [qw(forking mod_proxy_protocol mod_wrap2)],
},
};
sub new {
return shift()->SUPER::new(@_);
}
sub list_tests {
return testsuite_get_runnable_tests($TESTS);
}
sub proxy_protocol_wrap2_config_deny {
my $self = shift;
my $tmpdir = $self->{tmpdir};
my $setup = test_setup($tmpdir, 'proxy_protocol');
my $allow_file = File::Spec->rel2abs("$tmpdir/wrap2.allow");
if (open(my $fh, "> $allow_file")) {
unless (close($fh)) {
die("Can't write $allow_file: $!");
}
} else {
die("Can't open $allow_file: $!");
}
my $deny_file = File::Spec->rel2abs("$tmpdir/wrap2.deny");
if (open(my $fh, "> $deny_file")) {
print $fh "ALL: 1.1.1.1\n";
unless (close($fh)) {
die("Can't write $deny_file: $!");
}
} else {
die("Can't open $deny_file: $!");
}
my $config = {
PidFile => $setup->{pid_file},
ScoreboardFile => $setup->{scoreboard_file},
SystemLog => $setup->{log_file},
AuthUserFile => $setup->{auth_user_file},
AuthGroupFile => $setup->{auth_group_file},
IfModules => {
'mod_delay.c' => {
DelayEngine => 'off',
},
'mod_proxy_protocol.c' => {
ProxyProtocolEngine => 'on',
},
'mod_wrap2.c' => {
WrapEngine => 'on',
WrapTables => "file:$allow_file file:$deny_file",
WrapLog => $setup->{log_file},
}
},
};
my ($port, $config_user, $config_group) = config_write($setup->{config_file},
$config);
# Open pipes, for use between the parent and child processes. Specifically,
# the child will indicate when it's done with its test by writing a message
# to the parent.
my ($rfh, $wfh);
unless (pipe($rfh, $wfh)) {
die("Can't open pipe: $!");
}
my $ex;
# Fork child
$self->handle_sigchld();
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
sleep(2);
my $client = ProFTPD::TestSuite::ProxiedFTP->new('127.0.0.1', $port);
$client->send_proxy('1.1.1.1', '2.2.2.2', 111, 222);
eval { $client->login($setup->{user}, $setup->{passwd}) };
unless ($@) {
die("Login succeeded unexpectedly");
}
};
if ($@) {
$ex = $@;
}
$wfh->print("done\n");
$wfh->flush();
} else {
eval { server_wait($setup->{config_file}, $rfh, 10) };
if ($@) {
warn($@);
exit 1;
}
exit 0;
}
# Stop server
server_stop($setup->{pid_file});
$self->assert_child_ok($pid);
test_cleanup($setup->{log_file}, $ex);
}
1;
proftpd-mod_proxy_protocol-0.6/t/modules/ 0000775 0000000 0000000 00000000000 14336707071 0020717 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/modules/mod_proxy_protocol.t 0000664 0000000 0000000 00000000276 14336707071 0025052 0 ustar 00root root 0000000 0000000 #!/usr/bin/env perl
use lib qw(t/lib);
use strict;
use Test::Unit::HarnessUnit;
$| = 1;
my $r = Test::Unit::HarnessUnit->new();
$r->start("ProFTPD::Tests::Modules::mod_proxy_protocol");
proftpd-mod_proxy_protocol-0.6/t/modules/mod_proxy_protocol/ 0000775 0000000 0000000 00000000000 14336707071 0024660 5 ustar 00root root 0000000 0000000 proftpd-mod_proxy_protocol-0.6/t/modules/mod_proxy_protocol/ifsession.t 0000664 0000000 0000000 00000000311 14336707071 0027042 0 ustar 00root root 0000000 0000000 #!/usr/bin/env perl
use lib qw(t/lib);
use strict;
use Test::Unit::HarnessUnit;
$| = 1;
my $r = Test::Unit::HarnessUnit->new();
$r->start("ProFTPD::Tests::Modules::mod_proxy_protocol::ifsession");
proftpd-mod_proxy_protocol-0.6/t/modules/mod_proxy_protocol/sftp.t 0000664 0000000 0000000 00000000304 14336707071 0026016 0 ustar 00root root 0000000 0000000 #!/usr/bin/env perl
use lib qw(t/lib);
use strict;
use Test::Unit::HarnessUnit;
$| = 1;
my $r = Test::Unit::HarnessUnit->new();
$r->start("ProFTPD::Tests::Modules::mod_proxy_protocol::sftp");
proftpd-mod_proxy_protocol-0.6/t/modules/mod_proxy_protocol/tls.t 0000664 0000000 0000000 00000000303 14336707071 0025643 0 ustar 00root root 0000000 0000000 #!/usr/bin/env perl
use lib qw(t/lib);
use strict;
use Test::Unit::HarnessUnit;
$| = 1;
my $r = Test::Unit::HarnessUnit->new();
$r->start("ProFTPD::Tests::Modules::mod_proxy_protocol::tls");
proftpd-mod_proxy_protocol-0.6/t/modules/mod_proxy_protocol/wrap2.t 0000664 0000000 0000000 00000000305 14336707071 0026076 0 ustar 00root root 0000000 0000000 #!/usr/bin/env perl
use lib qw(t/lib);
use strict;
use Test::Unit::HarnessUnit;
$| = 1;
my $r = Test::Unit::HarnessUnit->new();
$r->start("ProFTPD::Tests::Modules::mod_proxy_protocol::wrap2");