summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2013-06-04 04:17:43 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2013-06-04 04:17:43 +0000
commit95ad9ef12960b03110a02a648883a7648922a42e (patch)
treea9b1698a9326144f3efb9a0975995181c903b814 /regress
parentf3342d9b31eff3980fd4f93a2cd0efbb7e7126dc (diff)
Add tests for raw IP divert. Set effective user ID to 0 only during
privileged operations for raw sockets and bind any.
Diffstat (limited to 'regress')
-rw-r--r--regress/sys/net/pf_divert/Client.pm21
-rw-r--r--regress/sys/net/pf_divert/Makefile6
-rw-r--r--regress/sys/net/pf_divert/Remote.pm9
-rw-r--r--regress/sys/net/pf_divert/Server.pm7
-rw-r--r--regress/sys/net/pf_divert/args-rip-reply.pl14
-rw-r--r--regress/sys/net/pf_divert/args-rip-to.pl14
-rw-r--r--regress/sys/net/pf_divert/args-tcp-reply.pl5
-rw-r--r--regress/sys/net/pf_divert/args-tcp-to.pl2
-rw-r--r--regress/sys/net/pf_divert/args-udp-reply.pl2
-rw-r--r--regress/sys/net/pf_divert/funcs.pl24
-rw-r--r--regress/sys/net/pf_divert/remote.pl33
11 files changed, 94 insertions, 43 deletions
diff --git a/regress/sys/net/pf_divert/Client.pm b/regress/sys/net/pf_divert/Client.pm
index 8c66a8e79ae..11c84151408 100644
--- a/regress/sys/net/pf_divert/Client.pm
+++ b/regress/sys/net/pf_divert/Client.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Client.pm,v 1.1 2013/06/03 05:06:38 bluhm Exp $
+# $OpenBSD: Client.pm,v 1.2 2013/06/04 04:17:42 bluhm Exp $
# Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -39,30 +39,32 @@ sub new {
or croak "$class connect domain not given";
$self->{connectaddr}
or croak "$class connect addr not given";
- $self->{connectport}
+ $self->{connectport} || $self->{protocol} !~ /^(tcp|udp)$/
or croak "$class connect port not given";
my $cs;
if ($self->{bindany}) {
- $cs = IO::Socket::INET6->new(
+ do { local $> = 0; $cs = IO::Socket::INET6->new(
+ Type => $self->{socktype},
Proto => $self->{protocol},
Domain => $self->{connectdomain},
Blocking => ($self->{nonblocking} ? 0 : 1),
- ) or die ref($self), " socket connect failed: $!";
- $cs->setsockopt(SOL_SOCKET, SO_BINDANY, 1)
+ ) } or die ref($self), " socket connect failed: $!";
+ do { local $> = 0; $cs->setsockopt(SOL_SOCKET, SO_BINDANY, 1) }
or die ref($self), " setsockopt SO_BINDANY failed: $!";
my @rres = getaddrinfo($self->{bindaddr}, $self->{bindport}||0,
$self->{connectdomain}, SOCK_STREAM, 0, AI_PASSIVE);
$cs->bind($rres[3])
or die ref($self), " bind failed: $!";
} elsif ($self->{bindaddr} || $self->{bindport}) {
- $cs = IO::Socket::INET6->new(
+ do { local $> = 0; $cs = IO::Socket::INET6->new(
+ Type => $self->{socktype},
Proto => $self->{protocol},
Domain => $self->{connectdomain},
Blocking => ($self->{nonblocking} ? 0 : 1),
LocalAddr => $self->{bindaddr},
LocalPort => $self->{bindport},
- ) or die ref($self), " socket connect failed: $!";
+ ) } or die ref($self), " socket connect failed: $!";
}
if ($cs) {
$self->{bindaddr} = $cs->sockhost();
@@ -76,11 +78,12 @@ sub new {
sub child {
my $self = shift;
- my $cs = $self->{cs} || IO::Socket::INET6->new(
+ my $cs = $self->{cs} || do { local $> = 0; IO::Socket::INET6->new(
+ Type => $self->{socktype},
Proto => $self->{protocol},
Domain => $self->{connectdomain},
Blocking => ($self->{nonblocking} ? 0 : 1),
- ) or die ref($self), " socket connect failed: $!";
+ ) } or die ref($self), " socket connect failed: $!";
if ($self->{oobinline}) {
setsockopt($cs, SOL_SOCKET, SO_OOBINLINE, pack('i', 1))
or die ref($self), " set oobinline connect failed: $!";
diff --git a/regress/sys/net/pf_divert/Makefile b/regress/sys/net/pf_divert/Makefile
index b06d572a39a..5c20b3a412f 100644
--- a/regress/sys/net/pf_divert/Makefile
+++ b/regress/sys/net/pf_divert/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.1 2013/06/03 05:06:38 bluhm Exp $
+# $OpenBSD: Makefile,v 1.2 2013/06/04 04:17:42 bluhm Exp $
# The following ports must be installed for the regression tests:
# p5-IO-Socket-INET6 object interface for AF_INET and AF_INET6 domain sockets
@@ -66,11 +66,11 @@ PERLPATH = ${.CURDIR}/
run-regress-$a: $a
.if !empty (LOCAL_ADDR)
@echo
- time SUDO=${SUDO} perl ${PERLINC} ${PERLPATH}remote.pl inet ${LOCAL_ADDR} ${FAKE_ADDR} ${REMOTE_SSH} ${PERLPATH}$a
+ time ${SUDO} SUDO=${SUDO} perl ${PERLINC} ${PERLPATH}remote.pl inet ${LOCAL_ADDR} ${FAKE_ADDR} ${REMOTE_SSH} ${PERLPATH}$a
.endif
.if !empty (LOCAL_ADDR6)
@echo
- time SUDO=${SUDO} perl ${PERLINC} ${PERLPATH}remote.pl inet6 ${LOCAL_ADDR6} ${FAKE_ADDR6} ${REMOTE_SSH} ${PERLPATH}$a
+ time ${SUDO} SUDO=${SUDO} perl ${PERLINC} ${PERLPATH}remote.pl inet6 ${LOCAL_ADDR6} ${FAKE_ADDR6} ${REMOTE_SSH} ${PERLPATH}$a
.endif
.endfor
diff --git a/regress/sys/net/pf_divert/Remote.pm b/regress/sys/net/pf_divert/Remote.pm
index 957c3ceafb5..a49eb64a192 100644
--- a/regress/sys/net/pf_divert/Remote.pm
+++ b/regress/sys/net/pf_divert/Remote.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Remote.pm,v 1.1 2013/06/03 05:06:38 bluhm Exp $
+# $OpenBSD: Remote.pm,v 1.2 2013/06/04 04:17:42 bluhm Exp $
# Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -46,7 +46,7 @@ sub new {
sub up {
my $self = Proc::up(shift, @_);
my $timeout = shift || 10;
- if ($self->{connectport}) {
+ if ($self->{connect}) {
$self->loggrep(qr/^Connected$/, $timeout)
or croak ref($self), " no Connected in $self->{logfile} ".
"after $timeout seconds";
@@ -67,9 +67,7 @@ sub child {
print STDERR $self->{up}, "\n";
my @opts = split(' ', $ENV{SSH_OPTIONS}) if $ENV{SSH_OPTIONS};
- # if sudo is set, run the remote perl as root, otherwise pass SUDO
- my @sudo = !$ENV{SUDO} ? () :
- $self->{sudo} ? $ENV{SUDO} : "SUDO=$ENV{SUDO}";
+ my @sudo = $ENV{SUDO} ? ($ENV{SUDO}, "SUDO=$ENV{SUDO}") : ();
my $dir = dirname($0);
$dir = getcwd() if ! $dir || $dir eq '.';
my @cmd = ('ssh', '-n', @opts, $self->{remotessh}, @sudo, 'perl',
@@ -78,6 +76,7 @@ sub child {
($self->{testfile} ? "$dir/".basename($self->{testfile}) :
()));
print STDERR "execute: @cmd\n";
+ $< = $>;
exec @cmd;
die "Exec @cmd failed: $!";
}
diff --git a/regress/sys/net/pf_divert/Server.pm b/regress/sys/net/pf_divert/Server.pm
index 06ca0698832..d0f1fafbe9e 100644
--- a/regress/sys/net/pf_divert/Server.pm
+++ b/regress/sys/net/pf_divert/Server.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Server.pm,v 1.1 2013/06/03 05:06:38 bluhm Exp $
+# $OpenBSD: Server.pm,v 1.2 2013/06/04 04:17:42 bluhm Exp $
# Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -34,13 +34,14 @@ sub new {
$self->{protocol} ||= "tcp";
$self->{listendomain}
or croak "$class listen domain not given";
- my $ls = IO::Socket::INET6->new(
+ my $ls = do { local $> = 0; IO::Socket::INET6->new(
+ Type => $self->{socktype},
Proto => $self->{protocol},
ReuseAddr => 1,
Domain => $self->{listendomain},
$self->{listenaddr} ? (LocalAddr => $self->{listenaddr}) : (),
$self->{listenport} ? (LocalPort => $self->{listenport}) : (),
- ) or die ref($self), " socket failed: $!";
+ ) } or die ref($self), " socket failed: $!";
if ($self->{oobinline}) {
setsockopt($ls, SOL_SOCKET, SO_OOBINLINE, pack('i', 1))
or die ref($self), " set oobinline listen failed: $!";
diff --git a/regress/sys/net/pf_divert/args-rip-reply.pl b/regress/sys/net/pf_divert/args-rip-reply.pl
new file mode 100644
index 00000000000..1c71ecddb20
--- /dev/null
+++ b/regress/sys/net/pf_divert/args-rip-reply.pl
@@ -0,0 +1,14 @@
+# test divert-reply with raw ip
+
+use strict;
+use warnings;
+use Socket;
+
+our %args = (
+ socktype => Socket::SOCK_RAW,
+ protocol => 254,
+ skip => sub { shift->{af} eq "inet" ? 20 : 0 },
+ client => { func => \&write_datagram, noin => 1, },
+ server => { func => \&read_datagram, noout => 1, },
+ divert => "reply",
+);
diff --git a/regress/sys/net/pf_divert/args-rip-to.pl b/regress/sys/net/pf_divert/args-rip-to.pl
new file mode 100644
index 00000000000..2fd414eb33c
--- /dev/null
+++ b/regress/sys/net/pf_divert/args-rip-to.pl
@@ -0,0 +1,14 @@
+# test divert-to with raw ip
+
+use strict;
+use warnings;
+use Socket;
+
+our %args = (
+ socktype => Socket::SOCK_RAW,
+ protocol => 254,
+ skip => sub { shift->{af} eq "inet" ? 20 : 0 },
+ client => { func => \&write_datagram, noin => 1, },
+ server => { func => \&read_datagram, noout => 1, },
+ divert => "to",
+);
diff --git a/regress/sys/net/pf_divert/args-tcp-reply.pl b/regress/sys/net/pf_divert/args-tcp-reply.pl
index 67f64f49173..82d435632d9 100644
--- a/regress/sys/net/pf_divert/args-tcp-reply.pl
+++ b/regress/sys/net/pf_divert/args-tcp-reply.pl
@@ -1,7 +1,4 @@
-# test divert-reply
-# swap client and server
-# server is local
-# client diverts packets with reply-to
+# test divert-reply with tcp
use strict;
use warnings;
diff --git a/regress/sys/net/pf_divert/args-tcp-to.pl b/regress/sys/net/pf_divert/args-tcp-to.pl
index e2af43dd2fe..0e67e4c873e 100644
--- a/regress/sys/net/pf_divert/args-tcp-to.pl
+++ b/regress/sys/net/pf_divert/args-tcp-to.pl
@@ -1,4 +1,4 @@
-# test divert-to
+# test divert-to with tcp
use strict;
use warnings;
diff --git a/regress/sys/net/pf_divert/args-udp-reply.pl b/regress/sys/net/pf_divert/args-udp-reply.pl
index e5ab629de58..7e2c5a77f37 100644
--- a/regress/sys/net/pf_divert/args-udp-reply.pl
+++ b/regress/sys/net/pf_divert/args-udp-reply.pl
@@ -1,4 +1,4 @@
-# test divert-to with udp
+# test divert-reply with udp
use strict;
use warnings;
diff --git a/regress/sys/net/pf_divert/funcs.pl b/regress/sys/net/pf_divert/funcs.pl
index 2004aead2d7..3fb71811d89 100644
--- a/regress/sys/net/pf_divert/funcs.pl
+++ b/regress/sys/net/pf_divert/funcs.pl
@@ -1,4 +1,4 @@
-# $OpenBSD: funcs.pl,v 1.2 2013/06/03 21:07:45 bluhm Exp $
+# $OpenBSD: funcs.pl,v 1.3 2013/06/04 04:17:42 bluhm Exp $
# Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -44,8 +44,18 @@ sub write_datagram {
sub read_datagram {
my $self = shift;
-
- my $in = <STDIN>;
+ my $skip = $self->{skip};
+ $skip = $skip->($self) if ref $skip eq 'CODE';
+
+ my $in;
+ if ($skip) {
+ # Raw sockets include the IPv4 header.
+ sysread(STDIN, $in, 70000);
+ # Cut the header off.
+ substr($in, 0, $skip, "");
+ } else {
+ $in = <STDIN>;
+ }
print STDERR "<<< $in";
}
@@ -65,15 +75,15 @@ sub check_inout {
my ($c, $s, %args) = @_;
if ($c && !$args{client}{nocheck}) {
- $c->loggrep(qr/^>>> Client$/) or die "no client out"
+ $c->loggrep(qr/^>>> Client$/) or die "no client output"
unless $args{client}{noout};
- $c->loggrep(qr/^<<< Server$/) or die "no client in"
+ $c->loggrep(qr/^<<< Server$/) or die "no client input"
unless $args{client}{noin};
}
if ($s && !$args{server}{nocheck}) {
- $s->loggrep(qr/^>>> Server$/) or die "no server out"
+ $s->loggrep(qr/^>>> Server$/) or die "no server output"
unless $args{server}{noout};
- $s->loggrep(qr/^<<< Client$/) or die "no server in"
+ $s->loggrep(qr/^<<< Client$/) or die "no server input"
unless $args{server}{noin};
}
}
diff --git a/regress/sys/net/pf_divert/remote.pl b/regress/sys/net/pf_divert/remote.pl
index 18e4af31389..30992ef5658 100644
--- a/regress/sys/net/pf_divert/remote.pl
+++ b/regress/sys/net/pf_divert/remote.pl
@@ -1,5 +1,5 @@
#!/usr/bin/perl
-# $OpenBSD: remote.pl,v 1.2 2013/06/03 21:07:45 bluhm Exp $
+# $OpenBSD: remote.pl,v 1.3 2013/06/04 04:17:42 bluhm Exp $
# Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -17,6 +17,13 @@
use strict;
use warnings;
+
+BEGIN {
+ if ($> == 0 && $ENV{SUDO_UID}) {
+ $> = $ENV{SUDO_UID};
+ }
+}
+
use File::Basename;
use File::Copy;
use Socket;
@@ -73,6 +80,7 @@ if ($local eq "server") {
func => $func,
%args,
%{$args{server}},
+ af => $af,
logfile => $logfile,
listendomain => $domain,
listenaddr => $mode ne "divert" ? $ARGV[0] :
@@ -87,9 +95,9 @@ if ($mode eq "auto") {
testfile => $test,
remotessh => $ARGV[2],
bindaddr => $ARGV[1],
+ connect => $remote eq "client",
connectaddr => $ARGV[0],
connectport => $s ? $s->{listenport} : 0,
- sudo => $ENV{SUDO},
);
$r->run->up;
$r->loggrep(qr/^Diverted$/, 10)
@@ -100,6 +108,7 @@ if ($local eq "client") {
func => $func,
%args,
%{$args{client}},
+ af => $af,
logfile => $logfile,
connectdomain => $domain,
connectaddr => $ARGV[1],
@@ -120,18 +129,22 @@ if ($mode eq "divert") {
};
copy($log, \*STDERR);
- my @sudo = $ENV{SUDO} ? $ENV{SUDO} : ();
- my @cmd = (@sudo, qw(pfctl -a regress -f -));
- open(my $pf, '|-', @cmd)
+ my @cmd = qw(pfctl -a regress -f -);
+ my $pf;
+ do { local $> = 0; open($pf, '|-', @cmd) }
or die "Open pipe to pf '@cmd' failed: $!";
if ($local eq "server") {
+ my $port = $args{protocol} =~ /^(tcp|udp)$/ ?
+ "port $s->{listenport}" : "";
+ my $divertport = $port || "port 1"; # XXX bad pf syntax
print $pf "pass in log $af proto $args{protocol} ".
- "from $ARGV[1] to $ARGV[0] port $s->{listenport} ".
- "divert-to $s->{listenaddr} port $s->{listenport}\n";
+ "from $ARGV[1] to $ARGV[0] $port ".
+ "divert-to $s->{listenaddr} $divertport\n";
} else {
+ my $port = $args{protocol} =~ /^(tcp|udp)$/ ?
+ "port $ARGV[2]" : "";
print $pf "pass out log $af proto $args{protocol} ".
- "from $c->{bindaddr} to $ARGV[1] port $ARGV[2] ".
- "divert-reply\n";
+ "from $c->{bindaddr} to $ARGV[1] $port divert-reply\n";
}
close($pf) or die $! ?
"Close pipe to pf '@cmd' failed: $!" :
@@ -156,4 +169,4 @@ $c->down if $c;
$r->down if $r;
$s->down if $s;
-check_logs($c, $s, %args);
+check_logs($c || $r, $s || $r, %args);