mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/openssl: avoid cyclic require.
* ext/openssl/lib/openssl/ssl-internal.rb: renamed from ssl.rb * ext/openssl/lib/openssl/x509-internal.rb: renamed from x509.rb. * lib/net/imap.rb: require openssl, instead of openssl/ssl. * lib/net/pop.rb: require openssl, instead of openssl/ssl. [ruby-dev:38018] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22378 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
47d55a02a3
commit
e14c9923b4
8 changed files with 197 additions and 183 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
Wed Feb 18 01:05:05 2009 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* ext/openssl: avoid cyclic require.
|
||||
|
||||
* ext/openssl/lib/openssl/ssl-internal.rb: renamed from ssl.rb
|
||||
|
||||
* ext/openssl/lib/openssl/x509-internal.rb: renamed from x509.rb.
|
||||
|
||||
* lib/net/imap.rb: require openssl, instead of openssl/ssl.
|
||||
|
||||
* lib/net/pop.rb: require openssl, instead of openssl/ssl.
|
||||
|
||||
[ruby-dev:38018]
|
||||
|
||||
Wed Feb 18 00:55:47 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* ext/etc/etc.c (Etc::Passwd.each, Etc::Group.each): new methods.
|
||||
|
|
|
@ -19,6 +19,6 @@ require 'openssl.so'
|
|||
require 'openssl/bn'
|
||||
require 'openssl/cipher'
|
||||
require 'openssl/digest'
|
||||
require 'openssl/ssl'
|
||||
require 'openssl/x509'
|
||||
require 'openssl/ssl-internal'
|
||||
require 'openssl/x509-internal'
|
||||
|
||||
|
|
178
ext/openssl/lib/openssl/ssl-internal.rb
Normal file
178
ext/openssl/lib/openssl/ssl-internal.rb
Normal file
|
@ -0,0 +1,178 @@
|
|||
=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"
|
||||
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 was not match with 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
|
|
@ -1,178 +1 @@
|
|||
=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"
|
||||
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 was not match with 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
|
||||
require 'openssl'
|
||||
|
|
|
@ -233,7 +233,6 @@ ossl_digest_block_length(VALUE self)
|
|||
void
|
||||
Init_ossl_digest()
|
||||
{
|
||||
rb_require("openssl");
|
||||
rb_require("digest");
|
||||
|
||||
#if 0 /* let rdoc know about mOSSL */
|
||||
|
|
|
@ -18,7 +18,7 @@ require "monitor"
|
|||
require "digest/md5"
|
||||
require "strscan"
|
||||
begin
|
||||
require "openssl/ssl"
|
||||
require "openssl"
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ require 'digest/md5'
|
|||
require 'timeout'
|
||||
|
||||
begin
|
||||
require "openssl/ssl"
|
||||
require "openssl"
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue