Skip to content

Commit

Permalink
* ext/openssl/ossl_ssl.c (ossl_call_servername_cb): set the ssl context
Browse files Browse the repository at this point in the history
  object returned by the servername callback on to the socket as an
  instance variable.  If the callback allocated a new context object
  and didn't keep a reference to it, it could be GC'd out from under
  the socket object.

* test/openssl/test_ssl.rb (class OpenSSL): test for change.

git-svn-id: svn+ssh:https://ci.ruby-lang.org/ruby/trunk@51387 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
tenderlove committed Jul 26, 2015
1 parent 2de804b commit 86ff702
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
10 changes: 10 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Sun Jul 26 10:26:35 2015 Aaron Patterson <[email protected]>

* ext/openssl/ossl_ssl.c (ossl_call_servername_cb): set the ssl context
object returned by the servername callback on to the socket as an
instance variable. If the callback allocated a new context object
and didn't keep a reference to it, it could be GC'd out from under
the socket object.

* test/openssl/test_ssl.rb (class OpenSSL): test for change.

Sun Jul 26 10:07:26 2015 Aaron Patterson <[email protected]>

* test/openssl/test_ssl.rb (class OpenSSL): add test coverage around
Expand Down
1 change: 1 addition & 0 deletions ext/openssl/ossl_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ ossl_call_servername_cb(VALUE ary)
GetSSL(ssl_obj, ssl);
GetSSLCTX(ret_obj, ctx2);
SSL_set_SSL_CTX(ssl, ctx2);
rb_iv_set(ssl_obj, "@context", ret_obj);
} else if (!NIL_P(ret_obj)) {
ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil");
}
Expand Down
33 changes: 33 additions & 0 deletions test/openssl/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,39 @@ def create_null_byte_SAN_certificate(critical = false)
cert
end

def test_servername_cb_sets_context_on_the_socket
hostname = 'example.org'

ctx3 = OpenSSL::SSL::SSLContext.new
ctx3.ciphers = "DH"

ctx2 = OpenSSL::SSL::SSLContext.new
ctx2.ciphers = "DH"
ctx2.servername_cb = lambda { |args| ctx3 }

sock1, sock2 = UNIXSocket.pair

s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2)

ctx1 = OpenSSL::SSL::SSLContext.new
ctx1.ciphers = "DH"

s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1)
s1.hostname = hostname
t = Thread.new { s1.connect }

assert_equal ctx2, s2.context
accepted = s2.accept
assert_equal ctx3, s2.context
assert t.value
ensure
s1.close if s1
s2.close if s2
sock1.close if sock1
sock2.close if sock2
accepted.close if accepted.respond_to?(:close)
end

def test_servername_cb_raises_an_exception_on_unknown_objects
hostname = 'example.org'

Expand Down

0 comments on commit 86ff702

Please sign in to comment.