Add regression tests for syslog over TLS.
authorbluhm <bluhm@openbsd.org>
Fri, 16 Jan 2015 11:51:59 +0000 (11:51 +0000)
committerbluhm <bluhm@openbsd.org>
Fri, 16 Jan 2015 11:51:59 +0000 (11:51 +0000)
13 files changed:
regress/usr.sbin/syslogd/RSyslogd.pm
regress/usr.sbin/syslogd/args-rsyslog-tls.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-server-tls-close.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-server-tls-error.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-server-tls-reconnect.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-server-tls-sendback.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-server-tls-tcp.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-server-tls4.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-server-tls6.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-sighup-tls.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-socket-tcp.pl
regress/usr.sbin/syslogd/args-socket-tls.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/funcs.pl

index 6a1e906..1335074 100644 (file)
@@ -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 <bluhm@openbsd.org>
 #
@@ -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 (file)
index 0000000..bb2d2e9
--- /dev/null
@@ -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 (file)
index 0000000..503bda1
--- /dev/null
@@ -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 (file)
index 0000000..eab272a
--- /dev/null
@@ -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 (file)
index 0000000..48d60ff
--- /dev/null
@@ -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 (file)
index 0000000..bd7d33f
--- /dev/null
@@ -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 (file)
index 0000000..f7a979d
--- /dev/null
@@ -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 (file)
index 0000000..9340a12
--- /dev/null
@@ -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 (file)
index 0000000..93011ac
--- /dev/null
@@ -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 (file)
index 0000000..844e6d3
--- /dev/null
@@ -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;
index cbd8bee..13429a6 100644 (file)
@@ -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 (file)
index 0000000..67faf5e
--- /dev/null
@@ -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;
index 9344005..85d086f 100644 (file)
@@ -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 <bluhm@openbsd.org>
 #
@@ -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) {