about summary refs log tree commit homepage
path: root/lib/PublicInbox/NNTP.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-06-24 02:52:38 +0000
committerEric Wong <e@80x24.org>2019-06-24 05:26:26 +0000
commitb70cf61f0c1f70621b88fe6420083a576d47f19f (patch)
tree88b4cd6fb40e983d7b9a536456067e42b7d890ba /lib/PublicInbox/NNTP.pm
parent93fc0336d39ba3ef07b479877e64371f07c86eab (diff)
downloadpublic-inbox-b70cf61f0c1f70621b88fe6420083a576d47f19f.tar.gz
It kinda, barely works, and I'm most happy I got it working
without any modifications to the main NNTP::event_step callback
thanks to the DS->write(CODE) support we inherited from
Danga::Socket.
Diffstat (limited to 'lib/PublicInbox/NNTP.pm')
-rw-r--r--lib/PublicInbox/NNTP.pm27
1 files changed, 24 insertions, 3 deletions
diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index a18641d3..659e44d5 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -1,4 +1,4 @@
-# Copyright (C) 2015-2018 all contributors <meta@public-inbox.org>
+# Copyright (C) 2015-2019 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 #
 # Each instance of this represents a NNTP client socket
@@ -98,11 +98,19 @@ sub expire_old () {
 sub new ($$$) {
         my ($class, $sock, $nntpd) = @_;
         my $self = fields::new($class);
-        $self->SUPER::new($sock, EPOLLOUT | EPOLLONESHOT);
+        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 |= EPOLLONESHOT;
+                $wbuf->[0] = \&PublicInbox::DS::accept_tls_step;
+        }
+        $self->SUPER::new($sock, $ev);
         $self->{nntpd} = $nntpd;
         my $greet = "201 $nntpd->{servername} ready - post via email\r\n";
         open my $fh, '<:scalar',  \$greet or die "open :scalar: $!";
-        $self->{wbuf} = [ $fh ];
+        push @$wbuf, $fh;
+        $self->{wbuf} = $wbuf;
         $self->{rbuf} = '';
         update_idle_time($self);
         $expt ||= PublicInbox::EvCleanup::later(*expire_old);
@@ -900,6 +908,19 @@ sub cmd_xover ($;$) {
         });
 }
 
+sub cmd_starttls ($) {
+        my ($self) = @_;
+        my $sock = $self->{sock} or return;
+        # RFC 4642 2.2.1
+        (ref($sock) eq 'IO::Socket::SSL') and return '502 Command unavailable';
+        my $opt = $self->{nntpd}->{accept_tls} or
+                return '580 can not initiate TLS negotiation';
+        res($self, '382 Continue with TLS negotiation');
+        $self->{sock} = IO::Socket::SSL->start_SSL($sock, %$opt);
+        requeue($self) if PublicInbox::DS::accept_tls_step($self);
+        undef;
+}
+
 sub cmd_xpath ($$) {
         my ($self, $mid) = @_;
         return r501 unless $mid =~ /\A<(.+)>\z/;