#!perl -w
# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
use v5.12;
use PublicInbox::TestCommon;
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...
require_mods(qw(DBD::SQLite IO::Socket::SSL Net::NNTP IO::Poll));
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) {
	plan skip_all =>
		"certs/ missing for $0, run $^X ./create-certs.perl in certs/";
}

use_ok 'PublicInbox::TLS';
use_ok 'IO::Socket::SSL';
our $need_zlib;
eval { require Compress::Raw::Zlib } or
	$need_zlib = 'Compress::Raw::Zlib missing';
my $version = 2; # v2 needs newer git
require_git('2.6') if $version >= 2;
my ($tmpdir, $for_destroy) = tmpdir();
my $err = "$tmpdir/stderr.log";
my $out = "$tmpdir/stdout.log";
my $group = 'test-nntpd-tls';
my $addr = $group . '@example.com';
my $starttls = tcp_server();
my $nntps = tcp_server();
my $pi_config;
my $ibx = create_inbox "v$version", version => $version, indexlevel => 'basic',
			sub {
	my ($im, $ibx) = @_;
	$pi_config = "$ibx->{inboxdir}/pi_config";
	open my $fh, '>', $pi_config or BAIL_OUT "open: $!";
	print $fh <<EOF or BAIL_OUT;
[publicinbox "nntpd-tls"]
	inboxdir = $ibx->{inboxdir}
	address = $addr
	indexlevel = basic
	newsgroup = $group
EOF
	close $fh or BAIL_OUT "close: $!";
	$im->add(eml_load 't/data/0001.patch') or BAIL_OUT;
};
$pi_config //= "$ibx->{inboxdir}/pi_config";
undef $ibx;
my $nntps_addr = tcp_host_port($nntps);
my $starttls_addr = tcp_host_port($starttls);
my $env = { PI_CONFIG => $pi_config };
my $td;

