ext/rubysl/openssl/ossl_ssl.c in rubysl-openssl-2.8.0 vs ext/rubysl/openssl/ossl_ssl.c in rubysl-openssl-2.9
- old
+ new
@@ -542,11 +542,11 @@
if (NIL_P(cb)) return;
(void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
}
-#ifdef HAVE_OPENSSL_NPN_NEGOTIATED
+#if defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) || defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
static VALUE
ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
{
int len = RSTRING_LENINT(cur);
char len_byte;
@@ -567,22 +567,10 @@
StringValueCStr(encoded);
return encoded;
}
static int
-ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg)
-{
- VALUE sslctx_obj = (VALUE) arg;
- VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols");
-
- *out = (const unsigned char *) RSTRING_PTR(protocols);
- *outlen = RSTRING_LENINT(protocols);
-
- return SSL_TLSEXT_ERR_OK;
-}
-
-static int
ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen)
{
VALUE selected;
long len;
VALUE protocols = rb_ary_new();
@@ -607,20 +595,34 @@
*outlen = (unsigned char)len;
return SSL_TLSEXT_ERR_OK;
}
+#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
static int
+ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg)
+{
+ VALUE sslctx_obj = (VALUE) arg;
+ VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols");
+
+ *out = (const unsigned char *) RSTRING_PTR(protocols);
+ *outlen = RSTRING_LENINT(protocols);
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
+static int
ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
{
VALUE sslctx_obj, cb;
sslctx_obj = (VALUE) arg;
cb = rb_iv_get(sslctx_obj, "@npn_select_cb");
return ssl_npn_select_cb_common(cb, (const unsigned char **)out, outlen, in, inlen);
}
+#endif
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
static int
ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
{
@@ -630,13 +632,12 @@
cb = rb_iv_get(sslctx_obj, "@alpn_select_cb");
return ssl_npn_select_cb_common(cb, out, outlen, in, inlen);
}
#endif
+#endif /* HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB || HAVE_SSL_CTX_SET_ALPN_SELECT_CB */
-#endif
-
/* This function may serve as the entry point to support further
* callbacks. */
static void
ssl_info_cb(const SSL *ssl, int where, int val)
{
@@ -685,12 +686,12 @@
* call-seq:
* ctx.setup => Qtrue # first time
* ctx.setup => nil # thereafter
*
* This method is called automatically when a new SSLSocket is created.
- * Normally you do not need to call this method (unless you are writing an
- * extension in C).
+ * However, it is not thread-safe and must be called before creating
+ * SSLSocket objects in a multi-threaded program.
*/
static VALUE
ossl_sslctx_setup(VALUE self)
{
SSL_CTX *ctx;
@@ -791,11 +792,11 @@
if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
val = ossl_sslctx_get_verify_dep(self);
if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
-#ifdef HAVE_OPENSSL_NPN_NEGOTIATED
+#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
val = rb_iv_get(self, "@npn_protocols");
if (!NIL_P(val)) {
rb_iv_set(self, "@_protocols", ssl_encode_npn_protocols(val));
SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self);
OSSL_Debug("SSL NPN advertise callback added");
@@ -804,11 +805,11 @@
SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
OSSL_Debug("SSL NPN select callback added");
}
#endif
-#ifdef HAVE_SSL_CTX_SET_ALPN_PROTOS
+#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
val = rb_iv_get(self, "@alpn_protocols");
if (!NIL_P(val)) {
VALUE rprotos = ssl_encode_npn_protocols(val);
SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)StringValueCStr(rprotos), RSTRING_LENINT(rprotos));
OSSL_Debug("SSL ALPN values added");
@@ -1530,11 +1531,17 @@
GetSSL(self, ssl);
GetOpenFile(ossl_ssl_get_io(self), fptr);
if (ssl) {
for (;;){
- nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
+ int num = RSTRING_LENINT(str);
+
+ /* SSL_write(3ssl) manpage states num == 0 is undefined */
+ if (num == 0)
+ goto end;
+
+ nwrite = SSL_write(ssl, RSTRING_PTR(str), num);
switch(ssl_get_error(ssl, nwrite)){
case SSL_ERROR_NONE:
goto end;
case SSL_ERROR_WANT_WRITE:
if (no_exception_p(opts)) { return sym_wait_writable; }
@@ -1594,28 +1601,22 @@
/*
* call-seq:
* ssl.stop => nil
*
- * Stops the SSL connection and prepares it for another connection.
+ * Sends "close notify" to the peer and tries to shut down the SSL connection
+ * gracefully.
*/
static VALUE
ossl_ssl_stop(VALUE self)
{
SSL *ssl;
- /* ossl_ssl_data_get_struct() is not usable here because it may return
- * from this function; */
+ ossl_ssl_data_get_struct(self, ssl);
- GetSSL(self, ssl);
+ ossl_ssl_shutdown(ssl);
- if (ssl) {
- ossl_ssl_shutdown(ssl);
- SSL_free(ssl);
- }
- DATA_PTR(self) = NULL;
-
return Qnil;
}
/*
* call-seq:
@@ -1859,11 +1860,11 @@
ca = SSL_get_client_CA_list(ssl);
return ossl_x509name_sk2ary(ca);
}
-# ifdef HAVE_OPENSSL_NPN_NEGOTIATED
+# ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
/*
* call-seq:
* ssl.npn_protocol => String
*
* Returns the protocol string that was finally selected by the client
@@ -2130,11 +2131,11 @@
* num_handshakes += 1
* raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
* end
*/
rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
-#ifdef HAVE_OPENSSL_NPN_NEGOTIATED
+#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
/*
* An Enumerable of Strings. Each String represents a protocol to be
* advertised as the list of supported protocols for Next Protocol
* Negotiation. Supported in OpenSSL 1.0.1 and higher. Has no effect
* on the client side. If not set explicitly, the NPN extension will
@@ -2305,10 +2306,10 @@
rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
# endif
-# ifdef HAVE_OPENSSL_NPN_NEGOTIATED
+# ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
# endif
#endif
#define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, LONG2NUM(SSL_##x))