Blob Blame History Raw
From 25ae268277121eeecd29830dec6a0229e4f8fbcb Mon Sep 17 00:00:00 2001
From: Heikki Vatiainen <hvn@radiatorsoftware.com>
Date: Fri, 20 Mar 2020 10:49:35 +0200
Subject: GH-160 Call Net::SSLeay::shutdown() from SSLeay::sslcat()
 and t/local/07_sslecho.t. (#161)

Fix for GH-160 seems to require SSL_shutdown() calls which were missing from
t/local/07_sslecho.t and Net::SSLeay::sslcat()

These seem to relate to this change in OpenSSL
'Detect EOF while reading in libssl':
https://github.com/openssl/openssl/commit/db943f43a60d1b5b1277e4b5317e8f288e7a0a3a

The newly added OpenSSL error message 'unexpected eof while reading' was seen
before the SSL_shutdown() calls were added.
---
 lib/Net/SSLeay.pm    |  1 +
 t/local/07_sslecho.t | 30 ++++++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/lib/Net/SSLeay.pm b/lib/Net/SSLeay.pm
index 7f14519..2cf79ed 100644
--- a/lib/Net/SSLeay.pm
+++ b/lib/Net/SSLeay.pm
@@ -1120,6 +1120,7 @@ sub sslcat { # address, port, message, $crt, $key --> reply / (reply,errs,cert)
     goto cleanup unless $written;
 
     sleep $slowly if $slowly;  # Closing too soon can abort broken servers
+    Net::SSLeay::shutdown($ssl); # Useful starting with OpenSSL 1.1.1e
     CORE::shutdown SSLCAT_S, 1;  # Half close --> No more output, send EOF to server
 
     warn "waiting for reply...\n" if $trace>2;
diff --git a/t/local/07_sslecho.t b/t/local/07_sslecho.t
index e876715..2ef4baf 100644
--- a/t/local/07_sslecho.t
+++ b/t/local/07_sslecho.t
@@ -13,7 +13,7 @@ BEGIN {
   plan skip_all => "fork() not supported on $^O" unless $Config{d_fork};
 }
 
-plan tests => 102;
+plan tests => 122;
 $SIG{'PIPE'} = 'IGNORE';
 
 my $sock;
@@ -103,8 +103,28 @@ Net::SSLeay::library_init();
 
             my $got = Net::SSLeay::ssl_read_all($ssl);
             is($got, $msg, 'ssl_read_all') if $_ < 7;
+
+	    is(Net::SSLeay::get_shutdown($ssl), Net::SSLeay::RECEIVED_SHUTDOWN(), 'shutdown from peer');
             ok(Net::SSLeay::ssl_write_all($ssl, uc($got)), 'ssl_write_all');
 
+	    # With 1.1.1e and $Net::SSLeay::trace=3 you'll see these without shutdown:
+	    # SSL_read 9740: 1 - error:14095126:SSL routines:ssl3_read_n:unexpected eof while reading
+	    my $sret = Net::SSLeay::shutdown($ssl);
+	    if ($sret < 0)
+	    {
+		# ERROR_SYSCALL seen on < 1.1.1, if so also print errno string
+		my $err = Net::SSLeay::get_error($ssl, $sret);
+		my $extra = ($err == Net::SSLeay::ERROR_SYSCALL()) ? "$err, $!" : "$err";
+
+		ok($err == Net::SSLeay::ERROR_ZERO_RETURN() ||
+		   $err == Net::SSLeay::ERROR_SYSCALL(),
+		    "server shutdown not success, but acceptable: $extra");
+	    }
+	    else
+	    {
+		pass('server shutdown success');
+	    }
+
             Net::SSLeay::free($ssl);
             close $ns;
         }
@@ -143,6 +163,7 @@ my @results;
     push @results, [ Net::SSLeay::get_cipher($ssl), 'get_cipher' ];
 
     push @results, [ Net::SSLeay::ssl_write_all($ssl, $msg), 'write' ];
+    push @results, [ Net::SSLeay::shutdown($ssl) >= 0, 'client side ssl shutdown' ];
     shutdown($s, 1);
 
     my $got = Net::SSLeay::ssl_read_all($ssl);
@@ -185,6 +206,7 @@ my @results;
 
             Net::SSLeay::ssl_write_all($ssl, $msg);
 
+	    push @results, [Net::SSLeay::shutdown($ssl) >= 0, 'verify: client side ssl shutdown' ];
             shutdown $s, 2;
             close $s;
             Net::SSLeay::free($ssl);
@@ -238,14 +260,17 @@ my @results;
 
             Net::SSLeay::connect($ssl1);
             Net::SSLeay::ssl_write_all($ssl1, $msg);
+	    push @results, [Net::SSLeay::shutdown($ssl1) >= 0, 'client side ssl1 shutdown' ];
             shutdown $s1, 2;
 
             Net::SSLeay::connect($ssl2);
             Net::SSLeay::ssl_write_all($ssl2, $msg);
+	    push @results, [Net::SSLeay::shutdown($ssl2) >= 0, 'client side ssl2 shutdown' ];
             shutdown $s2, 2;
 
             Net::SSLeay::connect($ssl3);
             Net::SSLeay::ssl_write_all($ssl3, $msg);
+	    push @results, [Net::SSLeay::shutdown($ssl3) >= 0, 'client side ssl3 shutdown' ];
             shutdown $s3, 2;
 
             close $s1;
@@ -362,6 +387,7 @@ my @results;
     my $written = Net::SSLeay::ssl_write_all($ssl, \$data);
     push @results, [ $written == length $data, 'ssl_write_all' ];
 
+    push @results, [Net::SSLeay::shutdown($ssl) >= 0, 'client side aaa write ssl shutdown' ];
     shutdown $s, 1;
 
     my $got = Net::SSLeay::ssl_read_all($ssl);
@@ -377,7 +403,7 @@ waitpid $pid, 0;
 push @results, [ $? == 0, 'server exited with 0' ];
 
 END {
-    Test::More->builder->current_test(73);
+    Test::More->builder->current_test(87);
     for my $t (@results) {
         ok( $t->[0], $t->[1] );
     }
-- 
2.25.1