From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 719541F567 for ; Tue, 3 Oct 2023 06:43:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1696315433; bh=fb18Y7jWoYpmKgNVYnwxZrYa/U/gZZeykkyQReL1OxI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=jPn77Glm9GSb/2H7Nt8qng0O+uuR/+yyS0xvpBkMeazYqpbf+J0suq5pFAnSkiQyN 6Kv4kuA6KnpTuvVqi4iD9nHKYl8pzs9/wKl1m6XrGRdvURcYIiHf2CqbpTRc/eZ7OI 7PnPd7K3CxOLvBZo3jLzbCEgySamyv+MEu5ED9zE= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 4/8] net_reader: support imap.sslVerify + nntp.sslVerify Date: Tue, 3 Oct 2023 06:43:48 +0000 Message-ID: <20231003064352.2902298-5-e@80x24.org> In-Reply-To: <20231003064352.2902298-1-e@80x24.org> References: <20231003064352.2902298-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: These options are useful for testing as well as users stuck on out-of-date systems, dealing with forgetful sysadmins, broken cronjobs, and/or are willing to risk MITM attacks. --- lib/PublicInbox/NetReader.pm | 28 ++++++++++++++++++++++------ t/imapd-tls.t | 14 +++++++++++--- t/nntpd-tls.t | 15 ++++++++++++--- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/lib/PublicInbox/NetReader.pm b/lib/PublicInbox/NetReader.pm index 5819f210..2d6cb0d6 100644 --- a/lib/PublicInbox/NetReader.pm +++ b/lib/PublicInbox/NetReader.pm @@ -49,6 +49,13 @@ sub mic_tls_opt ($$) { [ map { ($_, $o->{$_}) } keys %$o ]; } +sub set_ssl_verify_mode ($$) { + my ($o, $bool) = @_; + require IO::Socket::SSL; + $o->{SSL_verify_mode} = $bool ? IO::Socket::SSL::SSL_VERIFY_PEER() : + IO::Socket::SSL::SSL_VERIFY_NONE(); +} + sub mic_new ($$$$) { my ($self, $mic_arg, $sec, $uri) = @_; my %mic_arg = (%$mic_arg, Keepalive => 1); @@ -138,7 +145,6 @@ sub mic_for ($$$$) { # mic = Mail::IMAPClient Server => $host, %$common, # may set Starttls, Compress, Debug .... }; - $mic_arg->{Ssl} = 1 if $uri->scheme eq 'imaps'; require PublicInbox::IMAPClient; my $mic = mic_new($self, $mic_arg, $sec, $uri); ($mic && $mic->IsConnected) or @@ -341,6 +347,7 @@ sub imap_common_init ($;$) { } my $to = cfg_intvl($cfg, 'imap.timeout', $$uri); $mic_common->{$sec}->{Timeout} = $to if $to; + $mic_common->{$sec}->{Ssl} = 1 if $uri->scheme eq 'imaps'; # knobs we use ourselves: my $sa = socks_args($cfg->urlmatch('imap.Proxy', $$uri)); @@ -350,11 +357,18 @@ sub imap_common_init ($;$) { $self->{cfg_opt}->{$sec}->{$k} = $to; } my $k = 'imap.fetchBatchSize'; - my $bs = $cfg->urlmatch($k, $$uri) // next; - if ($bs =~ /\A([0-9]+)\z/ && $bs > 0) { - $self->{cfg_opt}->{$sec}->{batch_size} = $bs; - } else { - warn "$k=$bs is not a positive integer\n"; + if (defined(my $bs = $cfg->urlmatch($k, $$uri))) { + ($bs =~ /\A([0-9]+)\z/ && $bs > 0) ? + ($self->{cfg_opt}->{$sec}->{batch_size} = $bs) : + warn("$k=$bs is not a positive integer\n"); + } + my $v = $cfg->urlmatch(qw(--bool imap.sslVerify), $$uri); + if (defined $v) { + my $cur = $mic_common->{$sec} //= {}; + $cur->{Starttls} //= 1 if !$cur->{Ssl}; + for my $f (grep { $cur->{$_} } qw(Ssl Starttls)) { + set_ssl_verify_mode($cur->{$f} = {}, $v); + } } } # make sure we can connect and cache the credentials in memory @@ -402,6 +416,8 @@ sub nntp_common_init ($;$) { $v = $cfg->urlmatch('--bool', "nntp.$k", $$uri); $self->{cfg_opt}->{$sec}->{$k} = $v if defined $v; } + $v = $cfg->urlmatch(qw(--bool nntp.sslVerify), $$uri); + set_ssl_verify_mode($args, $v) if defined $v; # -watch internal option for my $k (qw(pollInterval)) { diff --git a/t/imapd-tls.t b/t/imapd-tls.t index 673a9436..e432ef07 100644 --- a/t/imapd-tls.t +++ b/t/imapd-tls.t @@ -1,8 +1,7 @@ #!perl -w -# Copyright (C) 2020-2021 all contributors +# Copyright (C) all contributors # License: AGPL-3.0+ -use strict; -use v5.10.1; +use v5.12; use Socket qw(IPPROTO_TCP SOL_SOCKET); use PublicInbox::TestCommon; # IO::Poll is part of the standard library, but distros may split it off... @@ -158,10 +157,19 @@ for my $args ( test_lei(sub { lei_ok qw(ls-mail-source), "imap://$starttls_addr", \'STARTTLS not used by default'; + my $plain_out = $lei_out; ok(!lei(qw(ls-mail-source -c imap.starttls), "imap://$starttls_addr"), 'STARTTLS verify fails'); unlike $lei_err, qr!W: imap\.starttls= .*? is not boolean!i, 'no non-boolean warning'; + lei_ok qw(-c imap.starttls -c imap.sslVerify= ls-mail-source), + "imap://$starttls_addr", + \'disabling imap.sslVerify works w/ STARTTLS'; + is $lei_out, $plain_out, 'sslVerify=false w/ STARTTLS output'; + lei_ok qw(ls-mail-source -c imap.sslVerify=false), + "imaps://$imaps_addr", + \'disabling imap.sslVerify works w/ imaps://'; + is $lei_out, $plain_out, 'sslVerify=false w/ IMAPS output'; }); SKIP: { diff --git a/t/nntpd-tls.t b/t/nntpd-tls.t index 095aef96..21377fc0 100644 --- a/t/nntpd-tls.t +++ b/t/nntpd-tls.t @@ -1,8 +1,7 @@ #!perl -w -# Copyright (C) 2019-2021 all contributors +# Copyright (C) all contributors # License: AGPL-3.0+ -use strict; -use v5.10.1; +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 @@ -149,12 +148,22 @@ for my $args ( 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: {