From 4ed6f0982cc0553e31e7beadf441beb8573a07d4 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Thu, 10 Dec 2020 21:52:44 +0100 Subject: libinterimap: add support for the TLS SNI (Server Name Indication) extension. This is controlled by the new 'SSL_hostname' option. The default value of that option is the value of the 'host' option when it is hostname, and the empty string (which disables SNI) when it is an IP literal. --- lib/Net/IMAP/InterIMAP.pm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm index a0efcc1..e3a5d31 100644 --- a/lib/Net/IMAP/InterIMAP.pm +++ b/lib/Net/IMAP/InterIMAP.pm @@ -65,6 +65,7 @@ my %OPTIONS = ( SSL_protocols => qr/\A(!?$RE_SSL_PROTO(?: !?$RE_SSL_PROTO)*)\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/, SSL_verify => qr/\A(YES|NO)\z/i, SSL_CApath => qr/\A(\P{Control}+)\z/, SSL_CAfile => qr/\A(\P{Control}+)\z/, @@ -1739,6 +1740,8 @@ sub _start_ssl($$) { $self->_ssl_error("X509_VERIFY_PARAM_set_purpose()") unless Net::SSLeay::X509_VERIFY_PARAM_set_purpose($vpm, $purpose) == 1; $self->_ssl_error("CTX_set_purpose()") unless Net::SSLeay::CTX_set_purpose($ctx, $purpose) == 1; + my $host = $self->{host} // $self->panic(); + my ($hostip, $hostipfam) = _parse_hostip($host); if ($self->{SSL_verify} // 1) { # for X509_VERIFY_PARAM_set1_{ip,host}() $self->panic("Failed requirement libssl >=1.0.2") if $openssl_version < 0x1000200f; @@ -1751,8 +1754,6 @@ sub _start_ssl($$) { } # verify DNS hostname or IP literal - my $host = $self->{host} // $self->panic(); - my ($hostip, $hostipfam) = _parse_hostip($host); if (defined $hostipfam) { my $addr = Socket::inet_pton($hostipfam, $hostip) // $self->panic(); $self->_ssl_error("X509_VERIFY_PARAM_set1_ip()") @@ -1770,6 +1771,16 @@ sub _start_ssl($$) { my $ssl = Net::SSLeay::new($ctx) or $self->fail("Can't create new SSL structure"); Net::SSLeay::set_fd($ssl, fileno $socket) or $self->fail("SSL filehandle association failed"); + + # always use 'SSL_hostname' when set, otherwise use 'host' (unless it's an IP) on OpenSSL >=0.9.8f + my $servername = $self->{SSL_hostname} // (defined $hostipfam ? "" : $host); + if ($servername ne "") { + $self->panic("Failed requirement libssl >=0.9.8f") if $openssl_version < 0x00908070; + $self->_ssl_error("Can't set TLS servername extension (value $servername)") + unless Net::SSLeay::set_tlsext_host_name($ssl, $servername) == 1; + $self->log("Using SNI with name $servername") if $self->{debug}; + } + $self->_ssl_error("Can't initiate TLS/SSL handshake") unless Net::SSLeay::connect($ssl) == 1; $self->panic() unless $self->{_SSL_PEER_VERIFIED}; # sanity check $self->panic() if ($self->{SSL_verify} // 1) and Net::SSLeay::get_verify_result($ssl) != Net::SSLeay::X509_V_OK(); -- cgit v1.2.3