From: Eric Wong <e@80x24.org>
Date: Mon, 24 Jun 2019 02:52:41 +0000 (+0000)
Subject: ds|nntp: use CORE::close on socket
X-Git-Tag: v1.2.0~156^2~19
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=b3e4b3b3c67b9df7868518978e721417b0aa7c9c;p=public-inbox.git

ds|nntp: use CORE::close on socket

IO::Socket::SSL will try to re-bless back to the original class
on TLS negotiation failure.  Unfortunately, the original class
is 'GLOB', and re-blessing to 'GLOB' takes away all the IO::Handle
methods, because Filehandle/IO are a special case in Perl5.
Anyways, since we already use syswrite() and sysread() as functions
on our socket, we might as well use CORE::close(), as well (and
it plays nicely with tied classes).
---

diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index 044b991c..2c886b4e 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -293,8 +293,8 @@ sub PostEventLoop {
     while (my $sock = shift @ToClose) {
         my $fd = fileno($sock);
 
-        # close the socket.  (not a PublicInbox::DS close)
-        $sock->close;
+        # close the socket. (not a PublicInbox::DS close)
+        CORE::close($sock);
 
         # and now we can finally remove the fd from the map.  see
         # comment above in ->close.
diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index 659e44d5..8840adbb 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -101,7 +101,7 @@ sub new ($$$) {
 	my $ev = EPOLLOUT | EPOLLONESHOT;
 	my $wbuf = [];
 	if (ref($sock) eq 'IO::Socket::SSL' && !$sock->accept_SSL) {
-		$ev = PublicInbox::TLS::epollbit() or return $sock->close;
+		$ev = PublicInbox::TLS::epollbit() or return CORE::close($sock);
 		$ev |= EPOLLONESHOT;
 		$wbuf->[0] = \&PublicInbox::DS::accept_tls_step;
 	}
diff --git a/t/nntpd-tls.t b/t/nntpd-tls.t
index 53890ff2..4727ee5b 100644
--- a/t/nntpd-tls.t
+++ b/t/nntpd-tls.t
@@ -135,6 +135,23 @@ for my $args (
 	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);
+	$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');
+
 	$c = undef;
 	kill('TERM', $pid);
 	is($pid, waitpid($pid, 0), 'nntpd exited successfully');