From ba64282cdc2e02a742ae5e0159d606051f188aa5 Mon Sep 17 00:00:00 2001 From: gotoyuzo Date: Mon, 18 Aug 2003 22:49:48 +0000 Subject: * ext/openssl/ossl_ssl.c: sync_close is moved to SSLSocket as a builtin. * ext/openssl/lib/openssl/buffering.rb (Buffering#close): ditto. * ext/openssl/lib/openssl/buffering.rb (Buffering#puts): should add a return to the tails of each line. * ext/openssl/lib/openssl/ssl.rb: new class OpenSSL::SSL::SSLServer. * ext/openssl/lib/net/protocols.rb (SSLIO#ssl_connect): use sync_close. * ext/openssl/sample/echo_svr.rb: use SSLServer. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4407 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/openssl/lib/net/protocols.rb | 11 ++------ ext/openssl/lib/openssl/buffering.rb | 13 +++++---- ext/openssl/lib/openssl/ssl.rb | 53 ++++++++++++++++++++++++++++++------ ext/openssl/ossl_ssl.c | 21 +++++++++----- ext/openssl/sample/echo_cli.rb | 5 ++-- ext/openssl/sample/echo_svr.rb | 12 ++++---- 6 files changed, 77 insertions(+), 38 deletions(-) (limited to 'ext') diff --git a/ext/openssl/lib/net/protocols.rb b/ext/openssl/lib/net/protocols.rb index 6f646b5785..25e940c54b 100644 --- a/ext/openssl/lib/net/protocols.rb +++ b/ext/openssl/lib/net/protocols.rb @@ -40,17 +40,12 @@ module Net end def ssl_connect() - @raw_socket = @socket - @socket = OpenSSL::SSL::SSLSocket.new(@raw_socket, @ssl_context) - @scoket.sync = true + @socket = OpenSSL::SSL::SSLSocket.new(@socket, @ssl_context) + @socket.sync = true + @socket.sync_close = true @socket.connect end - def close - super - @raw_socket.close if @raw_socket - end - def peer_cert @socket.peer_cert end diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb index 6ddec099bf..031af4baa3 100644 --- a/ext/openssl/lib/openssl/buffering.rb +++ b/ext/openssl/lib/openssl/buffering.rb @@ -16,7 +16,7 @@ module Buffering include Enumerable - attr_accessor :sync, :sync_close + attr_accessor :sync BLOCK_SIZE = 1024*16 # @@ -158,7 +158,12 @@ module Buffering def puts(*args) s = "" - args.each{ |arg| s << arg.to_s + $/ } + args.each{|arg| + s << arg.to_s + unless /#{$/}\Z/o =~ s + s << $/ + end + } do_write(s) nil end @@ -183,9 +188,7 @@ module Buffering end def close - flush + flush rescue nil sysclose - @sync_close ||= false - @io.close if @sync_close end end diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb index 39d975b1c8..6e6bdfe942 100644 --- a/ext/openssl/lib/openssl/ssl.rb +++ b/ext/openssl/lib/openssl/ssl.rb @@ -18,31 +18,66 @@ require 'openssl/buffering' module OpenSSL module SSL - class SSLSocket - include Buffering - + module SocketForwarder def addr - @io.addr + to_io.addr end def peeraddr - @io.peeraddr + to_io.peeraddr end def getsockopt(level, optname, optval) - @io.setsockopt(level, optname, optval) + to_io.setsockopt(level, optname, optval) end def setsockopt(level, optname) - @io.setsockopt(level, optname) + to_io.setsockopt(level, optname) end def fcntl(*args) - @io.fcntl(*args) + to_io.fcntl(*args) end def closed? - @io.closed? + to_io.closed? + end + end + + class SSLSocket + include Buffering + include SocketForwarder + end + + class SSLServer + include SocketForwarder + attr_accessor :start_immediately + + def initialize(svr, ctx) + @svr = svr + @ctx = ctx + @start_immediately = true + end + + def to_io + @svr + end + + def listen(basklog=5) + @svr.listen(backlog) + end + + def accept + sock = @svr.accept + ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) + ssl.sync = true + ssl.sync_close = true + ssl.accept if @start_immediately + ssl + end + + def close + @svr.close end end end diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 3f25a077fb..5611f43679 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -333,13 +333,16 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) /* * SSLSocket class */ -#define ossl_ssl_get_io(o) rb_iv_get((o),"@io") -#define ossl_ssl_get_ctx(o) rb_iv_get((o),"@context") +#define ossl_ssl_get_io(o) rb_iv_get((o),"@io") +#define ossl_ssl_get_ctx(o) rb_iv_get((o),"@context") +#define ossl_ssl_get_sync_close(o) rb_iv_get((o),"@sync_close") -#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_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)) -static char *ossl_ssl_attrs[] = { "io", "context", }; +static char *ossl_ssl_attr_readers[] = { "io", "context", }; +static char *ossl_ssl_attrs[] = { "sync_close", }; static void ossl_ssl_shutdown(SSL *ssl) @@ -376,6 +379,7 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self) 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); return self; @@ -522,8 +526,9 @@ ossl_ssl_close(VALUE self) SSL *ssl; Data_Get_Struct(self, SSL, ssl); - ossl_ssl_shutdown(ssl); + if (RTEST(ossl_ssl_get_sync_close(self))) + rb_funcall(ossl_ssl_get_io(self), rb_intern("close"), 0); return Qnil; } @@ -635,8 +640,10 @@ Init_ossl_ssl() /* class SSLSocket */ cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject); 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, 0, Qfalse); + 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); diff --git a/ext/openssl/sample/echo_cli.rb b/ext/openssl/sample/echo_cli.rb index 87dacaf545..29b356a7ad 100644 --- a/ext/openssl/sample/echo_cli.rb +++ b/ext/openssl/sample/echo_cli.rb @@ -26,11 +26,12 @@ end s = TCPSocket.new(host, port) ssl = OpenSSL::SSL::SSLSocket.new(s, ctx) -ssl.connect +ssl.connect # start SSL session +ssl.sync_close = true # if true the underlying socket will be + # closed in SSLSocket#close. (default: false) while line = $stdin.gets ssl.write line print ssl.gets end ssl.close -s.close diff --git a/ext/openssl/sample/echo_svr.rb b/ext/openssl/sample/echo_svr.rb index e35ad12a19..be8e10fa26 100644 --- a/ext/openssl/sample/echo_svr.rb +++ b/ext/openssl/sample/echo_svr.rb @@ -51,14 +51,12 @@ else $stderr.puts "!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!" end -svr = TCPServer.new(port) +tcps = TCPServer.new(port) +ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx) loop do - ns = svr.accept - ssl = OpenSSL::SSL::SSLSocket.new(ns, ctx) - ssl.accept - while line = ssl.gets - ssl.write line + ns = ssls.accept + while line = ns.gets + ns.write line end - ssl.close ns.close end -- cgit v1.2.3