Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tenderlove/4a579fd60d7d6d4421f4 to your computer and use it in GitHub Desktop.
Save tenderlove/4a579fd60d7d6d4421f4 to your computer and use it in GitHub Desktop.
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index e1b557c..20dd747 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -246,6 +246,43 @@ module OpenSSL
include SocketForwarder
include Nonblock
+ if ENABLED
+ attr_reader :io, :context
+ attr_accessor :sync_close
+ alias :to_io :io
+
+ attr_accessor(:hostname) if TLSEXT_HOST_NAME
+
+ ###
+ # call-seq:
+ # SSLSocket.new(io) => aSSLSocket
+ # SSLSocket.new(io, ctx) => aSSLSocket
+ #
+ # Creates a new SSL socket from +io+ which must be a real ruby object (not an
+ # IO-like object that responds to read/write).
+ #
+ # If +ctx+ is provided the SSL Sockets initial params will be taken from
+ # the context.
+ #
+ # The OpenSSL::Buffering module provides additional IO methods.
+ #
+ # This method will freeze the SSLContext if one is provided;
+ # however, session management is still allowed in the frozen SSLContext.
+ def initialize(io, context = SSLContext.new)
+ raise TypeError unless io.is_a? IO
+ raise TypeError unless context.is_a? SSLContext
+
+ @io = io
+ @context = context
+ @sync_close = false
+ @hostname = nil
+ context.setup
+ super()
+ end
+ else
+ def initialize(*args); raise NotImplementedError; end
+ end
+
##
# Perform hostname verification after an SSL connection is established
#
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 9fe3377..1ed6071 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -77,22 +77,11 @@ static VALUE eSSLErrorWaitWritable;
#define ossl_ssl_get_tmp_dh(o) rb_iv_get((o),"@tmp_dh")
#define ossl_ssl_get_tmp_ecdh(o) rb_iv_get((o),"@tmp_ecdh")
-#define ossl_ssl_set_io(o,v) rb_iv_set((o),"@io",(v))
-#define ossl_ssl_set_ctx(o,v) rb_iv_set((o),"@context",(v))
-#define ossl_ssl_set_sync_close(o,v) rb_iv_set((o),"@sync_close",(v))
#define ossl_ssl_set_x509(o,v) rb_iv_set((o),"@x509",(v))
#define ossl_ssl_set_key(o,v) rb_iv_set((o),"@key",(v))
#define ossl_ssl_set_tmp_dh(o,v) rb_iv_set((o),"@tmp_dh",(v))
#define ossl_ssl_set_tmp_ecdh(o,v) rb_iv_set((o),"@tmp_ecdh",(v))
-static const char *ossl_ssl_attr_readers[] = { "io", "context", };
-static const char *ossl_ssl_attrs[] = {
-#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
- "hostname",
-#endif
- "sync_close",
-};
-
ID ID_callback_state;
static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
@@ -1181,44 +1170,6 @@ ossl_ssl_s_alloc(VALUE klass)
return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL);
}
-/*
- * call-seq:
- * SSLSocket.new(io) => aSSLSocket
- * SSLSocket.new(io, ctx) => aSSLSocket
- *
- * Creates a new SSL socket from +io+ which must be a real ruby object (not an
- * IO-like object that responds to read/write).
- *
- * If +ctx+ is provided the SSL Sockets initial params will be taken from
- * the context.
- *
- * The OpenSSL::Buffering module provides additional IO methods.
- *
- * This method will freeze the SSLContext if one is provided;
- * however, session management is still allowed in the frozen SSLContext.
- */
-static VALUE
-ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
-{
- VALUE io, ctx;
-
- if (rb_scan_args(argc, argv, "11", &io, &ctx) == 1) {
- ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
- }
- OSSL_Check_Kind(ctx, cSSLContext);
- Check_Type(io, T_FILE);
- ossl_ssl_set_io(self, io);
- ossl_ssl_set_ctx(self, ctx);
- ossl_ssl_set_sync_close(self, Qfalse);
- ossl_sslctx_setup(ctx);
-
- rb_iv_set(self, "@hostname", Qnil);
-
- rb_call_super(0, 0);
-
- return self;
-}
-
static VALUE
ossl_ssl_setup(VALUE self)
{
@@ -2335,15 +2286,15 @@ Init_ossl_ssl(void)
*/
cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject);
#ifdef OPENSSL_NO_SOCK
- rb_define_method(cSSLSocket, "initialize", rb_notimplement, -1);
+ rb_define_const(cSSLSocket, "ENABLED", Qfalse);
#else
+ rb_define_const(cSSLSocket, "ENABLED", Qtrue);
+# ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
+ rb_define_const(cSSLSocket, "TLSEXT_HOST_NAME", Qtrue);
+# else
+ rb_define_const(cSSLSocket, "TLSEXT_HOST_NAME", Qfalse);
+# endif
rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc);
- for(i = 0; i < numberof(ossl_ssl_attr_readers); i++)
- rb_attr(cSSLSocket, rb_intern(ossl_ssl_attr_readers[i]), 1, 0, Qfalse);
- for(i = 0; i < numberof(ossl_ssl_attrs); i++)
- rb_attr(cSSLSocket, rb_intern(ossl_ssl_attrs[i]), 1, 1, Qfalse);
- rb_define_alias(cSSLSocket, "to_io", "io");
- rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1);
rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0);
rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, -1);
rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment