-# $OpenBSD: Makefile,v 1.8 2015/01/28 19:23:22 bluhm Exp $
+# $OpenBSD: Makefile,v 1.9 2015/06/15 21:44:57 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
.BEGIN:
@echo
[ -z "${SUDO}" ] || ${SUDO} true
+ ${SUDO} /etc/rc.d/syslogd stop
.END:
@echo
${SUDO} /etc/rc.d/syslogd restart
-# $OpenBSD: Syslogd.pm,v 1.11 2015/02/13 21:40:50 bluhm Exp $
+# $OpenBSD: Syslogd.pm,v 1.12 2015/06/15 21:44:57 bluhm Exp $
# Copyright (c) 2010-2015 Alexander Bluhm <bluhm@openbsd.org>
# Copyright (c) 2014 Florian Riehm <mail@friehm.de>
use Carp;
use Cwd;
use File::Basename;
+use Time::HiRes qw(time alarm sleep);
sub new {
my $class = shift;
$args{logfile} ||= "syslogd.log";
$args{up} ||= "syslogd: started";
$args{down} ||= "syslogd: exiting";
+ $args{up} = $args{down} = "execute:"
+ if $args{foreground} || $args{daemon};
+ $args{foreground} && $args{daemon}
+ and croak "$class cannot run in foreground and as daemon";
$args{func} = sub { Carp::confess "$class func may not be called" };
$args{conffile} ||= "syslogd.conf";
$args{outfile} ||= "file.log";
@ktrace = "ktrace" if $self->{ktrace} && !@ktrace;
push @ktrace, "-i", "-f", $self->{ktracefile} if @ktrace;
my $syslogd = $ENV{SYSLOGD} ? $ENV{SYSLOGD} : "syslogd";
- my @cmd = (@sudo, @libevent, @ktrace, $syslogd, "-d",
+ my @cmd = (@sudo, @libevent, @ktrace, $syslogd,
"-f", $self->{conffile});
- push @cmd, "-V", unless $self->{cacrt};
+ push @cmd, "-d" if !$self->{foreground} && !$self->{daemon};
+ push @cmd, "-F" if $self->{foreground};
+ push @cmd, "-V" unless $self->{cacrt};
push @cmd, "-C", $self->{cacrt}
if $self->{cacrt} && $self->{cacrt} ne "default";
push @cmd, "-s", $self->{ctlsock} if $self->{ctlsock};
sub up {
my $self = Proc::up(shift, @_);
-
- if ($self->{fstat}) {
- $self->fstat;
+ my $timeout = shift || 10;
+
+ my $end = time() + $timeout;
+
+ while ($self->{fstat}) {
+ $self->fstat();
+ last unless $self->{foreground} || $self->{daemon};
+
+ # in foreground mode and as daemon we have no debug output
+ # check fstat kqueue entry to detect statup
+ open(my $fh, '<', $self->{fstatfile}) or die ref($self),
+ " open $self->{fstatfile} for reading failed: $!";
+ last if grep { /kqueue/ } <$fh>;
+ time() < $end
+ or croak ref($self), " no 'kqueue' in $self->{fstatfile} ".
+ "after $timeout seconds";
+ sleep .1;
}
return $self;
}
options => ["-u"],
loggrep => {
get_charlog() => 5,
- }
+ },
},
server => {
listen => { domain => AF_UNSPEC, proto => "tcp", addr => "localhost" },
options => ["-u"],
loggrep => {
get_charlog() => 5,
- }
+ },
},
server => {
listen => { domain => AF_UNSPEC, proto => "tls", addr => "localhost" },
options => ["-u"],
loggrep => {
get_charlog() => 5,
- }
+ },
},
server => {
# >>> <13>Jan 31 00:10:11 0123456789ABC...lmn
syslogd => {
loggrep => {
get_charlog() => 5,
- }
+ },
},
file => {
# Feb 2 00:43:36 hostname 0123456789ABC...567
options => ["-u"],
loggrep => {
get_charlog() => 11,
- }
+ },
},
file => {
# Jan 31 00:12:39 localhost 0123456789ABC...567
our %args = (
syslogd => {
loggrep => qr/libevent using: kqueue/,
- ktrace => 1,
- kdump => qr/CALL kqueue/,
+ ktrace => qr/CALL kqueue/,
},
);
our %args = (
syslogd => {
loggrep => qr/libevent using: poll/,
- ktrace => 1,
- kdump => qr/CALL poll/,
+ ktrace => qr/CALL poll/,
},
);
our %args = (
syslogd => {
loggrep => qr/libevent using: select/,
- ktrace => 1,
- kdump => qr/CALL select/,
+ ktrace => qr/CALL select/,
},
);
connect => { domain => AF_INET, addr => "127.0.0.1", port => 514 },
},
syslogd => {
- fstat => 1,
+ fstat => {
+ qr/ internet6 / => 0,
+ },
loghost => '@127.0.0.1:$connectport',
options => ["-4nu"],
},
file => {
loggrep => qr/ 127.0.0.1 /. get_testlog(),
},
- fstat => {
- loggrep => {
- qr/ internet6 / => 0,
- },
- },
);
1;
connect => { domain => AF_INET6, addr => "::1", port => 514 },
},
syslogd => {
- fstat => 1,
+ fstat => {
+ qr/ internet / => 0,
+ },
loghost => '@[::1]:$connectport',
options => ["-6nu"],
},
file => {
loggrep => qr/ ::1 /. get_testlog(),
},
- fstat => {
- loggrep => {
- qr/ internet / => 0,
- },
- },
);
1;
--- /dev/null
+# Start syslogd in daemon mode.
+# The client writes a message to Sys::Syslog native method.
+# The syslogd writes it into a file and through a pipe.
+# The syslogd passes it via UDP to the loghost.
+# The server receives the message on its UDP socket.
+# Find the message in client, file, syslogd, server log.
+# Check fstat for the parent and child process.
+# Check ktrace for setting the correct uid and gid.
+# Check that stdio is dupped to /dev/null.
+
+use strict;
+use warnings;
+
+our %args = (
+ syslogd => {
+ daemon => 1,
+ loggrep => {
+ qr/ -F / => 0,
+ qr/ -d / => 0,
+ },
+ fstat => {
+ qr/^root .* wd / => 1,
+ qr/^root .* root / => 0,
+ qr/^root .* [012] .* null$/ => 3,
+ qr/^root .* kqueue / => 0,
+ qr/^root .* internet/ => 0,
+ qr/^_syslogd .* wd / => 1,
+ qr/^_syslogd .* root / => 1,
+ qr/^_syslogd .* [012] .* null$/ => 3,
+ qr/^_syslogd .* kqueue / => 1,
+ qr/^_syslogd .* internet/ => 2,
+ },
+ ktrace => {
+ qr/CALL setresuid(.*"_syslogd".*){3}/ => 2,
+ qr/CALL setresgid(.*"_syslogd".*){3}/ => 2,
+ qr/CALL setsid/ => 1,
+ qr/RET setsid.* errno / => 0,
+ },
+ },
+ pipe => {
+ nocheck => 1,
+ },
+);
+
+1;
--- /dev/null
+# Start syslogd in foreground mode.
+# The client writes a message to Sys::Syslog native method.
+# The syslogd writes it into a file and through a pipe.
+# The syslogd passes it via UDP to the loghost.
+# The server receives the message on its UDP socket.
+# Find the message in client, file, syslogd, server log.
+# Check fstat for the parent and child process.
+# Check ktrace for setting the correct uid and gid.
+# Check that stdio is dupped to /dev/null.
+
+use strict;
+use warnings;
+
+our %args = (
+ syslogd => {
+ foreground => 1,
+ loggrep => {
+ qr/ -F / => 1,
+ qr/ -d / => 0,
+ },
+ fstat => {
+ qr/^root .* wd / => 1,
+ qr/^root .* root / => 0,
+ qr/^root .* [012] .* null$/ => 3,
+ qr/^root .* kqueue / => 0,
+ qr/^root .* internet/ => 0,
+ qr/^_syslogd .* wd / => 1,
+ qr/^_syslogd .* root / => 1,
+ qr/^_syslogd .* [012] .* null$/ => 3,
+ qr/^_syslogd .* kqueue / => 1,
+ qr/^_syslogd .* internet/ => 2,
+ },
+ ktrace => {
+ qr/CALL setresuid(.*"_syslogd".*){3}/ => 2,
+ qr/CALL setresgid(.*"_syslogd".*){3}/ => 2,
+ qr/CALL setsid/ => 0,
+ },
+ },
+ pipe => {
+ nocheck => 1,
+ },
+);
+
+1;
--- /dev/null
+# The client writes a message to Sys::Syslog native method.
+# The syslogd writes it into a file and through a pipe.
+# The syslogd passes it via UDP to the loghost.
+# The server receives the message on its UDP socket.
+# Find the message in client, file, pipe, syslogd, server log.
+# Check fstat for the parent and child process.
+# Check ktrace for setting the correct uid and gid.
+
+use strict;
+use warnings;
+
+our %args = (
+ syslogd => {
+ loggrep => {
+ qr/ -F / => 0,
+ qr/ -d / => 1,
+ },
+ fstat => {
+ qr/^root .* wd / => 1,
+ qr/^root .* root / => 0,
+ qr/^root .* kqueue / => 0,
+ qr/^root .* internet/ => 0,
+ qr/^_syslogd .* wd / => 1,
+ qr/^_syslogd .* root / => 1,
+ qr/^_syslogd .* kqueue / => 1,
+ qr/^_syslogd .* internet/ => 2,
+ },
+ ktrace => {
+ qr/CALL setresuid(.*"_syslogd".*){3}/ => 2,
+ qr/CALL setresgid(.*"_syslogd".*){3}/ => 2,
+ qr/CALL setsid/ => 0,
+ },
+ },
+);
+
+1;
our %args = (
client => {
- ktrace => 1,
- kdump => {
+ ktrace => {
qr/CALL sendsyslog/ => 2,
qr/GIO fd -1 wrote \d+ bytes/ => 2,
qr/RET sendsyslog 0/ => 2,
loggrep => { get_between2loggrep() },
},
syslogd => {
- ktrace => 1,
- kdump => {
+ ktrace => {
qr/syslogd PSIG SIGHUP caught handler/ => 1,
qr/syslogd RET execve 0/ => 2,
},
loggrep => { get_between2loggrep() },
},
syslogd => {
- ktrace => 1,
- kdump => {
+ ktrace => {
qr/syslogd PSIG SIGHUP caught handler/ => 2,
qr/syslogd RET execve 0/ => 1,
},
loggrep => { get_between2loggrep() },
},
syslogd => {
- ktrace => 1,
- fstat => 1,
- kdump => {
+ fstat => {
+ # sighup must not leak a TCP socket
+ qr/internet stream tcp/ => 1,
+ },
+ ktrace => {
qr/syslogd PSIG SIGHUP caught handler/ => 1,
qr/syslogd RET execve 0/ => 1,
},
qr/Accepted/ => 2,
},
},
- fstat => {
- loggrep => {
- # sighup must not leak a TCP socket
- qr/internet stream tcp/ => 1,
- },
- },
);
1;
loggrep => { get_between2loggrep() },
},
syslogd => {
- ktrace => 1,
- fstat => 1,
- kdump => {
+ fstat => {
+ # sighup must not leak a TCP socket
+ qr/internet stream tcp/ => 1,
+ },
+ ktrace => {
qr/syslogd PSIG SIGHUP caught handler/ => 1,
qr/syslogd RET execve 0/ => 1,
},
qr/Accepted/ => 2,
},
},
- fstat => {
- loggrep => {
- # sighup must not leak a TCP socket
- qr/internet stream tcp/ => 1,
- },
- },
);
1;
loggrep => { get_between2loggrep() },
},
syslogd => {
- ktrace => 1,
- kdump => {
+ ktrace => {
qr/syslogd PSIG SIGHUP caught handler/ => 1,
qr/syslogd RET execve 0/ => 1,
},
loggrep => { get_between2loggrep() },
},
syslogd => {
- ktrace => 1,
- kdump => {
+ ktrace => {
qr/syslogd PSIG SIGPIPE/ => 0,
qr/syslogd RET execve 0/ => 1,
},
loggrep => { get_between2loggrep() },
},
syslogd => {
- ktrace => 1,
- kdump => {
+ ktrace => {
qr/syslogd PSIG SIGTERM caught handler/ => 1,
qr/syslogd RET execve 0/ => 1,
},
our %args = (
syslogd => {
- fstat => 1,
+ fstat => {
+ qr/ internet stream tcp / => 1,
+ },
loghost => '@tcp://127.0.0.1:$connectport',
options => ["-n"],
},
server => {
listen => { domain => AF_INET, addr => "127.0.0.1", proto => "tcp" },
},
- fstat => {
- loggrep => {
- qr/ internet stream tcp / => 1,
- },
- },
);
1;
our %args = (
syslogd => {
- fstat => 1,
+ fstat => {
+ qr/ internet stream tcp / => 1,
+ },
loghost => '@tls://127.0.0.1:$connectport',
options => ["-n"],
},
server => {
listen => { domain => AF_INET, addr => "127.0.0.1", proto => "tls" },
},
- fstat => {
- loggrep => {
- qr/ internet stream tcp / => 1,
- },
- },
);
1;
connect => { domain => AF_INET, addr => "127.0.0.1", port => 514 },
},
syslogd => {
- fstat => 1,
- options => ["-nu"],
- },
- fstat => {
- loggrep => {
+ fstat => {
qr/ internet dgram udp \*:514$/ => 1,
qr/ internet6 dgram udp \*:514$/ => 1,
},
+ options => ["-nu"],
},
);
-# $OpenBSD: funcs.pl,v 1.18 2015/02/12 23:16:02 bluhm Exp $
+# $OpenBSD: funcs.pl,v 1.19 2015/06/15 21:44:57 bluhm Exp $
# Copyright (c) 2010-2015 Alexander Bluhm <bluhm@openbsd.org>
#
check_log($c, $r, $s, @$m);
check_out($r, %args);
- check_stat($r, %args);
- check_kdump($c, $r, $s);
+ check_fstat($c, $r, $s);
+ check_ktrace($c, $r, $s);
if (my $file = $s->{"outfile"}) {
my $pattern = $s->{filegrep} || $testlog;
check_pattern(ref $s, $file, $pattern, \&filegrep);
}
}
-sub check_stat {
- my ($r, %args) = @_;
-
- foreach my $name (qw(fstat)) {
- next unless $r && $r->{$name};
- my $file = $r->{"${name}file"} or die;
- my $pattern = $args{$name}{loggrep} or die;
- check_pattern($name, $file, $pattern, \&filegrep);
+sub check_fstat {
+ foreach my $proc (@_) {
+ my $pattern = $proc && $proc->{fstat} or next;
+ my $file = $proc->{fstatfile} or die;
+ check_pattern("fstat", $file, $pattern, \&filegrep);
}
}
grep { /$pattern/ } <$fh> : first { /$pattern/ } <$fh>;
}
-sub check_kdump {
+sub check_ktrace {
foreach my $proc (@_) {
- next unless $proc && $proc->{ktrace};
+ my $pattern = $proc && $proc->{ktrace} or next;
my $file = $proc->{ktracefile} or die;
- my $pattern = $proc->{kdump} or die;
- check_pattern(ref $proc, $file, $pattern, \&kdumpgrep);
+ check_pattern("ktrace", $file, $pattern, \&kdumpgrep);
}
}