From 522666e8e2556d89c25013ce17d6db49e75443ef Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Mon, 21 Jan 2019 23:59:55 +0100 Subject: [PATCH] Net::IMAP::InterIMAP: add support for TLSv1.3 (on recent enough Net::SSLeay). Also, change "SSL_protocols" default value from "!SSLv2 !SSLv3" to "!SSLv2 !SSLv3 !TLSv1 !TLSv1.1". I.e., only enable TLSv1.2 and later, which is the default in Debian's OpenSSL as of 1.1.1-2, cf. https://tracker.debian.org/news/998835/accepted-openssl-111-2-source-into-unstable/ . --- Changelog | 3 +++ interimap.md | 7 ++++--- lib/Net/IMAP/InterIMAP.pm | 27 +++++++++++++++++---------- pullimap.md | 7 ++++--- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/Changelog b/Changelog index b4fb931..9fa46dd 100644 --- a/Changelog +++ b/Changelog @@ -7,6 +7,9 @@ interimap (0.4) UNRELEASED relative to $XDG_CONFIG_HOME/$NAME (or ~/.config/$NAME), to comply with the XDG specification. Thus the previous default config file $XDG_CONFIG_HOME/$NAME should become $XDG_CONFIG_HOME/$NAME/config. + * Library: add support for TLSv1.3 (on recent enough Net::SSLeay), and + change "SSL_protocols" default value from "!SSLv2 !SSLv3" to "!SSLv2 + !SSLv3 !TLSv1 !TLSv1.1". + Library: new API idle_start() and idle_stop(). + Add support for untagged ESEARCH responses from RFC 4731. + pullimap: Use extended SEARCH commands (RFC 4731) if supported by diff --git a/interimap.md b/interimap.md index 1831d39..4d85eaf 100644 --- a/interimap.md +++ b/interimap.md @@ -332,9 +332,10 @@ Valid options are: : A space-separated list of SSL protocols to enable or disable (if prefixed with an exclamation mark `!`. Known protocols are `SSLv2`, - `SSLv3`, `TLSv1`, `TLSv1.1`, and `TLSv1.2`. Enabling a protocol is - a short-hand for disabling all other protocols. - (Default: `!SSLv2 !SSLv3`, i.e., only enable TLSv1 and above.) + `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`. Enabling a + protocol is a short-hand for disabling all other protocols. + (Default: `!SSLv2 !SSLv3 !TLSv1 !TLSv1.1`, i.e., only enable TLSv1.2 + and above.) *SSL_cipher_list* diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index f783ea7..3d8bd97 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -45,7 +45,7 @@ my $RE_ATOM_CHAR = qr/[\x21\x23\x24\x26\x27\x2B-\x5B\x5E-\x7A\x7C-\x7E]/; my $RE_ASTRING_CHAR = qr/[\x21\x23\x24\x26\x27\x2B-\x5B\x5D-\x7A\x7C-\x7E]/; my $RE_TEXT_CHAR = qr/[\x01-\x09\x0B\x0C\x0E-\x7F]/; -my $RE_SSL_PROTO = qr/(?:SSLv[23]|TLSv1|TLSv1\.[0-2])/; +my $RE_SSL_PROTO = qr/(?:SSLv[23]|TLSv1|TLSv1\.[0-3])/; # Map each option to a regexp validating its values. my %OPTIONS = ( @@ -1599,13 +1599,19 @@ sub _ssl_verify($$$) { return $ok; # 1=accept cert, 0=reject } -my %SSL_proto = ( - 'SSLv2' => Net::SSLeay::OP_NO_SSLv2(), - 'SSLv3' => Net::SSLeay::OP_NO_SSLv3(), - 'TLSv1' => Net::SSLeay::OP_NO_TLSv1(), - 'TLSv1.1' => Net::SSLeay::OP_NO_TLSv1_1(), - 'TLSv1.2' => Net::SSLeay::OP_NO_TLSv1_2() -); +my %SSL_proto; +BEGIN { + sub _append_ssl_proto($$) { + my ($k, $v) = @_; + $SSL_proto{$k} = $v if defined $v; + } + _append_ssl_proto( "SSLv2", eval { Net::SSLeay::OP_NO_SSLv2() } ); + _append_ssl_proto( "SSLv3", eval { Net::SSLeay::OP_NO_SSLv3() } ); + _append_ssl_proto( "TLSv1", eval { Net::SSLeay::OP_NO_TLSv1() } ); + _append_ssl_proto( "TLSv1.1", eval { Net::SSLeay::OP_NO_TLSv1_1() } ); + _append_ssl_proto( "TLSv1.2", eval { Net::SSLeay::OP_NO_TLSv1_2() } ); + _append_ssl_proto( "TLSv1.3", eval { Net::SSLeay::OP_NO_TLSv1_3() } ); +} # $self->_start_ssl($socket) # Upgrade the $socket to SSL/TLS. @@ -1614,7 +1620,7 @@ sub _start_ssl($$) { my $ctx = Net::SSLeay::CTX_new() or $self->panic("Failed to create SSL_CTX $!"); my $ssl_options = Net::SSLeay::OP_SINGLE_DH_USE() | Net::SSLeay::OP_SINGLE_ECDH_USE(); - $self->{SSL_protocols} //= q{!SSLv2 !SSLv3}; + $self->{SSL_protocols} //= q{!SSLv2 !SSLv3 !TLSv1 !TLSv1.1}; my ($proto_include, $proto_exclude) = (0, 0); foreach (split /\s+/, $self->{SSL_protocols}) { my $neg = s/^!// ? 1 : 0; @@ -1629,7 +1635,7 @@ sub _start_ssl($$) { $proto_exclude |= $x; } my @proto_exclude = grep { ($proto_exclude & $SSL_proto{$_}) != 0 } keys %SSL_proto; - $self->log("Disabling SSL protocol: ".join(', ', sort @proto_exclude)) if $self->{debug}; + $self->log("Disabling SSL protocols: ".join(', ', sort @proto_exclude)) if $self->{debug}; $ssl_options |= $SSL_proto{$_} foreach @proto_exclude; $ssl_options |= Net::SSLeay::OP_NO_COMPRESSION(); @@ -1675,6 +1681,7 @@ sub _start_ssl($$) { $v == 0x0301 ? 'TLSv1' : $v == 0x0302 ? 'TLSv1.1' : $v == 0x0303 ? 'TLSv1.2' : + $v == 0x0304 ? 'TLSv1.3' : '??'), $v)); $self->log(sprintf('SSL cipher: %s (%d bits)' diff --git a/pullimap.md b/pullimap.md index eac8efa..a367dd1 100644 --- a/pullimap.md +++ b/pullimap.md @@ -198,9 +198,10 @@ Valid options are: : A space-separated list of SSL protocols to enable or disable (if prefixed with an exclamation mark `!`. Known protocols are `SSLv2`, - `SSLv3`, `TLSv1`, `TLSv1.1`, and `TLSv1.2`. Enabling a protocol is - a short-hand for disabling all other protocols. - (Default: `!SSLv2 !SSLv3`, i.e., only enable TLSv1 and above.) + `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`. Enabling a + protocol is a short-hand for disabling all other protocols. + (Default: `!SSLv2 !SSLv3 !TLSv1 !TLSv1.1`, i.e., only enable TLSv1.2 + and above.) *SSL_cipher_list* -- 2.39.2