X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=t%2Fnntpd-tls.t;h=4cf53daad8cd0325fdb7e9555ab56bc7a19906d4;hb=5769d488526b88a394b4b6741e77dd0e7441d248;hp=e8fb63b46fc80a204f774d1718b6158249687eba;hpb=1dc4d2f75a387c9113fc7646c463e3aac2d3de1f;p=public-inbox.git diff --git a/t/nntpd-tls.t b/t/nntpd-tls.t index e8fb63b4..4cf53daa 100644 --- a/t/nntpd-tls.t +++ b/t/nntpd-tls.t @@ -4,13 +4,16 @@ use strict; use warnings; use Test::More; use File::Temp qw(tempdir); -use Socket qw(SOCK_STREAM); +use Socket qw(SOCK_STREAM IPPROTO_TCP SOL_SOCKET); # IO::Poll and Net::NNTP are part of the standard library, but # distros may split them off... foreach my $mod (qw(DBD::SQLite IO::Socket::SSL Net::NNTP IO::Poll)) { eval "require $mod"; plan skip_all => "$mod missing for $0" if $@; } +Net::NNTP->can('starttls') or + plan skip_all => 'Net::NNTP does not support TLS'; + my $cert = 'certs/server-cert.pem'; my $key = 'certs/server-key.pem'; unless (-r $key && -r $cert) { @@ -34,15 +37,8 @@ my $pi_config = "$tmpdir/pi_config"; my $group = 'test-nntpd-tls'; my $addr = $group . '@example.com'; my $nntpd = 'blib/script/public-inbox-nntpd'; -my %opts = ( - LocalAddr => '127.0.0.1', - ReuseAddr => 1, - Proto => 'tcp', - Type => SOCK_STREAM, - Listen => 1024, -); -my $starttls = IO::Socket::INET->new(%opts); -my $nntps = IO::Socket::INET->new(%opts); +my $starttls = tcp_server(); +my $nntps = tcp_server(); my ($pid, $tail_pid); END { foreach ($pid, $tail_pid) { @@ -132,6 +128,8 @@ for my $args ( my $c = Net::NNTP->new($nntps_addr, %o, SSL => 1); my $list = $c->list; is_deeply($list, $expect, 'NNTPS LIST works'); + unlike(get_capa($c), qr/\bSTARTTLS\r\n/, + 'STARTTLS not advertised for NNTPS'); is($c->command('QUIT')->response(), Net::Cmd::CMD_OK(), 'QUIT works'); is(0, sysread($c, my $buf, 1), 'got EOF after QUIT'); @@ -143,6 +141,8 @@ for my $args ( is($c->code, 382, 'got 382 for STARTTLS'); $list = $c->list; is_deeply($list, $expect, 'LIST works after STARTTLS'); + unlike(get_capa($c), qr/\bSTARTTLS\r\n/, + 'STARTTLS not advertised after STARTTLS'); # Net::NNTP won't let us do dumb things, but we need to test # dumb things, so use Net::Cmd directly: @@ -153,6 +153,7 @@ for my $args ( # STARTTLS with bad hostname $o{SSL_hostname} = $o{SSL_verifycn_name} = 'server.invalid'; $c = Net::NNTP->new($starttls_addr, %o); + like(get_capa($c), qr/\bSTARTTLS\r\n/, 'STARTTLS advertised'); $list = $c->list; is_deeply($list, $expect, 'plain LIST works again'); ok(!$c->starttls, 'STARTTLS fails with bad hostname'); @@ -182,6 +183,27 @@ for my $args ( is(sysread($slow, my $eof, 4096), 0, 'got EOF'); $slow = undef; + SKIP: { + skip 'TCP_DEFER_ACCEPT is Linux-only', 2 if $^O ne 'linux'; + my $var = Socket::TCP_DEFER_ACCEPT(); + defined(my $x = getsockopt($nntps, IPPROTO_TCP, $var)) or die; + ok(unpack('i', $x) > 0, 'TCP_DEFER_ACCEPT set on NNTPS'); + defined($x = getsockopt($starttls, IPPROTO_TCP, $var)) or die; + is(unpack('i', $x), 0, 'TCP_DEFER_ACCEPT is 0 on plain NNTP'); + }; + SKIP: { + skip 'SO_ACCEPTFILTER is FreeBSD-only', 2 if $^O ne 'freebsd'; + if (system('kldstat -m accf_data >/dev/null')) { + skip 'accf_data not loaded? kldload accf_data', 2; + } + require PublicInbox::Daemon; + my $var = PublicInbox::Daemon::SO_ACCEPTFILTER(); + my $x = getsockopt($nntps, SOL_SOCKET, $var); + like($x, qr/\Adataready\0+\z/, 'got dataready accf for NNTPS'); + $x = getsockopt($starttls, IPPROTO_TCP, $var); + is($x, undef, 'no BSD accept filter for plain NNTP'); + }; + $c = undef; kill('TERM', $pid); is($pid, waitpid($pid, 0), 'nntpd exited successfully'); @@ -200,4 +222,17 @@ for my $args ( } } done_testing(); + +sub get_capa { + my ($sock) = @_; + syswrite($sock, "CAPABILITIES\r\n"); + my $capa = ''; + do { + my $r = sysread($sock, $capa, 8192, length($capa)); + die "unexpected: $!" unless defined($r); + die 'unexpected EOF' if $r == 0; + } until $capa =~ /\.\r\n\z/; + $capa; +} + 1;