From f247a5ed7f92b46341ce51bfe6ee4893d23715be Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Fri, 11 Dec 2020 12:38:37 +0100 Subject: manpages: improve wording. --- doc/interimap.1.md | 2 +- doc/pullimap.1.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'doc') diff --git a/doc/interimap.1.md b/doc/interimap.1.md index 2d2a637..5f19d66 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -420,7 +420,7 @@ Valid options are: *SSL_verify* -: Whether to verify the server certificate chain, and match its +: Whether to 1/ verify the server certificate chain, and 2/ match its Subject Alternative Name (SAN) or Subject CommonName (CN) against the value of the *host* option. (Default: `YES`.) diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index c9500e0..ea93ed3 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -239,7 +239,7 @@ Valid options are: *SSL_verify* -: Whether to verify the server certificate chain, and match its +: Whether to 1/ verify the server certificate chain, and 2/ match its Subject Alternative Name (SAN) or Subject CommonName (CN) against the value of the *host* option. (Default: `YES`.) -- cgit v1.2.3 From e3b95b0da424e55682c8c7b025d9d272a4a35ffe Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Fri, 11 Dec 2020 15:09:15 +0100 Subject: libinterimap: remove default SSL_protocols value. Namely, use the system default instead of "!SSLv2 !SSLv3 !TLSv1 !TLSv1.1". As of Debian Buster (OpenSSL 1.1.1) this does not make a difference, however using the system default provides better compatibility with future libssl versions. --- Changelog | 10 ++++++++++ doc/interimap.1.md | 11 +++++------ doc/pullimap.1.md | 11 +++++------ lib/Net/IMAP/InterIMAP.pm | 38 ++++++++++++++++++++------------------ tests/starttls/t | 1 - tests/tls-protocols/t | 7 +------ tests/tls/t | 1 - 7 files changed, 41 insertions(+), 38 deletions(-) (limited to 'doc') diff --git a/Changelog b/Changelog index 42cac7a..b809cd3 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,13 @@ +interimap (0.5.5) upstream; + + * libinterimap: remove default SSL_protocols value "!SSLv2 !SSLv3 + !TLSv1 !TLSv1.1" and use the system default instead. As of Debian + Buster (OpenSSL 1.1.1) this does not make a difference, however using + the system default provides better compatibility with future libssl + versions. + + -- Guilhem Moulin Fri, 11 Dec 2020 14:55:53 +0100 + interimap (0.5.4) upstream; * libinterimap: make SSL_verify also checks that the certificate diff --git a/doc/interimap.1.md b/doc/interimap.1.md index 5f19d66..9cfec7a 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -383,12 +383,11 @@ Valid options are: *SSL_protocols* -: 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`, `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.) +: A space-separated list of SSL protocols to explicitly enable or + disable (if prefixed with an exclamation mark `!`. Known protocols + are `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`. + Enabling a protocol is a short-hand for disabling all other + protocols. *SSL_cipher_list* diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index ea93ed3..84cae46 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -202,12 +202,11 @@ Valid options are: *SSL_protocols* -: 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`, `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.) +: A space-separated list of SSL protocols to explicitly enable or + disable (if prefixed with an exclamation mark `!`. Known protocols + are `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`. + Enabling a protocol is a short-hand for disabling all other + protocols. *SSL_cipher_list* diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 8b59ed2..221b016 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -1694,32 +1694,34 @@ sub _start_ssl($$) { my ($self, $socket) = @_; my $openssl_version = Net::SSLeay::OPENSSL_VERSION_NUMBER(); 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(); if (defined $self->{_OUTBUF} and $self->{_OUTBUF} ne '') { $self->warn("Truncating non-empty output buffer (unauthenticated response injection?)"); undef $self->{_OUTBUF}; } - $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; - s/\.0$//; - ($neg ? $proto_exclude : $proto_include) |= $SSL_proto{$_} // $self->panic("Unknown SSL protocol: $_"); - } - if ($proto_include != 0) { - # exclude all protocols except those explictly included - my $x = 0; - $x |= $_ foreach values %SSL_proto; - $x &= ~ $proto_include; - $proto_exclude |= $x; - } - my @proto_exclude = grep { ($proto_exclude & $SSL_proto{$_}) != 0 } keys %SSL_proto; - $self->log("Disabling SSL protocols: ".join(', ', sort @proto_exclude)) if $self->{debug}; - $ssl_options |= $SSL_proto{$_} foreach @proto_exclude; + my $ssl_options = Net::SSLeay::OP_SINGLE_DH_USE() | Net::SSLeay::OP_SINGLE_ECDH_USE(); $ssl_options |= Net::SSLeay::OP_NO_COMPRESSION(); + if (defined (my $protos = $self->{SSL_protocols})) { + my ($proto_include, $proto_exclude) = (0, 0); + foreach (split /\s+/, $protos) { + my $neg = s/^!// ? 1 : 0; + s/\.0$//; + ($neg ? $proto_exclude : $proto_include) |= $SSL_proto{$_} // $self->panic("Unknown SSL protocol: $_"); + } + if ($proto_include != 0) { + # exclude all protocols except those explictly included + my $x = 0; + $x |= $_ foreach values %SSL_proto; + $x &= ~ $proto_include; + $proto_exclude |= $x; + } + my @proto_exclude = grep { ($proto_exclude & $SSL_proto{$_}) != 0 } keys %SSL_proto; + $self->log("Disabling SSL protocols: ".join(', ', sort @proto_exclude)) if $self->{debug}; + $ssl_options |= $SSL_proto{$_} foreach @proto_exclude; + } + # https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_set_options.html Net::SSLeay::CTX_set_options($ctx, $ssl_options); diff --git a/tests/starttls/t b/tests/starttls/t index 5f9bd4f..55caf99 100644 --- a/tests/starttls/t +++ b/tests/starttls/t @@ -21,7 +21,6 @@ grep -Fx "STARTTLS" <"$TMPDIR/capabilities" || error grep -Fx "remote: C: 000000 STARTTLS" <"$STDERR" || error grep -Fx "remote: C: 000001 CAPABILITY" <"$STDERR" || error -grep -Fx "remote: Disabling SSL protocols: SSLv3, TLSv1, TLSv1.1" <"$STDERR" || error grep -Fx "remote: Peer certificate fingerprint: sha256\$$X509_SHA256" <"$STDERR" || error grep "^remote: SSL protocol: TLSv1\.[23] " <"$STDERR" || error grep "^remote: SSL cipher: " <"$STDERR" || error diff --git a/tests/tls-protocols/t b/tests/tls-protocols/t index f34a95b..5444658 100644 --- a/tests/tls-protocols/t +++ b/tests/tls-protocols/t @@ -5,12 +5,7 @@ with_remote_tls_protocols() { printf "SSL_protocols = %s\\n" "$*" >>"$XDG_CONFIG_HOME/interimap/config" } -# default -interimap --debug || error -grep -Fx "remote: Disabling SSL protocols: SSLv3, TLSv1, TLSv1.1" <"$STDERR" || error -grep -E "^remote: SSL protocol: TLSv1\.[23] " <"$STDERR" || error - -# also disable TLSv1.2 +# disable TLSv1.2 and earlier versions with_remote_tls_protocols "!SSLv2" "!SSLv3" "!TLSv1" "!TLSv1.1" "!TLSv1.2" interimap --debug || error grep -Fx "remote: Disabling SSL protocols: SSLv3, TLSv1, TLSv1.1, TLSv1.2" <"$STDERR" || error diff --git a/tests/tls/t b/tests/tls/t index 9fdd399..76f7c14 100644 --- a/tests/tls/t +++ b/tests/tls/t @@ -8,7 +8,6 @@ for ((i = 0; i < 32; i++)); do done interimap --debug || error -grep -Fx "remote: Disabling SSL protocols: SSLv3, TLSv1, TLSv1.1" <"$STDERR" || error grep -Fx "remote: Peer certificate fingerprint: sha256\$$X509_SHA256" <"$STDERR" || error grep "^remote: SSL protocol: TLSv1\.[23] " <"$STDERR" || error grep "^remote: SSL cipher: " <"$STDERR" || error -- cgit v1.2.3 From feeb91998a29ca040f6e5dd103e09507a6355e32 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Fri, 11 Dec 2020 18:39:46 +0100 Subject: libinterimap: deprecate SSL_protocols and introduce SSL_protocol_{min,max}. Using the libssl interface simplifies our protocol black/whitelist greatly; this only allows simple min/max bounds, but holes are arguably not very useful here. Using the new settings bumps the required libssl version to 1.1.0. --- Changelog | 8 +++++- doc/interimap.1.md | 9 +++++++ doc/pullimap.1.md | 9 +++++++ lib/Net/IMAP/InterIMAP.pm | 32 +++++++++++++++++++++--- tests/tls-protocols/t | 64 +++++++++++++++++++++++++++++++++++++++++++++-- tests/tls-rsa+ecdsa/t | 2 +- 6 files changed, 117 insertions(+), 7 deletions(-) (limited to 'doc') diff --git a/Changelog b/Changelog index 01e272c..c2f60dc 100644 --- a/Changelog +++ b/Changelog @@ -5,6 +5,11 @@ interimap (0.5.5) upstream; Buster (OpenSSL 1.1.1) this does not make a difference, however using the system default provides better compatibility with future libssl versions. + * libinterimap: deprecate SSL_protocols, obsoleted by new settings + SSL_protocol_{min,max}. Using the libssl interface simplifies our + protocol black/whilelist greatly; this only allows simple min/max + bounds, but holes are arguably not very useful here. Using the new + settings bumps the required libssl version to 1.1.0. - libinterimap: make $OPENSSL_VERSION global. - libinterimap: use Net::SSLeay::get_version() to get the protocol version string. @@ -24,7 +29,8 @@ interimap (0.5.4) upstream; Subject Alternative Name (SAN) or Subject CommonName (CN) matches the hostname or IP literal specified by the 'host' option. Previously it was only checking the chain of trust. This bumps the minimum - Net::SSLeay version to 1.83 and OpenSSL version to 1.0.2. + Net::SSLeay version to 1.83 and OpenSSL version to 1.0.2 (when + SSL_verify is used). * libinterimap: add support for the TLS SNI (Server Name Indication) extension, controlled by the new 'SSL_hostname' option. The default value of that option is the value of the 'host' option when it is diff --git a/doc/interimap.1.md b/doc/interimap.1.md index 9cfec7a..9b14a49 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -389,6 +389,15 @@ Valid options are: Enabling a protocol is a short-hand for disabling all other protocols. + *Deprecacted*: Use *SSL_protocol_min* and/or *SSL_protocol_max* + instead. + +*SSL_protocol_min*, *SSL_protocol_max* + +: Set minimum resp. maximum SSL/TLS protocol version to use for the + connection. Accepted values are `SSLv3`, `TLSv1`, `TLSv1.1`, + `TLSv1.2`, and `TLSv1.3`. + *SSL_cipher_list* : The cipher list to send to the server. Although the server diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index 84cae46..028cbaa 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -208,6 +208,15 @@ Valid options are: Enabling a protocol is a short-hand for disabling all other protocols. + *Deprecacted*: Use *SSL_protocol_min* and/or *SSL_protocol_max* + instead. + +*SSL_protocol_min*, *SSL_protocol_max* + +: Set minimum resp. maximum SSL/TLS protocol version to use for the + connection. Accepted values are `SSLv3`, `TLSv1`, `TLSv1.1`, + `TLSv1.2`, and `TLSv1.3`. + *SSL_cipher_list* : The cipher list to send to the server. Although the server diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index e2b89ec..49ea343 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -63,7 +63,9 @@ my %OPTIONS = ( command => qr/\A(\P{Control}+)\z/, 'null-stderr' => qr/\A(YES|NO)\z/i, compress => qr/\A(YES|NO)\z/i, - SSL_protocols => qr/\A(!?$RE_SSL_PROTO(?: !?$RE_SSL_PROTO)*)\z/, + SSL_protocols => qr/\A(!?$RE_SSL_PROTO(?: !?$RE_SSL_PROTO)*)\z/, # TODO deprecated, remove in 0.6 + SSL_protocol_min => qr/\A(\P{Control}+)\z/, + SSL_protocol_max => qr/\A(\P{Control}+)\z/, SSL_fingerprint => qr/\A((?:[A-Za-z0-9]+\$)?\p{AHex}+(?: (?:[A-Za-z0-9]+\$)?\p{AHex}+)*)\z/, SSL_cipherlist => qr/\A(\P{Control}+)\z/, SSL_hostname => qr/\A(\P{Control}*)\z/, @@ -1676,7 +1678,7 @@ sub _ssl_verify($$$) { } my %SSL_proto; -BEGIN { +BEGIN { # TODO deprecated, remove in 0.6 sub _append_ssl_proto($$) { my ($k, $v) = @_; $SSL_proto{$k} = $v if defined $v; @@ -1689,6 +1691,15 @@ BEGIN { _append_ssl_proto( "TLSv1.3", eval { Net::SSLeay::OP_NO_TLSv1_3() } ); } +# see ssl/ssl_conf.c:protocol_from_string() in the OpenSSL source tree +my %SSL_protocol_versions = ( + "SSLv3" => eval { Net::SSLeay::SSL3_VERSION() } + , "TLSv1" => eval { Net::SSLeay::TLS1_VERSION() } + , "TLSv1.1" => eval { Net::SSLeay::TLS1_1_VERSION() } + , "TLSv1.2" => eval { Net::SSLeay::TLS1_2_VERSION() } + , "TLSv1.3" => eval { Net::SSLeay::TLS1_3_VERSION() } +); + # $self->_start_ssl($socket) # Upgrade the $socket to SSL/TLS. sub _start_ssl($$) { @@ -1703,7 +1714,22 @@ sub _start_ssl($$) { my $ssl_options = Net::SSLeay::OP_SINGLE_DH_USE() | Net::SSLeay::OP_SINGLE_ECDH_USE(); $ssl_options |= Net::SSLeay::OP_NO_COMPRESSION(); - if (defined (my $protos = $self->{SSL_protocols})) { + if (defined $self->{SSL_protocol_min} or defined $self->{SSL_protocol_max}) { + $self->panic("Failed requirement libssl >=1.1.0") if $OPENSSL_VERSION < 0x1010000f; + my ($min, $max) = @$self{qw/SSL_protocol_min SSL_protocol_max/}; + if (defined $min) { + my $v = $SSL_protocol_versions{$min} // $self->panic("Unknown protocol version: $min"); + $self->_ssl_error("CTX_set_min_proto_version()") unless Net::SSLeay::CTX_set_min_proto_version($ctx, $v) == 1; + $self->log("Minimum SSL/TLS protocol version: ", $min) if $self->{debug}; + } + if (defined $max) { + my $v = $SSL_protocol_versions{$max} // $self->panic("Unknown protocol version: $max"); + $self->_ssl_error("CTX_set_max_proto_version()") unless Net::SSLeay::CTX_set_max_proto_version($ctx, $v) == 1; + $self->log("Maximum SSL/TLS protocol version: ", $max) if $self->{debug}; + } + } elsif (defined (my $protos = $self->{SSL_protocols})) { # TODO deprecated, remove in 0.6 + $self->warn("SSL_protocols is deprecated and will be removed in a future release! ", + "Use SSL_protocol_{min,max} instead."); my ($proto_include, $proto_exclude) = (0, 0); foreach (split /\s+/, $protos) { my $neg = s/^!// ? 1 : 0; diff --git a/tests/tls-protocols/t b/tests/tls-protocols/t index 5444658..b65d93c 100644 --- a/tests/tls-protocols/t +++ b/tests/tls-protocols/t @@ -1,3 +1,10 @@ +# system default +interimap --debug || error +! grep -E "^remote: Disabling SSL protocols: " <"$STDERR" || error # TODO deprecated +! grep -E "^remote: Minimum SSL/TLS protocol version: " <"$STDERR" || error +! grep -E "^remote: Maximum SSL/TLS protocol version: " <"$STDERR" || error +grep -E "^remote: SSL protocol: TLSv" <"$STDERR" || error + # backup config install -m0600 "$XDG_CONFIG_HOME/interimap/config" "$XDG_CONFIG_HOME/interimap/config~" with_remote_tls_protocols() { @@ -5,12 +12,15 @@ with_remote_tls_protocols() { printf "SSL_protocols = %s\\n" "$*" >>"$XDG_CONFIG_HOME/interimap/config" } -# disable TLSv1.2 and earlier versions +# disable TLSv1.2 and earlier with_remote_tls_protocols "!SSLv2" "!SSLv3" "!TLSv1" "!TLSv1.1" "!TLSv1.2" interimap --debug || error grep -Fx "remote: Disabling SSL protocols: SSLv3, TLSv1, TLSv1.1, TLSv1.2" <"$STDERR" || error grep -E "^remote: SSL protocol: TLSv1\.3 " <"$STDERR" || error +interimap || error +grep -E "^remote: SSL_protocols is deprecated " <"$STDERR" || error "no deprecation message" + # force TLSv1.2 with_remote_tls_protocols "TLSv1.2" interimap --debug || error @@ -23,7 +33,7 @@ interimap --debug || error grep -Fx "remote: Disabling SSL protocols: SSLv3, TLSv1.3" <"$STDERR" || error grep -E "^remote: SSL protocol: TLSv(1\.[12])? " <"$STDERR" || error -# force SSLv2 and SSLv3, fails as it's disabled server side +# force SSLv2 and SSLv3; this fails due to dovecot's ssl_min_protocol=TLSv1 with_remote_tls_protocols "SSLv2" "SSLv3" ! interimap --debug || error grep -Fx "remote: Disabling SSL protocols: TLSv1, TLSv1.1, TLSv1.2, TLSv1.3" <"$STDERR" || error @@ -31,4 +41,54 @@ grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error # make sure we didn't send any credentials ! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error + +# new interface: SSL_protocol_{min,max} +with_remote_tls_protocol_min_max() { + install -m0600 "$XDG_CONFIG_HOME/interimap/config~" "$XDG_CONFIG_HOME/interimap/config" + if [ -n "${1-}" ]; then + printf "SSL_protocol_min = %s\\n" "$1" >>"$XDG_CONFIG_HOME/interimap/config" + fi + if [ -n "${2-}" ]; then + printf "SSL_protocol_max = %s\\n" "$2" >>"$XDG_CONFIG_HOME/interimap/config" + fi +} + +# disable TLSv1.2 and earlier +# XXX this test assumes that TLSv1.3 is the highest version supported +with_remote_tls_protocol_min_max "TLSv1.3" +interimap --debug || error +grep -Fx "remote: Minimum SSL/TLS protocol version: TLSv1.3" <"$STDERR" || error +! grep -E "^remote: Maximum SSL/TLS protocol version: " <"$STDERR" || error +grep -E "^remote: SSL protocol: TLSv1\.3 " <"$STDERR" || error + +# force TLSv1.2 +with_remote_tls_protocol_min_max "TLSv1.2" "TLSv1.2" +interimap --debug || error +grep -Fx "remote: Minimum SSL/TLS protocol version: TLSv1.2" <"$STDERR" || error +grep -Fx "remote: Maximum SSL/TLS protocol version: TLSv1.2" <"$STDERR" || error +grep -E "^remote: SSL protocol: TLSv1\.2 " <"$STDERR" || error + +# disable TLSv1.2 and later +with_remote_tls_protocol_min_max "" "TLSv1.1" +interimap --debug || error +! grep -E "^remote: Minimum SSL/TLS protocol version: " <"$STDERR" || error +grep -Fx "remote: Maximum SSL/TLS protocol version: TLSv1.1" <"$STDERR" || error +grep -E "^remote: SSL protocol: TLSv1\.1 " <"$STDERR" || error + +# force SSLv3 to to TLSv1.1 +with_remote_tls_protocol_min_max "SSLv3" "TLSv1.1" +interimap --debug || error +grep -Fx "remote: Minimum SSL/TLS protocol version: SSLv3" <"$STDERR" || error +grep -Fx "remote: Maximum SSL/TLS protocol version: TLSv1.1" <"$STDERR" || error +grep -E "^remote: SSL protocol: TLSv1(\.1)? " <"$STDERR" || error + +# force SSLv3; this fails due to dovecot's ssl_min_protocol=TLSv1 +with_remote_tls_protocol_min_max "SSLv3" "SSLv3" +! interimap --debug || error +grep -Fx "remote: Minimum SSL/TLS protocol version: SSLv3" <"$STDERR" || error +grep -Fx "remote: Maximum SSL/TLS protocol version: SSLv3" <"$STDERR" || error +grep -Fx "remote: ERROR: Can't initiate TLS/SSL handshake" <"$STDERR" || error +# make sure we didn't send any credentials +! grep -E "^remote: C: .* (AUTHENTICATE|LOGIN) " <"$STDERR" || error + # vim: set filetype=sh : diff --git a/tests/tls-rsa+ecdsa/t b/tests/tls-rsa+ecdsa/t index 2adf930..8b811fd 100644 --- a/tests/tls-rsa+ecdsa/t +++ b/tests/tls-rsa+ecdsa/t @@ -38,7 +38,7 @@ grep -Fx -e "remote: Peer certificate matches pinned SPKI digest sha256\$$PKEY_S # force RSA (XXX do we really have to force TLSv1.2 here?) cat >>"$XDG_CONFIG_HOME/interimap/config" <<-EOF - SSL_protocols = TLSv1.2 + SSL_protocol_max = TLSv1.2 SSL_cipherlist = EECDH+AESGCM+aRSA EOF interimap --debug || error -- cgit v1.2.3 From ea120902dfe146cd7f04a289da9fa05a9e06e44c Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Fri, 11 Dec 2020 21:24:32 +0100 Subject: typofix, spelling --- Changelog | 14 +++++++------- doc/getting-started.md | 2 +- doc/interimap.1.md | 17 +++++++++-------- doc/pullimap.1.md | 23 ++++++++++++----------- interimap | 2 +- lib/Net/IMAP/InterIMAP.pm | 2 +- tests/preauth-plaintext/t | 2 +- 7 files changed, 32 insertions(+), 30 deletions(-) (limited to 'doc') diff --git a/Changelog b/Changelog index b9c7df2..43fbf8f 100644 --- a/Changelog +++ b/Changelog @@ -7,7 +7,7 @@ interimap (0.5.5) upstream; versions. * libinterimap: deprecate SSL_protocols, obsoleted by new settings SSL_protocol_{min,max}. Using the libssl interface simplifies our - protocol black/whilelist greatly; this only allows simple min/max + protocol black/whitelist greatly; this only allows simple min/max bounds, but holes are arguably not very useful here. Using the new settings bumps the required libssl version to 1.1.0. + `make release`: also bump libinterimap version and pin it in 'use' @@ -54,7 +54,7 @@ interimap (0.5.4) upstream; interimap (0.5.3) upstream; - * libinterimap: SSL_fingerprint now supports a space-separate list of + * libinterimap: SSL_fingerprint now supports a space-separated list of digests to pin, and succeeds if, and only if, the peer certificate SPKI matches one of the pinned digest values. Specifying multiple digest values can key useful in key rollover scenarios and/or when @@ -103,7 +103,7 @@ interimap (0.5) upstream; (regardless of the hierarchy delimiter in use). Other changes: - * interimap: the space-speparated list of names and/or patterns in + * interimap: the space-separated list of names and/or patterns in 'list-mailbox' can now contain C-style escape sequences (backslash and hexadecimal escape). * interimap: fail when two non-INBOX LIST replies return different @@ -111,7 +111,7 @@ interimap (0.5) upstream; happen if mailboxes from different namespaces are being listed. The workaround here is to run a new interimap instance for each namespace. - * libinterimap: in tunnel mode, use a socketpair rather than two pipes + * libinterimap: in tunnel mode, use a socket pair rather than two pipes for IPC between the interimap and the IMAP server. Also, use SOCK_CLOEXEC to save an fcntl() call when setting the close-on-exec flag on the socket. @@ -174,7 +174,7 @@ interimap (0.5) upstream; - libinterimap: use directories relative to $HOME for the XDG environment variables default values. Previously getpwuid() was called to determine the user's home directory, while the XDG - specification explicitely mentions $HOME. Conveniently our docs + specification explicitly mentions $HOME. Conveniently our docs always mentioned ~/, which on POSIX-compliant systems expands to the value of the variable HOME. (Cf. Shell and Utilities volume of POSIX.1-2017, sec. 2.6.1.) @@ -188,7 +188,7 @@ interimap (0.5) upstream; - libinterimap: push_flag_updates(): ignore UIDs for which no untagged FETCH response was received. - libinterimap: push_flag_updates(): don't ignores received updates (by - another client) to a superset of the desigred flag list. + another client) to a superset of the desired flag list. - libinterimap: avoid sending large UID EXPUNGE|FETCH|STORE commands as they might exceed the server's max acceptable command size; these commands are now split into multiple (sequential) commands when their @@ -198,7 +198,7 @@ interimap (0.5) upstream; This is a also a workaround for a bug in Dovecot 2.3.4: https://dovecot.org/pipermail/dovecot/2019-November/117522.html - interimap: for the reason explained above, limit number of messages - to 128 per APPEND command (only on servers advertizing MULTIAPPEND, + to 128 per APPEND command (only on servers advertising MULTIAPPEND, for other servers the number remains 1). - interimap: gracefully ignore messages with a NIL RFC822 attribute. - pullimap: treat messages with a NIL RFC822 attribute as empty. diff --git a/doc/getting-started.md b/doc/getting-started.md index 83d3ba9..74fc8da 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -20,7 +20,7 @@ format][mbox]). Local mail clients usually access it directly. They also often maintain their own cache in order to speed up message header listing and searches. -While most bidirectional synchronisation software (such as [OfflineIMAP]) +While most bidirectional synchronization software (such as [OfflineIMAP]) are able to handle a mail storage in Maildir format, *InterIMAP is not*. Instead, InterIMAP needs an [IMAP4rev1] server on *both* peers to synchronize. This may sound like a severe limitation at first, but by diff --git a/doc/interimap.1.md b/doc/interimap.1.md index 9b14a49..2310cb3 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -249,7 +249,7 @@ Valid options are: Two wildcards are available, and passed verbatim to the IMAP server: a ‘\*’ character matches zero or more characters, while a ‘%’ character matches zero or more characters up to the hierarchy - delimiter. Hardcoding the hierarchy delimiter in this setting is + delimiter. Hard-coding the hierarchy delimiter in this setting is not advised because the server might silently change it at some point. A null character should be used instead. For instance, if *list-mailbox* is set `"foo\x00bar"` then, assuming the hierarchy @@ -309,7 +309,7 @@ Valid options are: `type=imap` and `type=imaps` are respectively used for IMAP and IMAP over SSL/TLS connections over an INET socket. `type=tunnel` causes `interimap` to create an unnamed pair of - connected sockets for interprocess communication with a *command* + connected sockets for inter-process communication with a *command* instead of opening a network socket. Note that specifying `type=tunnel` in the `[remote]` section makes the default *database* to be `localhost.db`. @@ -383,13 +383,14 @@ Valid options are: *SSL_protocols* -: A space-separated list of SSL protocols to explicitly enable or - disable (if prefixed with an exclamation mark `!`. Known protocols - are `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`. +: Space-separated list of SSL/TLS protocol versions to explicitly + enable (or disable if prefixed with an exclamation mark `!`). Known + protocols are `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and + `TLSv1.3`. Enabling a protocol is a short-hand for disabling all other protocols. - *Deprecacted*: Use *SSL_protocol_min* and/or *SSL_protocol_max* + *DEPRECATED*: Use *SSL_protocol_min* and/or *SSL_protocol_max* instead. *SSL_protocol_min*, *SSL_protocol_max* @@ -398,7 +399,7 @@ Valid options are: connection. Accepted values are `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`. -*SSL_cipher_list* +*SSL_cipherlist* : The cipher list to send to the server. Although the server determines which cipher suite is used, it should take the first @@ -428,7 +429,7 @@ Valid options are: *SSL_verify* -: Whether to 1/ verify the server certificate chain, and 2/ match its +: Whether to 1/ verify the server certificate chain; and 2/ match its Subject Alternative Name (SAN) or Subject CommonName (CN) against the value of the *host* option. (Default: `YES`.) diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index 028cbaa..cf6ec52 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -106,14 +106,14 @@ Valid options are: *deliver-ehlo* -: Hostname to use in `EHLO` or `LHLO` commands. +: Name to use in `EHLO` or `LHLO` commands. (Default: `localhost.localdomain`.) *deliver-rcpt* : Message recipient. Note that the local part needs to quoted if it contains special characters; see [RFC 5321] for details. - (Default: the username associated with the effective uid of the + (Default: the username associated with the effective user ID of the `pullimap` process.) *purge-after* @@ -123,7 +123,7 @@ Valid options are: `SEARCH` criterion ignoring time and timezone.) If *purge-after* is set to `0` then messages are deleted immediately after delivery. Otherwise `pullimap` issues an IMAP `SEARCH` (or - extended `SEARCH` on servers advertizing the [`ESEARCH`][RFC 4731] + extended `SEARCH` on servers advertising the [`ESEARCH`][RFC 4731] capability) command to list old messages; if `--idle` is set then the `SEARCH` command is issued again every 12 hours. @@ -133,7 +133,7 @@ Valid options are: `type=imap` and `type=imaps` are respectively used for IMAP and IMAP over SSL/TLS connections over an INET socket. `type=tunnel` causes `pullimap` to create an unnamed pair of - connected sockets for interprocess communication with a *command* + connected sockets for inter-process communication with a *command* instead of opening a network socket. (Default: `imaps`.) @@ -202,13 +202,14 @@ Valid options are: *SSL_protocols* -: A space-separated list of SSL protocols to explicitly enable or - disable (if prefixed with an exclamation mark `!`. Known protocols - are `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`. +: Space-separated list of SSL/TLS protocol versions to explicitly + enable (or disable if prefixed with an exclamation mark `!`). Known + protocols are `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and + `TLSv1.3`. Enabling a protocol is a short-hand for disabling all other protocols. - *Deprecacted*: Use *SSL_protocol_min* and/or *SSL_protocol_max* + *DEPRECATED*: Use *SSL_protocol_min* and/or *SSL_protocol_max* instead. *SSL_protocol_min*, *SSL_protocol_max* @@ -217,7 +218,7 @@ Valid options are: connection. Accepted values are `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`. -*SSL_cipher_list* +*SSL_cipherlist* : The cipher list to send to the server. Although the server determines which cipher suite is used, it should take the first @@ -247,7 +248,7 @@ Valid options are: *SSL_verify* -: Whether to 1/ verify the server certificate chain, and 2/ match its +: Whether to 1/ verify the server certificate chain; and 2/ match its Subject Alternative Name (SAN) or Subject CommonName (CN) against the value of the *host* option. (Default: `YES`.) @@ -330,7 +331,7 @@ In more details, `pullimap` works as follows: to terminate it gracefully. 3. Issue a `UID STORE` command to mark all retrieved messages (and - stalled UIDs found in the *statefile* after the eigth byte) as + stalled UIDs found in the *statefile* after the eighth byte) as `\Seen`. 4. Update the *statefile* with the new UIDNEXT value (bytes 5-8). diff --git a/interimap b/interimap index 68cb60b..67651d4 100755 --- a/interimap +++ b/interimap @@ -286,7 +286,7 @@ sub list_mailboxes($) { my ($m) = sort keys %$delims; $imap->{delimiter} = delete $delims->{$m}; } else { - # didn't get a non-INBOX LIST reply so we need to explicitely query + # didn't get a non-INBOX LIST reply so we need to explicitly query # the hierarchy delimiter get_delimiter($name, $imap, $ref); } diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 49ea343..2e36d6e 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -1371,7 +1371,7 @@ sub push_flag_updates($$@) { $modified->{$uid} //= [ 0, undef ]; } elsif (defined (my $m = $modified->{$uid})) { # received an untagged FETCH response, remove from the list of pending changes - # if the flag list was up to date (either implicitely or explicitely) + # if the flag list was up to date (either implicitely or explicitly) if (!defined $m->[1] or $m->[1] eq $flags) { delete $modified->{$uid}; push @ok, $uid; diff --git a/tests/preauth-plaintext/t b/tests/preauth-plaintext/t index 427d57b..bc287dd 100644 --- a/tests/preauth-plaintext/t +++ b/tests/preauth-plaintext/t @@ -10,7 +10,7 @@ grep -Fx 'remote: ERROR: PREAUTH greeting on plaintext connection? MiTM in actio ! grep '^remote: C: ' <"$STDERR" || error "wrote command in MiTM'ed PREAUTH connection!" -# Ignore the warning when STARTTLS is explicitely disabled +# Ignore the warning when STARTTLS is explicitly disabled echo "STARTTLS = NO" >>"$XDG_CONFIG_HOME/interimap/config" interimap --debug || true -- cgit v1.2.3 From 8c43ed9baa905d907a6aad77de2282a852ba69a9 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Sun, 13 Dec 2020 17:43:52 +0100 Subject: libinterimap: use default locations for trusted CA certificates when neither CAfile nor CApath are set. In particular, OpenSSL's default locations can be overridden by the SSL_CERT_FILE resp. SSL_CERT_DIR environment variables, see SSL_CTX_load_verify_locations(3ssl). This bumps the minimum OpenSSL version to 1.1.0 (when SSL_verify is used). --- Changelog | 6 ++++++ doc/interimap.1.md | 14 ++++++++++---- doc/pullimap.1.md | 14 ++++++++++---- interimap.sample | 1 - lib/Net/IMAP/InterIMAP.pm | 10 +++++++--- pullimap.sample | 1 - tests/run | 3 +++ tests/tls-verify-peer/t | 27 ++++++++++++++++++++++++--- 8 files changed, 60 insertions(+), 16 deletions(-) (limited to 'doc') diff --git a/Changelog b/Changelog index 9a36e8a..2fbdf36 100644 --- a/Changelog +++ b/Changelog @@ -10,6 +10,12 @@ interimap (0.5.5) upstream; protocol black/whitelist greatly; this only allows simple min/max bounds, but holes are arguably not very useful here. Using the new settings bumps the required libssl version to 1.1.0. + * libinterimap: use default locations for trusted CA certificates when + neither CAfile nor CApath are set. In particular, OpenSSL's default + locations can be overridden by the SSL_CERT_FILE resp. SSL_CERT_DIR + environment variables, see SSL_CTX_load_verify_locations(3ssl). + This bumps the minimum OpenSSL version to 1.1.0 (when SSL_verify is + used). + `make release`: also bump libinterimap version and pin it in 'use' declarations. + Make error messages more uniform and consistent. diff --git a/doc/interimap.1.md b/doc/interimap.1.md index 2310cb3..63d5ab0 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -439,6 +439,14 @@ Valid options are: measure as it pins directly its key material and ignore its chain of trust. +*SSL_CAfile* + +: File containing trusted certificates to use during server + certificate verification when `SSL_verify=YES`. + + Trusted CA certificates are loaded from the default system locations + unless one (or both) of *SSL_CAfile* or *SSL_CApath* is set. + *SSL_CApath* : Directory to use for server certificate verification when @@ -446,10 +454,8 @@ Valid options are: This directory must be in “hash format”, see [`verify`(1ssl)] for more information. -*SSL_CAfile* - -: File containing trusted certificates to use during server - certificate verification when `SSL_verify=YES`. + Trusted CA certificates are loaded from the default system locations + unless one (or both) of *SSL_CAfile* or *SSL_CApath* is set. *SSL_hostname* diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index cf6ec52..05cbcaf 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -258,6 +258,14 @@ Valid options are: measure as it pins directly its key material and ignore its chain of trust. +*SSL_CAfile* + +: File containing trusted certificates to use during server + certificate verification when `SSL_verify=YES`. + + Trusted CA certificates are loaded from the default system locations + unless one (or both) of *SSL_CAfile* or *SSL_CApath* is set. + *SSL_CApath* : Directory to use for server certificate verification when @@ -265,10 +273,8 @@ Valid options are: This directory must be in “hash format”, see [`verify`(1ssl)] for more information. -*SSL_CAfile* - -: File containing trusted certificates to use during server - certificate verification when `SSL_verify=YES`. + Trusted CA certificates are loaded from the default system locations + unless one (or both) of *SSL_CAfile* or *SSL_CApath* is set. *SSL_hostname* diff --git a/interimap.sample b/interimap.sample index e54c8a0..36eeb2a 100644 --- a/interimap.sample +++ b/interimap.sample @@ -23,7 +23,6 @@ password = xxxxxxxxxxxxxxxx #compress = YES # SSL options -#SSL_CApath = /etc/ssl/certs #SSL_verify = YES #SSL_protocol_min = TLSv1.2 #SSL_fingerprint = sha256$29111aea5d5be7e448bdc5c6e8a9d03bc9221c53c09b1cfbe6f953221e24dda0 diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 5bdd954..89e5cba 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -1776,10 +1776,14 @@ sub _start_ssl($$) { $self->panic("Failed requirement libssl >=1.0.2") if $OPENSSL_VERSION < 0x1000200f; # verify certificate chain - my ($file, $path) = ($self->{SSL_CAfile} // '', $self->{SSL_CApath} // ''); - if ($file ne '' or $path ne '') { + if (defined $self->{SSL_CAfile} or defined $self->{SSL_CApath}) { $self->_ssl_error("SSL_CTX_load_verify_locations()") - unless Net::SSLeay::CTX_load_verify_locations($ctx, $file, $path) == 1; + unless Net::SSLeay::CTX_load_verify_locations($ctx, + $self->{SSL_CAfile} // '', $self->{SSL_CApath} // '') == 1; + } else { + $self->log("Using default locations for trusted CA certificates") if $self->{debug}; + $self->_ssl_error("SSL_CTX_set_default_verify_paths()") + unless Net::SSLeay::CTX_set_default_verify_paths($ctx) == 1; } # verify DNS hostname or IP literal diff --git a/pullimap.sample b/pullimap.sample index d911851..f1a66f9 100644 --- a/pullimap.sample +++ b/pullimap.sample @@ -4,7 +4,6 @@ deliver-method = smtp:[127.0.0.1]:25 purge-after = 90 # SSL options -#SSL_CApath = /etc/ssl/certs #SSL_verify = YES #SSL_protocol_min = TLSv1.2 diff --git a/tests/run b/tests/run index 29384ec..329f3e3 100755 --- a/tests/run +++ b/tests/run @@ -209,6 +209,8 @@ _interimap_cmd() { local script="$1" rv=0 shift environ_set "local" + [ -z "${SSL_CERT_FILE+x}" ] || ENVIRON+=( SSL_CERT_FILE="$SSL_CERT_FILE" ) + [ -z "${SSL_CERT_DIR+x}" ] || ENVIRON+=( SSL_CERT_DIR="$SSL_CERT_DIR" ) env -i "${ENVIRON[@]}" perl -I./lib -T "./$script" "$@" 2>"$STDERR" || rv=$? cat <"$STDERR" >&2 return $rv @@ -445,6 +447,7 @@ passed() { # Run test in a sub-shell declare -a ENVIRON=() environ_set "local" +unset SSL_CERT_FILE SSL_CERT_DIR export TMPDIR TESTDIR STDERR "${ENVIRON[@]}" OPENSSL_CONF export -f environ_set doveadm interimap interimap_init pullimap _interimap_cmd export -f sqlite3 sample_message deliver ptree_abort step_start step_done passed diff --git a/tests/tls-verify-peer/t b/tests/tls-verify-peer/t index 8cc098a..8326521 100644 --- a/tests/tls-verify-peer/t +++ b/tests/tls-verify-peer/t @@ -46,7 +46,9 @@ with_remote_config() { } step_start "peer verification enabled by default" +# assume our fake root CA is not among OpenSSL's default trusted CAs unverified_peer +grep -Fx "remote: Using default locations for trusted CA certificates" <"$STDERR" || error step_done step_start "peer verification result honored when pinned pubkey matches" @@ -54,13 +56,23 @@ with_remote_config <<-EOF SSL_fingerprint = sha256\$$PKEY_SHA256 EOF unverified_peer +grep -Fx "remote: Using default locations for trusted CA certificates" <"$STDERR" || error grep -Fx "remote: Peer certificate matches pinned SPKI digest sha256\$$PKEY_SHA256" <"$STDERR" || error step_done + capath=$(mktemp --tmpdir="$TMPDIR" --directory capath.XXXXXX) cp -T -- ~/.dovecot/conf.d/ca.crt "$capath/ca-certificates.crt" -step_start "SSL_CAfile" +step_start "SSL_CAfile/\$SSL_CERT_FILE" + +# verify that an error is raised when CAfile can't be loaded +# (it's not the case for $SSL_CERT_FILE, cf. SSL_CTX_load_verify_locations(3ssl)) +with_remote_config <<<"SSL_CAfile = /nonexistent" +! interimap --debug || error +grep -Fx "remote: ERROR: SSL_CTX_load_verify_locations()" <"$STDERR" || error +grep -Fx "remote: IMAP traffic (bytes): recv 0 sent 0" <"$STDERR" || error + if [ -f "/etc/ssl/certs/ca-certificates.crt" ]; then # assume our fake root CA is not there with_remote_config <<<"SSL_CAfile = /etc/ssl/certs/ca-certificates.crt" @@ -71,6 +83,10 @@ fi with_remote_config <<<"SSL_CAfile = $capath/ca-certificates.crt" verified_peer +with_remote_config Date: Sun, 13 Dec 2020 18:47:51 +0100 Subject: manual: improve wording. --- doc/interimap.1.md | 4 ++-- doc/pullimap.1.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'doc') diff --git a/doc/interimap.1.md b/doc/interimap.1.md index 63d5ab0..bcd27f9 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -424,8 +424,8 @@ Valid options are: Specifying multiple digest values can be useful in key rollover scenarios and/or when the server supports certificates of different - types (for instance RSA+ECDSA). In that case the connection is - aborted when none of the specified digests matches. + types (for instance a dual-cert RSA/ECDSA setup). In that case the + connection is aborted when none of the specified digests matches. *SSL_verify* diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index 05cbcaf..94fa831 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -243,8 +243,8 @@ Valid options are: Specifying multiple digest values can be useful in key rollover scenarios and/or when the server supports certificates of different - types (for instance RSA+ECDSA). In that case the connection is - aborted when none of the specified digests matches. + types (for instance a dual-cert RSA/ECDSA setup). In that case the + connection is aborted when none of the specified digests matches. *SSL_verify* -- cgit v1.2.3 From 1a19feb7a4b3d70f44e4e1fb0f9920b063842422 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 17 Dec 2020 14:54:34 +0100 Subject: manuals: Clarify that known TLS protocol versions depend on the OpenSSL version used. --- Changelog | 2 ++ doc/interimap.1.md | 12 +++++++----- doc/pullimap.1.md | 12 +++++++----- 3 files changed, 16 insertions(+), 10 deletions(-) (limited to 'doc') diff --git a/Changelog b/Changelog index c401c2d..afee1ca 100644 --- a/Changelog +++ b/Changelog @@ -39,6 +39,8 @@ interimap (0.5.5) upstream; - test suite: ensure we haven't started speaking IMAP when the SSL/TLS handshake is aborted (unless STARTTLS is used to upgrade to connection). + - documentation: Clarify that known TLS protocol versions depend on the + OpenSSL version used. -- Guilhem Moulin Fri, 11 Dec 2020 14:55:53 +0100 diff --git a/doc/interimap.1.md b/doc/interimap.1.md index bcd27f9..ae6224b 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -384,9 +384,10 @@ Valid options are: *SSL_protocols* : Space-separated list of SSL/TLS protocol versions to explicitly - enable (or disable if prefixed with an exclamation mark `!`). Known - protocols are `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and - `TLSv1.3`. + enable (or disable if prefixed with an exclamation mark `!`). + Potentially known protocols are `SSLv2`, `SSLv3`, `TLSv1`, + `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`, depending on the OpenSSL + version used. Enabling a protocol is a short-hand for disabling all other protocols. @@ -396,8 +397,9 @@ Valid options are: *SSL_protocol_min*, *SSL_protocol_max* : Set minimum resp. maximum SSL/TLS protocol version to use for the - connection. Accepted values are `SSLv3`, `TLSv1`, `TLSv1.1`, - `TLSv1.2`, and `TLSv1.3`. + connection. Potentially recognized values are `SSLv3`, `TLSv1`, + `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`, depending on the OpenSSL + version used. *SSL_cipherlist* diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index 94fa831..b0bc2fd 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -203,9 +203,10 @@ Valid options are: *SSL_protocols* : Space-separated list of SSL/TLS protocol versions to explicitly - enable (or disable if prefixed with an exclamation mark `!`). Known - protocols are `SSLv2`, `SSLv3`, `TLSv1`, `TLSv1.1`, `TLSv1.2`, and - `TLSv1.3`. + enable (or disable if prefixed with an exclamation mark `!`). + Potentially known protocols are `SSLv2`, `SSLv3`, `TLSv1`, + `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`, depending on the OpenSSL + version used. Enabling a protocol is a short-hand for disabling all other protocols. @@ -215,8 +216,9 @@ Valid options are: *SSL_protocol_min*, *SSL_protocol_max* : Set minimum resp. maximum SSL/TLS protocol version to use for the - connection. Accepted values are `SSLv3`, `TLSv1`, `TLSv1.1`, - `TLSv1.2`, and `TLSv1.3`. + connection. Potentially recognized values are `SSLv3`, `TLSv1`, + `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`, depending on the OpenSSL + version used. *SSL_cipherlist* -- cgit v1.2.3 From 57988c83bb4b3f1780f045880ac4a8f36a51c55c Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 17 Dec 2020 17:38:17 +0100 Subject: libinterimap: new option SSL_ciphersuites to set the TLSv1.3 ciphersuites. Also, clarify that SSL_cipherlist only applies to TLSv1.2 and below. See SSL_CTX_set_cipher_list(3ssl). --- Changelog | 3 +++ doc/interimap.1.md | 12 +++++++----- doc/pullimap.1.md | 12 +++++++----- lib/Net/IMAP/InterIMAP.pm | 4 ++++ tests/list | 1 + tests/tls-ciphers/interimap.remote | 1 + tests/tls-ciphers/remote.conf | 1 + tests/tls-ciphers/t | 31 +++++++++++++++++++++++++++++++ tests/tls-rsa+ecdsa/t | 4 +++- 9 files changed, 58 insertions(+), 11 deletions(-) create mode 120000 tests/tls-ciphers/interimap.remote create mode 120000 tests/tls-ciphers/remote.conf create mode 100644 tests/tls-ciphers/t (limited to 'doc') diff --git a/Changelog b/Changelog index afee1ca..29ca360 100644 --- a/Changelog +++ b/Changelog @@ -18,6 +18,9 @@ interimap (0.5.5) upstream; settings SSL_protocol_{min,max} are not used, however it's cumbersome to do individual checks for specific settings, let alone maintain test coverage with multiple OpenSSL versions. + * libinterimap: new option SSL_ciphersuites to set the TLSv1.3 + ciphersuites; also, clarify that SSL_cipherlist only applies to + TLSv1.2 and below, see SSL_CTX_set_cipher_list(3ssl). + `make release`: also bump libinterimap version and pin it in 'use' declarations. + Make error messages more uniform and consistent. diff --git a/doc/interimap.1.md b/doc/interimap.1.md index ae6224b..2d588ae 100644 --- a/doc/interimap.1.md +++ b/doc/interimap.1.md @@ -401,12 +401,14 @@ Valid options are: `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`, depending on the OpenSSL version used. -*SSL_cipherlist* +*SSL_cipherlist*, *SSL_ciphersuites* -: The cipher list to send to the server. Although the server - determines which cipher suite is used, it should take the first - supported cipher in the list sent by the client. See - [`ciphers`(1ssl)] for more information. +: Sets the TLSv1.2 and below cipher list resp. TLSv1.3 cipher suites. + The combination of these lists is sent to the server, which then + determines which cipher to use (normally the first supported one + from the list sent by the client). The default suites depend on the + OpenSSL version and its configuration, see [`ciphers`(1ssl)] for + more information. *SSL_fingerprint* diff --git a/doc/pullimap.1.md b/doc/pullimap.1.md index b0bc2fd..89969b2 100644 --- a/doc/pullimap.1.md +++ b/doc/pullimap.1.md @@ -220,12 +220,14 @@ Valid options are: `TLSv1.1`, `TLSv1.2`, and `TLSv1.3`, depending on the OpenSSL version used. -*SSL_cipherlist* +*SSL_cipherlist*, *SSL_ciphersuites* -: The cipher list to send to the server. Although the server - determines which cipher suite is used, it should take the first - supported cipher in the list sent by the client. See - [`ciphers`(1ssl)] for more information. +: Sets the TLSv1.2 and below cipher list resp. TLSv1.3 cipher suites. + The combination of these lists is sent to the server, which then + determines which cipher to use (normally the first supported one + from the list sent by the client). The default suites depend on the + OpenSSL version and its configuration, see [`ciphers`(1ssl)] for + more information. *SSL_fingerprint* diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index 856c5c8..09f510f 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -67,6 +67,7 @@ my %OPTIONS = ( SSL_protocol_max => qr/\A(\P{Control}+)\z/, SSL_fingerprint => qr/\A((?:[A-Za-z0-9]+\$)?\p{AHex}+(?: (?:[A-Za-z0-9]+\$)?\p{AHex}+)*)\z/, SSL_cipherlist => qr/\A(\P{Control}+)\z/, + SSL_ciphersuites => qr/\A(\P{Control}*)\z/, # "an empty list is permissible" SSL_hostname => qr/\A(\P{Control}*)\z/, SSL_verify => qr/\A(YES|NO)\z/i, SSL_CApath => qr/\A(\P{Control}+)\z/, @@ -1766,6 +1767,9 @@ sub _start_ssl($$) { if (defined (my $str = $self->{SSL_cipherlist})) { $self->_ssl_error("SSL_CTX_set_cipher_list()") unless Net::SSLeay::CTX_set_cipher_list($ctx, $str) == 1; } + if (defined (my $str = $self->{SSL_ciphersuites})) { + $self->_ssl_error("SSL_CTX_set_ciphersuites()") unless Net::SSLeay::CTX_set_ciphersuites($ctx, $str) == 1; + } my $vpm = Net::SSLeay::X509_VERIFY_PARAM_new() or $self->_ssl_error("X509_VERIFY_PARAM_new()"); my $purpose = Net::SSLeay::X509_PURPOSE_SSL_SERVER(); diff --git a/tests/list b/tests/list index cb31a73..d1058ba 100644 --- a/tests/list +++ b/tests/list @@ -54,6 +54,7 @@ split-set Split large sets to avoid extra-long command lines tls-rsa+ecdsa pubkey fingerprint pinning for dual-cert RSA+ECDSA tls-sni TLS servername extension (SNI) tls-protocols force TLS protocol versions + tls-ciphers force TLS cipher list/suites . Live synchronization (60s) sync-live local/remote simulation diff --git a/tests/tls-ciphers/interimap.remote b/tests/tls-ciphers/interimap.remote new file mode 120000 index 0000000..daf3741 --- /dev/null +++ b/tests/tls-ciphers/interimap.remote @@ -0,0 +1 @@ +../tls/interimap.remote \ No newline at end of file diff --git a/tests/tls-ciphers/remote.conf b/tests/tls-ciphers/remote.conf new file mode 120000 index 0000000..6029749 --- /dev/null +++ b/tests/tls-ciphers/remote.conf @@ -0,0 +1 @@ +../tls/remote.conf \ No newline at end of file diff --git a/tests/tls-ciphers/t b/tests/tls-ciphers/t new file mode 100644 index 0000000..0dfc771 --- /dev/null +++ b/tests/tls-ciphers/t @@ -0,0 +1,31 @@ +# backup config +install -m0600 "$XDG_CONFIG_HOME/interimap/config" "$XDG_CONFIG_HOME/interimap/config~" +with_remote_config() { + install -m0600 "$XDG_CONFIG_HOME/interimap/config~" "$XDG_CONFIG_HOME/interimap/config" + cat >>"$XDG_CONFIG_HOME/interimap/config" +} + +with_remote_config <<-EOF + SSL_protocol_max = TLSv1.2 + SSL_cipherlist = DHE-RSA-AES128-SHA256:ALL:!COMPLEMENTOFDEFAULT:!eNULL +EOF +interimap --debug || error +grep -Fx "remote: SSL cipher: DHE-RSA-AES128-SHA256 (128 bits)" <"$STDERR" || error + +with_remote_config <<-EOF + SSL_protocol_max = TLSv1.2 + SSL_cipherlist = NONEXISTENT:ECDHE-RSA-AES256-SHA384:ALL:!COMPLEMENTOFDEFAULT:!eNULL + SSL_ciphersuites = TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 +EOF +interimap --debug || error +grep -Fx "remote: SSL cipher: ECDHE-RSA-AES256-SHA384 (256 bits)" <"$STDERR" || error + +with_remote_config <<-EOF + SSL_protocol_min = TLSv1.3 + SSL_cipherlist = DHE-RSA-AES128-SHA256 + SSL_ciphersuites = TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 +EOF +interimap --debug || error +grep -Fx "remote: SSL cipher: TLS_CHACHA20_POLY1305_SHA256 (256 bits)" <"$STDERR" || error + +# vim: set filetype=sh : diff --git a/tests/tls-rsa+ecdsa/t b/tests/tls-rsa+ecdsa/t index 8b811fd..c9f5b96 100644 --- a/tests/tls-rsa+ecdsa/t +++ b/tests/tls-rsa+ecdsa/t @@ -36,7 +36,9 @@ grep -Fx -e "remote: Peer certificate matches pinned SPKI digest sha256\$$PKEY_S -e "remote: Peer certificate matches pinned SPKI digest sha256\$$PKEY_ALT_SHA256" \ <"$STDERR" || error -# force RSA (XXX do we really have to force TLSv1.2 here?) +# force RSA +# XXX we also have to force TLS <=1.2 here as the TLSv1.3 ciphersuites +# don't specify the certificate type (nor key exchange) cat >>"$XDG_CONFIG_HOME/interimap/config" <<-EOF SSL_protocol_max = TLSv1.2 SSL_cipherlist = EECDH+AESGCM+aRSA -- cgit v1.2.3