-# $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>
#
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;
--- /dev/null
+# 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;
--- /dev/null
+# 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;
--- /dev/null
+# 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;
--- /dev/null
+# 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;
--- /dev/null
+# 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;
--- /dev/null
+# 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;
--- /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 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;
--- /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 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;
--- /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 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;
-# 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.
--- /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 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;
-# $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>
#
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) {