@@ -218,6 +218,88 @@ def test_synthetic_io_write_nonblock_exception
218
218
end
219
219
end
220
220
221
+ def test_synthetic_io_errors_in_servername_cb
222
+ assert_separately ( [ "-ropenssl" ] , <<~"end;" )
223
+ begin
224
+ #sock1, sock2 = socketpair
225
+ sock1, sock2 = if defined? UNIXSocket
226
+ UNIXSocket.pair
227
+ else
228
+ Socket.pair(Socket::AF_INET, Socket::SOCK_STREAM, 0)
229
+ end
230
+
231
+ t = Thread.new {
232
+ s1 = OpenSSL::SSL::SSLSocket.new(sock1)
233
+ s1.hostname = "localhost"
234
+ assert_raise_with_message(OpenSSL::SSL::SSLError, /unrecognized.name/i) {
235
+ s1.connect
236
+ }
237
+ }
238
+
239
+ ctx2 = OpenSSL::SSL::SSLContext.new
240
+ ctx2.servername_cb = lambda { |args| raise RuntimeError, "exc in servername_cb" }
241
+ obj = Object.new
242
+ obj.define_singleton_method(:method_missing) { |name, *args, **kwargs| sock2.__send__(name, *args, **kwargs) }
243
+ obj.define_singleton_method(:respond_to_missing?) { |name, *args, **kwargs| sock2.respond_to?(name, *args, **kwargs) }
244
+ obj.define_singleton_method(:write_nonblock) { |*args, **kwargs|
245
+ begin
246
+ raise "exc in write_nonblock"
247
+ rescue
248
+ p $!
249
+ end
250
+ p $!
251
+ sock2.write_nonblock(*args, **kwargs)
252
+ }
253
+ s2 = OpenSSL::SSL::SSLSocket.new(obj, ctx2)
254
+ assert_raise_with_message(RuntimeError, "exc in servername_cb") { s2.accept }
255
+ assert t.join
256
+ ensure
257
+ sock1.close
258
+ sock2.close
259
+ end
260
+ end;
261
+ end
262
+
263
+ def test_synthetic_io_errors_in_callback_and_socket
264
+ assert_separately ( [ "-ropenssl" ] , <<~"end;" )
265
+ begin
266
+ #sock1, sock2 = socketpair
267
+ sock1, sock2 = if defined? UNIXSocket
268
+ UNIXSocket.pair
269
+ else
270
+ Socket.pair(Socket::AF_INET, Socket::SOCK_STREAM, 0)
271
+ end
272
+
273
+ t = Thread.new {
274
+ s1 = OpenSSL::SSL::SSLSocket.new(sock1)
275
+ s1.hostname = "localhost"
276
+ assert_raise_with_message(OpenSSL::SSL::SSLError, /unrecognized.name/i) {
277
+ s1.connect
278
+ }
279
+ }
280
+
281
+ ctx2 = OpenSSL::SSL::SSLContext.new
282
+ ctx2.servername_cb = lambda { |args|
283
+ throw :throw_from, :servername_cb
284
+ }
285
+ obj = Object.new
286
+ obj.define_singleton_method(:method_missing) { |name, *args, **kwargs| sock2.__send__(name, *args, **kwargs) }
287
+ obj.define_singleton_method(:respond_to_missing?) { |name, *args, **kwargs| sock2.respond_to?(name, *args, **kwargs) }
288
+ obj.define_singleton_method(:write_nonblock) { |*args, **kwargs|
289
+ raise "write_nonblock"
290
+ }
291
+ s2 = OpenSSL::SSL::SSLSocket.new(obj, ctx2)
292
+
293
+ ret = catch(:throw_from) { s2.accept }
294
+ assert_equal(:servername_cb, ret)
295
+ assert t.join
296
+ ensure
297
+ sock1.close
298
+ sock2.close
299
+ end
300
+ end;
301
+ end
302
+
221
303
def test_add_certificate
222
304
ctx_proc = -> ctx {
223
305
# Unset values set by start_server
0 commit comments