Skip to content

Commit e3a6ba4

Browse files
nevansrhenium
andcommitted
🍒 pick 257ede0: 🥅 Re-raise #starttls error from receiver thread [backports #395]
Backports #395 to `v0.3-stable`. The tests required an additional rescue-and-ignore for the server thread in `starttls_test`, which was already present in all later branches. --------- When `start_tls_session` raises an exception, that's caught in the receiver thread, but not re-raised. Fortunately, `@sock` will now be a permanently broken SSLSocket, so I don't think this can lead to accidentally using an insecure connection. Even so, `#starttls` should disconnect the socket and re-raise the error immediately. Failing test case was provided by @rhenium in #394. Co-authored-by: Kazuki Yamaguchi <k@rhe.jp>
1 parent d86186d commit e3a6ba4

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

lib/net/imap.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,8 @@ def logout
10141014
# unsolicited untagged response immeditely _after_ #starttls completes.
10151015
#
10161016
def starttls(options = {}, verify = true)
1017-
send_command("STARTTLS") do |resp|
1017+
error = nil
1018+
ok = send_command("STARTTLS") do |resp|
10181019
if resp.kind_of?(TaggedResponse) && resp.name == "OK"
10191020
begin
10201021
# for backward compatibility
@@ -1024,7 +1025,14 @@ def starttls(options = {}, verify = true)
10241025
end
10251026
start_tls_session(options)
10261027
end
1028+
rescue Exception => error
1029+
raise # note that the error backtrace is in the receiver_thread
10271030
end
1031+
if error
1032+
disconnect
1033+
raise error
1034+
end
1035+
ok
10281036
end
10291037

10301038
# :call-seq:

test/net/imap/test_imap.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ def test_imaps_post_connection_check
7575
end
7676

7777
if defined?(OpenSSL::SSL)
78+
def test_starttls_unknown_ca
79+
imap = nil
80+
ex = nil
81+
starttls_test do |port|
82+
imap = Net::IMAP.new("localhost", port: port)
83+
begin
84+
imap.starttls
85+
rescue => ex
86+
end
87+
imap
88+
end
89+
assert_kind_of(OpenSSL::SSL::SSLError, ex)
90+
end
91+
7892
def test_starttls
7993
imap = nil
8094
starttls_test do |port|
@@ -1004,6 +1018,7 @@ def starttls_test
10041018
sock.gets
10051019
sock.print("* BYE terminating connection\r\n")
10061020
sock.print("RUBY0002 OK LOGOUT completed\r\n")
1021+
rescue OpenSSL::SSL::SSLError
10071022
ensure
10081023
sock.close
10091024
server.close

0 commit comments

Comments
 (0)