summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--ext/openssl/ossl.c7
-rw-r--r--test/openssl/test_pair.rb2
-rw-r--r--test/openssl/test_ssl.rb20
-rw-r--r--test/openssl/utils.rb2
5 files changed, 39 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index de2a26c94c..b81f351ac2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Thu Jul 14 12:19:34 2011 Hiroshi Nakamura <nahi@ruby-lang.org>
+
+ * ext/openssl/ossl.c (ossl_verify_cb): trap the exception from
+ verify callback of SSLContext and X509Store and make the
+ verification fail normally. Raising exception directly from callback
+ causes orphan resouces in OpenSSL stack. Patched by Ippei Obayashi.
+ See #4445.
+
+ * test/openssl/test_ssl.rb
+ (test_exception_in_verify_callback_is_ignored): test it.
+
Tue Jul 12 23:41:49 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* NEWS: add a description of Signal.trap change.
diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c
index c5321b60ae..f3410b64e8 100644
--- a/ext/openssl/ossl.c
+++ b/ext/openssl/ossl.c
@@ -223,8 +223,11 @@ ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
args.proc = proc;
args.preverify_ok = ok ? Qtrue : Qfalse;
args.store_ctx = rctx;
- ret = rb_ensure(ossl_call_verify_cb_proc, (VALUE)&args,
- ossl_x509stctx_clear_ptr, rctx);
+ ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state);
+ ossl_x509stctx_clear_ptr(rctx);
+ if (state) {
+ rb_warn("exception in verify_callback is ignored");
+ }
}
if (ret == Qtrue) {
X509_STORE_CTX_set_error(ctx, X509_V_OK);
diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
index d31781f6e7..940fa0c0db 100644
--- a/test/openssl/test_pair.rb
+++ b/test/openssl/test_pair.rb
@@ -238,6 +238,8 @@ class OpenSSL::TestPair < Test::Unit::TestCase
s1.print "a\ndef"
assert_equal("a\n", s2.gets)
ensure
+ s1.close if s1 && !s1.closed?
+ s2.close if s2 && !s2.closed?
serv.close if serv && !serv.closed?
sock1.close if sock1 && !sock1.closed?
sock2.close if sock2 && !sock2.closed?
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 8c3d00e5e5..07154eac01 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -238,6 +238,26 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
end
+ def test_exception_in_verify_callback_is_ignored
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
+ sock = TCPSocket.new("127.0.0.1", port)
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.set_params(
+ :verify_callback => Proc.new do |preverify_ok, store_ctx|
+ store_ctx.error = OpenSSL::X509::V_OK
+ raise RuntimeError
+ end
+ )
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
+ OpenSSL::TestUtils.silent do
+ # SSLError, not RuntimeError
+ assert_raise(OpenSSL::SSL::SSLError) { ssl.connect }
+ end
+ assert_equal(OpenSSL::X509::V_ERR_CERT_REJECTED, ssl.verify_result)
+ ssl.close
+ }
+ end
+
def test_sslctx_set_params
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
sock = TCPSocket.new("127.0.0.1", port)
diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb
index 77a6b3cc77..c4c0a0c040 100644
--- a/test/openssl/utils.rb
+++ b/test/openssl/utils.rb
@@ -275,7 +275,7 @@ aPgwHyJBiK1/ebK3tYcrSKrOoRyrAgEC
server_loop(ctx, ssls, server_proc)
end
- $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, pid, port) if $DEBUG
+ $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, $$, port) if $DEBUG
block.call(server, port.to_i)
ensure