diff options
author | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-07-25 06:30:07 +0000 |
---|---|---|
committer | nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-07-25 06:30:07 +0000 |
commit | 0a9b952c6f314665af1a58f6f411f752343e9691 (patch) | |
tree | eca0a7253d050794c0f7d851f323ecaa83c49811 /ext/openssl/lib/openssl/ssl.rb | |
parent | 8c30497aaefac8e4b11fd1f564509c75bb6a249b (diff) |
* ext/openssl/lib/openssl.rb: End of transition period introduced by
[ruby-dev:38018]. From the next version of 1.9.3, you should use
require "openssl"
instead of
require "openssl/ssl"
and
require "openssl/x509"
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32664 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl/lib/openssl/ssl.rb')
-rw-r--r-- | ext/openssl/lib/openssl/ssl.rb | 178 |
1 files changed, 177 insertions, 1 deletions
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb index 3f17f5aa29..c70b5b8f6b 100644 --- a/ext/openssl/lib/openssl/ssl.rb +++ b/ext/openssl/lib/openssl/ssl.rb @@ -1 +1,177 @@ -require 'openssl' +=begin += $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL + += Info + 'OpenSSL for Ruby 2' project + Copyright (C) 2001 GOTOU YUUZOU <gotoyuzo@notwork.org> + All rights reserved. + += Licence + This program is licenced under the same licence as Ruby. + (See the file 'LICENCE'.) + += Version + $Id$ +=end + +require "openssl/buffering" +require "fcntl" + +module OpenSSL + module SSL + class SSLContext + DEFAULT_PARAMS = { + :ssl_version => "SSLv23", + :verify_mode => OpenSSL::SSL::VERIFY_PEER, + :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW", + :options => OpenSSL::SSL::OP_ALL, + } + + DEFAULT_CERT_STORE = OpenSSL::X509::Store.new + DEFAULT_CERT_STORE.set_default_paths + if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL) + DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL + end + + def set_params(params={}) + params = DEFAULT_PARAMS.merge(params) + params.each{|name, value| self.__send__("#{name}=", value) } + if self.verify_mode != OpenSSL::SSL::VERIFY_NONE + unless self.ca_file or self.ca_path or self.cert_store + self.cert_store = DEFAULT_CERT_STORE + end + end + return params + end + end + + module SocketForwarder + def addr + to_io.addr + end + + def peeraddr + to_io.peeraddr + end + + def setsockopt(level, optname, optval) + to_io.setsockopt(level, optname, optval) + end + + def getsockopt(level, optname) + to_io.getsockopt(level, optname) + end + + def fcntl(*args) + to_io.fcntl(*args) + end + + def closed? + to_io.closed? + end + + def do_not_reverse_lookup=(flag) + to_io.do_not_reverse_lookup = flag + end + end + + module Nonblock + def initialize(*args) + flag = File::NONBLOCK + flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL) + @io.fcntl(Fcntl::F_SETFL, flag) + super + end + end + + def verify_certificate_identity(cert, hostname) + should_verify_common_name = true + cert.extensions.each{|ext| + next if ext.oid != "subjectAltName" + ext.value.split(/,\s+/).each{|general_name| + if /\ADNS:(.*)/ =~ general_name + should_verify_common_name = false + reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+") + return true if /\A#{reg}\z/i =~ hostname + elsif /\AIP Address:(.*)/ =~ general_name + should_verify_common_name = false + return true if $1 == hostname + end + } + } + if should_verify_common_name + cert.subject.to_a.each{|oid, value| + if oid == "CN" + reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") + return true if /\A#{reg}\z/i =~ hostname + end + } + end + return false + end + module_function :verify_certificate_identity + + class SSLSocket + include Buffering + include SocketForwarder + include Nonblock + + def post_connection_check(hostname) + unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) + raise SSLError, "hostname does not match the server certificate" + end + return true + end + + def session + SSL::Session.new(self) + rescue SSL::Session::SessionError + nil + end + end + + class SSLServer + include SocketForwarder + attr_accessor :start_immediately + + def initialize(svr, ctx) + @svr = svr + @ctx = ctx + unless ctx.session_id_context + session_id = OpenSSL::Digest::MD5.hexdigest($0) + @ctx.session_id_context = session_id + end + @start_immediately = true + end + + def to_io + @svr + end + + def listen(backlog=5) + @svr.listen(backlog) + end + + def shutdown(how=Socket::SHUT_RDWR) + @svr.shutdown(how) + end + + def accept + sock = @svr.accept + begin + ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) + ssl.sync_close = true + ssl.accept if @start_immediately + ssl + rescue SSLError => ex + sock.close + raise ex + end + end + + def close + @svr.close + end + end + end +end |