From a0156d40691964295264c62096b2cf52fd26850a Mon Sep 17 00:00:00 2001 From: bluhm Date: Sun, 28 Dec 2014 14:08:01 +0000 Subject: [PATCH] Add regression tests where OpenBSD syslogd is sending messages to rsyslogd from ports. If the rsyslog package is installed, rsyslogd is used as drain to test interoperability. This will be especially useful for syslog via TCP and TLS. --- regress/usr.sbin/syslogd/Makefile | 13 ++- regress/usr.sbin/syslogd/README | 3 + regress/usr.sbin/syslogd/RSyslogd.pm | 93 ++++++++++++++++++++ regress/usr.sbin/syslogd/Server.pm | 12 +-- regress/usr.sbin/syslogd/Syslogd.pm | 4 +- regress/usr.sbin/syslogd/args-rsyslog-tcp.pl | 22 +++++ regress/usr.sbin/syslogd/args-rsyslog-udp.pl | 16 ++++ regress/usr.sbin/syslogd/funcs.pl | 26 +++++- regress/usr.sbin/syslogd/syslogd.pl | 23 +++-- 9 files changed, 195 insertions(+), 17 deletions(-) create mode 100644 regress/usr.sbin/syslogd/RSyslogd.pm create mode 100644 regress/usr.sbin/syslogd/args-rsyslog-tcp.pl create mode 100644 regress/usr.sbin/syslogd/args-rsyslog-udp.pl diff --git a/regress/usr.sbin/syslogd/Makefile b/regress/usr.sbin/syslogd/Makefile index 5647005e1a4..a40f36d6062 100644 --- a/regress/usr.sbin/syslogd/Makefile +++ b/regress/usr.sbin/syslogd/Makefile @@ -1,10 +1,13 @@ -# $OpenBSD: Makefile,v 1.5 2014/09/13 23:38:24 bluhm Exp $ +# $OpenBSD: Makefile,v 1.6 2014/12/28 14:08:01 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 # p5-Socket6 Perl defines relating to AF_INET6 sockets # p5-IO-Socket-SSL perl interface to SSL sockets # +# This package enables additional interoperability tests +# rsyslog syslog daemon supporting databases, TCP, SSL, RELP +# # Check wether all required perl packages are installed. If some # are missing print a warning and skip the tests, but do not fail. @@ -22,10 +25,14 @@ regress: # Automatically generate regress targets from test cases in directory. ARGS != cd ${.CURDIR} && ls args-*.pl +.if exists (/usr/local/sbin/rsyslogd) TARGETS ?= ${ARGS} +.else +TARGETS ?= ${ARGS:Nargs-rsyslog*} +.endif REGRESS_TARGETS = ${TARGETS:S/^/run-regress-/} -CLEANFILES += *.log *.log.? *.pem *.crt *.key syslogd.conf stamp-* -CLEANFILES += *.sock ktrace.out *.ktrace *.fstat +CLEANFILES += *.log *.log.? *.pem *.crt *.key *.conf stamp-* +CLEANFILES += *.out *.sock ktrace.out *.ktrace *.fstat .MAIN: all diff --git a/regress/usr.sbin/syslogd/README b/regress/usr.sbin/syslogd/README index 61092a27432..a263a585554 100644 --- a/regress/usr.sbin/syslogd/README +++ b/regress/usr.sbin/syslogd/README @@ -14,6 +14,9 @@ When invoked with "make libevent", all tests are executed three times. They pass the EVENT_NO... environment variables over sudo into syslogd. This way the select(2) and poll(2) and kqueue(2) backend is tested. +If the rsyslog package is installed, messages are sent to the +rsyslogd to test interoperability. This is especially useful for +TCP and TLS. SUDO=sudo As syslogd needs root privileges either run the tests as root or diff --git a/regress/usr.sbin/syslogd/RSyslogd.pm b/regress/usr.sbin/syslogd/RSyslogd.pm new file mode 100644 index 00000000000..6a1e9064dd1 --- /dev/null +++ b/regress/usr.sbin/syslogd/RSyslogd.pm @@ -0,0 +1,93 @@ +# $OpenBSD: RSyslogd.pm,v 1.1 2014/12/28 14:08:01 bluhm Exp $ + +# Copyright (c) 2010-2014 Alexander Bluhm +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; + +package RSyslogd; +use parent 'Proc'; +use Carp; +use Cwd; + +sub new { + my $class = shift; + my %args = @_; + $args{logfile} ||= "rsyslogd.log"; + $args{up} ||= "calling select"; + $args{down} ||= "Clean shutdown completed"; + $args{func} = sub { Carp::confess "$class func may not be called" }; + $args{conffile} ||= "rsyslogd.conf"; + $args{pidfile} ||= "rsyslogd.pid"; + $args{outfile} ||= "rsyslogd.out"; + my $self = Proc::new($class, %args); + + _make_abspath(\$self->{$_}) foreach (qw(conffile pidfile outfile)); + + # substitute variables in config file + my $listendomain = $self->{listendomain} + or croak "$class listen domain not given"; + my $listenaddr = $self->{listenaddr} + or croak "$class listen address not given"; + my $listenproto = $self->{listenproto} + or croak "$class listen protocol not given"; + my $listenport = $self->{listenport} + or croak "$class listen port not given"; + + open(my $fh, '>', $self->{conffile}) + or die ref($self), " create conf file $self->{conffile} failed: $!"; + if ($listenproto eq "udp") { + print $fh "\$ModLoad imudp\n"; + print $fh "\$UDPServerRun $listenport\n"; + } + if ($listenproto eq "tcp") { + print $fh "\$ModLoad imtcp\n"; + print $fh "\$InputTCPServerRun $listenport\n"; + } + print $fh "*.* $self->{outfile}\n"; + print $fh $self->{conf} if $self->{conf}; + close $fh; + + unlink($self->{outfile}); + return $self; +} + +sub child { + my $self = shift; + + my @cmd = ("rsyslogd", "-dn", "-c4", "-f", $self->{conffile}, + "-i", $self->{pidfile}); + print STDERR "execute: @cmd\n"; + exec @cmd; + die ref($self), " exec '@cmd' failed: $!"; +} + +sub _make_abspath { + my $file = ref($_[0]) ? ${$_[0]} : $_[0]; + if (substr($file, 0, 1) ne "/") { + $file = getcwd(). "/". $file; + ${$_[0]} = $file if ref($_[0]); + } + return $file; +} + +sub down { + my $self = shift; + + $self->kill(); + return Proc::down($self); +} + +1; diff --git a/regress/usr.sbin/syslogd/Server.pm b/regress/usr.sbin/syslogd/Server.pm index 8bcdf73d630..818e694eba1 100644 --- a/regress/usr.sbin/syslogd/Server.pm +++ b/regress/usr.sbin/syslogd/Server.pm @@ -1,4 +1,4 @@ -# $OpenBSD: Server.pm,v 1.2 2014/08/25 17:55:27 bluhm Exp $ +# $OpenBSD: Server.pm,v 1.3 2014/12/28 14:08:01 bluhm Exp $ # Copyright (c) 2010-2014 Alexander Bluhm # @@ -33,13 +33,13 @@ sub new { $args{logfile} ||= "server.log"; $args{up} ||= "Accepted"; my $self = Proc::new($class, %args); - $self->{listenprotocol} ||= "udp"; + $self->{listenproto} ||= "udp"; defined($self->{listendomain}) or croak "$class listen domain not given"; $SSL_ERROR = ""; - my $iosocket = $self->{listenprotocol} eq "tls" ? + my $iosocket = $self->{listenproto} eq "tls" ? "IO::Socket::SSL" : "IO::Socket::INET6"; - my $proto = $self->{listenprotocol}; + my $proto = $self->{listenproto}; $proto = "tcp" if $proto eq "tls"; my $ls = $iosocket->new( Proto => $proto, @@ -51,7 +51,7 @@ sub new { SSL_cert_file => "server-cert.pem", SSL_verify_mode => SSL_VERIFY_NONE, ) or die ref($self), " $iosocket socket listen failed: $!,$SSL_ERROR"; - if ($self->{listenprotocol} eq "tcp") { + if ($self->{listenproto} eq "tcp") { listen($ls, 1) or die ref($self), " socket failed: $!"; } @@ -68,7 +68,7 @@ sub child { my $iosocket = $self->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET6"; my $as = $self->{ls}; - if ($self->{listenprotocol} ne "udp") { + if ($self->{listenproto} ne "udp") { $as = $self->{ls}->accept() or die ref($self), " $iosocket socket accept failed: $!"; print STDERR "accept sock: ",$as->sockhost()," ", diff --git a/regress/usr.sbin/syslogd/Syslogd.pm b/regress/usr.sbin/syslogd/Syslogd.pm index 28bf627929b..b70a8eafd5c 100644 --- a/regress/usr.sbin/syslogd/Syslogd.pm +++ b/regress/usr.sbin/syslogd/Syslogd.pm @@ -1,4 +1,4 @@ -# $OpenBSD: Syslogd.pm,v 1.6 2014/10/29 16:42:57 bluhm Exp $ +# $OpenBSD: Syslogd.pm,v 1.7 2014/12/28 14:08:01 bluhm Exp $ # Copyright (c) 2010-2014 Alexander Bluhm # Copyright (c) 2014 Florian Riehm @@ -48,9 +48,9 @@ sub new { _make_abspath(\$self->{$_}) foreach (qw(conffile outfile outpipe)); # substitute variables in config file - my $connectprotocol = $self->{connectprotocol}; my $connectdomain = $self->{connectdomain}; my $connectaddr = $self->{connectaddr}; + my $connectproto = $self->{connectproto}; my $connectport = $self->{connectport}; open(my $fh, '>', $self->{conffile}) diff --git a/regress/usr.sbin/syslogd/args-rsyslog-tcp.pl b/regress/usr.sbin/syslogd/args-rsyslog-tcp.pl new file mode 100644 index 00000000000..499695d1754 --- /dev/null +++ b/regress/usr.sbin/syslogd/args-rsyslog-tcp.pl @@ -0,0 +1,22 @@ +# Test with rsyslogd as receiver. +# 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 TCP to the rsyslogd. +# The rsyslogd receives the message on its TCP socket. +# Find the message in client, file, pipe, syslogd, rsyslogd log. +# Check that the message is in the rsyslogd out file. + +use strict; +use warnings; + +our %args = ( + syslogd => { + loghost => '@tcp://127.0.0.1:$connectport', + late => 1, # connect after the listen socket has been created + }, + rsyslogd => { + listen => { proto => "tcp" }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-rsyslog-udp.pl b/regress/usr.sbin/syslogd/args-rsyslog-udp.pl new file mode 100644 index 00000000000..5d087ec90cf --- /dev/null +++ b/regress/usr.sbin/syslogd/args-rsyslog-udp.pl @@ -0,0 +1,16 @@ +# Test with rsyslogd as receiver. +# 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 rsyslogd. +# The rsyslogd receives the message on its UDP socket. +# Find the message in client, file, pipe, syslogd, rsyslogd log. +# Check that the message is in the rsyslogd out file. + +use strict; +use warnings; + +our %args = ( + rsyslogd => {}, +); + +1; diff --git a/regress/usr.sbin/syslogd/funcs.pl b/regress/usr.sbin/syslogd/funcs.pl index b6e9c289a73..d71d73bbcc9 100644 --- a/regress/usr.sbin/syslogd/funcs.pl +++ b/regress/usr.sbin/syslogd/funcs.pl @@ -1,4 +1,4 @@ -# $OpenBSD: funcs.pl,v 1.7 2014/09/13 23:38:24 bluhm Exp $ +# $OpenBSD: funcs.pl,v 1.8 2014/12/28 14:08:01 bluhm Exp $ # Copyright (c) 2010-2014 Alexander Bluhm # @@ -28,6 +28,26 @@ my $firstlog = "syslogd regress test first message"; my $testlog = "syslogd regress test log message"; my $downlog = "syslogd regress client shutdown"; +sub find_ports { + my %args = @_; + my $num = delete $args{num} // 1; + my $domain = delete $args{domain} // AF_INET; + my $addr = delete $args{addr} // "127.0.0.1"; + my $proto = delete $args{proto} // "udp"; + + my @sockets = (1..$num); + foreach my $s (@sockets) { + $s = IO::Socket::INET6->new( + Domain => $domain, + LocalAddr => $addr, + Proto => $proto, + ) or die "find_ports: create and bind socket failed: $!"; + } + my @ports = map { $_->sockport() } @sockets; + + return wantarray ? @ports : $ports[0]; +} + ######################################################################## # Client funcs ######################################################################## @@ -144,6 +164,10 @@ sub check_logs { check_out($r, %args); check_stat($r, %args); check_kdump($c, $r, $s); + if (my $file = $s->{"outfile"}) { + my $pattern = $s->{filegrep} || $testlog; + check_pattern(ref $s, $file, $pattern, \&filegrep); + } } sub compare($$) { diff --git a/regress/usr.sbin/syslogd/syslogd.pl b/regress/usr.sbin/syslogd/syslogd.pl index 80a7085af5b..9c5a852e17a 100644 --- a/regress/usr.sbin/syslogd/syslogd.pl +++ b/regress/usr.sbin/syslogd/syslogd.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $OpenBSD: syslogd.pl,v 1.3 2014/09/13 23:38:24 bluhm Exp $ +# $OpenBSD: syslogd.pl,v 1.4 2014/12/28 14:08:01 bluhm Exp $ # Copyright (c) 2010-2014 Alexander Bluhm # @@ -24,6 +24,7 @@ use Client; use Syslogd; use Server; use Syslogc; +use RSyslogd; require 'funcs.pl'; sub usage { @@ -39,16 +40,27 @@ if (@ARGV and -f $ARGV[-1]) { } @ARGV == 0 or usage(); -foreach my $name (qw(client syslogd server)) { +if ($args{rsyslogd}) { + $args{rsyslogd}{listen}{domain} ||= AF_INET; + $args{rsyslogd}{listen}{addr} ||= "127.0.0.1"; + $args{rsyslogd}{listen}{proto} ||= "udp"; +} +foreach my $name (qw(client syslogd server rsyslogd)) { + $args{$name} or next; foreach my $action (qw(connect listen)) { my $h = $args{$name}{$action} or next; - foreach my $k (qw(protocol domain addr port)) { + foreach my $k (qw(domain addr proto port)) { $args{$name}{"$action$k"} = $h->{$k}; } } } my($s, $c, $r, @m); -$s = Server->new( +$s = RSyslogd->new( + %{$args{rsyslogd}}, + listenport => scalar find_ports(%{$args{rsyslogd}{listen}}), + testfile => $testfile, +) if $args{rsyslogd}; +$s ||= Server->new( func => \&read_log, listendomain => AF_INET, listenaddr => "127.0.0.1", @@ -82,8 +94,9 @@ $c = Client->new( server => \$s, ) unless $args{client}{noclient}; -$r->run; +$r->run unless $r->{late}; $s->run->up unless $args{server}{noserver}; +$r->run if $r->{late}; $r->up; my $control = 0; foreach (@m) { -- 2.20.1