user/dev discussion of public-inbox itself
 help / color / Atom feed
From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 2/2] nntp: add support for CAPABILITIES command
Date: Sun, 30 Jun 2019 22:36:35 +0000
Message-ID: <20190630223635.4687-3-e@80x24.org> (raw)
In-Reply-To: <20190630223635.4687-1-e@80x24.org>

Some clients may rely on this for STARTTLS support.
---
 lib/PublicInbox/NNTP.pm | 19 +++++++++++++++++++
 t/nntpd-tls.t           | 18 ++++++++++++++++++
 t/nntpd.t               |  5 +++++
 3 files changed, 42 insertions(+)

diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index 57a67a50..d106e315 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -31,6 +31,14 @@ my @OVERVIEW = qw(Subject From Date Message-ID References Xref);
 my $OVERVIEW_FMT = join(":\r\n", @OVERVIEW, qw(Bytes Lines)) . ":\r\n";
 my $LIST_HEADERS = join("\r\n", @OVERVIEW,
 			qw(:bytes :lines Xref To Cc)) . "\r\n";
+my $CAPABILITIES = <<"";
+101 Capability list:\r
+VERSION 2\r
+READER\r
+NEWNEWS\r
+LIST ACTIVE ACTIVE.TIMES NEWSGROUPS OVERVIEW.FMT\r
+HDR\r
+OVER\r
 
 my $EXPMAP; # fd -> [ idle_time, $self ]
 my $expt;
@@ -121,6 +129,17 @@ sub process_line ($$) {
 	res($self, $res);
 }
 
+# The keyword argument is not used (rfc3977 5.2.2)
+sub cmd_capabilities ($;$) {
+	my ($self, undef) = @_;
+	my $res = $CAPABILITIES;
+	if (ref($self->{sock}) ne 'IO::Socket::SSL' &&
+			$self->{nntpd}->{accept_tls}) {
+		$res .= "STARTTLS\r\n";
+	}
+	$res .= '.';
+}
+
 sub cmd_mode ($$) {
 	my ($self, $arg) = @_;
 	$arg = uc $arg;
diff --git a/t/nntpd-tls.t b/t/nntpd-tls.t
index 82b63f3e..4cf53daa 100644
--- a/t/nntpd-tls.t
+++ b/t/nntpd-tls.t
@@ -128,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');
 
@@ -139,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:
@@ -149,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');
@@ -217,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;
diff --git a/t/nntpd.t b/t/nntpd.t
index 0e59de07..1c5ae8d7 100644
--- a/t/nntpd.t
+++ b/t/nntpd.t
@@ -143,6 +143,11 @@ EOF
 		'got greeting');
 	$s->autoflush(1);
 
+	syswrite($s, "CAPABILITIES\r\n");
+	$buf = read_til_dot($s);
+	like($buf, qr/\r\nVERSION 2\r\n/s, 'CAPABILITIES works');
+	unlike($buf, qr/STARTTLS/s, 'STARTTLS not advertised');
+
 	syswrite($s, "NEWGROUPS 19990424 000000 GMT\r\n");
 	$buf = read_til_dot($s);
 	like($buf, qr/\A231 list of /, 'newgroups OK');
-- 
EW


      parent reply index

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-30 22:36 [PATCH 0/2] nntp: cleanup and support CAPABILITIES Eric Wong
2019-06-30 22:36 ` [PATCH 1/2] nntp: remove DISABLED hash checks Eric Wong
2019-06-30 22:36 ` Eric Wong [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190630223635.4687-3-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

user/dev discussion of public-inbox itself

Archives are clonable:
	git clone --mirror https://public-inbox.org/meta
	git clone --mirror http://czquwvybam4bgbro.onion/meta
	git clone --mirror http://hjrcffqmbrq6wope.onion/meta
	git clone --mirror http://ou63pmih66umazou.onion/meta

Example config snippet for mirrors

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.mail.public-inbox.meta
	nntp://ou63pmih66umazou.onion/inbox.comp.mail.public-inbox.meta
	nntp://czquwvybam4bgbro.onion/inbox.comp.mail.public-inbox.meta
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.mail.public-inbox.meta
	nntp://news.gmane.io/gmane.mail.public-inbox.general

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git