|
0 |
From bbf443c3a90e5f50574b030ff3eecbc3a9681678 Mon Sep 17 00:00:00 2001
|
|
1 |
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
|
2 |
Date: Wed, 13 Oct 2021 11:48:58 +0200
|
|
3 |
Subject: [PATCH] Adapt to OpenSSL 3
|
|
4 |
MIME-Version: 1.0
|
|
5 |
Content-Type: text/plain; charset=UTF-8
|
|
6 |
Content-Transfer-Encoding: 8bit
|
|
7 |
|
|
8 |
OpenSSL 3 changed handling of I/O errors in SSL_accept(). That became
|
|
9 |
visible when a client disconnected to early. As a result
|
|
10 |
t/simple_parallel.t started failing randomly:
|
|
11 |
|
|
12 |
# Failed test 'SERVER: SSLify_Options 156: private key
|
|
13 |
# '
|
|
14 |
# at t/simple_parallel.t line 52.
|
|
15 |
# Failed test 'SERVER: Server_SSLify Please do SSLify_Options() first ( or pass in a $ctx object ) at /builddir/build/BUILD/POE-Component
|
|
16 |
-SSLify-1.012/blib/lib/POE/Component/SSLify.pm line 247.
|
|
17 |
# '
|
|
18 |
# at t/simple_parallel.t line 55.
|
|
19 |
Can't use an undefined value as a symbol reference at /builddir/build/BUILD/POE-Component-SSLify-1.012/blib/lib/POE/Component/SSLify.pm line 457.
|
|
20 |
# Tests were run but no plan was declared and done_testing() was not seen.
|
|
21 |
# Looks like your test exited with 22 just after 94.
|
|
22 |
t/simple_parallel.t ...........
|
|
23 |
Dubious, test returned 22 (wstat 5632, 0x1600)
|
|
24 |
Failed 2/94 subtests
|
|
25 |
|
|
26 |
This patch fixes these bugs in POE-Component-SSLify:
|
|
27 |
|
|
28 |
TIEHANDLE() did not properly handled ERROR_WANT_READ/ERROR_WANT_WRITE
|
|
29 |
soft errors of Net::SSLeay::accept().
|
|
30 |
|
|
31 |
Various Net::SSLeay calls inspected a global error stack instead of
|
|
32 |
the actual return value. That lead to misreporting errors at a wrong
|
|
33 |
place. Expecially after CTX_set_options() which cannot error.
|
|
34 |
|
|
35 |
The test retried SSLify_Options() with wrong file paths.
|
|
36 |
|
|
37 |
This patch should fix all of them.
|
|
38 |
|
|
39 |
CPAN RT#139684
|
|
40 |
|
|
41 |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
42 |
---
|
|
43 |
lib/POE/Component/SSLify.pm | 16 +++++++++-------
|
|
44 |
lib/POE/Component/SSLify/ServerHandle.pm | 21 ++++++++++++++++-----
|
|
45 |
t/simple_parallel.t | 1 -
|
|
46 |
3 files changed, 25 insertions(+), 13 deletions(-)
|
|
47 |
|
|
48 |
--- a/lib/POE/Component/SSLify.pm
|
|
49 |
+++ b/lib/POE/Component/SSLify.pm
|
|
50 |
@@ -380,20 +380,21 @@ sub _createSSLcontext {
|
|
51 |
# do we need to set options?
|
|
52 |
if ( defined $options ) {
|
|
53 |
Net::SSLeay::CTX_set_options( $context, $options );
|
|
54 |
- die_if_ssl_error( 'ssl ctx set options' ) if ! $IGNORE_SSL_ERRORS;
|
|
55 |
}
|
|
56 |
|
|
57 |
# do we need to set key/etc?
|
|
58 |
if ( defined $key ) {
|
|
59 |
# Following will ask password unless private key is not encrypted
|
|
60 |
- Net::SSLeay::CTX_use_RSAPrivateKey_file( $context, $key, FILETYPE_PEM );
|
|
61 |
- die_if_ssl_error( 'private key' ) if ! $IGNORE_SSL_ERRORS;
|
|
62 |
+ unless ( Net::SSLeay::CTX_use_RSAPrivateKey_file( $context, $key, FILETYPE_PEM ) ) {
|
|
63 |
+ die_if_ssl_error( "private key $key: $!" ) if ! $IGNORE_SSL_ERRORS;
|
|
64 |
+ }
|
|
65 |
}
|
|
66 |
|
|
67 |
# Set the cert file
|
|
68 |
if ( defined $cert ) {
|
|
69 |
- Net::SSLeay::CTX_use_certificate_chain_file( $context, $cert );
|
|
70 |
- die_if_ssl_error( 'certificate' ) if ! $IGNORE_SSL_ERRORS;
|
|
71 |
+ unless ( Net::SSLeay::CTX_use_certificate_chain_file( $context, $cert ) ) {
|
|
72 |
+ die_if_ssl_error( 'certificate' ) if ! $IGNORE_SSL_ERRORS;
|
|
73 |
+ }
|
|
74 |
}
|
|
75 |
|
|
76 |
# All done!
|
|
77 |
--- a/lib/POE/Component/SSLify/ServerHandle.pm
|
|
78 |
+++ b/lib/POE/Component/SSLify/ServerHandle.pm
|
|
79 |
@@ -26,11 +26,22 @@ sub TIEHANDLE {
|
|
80 |
|
|
81 |
Net::SSLeay::set_fd( $ssl, $fileno );
|
|
82 |
|
|
83 |
- # Socket is in non-blocking mode, so accept() will return immediately.
|
|
84 |
- # die_if_ssl_error won't die on non-blocking errors. We don't need to call accept()
|
|
85 |
- # again, because OpenSSL I/O functions (read, write, ...) can handle that entirely
|
|
86 |
- # by self (it's needed to accept() once to determine connection type).
|
|
87 |
- my $res = Net::SSLeay::accept( $ssl ) and die_if_ssl_error( 'ssl accept' );
|
|
88 |
+ # Socket is in non-blocking mode, so accept() will usually return immediately.
|
|
89 |
+ # die_if_ssl_error() would die on non-blocking errors. The accept() call
|
|
90 |
+ # will be repeated in _check_status() invoked by READ()/WRITE() handlers.
|
|
91 |
+ my $res = Net::SSLeay::accept( $ssl );
|
|
92 |
+ if ( $res == -1 ) {
|
|
93 |
+ my $error = Net::SSLeay::get_error( $ssl, $res );
|
|
94 |
+ if ( $error != ERROR_WANT_READ && $error != ERROR_WANT_WRITE ) {
|
|
95 |
+ # Cannot use die_if_ssl_error(). get_error() already
|
|
96 |
+ # popped the error stack. Mimic the output here.
|
|
97 |
+ $error = Net::SSLeay::ERR_error_string( $error );
|
|
98 |
+ die( "$$: ssl accept: $error" );
|
|
99 |
+ }
|
|
100 |
+ # else accept() retried later in _check_status().
|
|
101 |
+ } elsif ( $res == 0 || $res < -1 ) {
|
|
102 |
+ die_if_ssl_error( 'ssl accept' );
|
|
103 |
+ }
|
|
104 |
|
|
105 |
my $self = bless {
|
|
106 |
'ssl' => $ssl,
|
|
107 |
--- a/t/simple_parallel.t
|
|
108 |
+++ b/t/simple_parallel.t
|
|
109 |
@@ -48,7 +48,6 @@ POE::Component::Server::TCP->new
|
|
110 |
ClientPreConnect => sub
|
|
111 |
{
|
|
112 |
eval { SSLify_Options('mylib/example.key', 'mylib/example.crt', 'default') };
|
|
113 |
- eval { SSLify_Options('../mylib/example.key', '../mylib/example.crt', 'default') } if ($@);
|
|
114 |
ok(!$@, "SERVER: SSLify_Options $@");
|
|
115 |
|
|
116 |
my $socket = eval { Server_SSLify($_[ARG0]) };
|