summaryrefslogtreecommitdiffstats
path: root/ext/openssl
diff options
context:
space:
mode:
authorgotoyuzo <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-18 22:49:48 +0000
committergotoyuzo <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-08-18 22:49:48 +0000
commite986e7123643b91ece134ea47db9935670108ca2 (patch)
treef2a04d9bf6592f11b1d81a233991d4b75b0faeaa /ext/openssl
parentf713c829dfc3339b15848907fde9fdd82a8a8b5d (diff)
downloadruby-e986e7123643b91ece134ea47db9935670108ca2.tar.gz
ruby-e986e7123643b91ece134ea47db9935670108ca2.tar.xz
ruby-e986e7123643b91ece134ea47db9935670108ca2.zip
* 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: http://svn.ruby-lang.org/repos/ruby/trunk@4407 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl')
-rw-r--r--ext/openssl/lib/net/protocols.rb11
-rw-r--r--ext/openssl/lib/openssl/buffering.rb13
-rw-r--r--ext/openssl/lib/openssl/ssl.rb53
-rw-r--r--ext/openssl/ossl_ssl.c21
-rw-r--r--ext/openssl/sample/echo_cli.rb5
-rw-r--r--ext/openssl/sample/echo_svr.rb12
6 files changed, 77 insertions, 38 deletions
diff --git a/ext/openssl/lib/net/protocols.rb b/ext/openssl/lib/net/protocols.rb
index 6f646b578..25e940c54 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 6ddec099b..031af4baa 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 39d975b1c..6e6bdfe94 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 3f25a077f..5611f4367 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 87dacaf54..29b356a7a 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 e35ad12a1..be8e10fa2 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