]> Sergey Matveev's repositories - public-inbox.git/commitdiff
ds|nntp: use CORE::close on socket
authorEric Wong <e@80x24.org>
Mon, 24 Jun 2019 02:52:41 +0000 (02:52 +0000)
committerEric Wong <e@80x24.org>
Mon, 24 Jun 2019 05:26:27 +0000 (05:26 +0000)
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).

lib/PublicInbox/DS.pm
lib/PublicInbox/NNTP.pm
t/nntpd-tls.t

index 044b991c8c602abbee79a7b947ac3a21bacae50b..2c886b4e4ff64674b6d367be0b528c5322417cdf 100644 (file)
@@ -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.
index 659e44d5501194499eac24634c81243282bd4441..8840adbb8a807aa2fb0a2741675a0d137b232320 100644 (file)
@@ -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;
        }
index 53890ff26e4eb09f4c20ead092126022aee2c37b..4727ee5bb6f68e5e88e0e8f1cf180effad842f45 100644 (file)
@@ -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');