perl-Net-SSLeay/Net-SSLeay-1.85-Move-SSL_ERROR_WANT_READ-SSL_ERROR_WANT_WRITE-retry-.patch
Dirk Stoecker f7b5300fb7 Accepting request 633049 from home:vitezslav_cizek:branches:devel:languages:perl
- Add patches to support openssl 1.1.1 from Fedora
  * Net-SSLeay-1.85-Avoid-SIGPIPE-in-t-local-36_verify.t.patch
  * Net-SSLeay-1.85-Move-SSL_ERROR_WANT_READ-SSL_ERROR_WANT_WRITE-retry-.patch
  * Net-SSLeay-1.85-Move-SSL_ERROR_WANT_READ-SSL_ERROR_WANT_WRITE-retry-from_write_partial.patch
  * Net-SSLeay-1.85-Adapt-to-OpenSSL-1.1.1.patch

OBS-URL: https://build.opensuse.org/request/show/633049
OBS-URL: https://build.opensuse.org/package/show/devel:languages:perl/perl-Net-SSLeay?expand=0&rev=40
2018-09-05 08:29:59 +00:00

226 lines
7.1 KiB
Diff

From e0b42b0120b941b5675e4071445424dc8a1230e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Wed, 15 Aug 2018 14:46:52 +0200
Subject: [PATCH] Move SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE retry from
read()/write() up
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Original OpenSSL 1.1.1 fix broke IO-Socket-SSL-2.058's t/core.t test
because it tests non-blocking socket operations and expects to see
SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE errors and to handle them
byt itself.
This patch purifies Net::SSLeay::{read,write}() to behave exactly as
underlying OpenSSL functions. The retry is moved to
Net::SSLeay::ssl_read_all. All relevant Net::SSLeay::{read,write}() calls in
tests are changed into Net::SSLea::ssl_{read,write}_all().
All applications should implement the retry themsleves or use
ssl_*_all() instead.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
SSLeay.xs | 28 +++++++---------------------
lib/Net/SSLeay.pm | 22 +++++++++++++++-------
t/local/07_sslecho.t | 12 ++++++------
t/local/36_verify.t | 9 +++++----
4 files changed, 33 insertions(+), 38 deletions(-)
diff --git a/SSLeay.xs b/SSLeay.xs
index 5aed4d7..7cb6eab 100644
--- a/SSLeay.xs
+++ b/SSLeay.xs
@@ -1997,19 +1997,13 @@ SSL_read(s,max=32768)
PREINIT:
char *buf;
int got;
+ int succeeded = 1;
PPCODE:
New(0, buf, max, char);
- do {
- int err;
-
- got = SSL_read(s, buf, max);
- if (got > 0)
- break;
- err = SSL_get_error(s, got);
- if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
- break;
- } while (1);
+ got = SSL_read(s, buf, max);
+ if (got <= 0 && SSL_ERROR_ZERO_RETURN != SSL_get_error(s, got))
+ succeeded = 0;
/* If in list context, return 2-item list:
* first return value: data gotten, or undef on error (got<0)
@@ -2017,13 +2011,13 @@ SSL_read(s,max=32768)
*/
if (GIMME_V==G_ARRAY) {
EXTEND(SP, 2);
- PUSHs(sv_2mortal(got>=0 ? newSVpvn(buf, got) : newSV(0)));
+ PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0)));
PUSHs(sv_2mortal(newSViv(got)));
/* If in scalar or void context, return data gotten, or undef on error. */
} else {
EXTEND(SP, 1);
- PUSHs(sv_2mortal(got>=0 ? newSVpvn(buf, got) : newSV(0)));
+ PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0)));
}
Safefree(buf);
@@ -2066,15 +2060,7 @@ SSL_write(s,buf)
INPUT:
char * buf = SvPV( ST(1), len);
CODE:
- do {
- ret = SSL_write (s, buf, (int)len);
- if (ret > 0)
- break;
- err = SSL_get_error(s, ret);
- if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
- break;
- } while (1);
- RETVAL = ret;
+ RETVAL = SSL_write (s, buf, (int)len);
OUTPUT:
RETVAL
diff --git a/lib/Net/SSLeay.pm b/lib/Net/SSLeay.pm
index 3adf12c..afc6c8f 100644
--- a/lib/Net/SSLeay.pm
+++ b/lib/Net/SSLeay.pm
@@ -579,14 +579,22 @@ sub debug_read {
sub ssl_read_all {
my ($ssl,$how_much) = @_;
$how_much = 2000000000 unless $how_much;
- my ($got, $errs);
+ my ($got, $rv, $errs);
my $reply = '';
while ($how_much > 0) {
- $got = Net::SSLeay::read($ssl,
+ ($got, $rv) = Net::SSLeay::read($ssl,
($how_much > 32768) ? 32768 : $how_much
);
- last if $errs = print_errs('SSL_read');
+ if (! defined $got) {
+ my $err = Net::SSLeay::get_error($ssl, $rv);
+ if ($err != Net::SSLeay::ERROR_WANT_READ() and
+ $err != Net::SSLeay::ERROR_WANT_WRITE()) {
+ $errs = print_errs('SSL_read');
+ last;
+ }
+ next;
+ }
$how_much -= blength($got);
debug_read(\$reply, \$got) if $trace>1;
last if $got eq ''; # EOF
@@ -839,14 +847,14 @@ sub ssl_read_until ($;$$) {
$found = index($match, $delim);
if ($found > -1) {
- #$got = Net::SSLeay::read($ssl, $found+$len_delim);
+ #$got = Net::SSLeay::ssl_read_all($ssl, $found+$len_delim);
#read up to the end of the delimiter
- $got = Net::SSLeay::read($ssl,
+ $got = Net::SSLeay::ssl_read_all($ssl,
$found + $len_delim
- ((blength($match)) - (blength($got))));
$done = 1;
} else {
- $got = Net::SSLeay::read($ssl, $peek_length);
+ $got = Net::SSLeay::ssl_read_all($ssl, $peek_length);
$done = 1 if ($peek_length == $max_length - blength($reply));
}
@@ -857,7 +865,7 @@ sub ssl_read_until ($;$$) {
}
} else {
while (!defined $max_length || length $reply < $max_length) {
- $got = Net::SSLeay::read($ssl,1); # one by one
+ $got = Net::SSLeay::ssl_read_all($ssl,1); # one by one
last if print_errs('SSL_read');
debug_read(\$reply, \$got) if $trace>1;
last if $got eq '';
diff --git a/t/local/07_sslecho.t b/t/local/07_sslecho.t
index 74e317a..7f19027 100644
--- a/t/local/07_sslecho.t
+++ b/t/local/07_sslecho.t
@@ -134,10 +134,10 @@ my @results;
push @results, [ Net::SSLeay::get_cipher($ssl), 'get_cipher' ];
- push @results, [ Net::SSLeay::write($ssl, $msg), 'write' ];
+ push @results, [ Net::SSLeay::ssl_write_all($ssl, $msg), 'write' ];
shutdown($s, 1);
- my ($got) = Net::SSLeay::read($ssl);
+ my $got = Net::SSLeay::ssl_read_all($ssl);
push @results, [ $got eq uc($msg), 'read' ];
Net::SSLeay::free($ssl);
@@ -177,7 +177,7 @@ my @results;
Net::SSLeay::set_fd($ssl, fileno($s));
Net::SSLeay::connect($ssl);
- Net::SSLeay::write($ssl, $msg);
+ Net::SSLeay::ssl_write_all($ssl, $msg);
shutdown $s, 2;
close $s;
@@ -231,15 +231,15 @@ my @results;
Net::SSLeay::set_fd($ssl3, $s3);
Net::SSLeay::connect($ssl1);
- Net::SSLeay::write($ssl1, $msg);
+ Net::SSLeay::ssl_write_all($ssl1, $msg);
shutdown $s1, 2;
Net::SSLeay::connect($ssl2);
- Net::SSLeay::write($ssl2, $msg);
+ Net::SSLeay::ssl_write_all($ssl2, $msg);
shutdown $s2, 2;
Net::SSLeay::connect($ssl3);
- Net::SSLeay::write($ssl3, $msg);
+ Net::SSLeay::ssl_write_all($ssl3, $msg);
shutdown $s3, 2;
close $s1;
diff --git a/t/local/36_verify.t b/t/local/36_verify.t
index 2837288..b04be13 100644
--- a/t/local/36_verify.t
+++ b/t/local/36_verify.t
@@ -252,8 +252,9 @@ sub client {
Net::SSLeay::set_fd($ssl, $cl);
Net::SSLeay::connect($ssl);
my $end = "end";
- Net::SSLeay::write($ssl, $end);
- ok($end eq Net::SSLeay::read($ssl), 'Successful termination');
+ Net::SSLeay::ssl_write_all($ssl, $end);
+ Net::SSLeay::shutdown($ssl);
+ ok($end eq Net::SSLeay::ssl_read_all($ssl), 'Successful termination');
return;
}
@@ -291,10 +292,10 @@ sub run_server
next unless $ret == 1;
# Termination request or other message from client
- my $msg = Net::SSLeay::read($ssl);
+ my $msg = Net::SSLeay::ssl_read_all($ssl);
if (defined $msg and $msg eq 'end')
{
- Net::SSLeay::write($ssl, 'end');
+ Net::SSLeay::ssl_write_all($ssl, 'end');
exit (0);
}
}
--
2.14.4