for my $args (
	[ "--cert=$cert", "--key=$key",
		"-lnntps://$nntps_addr",
		"-lnntp://$starttls_addr" ],
) {
	for ($out, $err) {
		open my $fh, '>', $_ or die "truncate: $!";
	}
	my $cmd = [ '-nntpd', '-W0', @$args, "--stdout=$out", "--stderr=$err" ];
	$td = start_script($cmd, $env, { 3 => $starttls, 4 => $nntps });
	my %o = (
		SSL_hostname => 'server.local',
		SSL_verifycn_name => 'server.local',
		SSL_verify_mode => SSL_VERIFY_PEER(),
		SSL_ca_file => 'certs/test-ca.pem',
	);
	my $expect = { $group => [qw(1 1 n)] };

	# start negotiating a slow TLS connection
	my $slow = tcp_connect($nntps, Blocking => 0);
	$slow = IO::Socket::SSL->start_SSL($slow, SSL_startHandshake => 0, %o);
	my $slow_done = $slow->connect_SSL;
	my @poll;
	if ($slow_done) {
		diag('W: connect_SSL early OK, slow client test invalid');
		use PublicInbox::Syscall qw(EPOLLIN EPOLLOUT);
		@poll = (fileno($slow), EPOLLIN | EPOLLOUT);
	} else {
		@poll = (fileno($slow), PublicInbox::TLS::epollbit());
	}
	# we should call connect_SSL much later...

	# NNTPS
	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');

	# STARTTLS
	$c = Net::NNTP->new($starttls_addr, %o);
	$list = $c->list;
	is_deeply($list, $expect, 'plain LIST works');
	ok($c->starttls, 'STARTTLS succeeds');
	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:
	my $n = $c->command('STARTTLS')->response();
	is($n, Net::Cmd::CMD_ERROR(), 'error attempting STARTTLS again');
	is($c->code, 502, '502 according to RFC 4642 sec#2.2.1');

	# 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');
	$c = Net::NNTP->new($starttls_addr, %o);
	$list = $c->list;
	is_deeply($list, $expect, 'not broken after bad negotiation');

	# NNTPS with bad hostname
	$c = Net::NNTP->new($nntps_addr, %o, SSL => 1);
	is($c, undef, 'NNTPS fails with bad hostname');
	$o{SSL_hostname} = $o{SSL_verifycn_name} = 'server.local';
	$c = Net::NNTP->new($nntps_addr, %o, SSL => 1);
	ok($c, 'NNTPS succeeds again with valid hostname');

	# slow TLS connection did not block the other fast clients while
	# connecting, finish it off:
	until ($slow_done) {
		IO::Poll::_poll(-1, @poll);
		$slow_done = $slow->connect_SSL and last;
		@poll = (fileno($slow), PublicInbox::TLS::epollbit());
	}
	$slow->blocking(1);
	ok(sysread($slow, my $greet, 4096) > 0, 'slow got greeting');
	like($greet, qr/\A201 /, 'got expected greeting');
	is(syswrite($slow, "QUIT\r\n"), 6, 'slow wrote QUIT');
	ok(sysread($slow, my $end, 4096) > 0, 'got EOF');
	is(sysread($slow, my $eof, 4096), 0, 'got EOF');
	$slow = undef;

	test_lei(sub {
		lei_ok qw(ls-mail-source), "nntp://$starttls_addr",
			\'STARTTLS not used by default';
		my $plain_out = $lei_out;
		ok(!lei(qw(ls-mail-source -c nntp.starttls),
			"nntp://$starttls_addr"), 'STARTTLS verify fails');
		like $lei_err, qr/STARTTLS requested/,
			'STARTTLS noted in stderr';
		unlike $lei_err, qr!W: nntp\.starttls= .*? is not boolean!i,
			'no non-boolean warning';
		lei_ok qw(-c nntp.starttls -c nntp.sslVerify= ls-mail-source),
			"nntp://$starttls_addr",
			\'disabling nntp.sslVerify works w/ STARTTLS';
		is $lei_out, $plain_out, 'sslVerify=false w/ STARTTLS output';

		lei_ok qw(ls-mail-source -c nntp.sslVerify=false),
			"nntps://$nntps_addr",
			\'disabling nntp.sslVerify works w/ nntps://';
		is $lei_out, $plain_out, 'sslVerify=false w/ NNTPS output';
	});

	SKIP: {
		skip 'TCP_DEFER_ACCEPT is Linux-only', 2 if $^O ne 'linux';
		my $var = eval { Socket::TCP_DEFER_ACCEPT() } // 9;
		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: {
		require_mods '+accf_data';
		require PublicInbox::Daemon;
		my $x = getsockopt($nntps, SOL_SOCKET,
				$PublicInbox::Daemon::SO_ACCEPTFILTER);
		like($x, qr/\Adataready\0+\z/, 'got dataready accf for NNTPS');
		$x = getsockopt($starttls, IPPROTO_TCP,
				$PublicInbox::Daemon::SO_ACCEPTFILTER);
		is($x, undef, 'no BSD accept filter for plain NNTP');
	};

	my $s = tcp_connect($nntps);
	syswrite($s, '->accept_SSL_ will fail on this!');
	my @r;
	do { # some platforms or OpenSSL versions need an extra read
		push @r, sysread($s, my $rbuf, 128);
	} while ($r[-1] && @r < 2);
	ok(!$r[-1], 'EOF or ECONNRESET on ->accept_SSL fail') or
		diag explain(\@r);
	$c = undef;
	$td->kill;
	$td->join;
	is($?, 0, 'no error in exited process');
	my $eout = eval {
		open my $fh, '<', $err or die "open $err failed: $!";
		local $/;
		<$fh>;
	};
	unlike($eout, qr/wide/i, 'no Wide character warnings');
	unlike($eout, qr/^E:/, 'no other errors');
}
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/;

	my $deflate_capa = qr/\r\nCOMPRESS DEFLATE\r\n/;
	if ($need_zlib) {
		unlike($capa, $deflate_capa,
			'COMPRESS DEFLATE NOT advertised '.$need_zlib);
	} else {
		like($capa, $deflate_capa, 'COMPRESS DEFLATE advertised');
	}
	$capa;
}

1;
