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))