From ed85c5ed438c259982ceb6922f234cfa0ed71123 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Fri, 20 May 2016 13:59:50 +0900 Subject: openssl: SSLSocket#{write,read} should fail if session is not started Currently they directly read/write to the underlying IO. A warning is emitted but it isn't shown unless $DEBUG = true. --- ext/openssl/ossl_ssl.c | 120 ++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 66 deletions(-) diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 87df7f9f78..fc7c64ee0b 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1430,6 +1430,10 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) rb_scan_args(argc, argv, "11", &len, &str); } + GetSSL(self, ssl); + if (!ssl) + rb_raise(eSSLError, "SSL session is not started yet"); + ilen = NUM2INT(len); if(NIL_P(str)) str = rb_str_new(0, ilen); else{ @@ -1439,48 +1443,36 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) } if(ilen == 0) return str; - GetSSL(self, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); - if (ssl) { - if(!nonblock && SSL_pending(ssl) <= 0) - rb_thread_wait_fd(FPTR_TO_FD(fptr)); - for (;;){ - nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); - switch(ssl_get_error(ssl, nread)){ - case SSL_ERROR_NONE: - goto end; - case SSL_ERROR_ZERO_RETURN: + if(!nonblock && SSL_pending(ssl) <= 0) + rb_thread_wait_fd(FPTR_TO_FD(fptr)); + for (;;){ + nread = SSL_read(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); + switch(ssl_get_error(ssl, nread)){ + case SSL_ERROR_NONE: + goto end; + case SSL_ERROR_ZERO_RETURN: + if (no_exception_p(opts)) { return Qnil; } + rb_eof_error(); + case SSL_ERROR_WANT_WRITE: + if (no_exception_p(opts)) { return sym_wait_writable; } + write_would_block(nonblock); + rb_io_wait_writable(FPTR_TO_FD(fptr)); + continue; + case SSL_ERROR_WANT_READ: + if (no_exception_p(opts)) { return sym_wait_readable; } + read_would_block(nonblock); + rb_io_wait_readable(FPTR_TO_FD(fptr)); + continue; + case SSL_ERROR_SYSCALL: + if(ERR_peek_error() == 0 && nread == 0) { if (no_exception_p(opts)) { return Qnil; } rb_eof_error(); - case SSL_ERROR_WANT_WRITE: - if (no_exception_p(opts)) { return sym_wait_writable; } - write_would_block(nonblock); - rb_io_wait_writable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_WANT_READ: - if (no_exception_p(opts)) { return sym_wait_readable; } - read_would_block(nonblock); - rb_io_wait_readable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_SYSCALL: - if(ERR_peek_error() == 0 && nread == 0) { - if (no_exception_p(opts)) { return Qnil; } - rb_eof_error(); - } - rb_sys_fail(0); - default: - ossl_raise(eSSLError, "SSL_read"); } - } - } - else { - ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); - rb_warning("SSL session is not started yet."); - if (nonblock) { - return rb_funcall(ossl_ssl_get_io(self), meth, 3, len, str, opts); - } else { - return rb_funcall(ossl_ssl_get_io(self), meth, 2, len, str); - } + rb_sys_fail(0); + default: + ossl_raise(eSSLError, "SSL_read"); + } } end: @@ -1531,37 +1523,33 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) rb_io_t *fptr; int nonblock = opts != Qfalse; - StringValue(str); GetSSL(self, ssl); + if (!ssl) + rb_raise(eSSLError, "SSL session is not started yet"); + + StringValue(str); GetOpenFile(ossl_ssl_get_io(self), fptr); - if (ssl) { - for (;;){ - nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); - 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; } - write_would_block(nonblock); - rb_io_wait_writable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_WANT_READ: - if (no_exception_p(opts)) { return sym_wait_readable; } - read_would_block(nonblock); - rb_io_wait_readable(FPTR_TO_FD(fptr)); - continue; - case SSL_ERROR_SYSCALL: - if (errno) rb_sys_fail(0); - default: - ossl_raise(eSSLError, "SSL_write"); - } - } - } - else { - ID id_syswrite = rb_intern("syswrite"); - rb_warning("SSL session is not started yet."); - return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str); + for (;;){ + nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); + 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; } + write_would_block(nonblock); + rb_io_wait_writable(FPTR_TO_FD(fptr)); + continue; + case SSL_ERROR_WANT_READ: + if (no_exception_p(opts)) { return sym_wait_readable; } + read_would_block(nonblock); + rb_io_wait_readable(FPTR_TO_FD(fptr)); + continue; + case SSL_ERROR_SYSCALL: + if (errno) rb_sys_fail(0); + default: + ossl_raise(eSSLError, "SSL_write"); + } } end: -- cgit v1.2.3