From: bluhm Date: Fri, 16 Jan 2015 11:51:59 +0000 (+0000) Subject: Add regression tests for syslog over TLS. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=a588825ed48498b851b72f2a9acfdc5355a9ea9f;p=openbsd Add regression tests for syslog over TLS. --- diff --git a/regress/usr.sbin/syslogd/RSyslogd.pm b/regress/usr.sbin/syslogd/RSyslogd.pm index 6a1e9064dd1..133507436de 100644 --- a/regress/usr.sbin/syslogd/RSyslogd.pm +++ b/regress/usr.sbin/syslogd/RSyslogd.pm @@ -1,4 +1,4 @@ -# $OpenBSD: RSyslogd.pm,v 1.1 2014/12/28 14:08:01 bluhm Exp $ +# $OpenBSD: RSyslogd.pm,v 1.2 2015/01/16 11:51:59 bluhm Exp $ # Copyright (c) 2010-2014 Alexander Bluhm # @@ -56,6 +56,22 @@ sub new { print $fh "\$ModLoad imtcp\n"; print $fh "\$InputTCPServerRun $listenport\n"; } + if ($listenproto eq "tls") { + print $fh "\$DefaultNetstreamDriver gtls\n"; + my %cert = ( + CA => "ca.crt", + Cert => "server.crt", + Key => "server.key", + ); + while(my ($k, $v) = each %cert) { + _make_abspath(\$v); + print $fh "\$DefaultNetstreamDriver${k}File $v\n"; + } + print $fh "\$ModLoad imtcp\n"; + print $fh "\$InputTCPServerStreamDriverMode 1\n"; + print $fh "\$InputTCPServerStreamDriverAuthMode anon\n"; + print $fh "\$InputTCPServerRun $listenport\n"; + } print $fh "*.* $self->{outfile}\n"; print $fh $self->{conf} if $self->{conf}; close $fh; diff --git a/regress/usr.sbin/syslogd/args-rsyslog-tls.pl b/regress/usr.sbin/syslogd/args-rsyslog-tls.pl new file mode 100644 index 00000000000..bb2d2e9749c --- /dev/null +++ b/regress/usr.sbin/syslogd/args-rsyslog-tls.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 TLS to the rsyslogd. +# The rsyslogd receives the message on its TLS 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 => '@tls://127.0.0.1:$connectport', + late => 1, # connect after the listen socket has been created + }, + rsyslogd => { + listen => { proto => "tls" }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-server-tls-close.pl b/regress/usr.sbin/syslogd/args-server-tls-close.pl new file mode 100644 index 00000000000..503bda147be --- /dev/null +++ b/regress/usr.sbin/syslogd/args-server-tls-close.pl @@ -0,0 +1,48 @@ +# The TLS server closes the connection to syslogd. +# 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 IPv4 TLS to an explicit loghost. +# The server receives the message on its TLS socket. +# Find the message in client, pipe, syslogd log. +# Check that syslogd writes a log message about the server close. + +use strict; +use warnings; +use Socket; + +our %args = ( + client => { + func => sub { + my $self = shift; + ${$self->{syslogd}}->loggrep("loghost .* connection error", 5) + or die "no connection error in syslogd.log"; + write_log($self, @_); + }, + }, + syslogd => { + loghost => '@tls://127.0.0.1:$connectport', + loggrep => { + qr/Logging to FORWTLS \@tls:\/\/127.0.0.1:\d+/ => '>=4', + get_testlog() => 1, + qr/syslogd: loghost .* connection error/ => 2, + }, + }, + server => { + listen => { domain => AF_INET, proto => "tls", addr => "127.0.0.1" }, + func => sub { + my $self = shift; + shutdown(\*STDOUT, 1) + or die "shutdown write failed: $!"; + ${$self->{syslogd}}->loggrep("loghost .* connection error", 5) + or die "no connection error in syslogd.log"; + }, + loggrep => {}, + }, + file => { + loggrep => { + qr/syslogd: loghost .* connection error: read failed \(5\)/ => 1, + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-server-tls-error.pl b/regress/usr.sbin/syslogd/args-server-tls-error.pl new file mode 100644 index 00000000000..eab272a1202 --- /dev/null +++ b/regress/usr.sbin/syslogd/args-server-tls-error.pl @@ -0,0 +1,46 @@ +# The TLS server aborts the connection to syslogd. +# 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 IPv4 TLS to an explicit loghost. +# The server receives the message on its TLS socket. +# Find the message in client, pipe, syslogd log. +# Check that syslogd writes a log message about the server error. + +use strict; +use warnings; +use Socket; + +our %args = ( + client => { + func => sub { + my $self = shift; + ${$self->{syslogd}}->loggrep("loghost .* connection error", 5) + or die "no connection error in syslogd.log"; + write_log($self, @_); + }, + }, + syslogd => { + loghost => '@tls://127.0.0.1:$connectport', + loggrep => { + qr/Logging to FORWTLS \@tls:\/\/127.0.0.1:\d+/ => '>=4', + get_testlog() => 1, + qr/syslogd: loghost .* connection error/ => 2, + }, + }, + server => { + listen => { domain => AF_INET, proto => "tls", addr => "127.0.0.1" }, + func => sub { + my $self = shift; + setsockopt(STDOUT, SOL_SOCKET, SO_LINGER, pack('ii', 1, 0)) + or die "set socket linger failed: $!"; + }, + loggrep => {}, + }, + file => { + loggrep => { + qr/syslogd: loghost .* connection error: read failed \(5\)/ => 1, + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-server-tls-reconnect.pl b/regress/usr.sbin/syslogd/args-server-tls-reconnect.pl new file mode 100644 index 00000000000..48d60ffdd4d --- /dev/null +++ b/regress/usr.sbin/syslogd/args-server-tls-reconnect.pl @@ -0,0 +1,65 @@ +# The TLS server closes the connection to syslogd. +# The client writes a message to Sys::Syslog native method. +# The syslogd writes it into a file and through a pipe. +# The syslogd does a TLS reconnect and passes it to loghost. +# The server receives the message on its new accepted TLS socket. +# Find the message in client, pipe, syslogd, server log. +# Check that syslogd and server close and reopen the connection. + +use strict; +use warnings; +use Socket; + +our %args = ( + client => { + func => sub { + my $self = shift; + write_between2logs($self, sub { + ${$self->{syslogd}}->loggrep("Connection refused", 5) + or die "no connection refused in syslogd.log"; + }); + }, + }, + syslogd => { + loghost => '@tls://127.0.0.1:$connectport', + loggrep => { + qr/Logging to FORWTLS \@tls:\/\/127.0.0.1:\d+/ => '>=6', + qr/syslogd: connect .* Connection refused/ => '>=2', + get_between2loggrep(), + }, + }, + server => { + listen => { domain => AF_INET, proto => "tls", addr => "127.0.0.1" }, + redo => 0, + func => sub { + my $self = shift; + read_between2logs($self, sub { + if ($self->{redo}) { + $self->{redo}--; + return; + } + $self->close(); + shutdown(\*STDOUT, 1) + or die "shutdown write failed: $!"; + ${$self->{syslogd}}->loggrep("Connection refused", 5) + or die "no connection refused in syslogd.log"; + $self->listen(); + $self->{redo}++; + }); + }, + loggrep => { + qr/Accepted/ => 2, + qr/syslogd: loghost .* connection error/ => 1, + qr/syslogd: connect .* Connection refused/ => 1, + get_between2loggrep(), + }, + }, + file => { + loggrep => { + qr/syslogd: connect .* Connection refused/ => '>=1', + get_between2loggrep(), + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-server-tls-sendback.pl b/regress/usr.sbin/syslogd/args-server-tls-sendback.pl new file mode 100644 index 00000000000..bd7d33fd72c --- /dev/null +++ b/regress/usr.sbin/syslogd/args-server-tls-sendback.pl @@ -0,0 +1,46 @@ +# The TLS server writes a message back to the syslogd. +# 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 IPv4 TLS to an explicit loghost. +# The server receives the message on its TLS socket. +# Find the message in client, pipe, syslogd, server log. +# Check that syslogd writes a debug message about the message sent back. + +use strict; +use warnings; +use Socket; + +my $sendback = "syslogd tcp server send back message"; + +our %args = ( + client => { + func => sub { + my $self = shift; + ${$self->{syslogd}}->loggrep("loghost .* did send .* back", 5) + or die "no send back in syslogd.log"; + write_log($self, @_); + }, + }, + syslogd => { + loghost => '@tls://127.0.0.1:$connectport', + loggrep => { + qr/Logging to FORWTLS \@tls:\/\/127.0.0.1:\d+/ => '>=4', + get_testlog() => 1, + qr/did send /.length($sendback).qr/ bytes back/ => 1, + }, + }, + server => { + listen => { domain => AF_INET, proto => "tls", addr => "127.0.0.1" }, + func => sub { + print($sendback); + read_log(@_); + }, + }, + file => { + loggrep => { + qr/$sendback/ => 0, + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-server-tls-tcp.pl b/regress/usr.sbin/syslogd/args-server-tls-tcp.pl new file mode 100644 index 00000000000..f7a979d96ff --- /dev/null +++ b/regress/usr.sbin/syslogd/args-server-tls-tcp.pl @@ -0,0 +1,48 @@ +# The TCP server writes cleartext into the TLS connection to syslogd. +# 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 IPv4 TLS to an explicit loghost. +# The server accepts an TCP socket. +# Find the message in client, pipe, syslogd log. +# Check that syslogd writes a log message about the SSL connect error. + +use strict; +use warnings; +use Socket; + +our %args = ( + client => { + func => sub { + my $self = shift; + ${$self->{syslogd}}->loggrep("loghost .* connection error", 5) + or die "no connection error in syslogd.log"; + write_log($self, @_); + }, + }, + syslogd => { + loghost => '@tls://127.0.0.1:$connectport', + loggrep => { + qr/Logging to FORWTLS \@tls:\/\/127.0.0.1:\d+/ => '>=4', + get_testlog() => 1, + qr/syslogd: loghost .* connection error/ => 2, + }, + }, + server => { + listen => { domain => AF_INET, proto => "tcp", addr => "127.0.0.1" }, + func => sub { + my $self = shift; + print "Writing cleartext into a TLS connection is a bad idea\n"; + ${$self->{syslogd}}->loggrep("loghost .* connection error", 5) + or die "no connection error in syslogd.log"; + }, + loggrep => {}, + }, + file => { + loggrep => { + qr/syslogd: loghost .* connection error: SSL connect failed: 1/ + => 1, + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-server-tls4.pl b/regress/usr.sbin/syslogd/args-server-tls4.pl new file mode 100644 index 00000000000..9340a1263a6 --- /dev/null +++ b/regress/usr.sbin/syslogd/args-server-tls4.pl @@ -0,0 +1,29 @@ +# 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 IPv4 TLS to an explicit loghost. +# The server receives the message on its TLS socket. +# Find the message in client, file, pipe, syslogd, server log. +# Check that syslogd and server log contain 127.0.0.1 address. + +use strict; +use warnings; +use Socket; + +our %args = ( + syslogd => { + loghost => '@tls://127.0.0.1:$connectport', + loggrep => { + qr/Logging to FORWTLS \@tls:\/\/127.0.0.1:\d+/ => '>=4', + get_testlog() => 1, + }, + }, + server => { + listen => { domain => AF_INET, proto => "tls", addr => "127.0.0.1" }, + loggrep => { + qr/listen sock: 127.0.0.1 \d+/ => 1, + get_testlog() => 1, + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-server-tls6.pl b/regress/usr.sbin/syslogd/args-server-tls6.pl new file mode 100644 index 00000000000..93011acb3e3 --- /dev/null +++ b/regress/usr.sbin/syslogd/args-server-tls6.pl @@ -0,0 +1,29 @@ +# 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 IPv6 TLS to an explicit loghost. +# The server receives the message on its TLS socket. +# Find the message in client, file, pipe, syslogd, server log. +# Check that syslogd and server log contain ::1 address. + +use strict; +use warnings; +use Socket; + +our %args = ( + syslogd => { + loghost => '@tls://[::1]:$connectport', + loggrep => { + qr/Logging to FORWTLS \@tls:\/\/\[::1\]:\d+/ => '>=4', + get_testlog() => 1, + }, + }, + server => { + listen => { domain => AF_INET6, proto => "tls", addr => "::1" }, + loggrep => { + qr/listen sock: ::1 \d+/ => 1, + get_testlog() => 1, + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-sighup-tls.pl b/regress/usr.sbin/syslogd/args-sighup-tls.pl new file mode 100644 index 00000000000..844e6d3a9e9 --- /dev/null +++ b/regress/usr.sbin/syslogd/args-sighup-tls.pl @@ -0,0 +1,71 @@ +# 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 TLS to the loghost. +# The server receives the message on its TLS socket. +# Find the message in client, file, pipe, syslogd, server log. +# Check that a SIGHUP reconnects the TLS stream and closes the socket. + +use strict; +use warnings; + +our %args = ( + client => { + func => sub { + my $self = shift; + write_between2logs($self, sub { + ${$self->{server}}->loggrep("Signal", 8) + or die ref($self), " no 'Signal' between logs"; + }); + }, + loggrep => { get_between2loggrep() }, + }, + syslogd => { + ktrace => 1, + fstat => 1, + kdump => { + qr/syslogd PSIG SIGHUP caught handler/ => 1, + qr/syslogd RET execve 0/ => 1, + }, + loghost => '@tls://127.0.0.1:$connectport', + loggrep => { + qr/config file changed: dying/ => 0, + qr/config file modified: restarting/ => 0, + qr/syslogd: restarted/ => 1, + get_between2loggrep(), + }, + }, + server => { + listen => { domain => AF_INET, addr => "127.0.0.1", proto => "tls" }, + redo => 0, + func => sub { + my $self = shift; + read_between2logs($self, sub { + if ($self->{redo}) { + $self->{redo}--; + return; + } + ${$self->{syslogd}}->rotate(); + ${$self->{syslogd}}->kill_syslogd('HUP'); + ${$self->{syslogd}}->loggrep("syslogd: restarted", 5) + or die ref($self), " no 'syslogd: restarted' between logs"; + print STDERR "Signal\n"; + # regeneate fstat file + ${$self->{syslogd}}->fstat(); + $self->{redo}++; + }); + }, + loggrep => { + get_between2loggrep(), + qr/Signal/ => 1, + qr/Accepted/ => 2, + }, + }, + fstat => { + loggrep => { + # sighup must not leak a TCP socket + qr/internet stream tcp/ => 1, + }, + }, +); + +1; diff --git a/regress/usr.sbin/syslogd/args-socket-tcp.pl b/regress/usr.sbin/syslogd/args-socket-tcp.pl index cbd8bee3427..13429a6dc2e 100644 --- a/regress/usr.sbin/syslogd/args-socket-tcp.pl +++ b/regress/usr.sbin/syslogd/args-socket-tcp.pl @@ -1,5 +1,4 @@ -# Test with default values, that is: -# The client writes a message to a localhost IPv4 TCP socket. +# 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 loghost. # The server receives the message on its TCP socket. diff --git a/regress/usr.sbin/syslogd/args-socket-tls.pl b/regress/usr.sbin/syslogd/args-socket-tls.pl new file mode 100644 index 00000000000..67faf5e1801 --- /dev/null +++ b/regress/usr.sbin/syslogd/args-socket-tls.pl @@ -0,0 +1,28 @@ +# 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 TLS to the loghost. +# The server receives the message on its TLS socket. +# Find the message in client, file, pipe, syslogd, server log. +# Check that the syslogd has one TCP socket in fstat output. + +use strict; +use warnings; +use Socket; + +our %args = ( + syslogd => { + fstat => 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; diff --git a/regress/usr.sbin/syslogd/funcs.pl b/regress/usr.sbin/syslogd/funcs.pl index 93440059fd8..85d086ffaaf 100644 --- a/regress/usr.sbin/syslogd/funcs.pl +++ b/regress/usr.sbin/syslogd/funcs.pl @@ -1,4 +1,4 @@ -# $OpenBSD: funcs.pl,v 1.10 2015/01/15 13:15:17 bluhm Exp $ +# $OpenBSD: funcs.pl,v 1.11 2015/01/16 11:51:59 bluhm Exp $ # Copyright (c) 2010-2015 Alexander Bluhm # @@ -34,6 +34,7 @@ sub find_ports { my $domain = delete $args{domain} // AF_INET; my $addr = delete $args{addr} // "127.0.0.1"; my $proto = delete $args{proto} // "udp"; + $proto = "tcp" if $proto eq "tls"; my @sockets = (1..$num); foreach my $s (@sockets) {