diff options
author | gotoyuzo <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-08-19 06:00:36 +0000 |
---|---|---|
committer | gotoyuzo <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-08-19 06:00:36 +0000 |
commit | 65652ecdb5145fae92e3c86611a4425a476da6ec (patch) | |
tree | eedc2d207ffde1876c9d7271f8492741ee065584 /lib/webrick/https.rb | |
parent | 90e010abb9efeaaf706c363af31beedf65c8be3b (diff) | |
download | ruby-65652ecdb5145fae92e3c86611a4425a476da6ec.tar.gz |
* lib/webrick/ssl.rb: new file; SSL/TLS enhancement for GenericServer.
* lib/webrick/https.rb: SSLSocket handling is moved to webrick/ssl.rb.
* lib/webrick/compat.rb (File::fnmatch): remove old migration code.
* lib/webrick/httpserver.rb (HTTPServer#run): ditto.
* lib/webrick/server.rb (GenericServer#listen): the body of this
method is pull out as Utils::create_lisnteners.
* lib/webrick/utils.rb (Utils::create_lisnteners): new method.
* lib/webrick/server.rb (GenericServer#start): should not
through unknown errors. and refine comments.
* ext/openssl/lib/openssl/ssl.rb (SSLServer#accept): should close
socket if SSLSocket raises error.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4409 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/webrick/https.rb')
-rw-r--r-- | lib/webrick/https.rb | 127 |
1 files changed, 11 insertions, 116 deletions
diff --git a/lib/webrick/https.rb b/lib/webrick/https.rb index fa8c667d2a..4e44cfab32 100644 --- a/lib/webrick/https.rb +++ b/lib/webrick/https.rb @@ -8,31 +8,11 @@ # # $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $ -require 'webrick' -require 'openssl' +require 'webrick/ssl' module WEBrick module Config - HTTP.update( - :SSLEnable => true, - :SSLCertificate => nil, - :SSLPrivateKey => nil, - :SSLClientCA => nil, - :SSLCACertificateFile => nil, - :SSLCACertificatePath => nil, - :SSLCertificateStore => nil, - :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE, - :SSLVerifyDepth => nil, - :SSLVerifyCallback => nil, # custom verification - :SSLTimeout => nil, - :SSLOptions => nil, - # Must specify if you use auto generated certificate. - :SSLCertName => nil, - :SSLCertComment => "Generated by Ruby/OpenSSL" - ) - - osslv = ::OpenSSL::OPENSSL_VERSION.split[1] - HTTP[:ServerSoftware] << " OpenSSL/#{osslv}" + HTTP.update(SSL) end class HTTPRequest @@ -41,16 +21,18 @@ module WEBrick alias orig_parse parse def parse(socket=nil) + if socket && socket.is_a?(OpenSSL::SSL::SSLSocket) + @server_cert = @config[:SSLCertificate] + @client_cert = socket.peer_cert + @cipher = socket.cipher + end orig_parse(socket) - @cipher = socket.respond_to?(:cipher) ? socket.cipher : nil - @client_cert = socket.respond_to?(:peer_cert) ? socket.peer_cert : nil - @server_cert = @config[:SSLCertificate] end alias orig_parse_uri parse_uri def parse_uri(str, scheme="https") - if @config[:SSLEnable] + if @server_cert return orig_parse_uri(str, scheme) end return orig_parse_uri(str) @@ -60,100 +42,13 @@ module WEBrick def meta_vars meta = orig_meta_vars - if @config[:SSLEnable] + if @server_cert meta["HTTPS"] = "on" - meta["SSL_CIPHER"] = @cipher ? @cipher[0] : "" + meta["SSL_SERVER_CERT"] = @server_cert.to_pem meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : "" - meta["SSL_SERVER_CERT"] = @server_cert ? @server_cert.to_pem : "" + meta["SSL_CIPHER"] = @cipher[0] end meta end end - - class HTTPServer - alias orig_init initialize - - def initialize(*args) - orig_init(*args) - - if @config[:SSLEnable] - unless @config[:SSLCertificate] - rsa = OpenSSL::PKey::RSA.new(512){|p, n| - case p - when 0; $stderr.putc "." # BN_generate_prime - when 1; $stderr.putc "+" # BN_generate_prime - when 2; $stderr.putc "*" # searching good prime, - # n = #of try, - # but also data from BN_generate_prime - when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q, - # but also data from BN_generate_prime - else; $stderr.putc "*" # BN_generate_prime - end - } - cert = OpenSSL::X509::Certificate.new - cert.version = 3 - cert.serial = 0 - name = OpenSSL::X509::Name.new(@config[:SSLCertName]) - cert.subject = name - cert.issuer = name - cert.not_before = Time.now - cert.not_after = Time.now + (365*24*60*60) - cert.public_key = rsa.public_key - - ef = OpenSSL::X509::ExtensionFactory.new(nil,cert) - cert.extensions = [ - ef.create_extension("basicConstraints","CA:FALSE"), - ef.create_extension("subjectKeyIdentifier", "hash"), - ef.create_extension("extendedKeyUsage", "serverAuth") - ] - ef.issuer_certificate = cert - ext = ef.create_extension("authorityKeyIdentifier", - "keyid:always,issuer:always") - cert.add_extension(ext) - if comment = @config[:SSLCertComment] - cert.add_extension(ef.create_extension("nsComment", comment)) - end - cert.sign(rsa, OpenSSL::Digest::SHA1.new) - - @config[:SSLPrivateKey] = rsa - @config[:SSLCertificate] = cert - @logger.info cert.to_s - end - @ctx = OpenSSL::SSL::SSLContext.new - set_ssl_context(@ctx, @config) - end - end - - alias orig_run run - - def run(sock) - if @config[:SSLEnable] - ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) - ssl.sync = true - ssl.accept - Thread.current[:WEBrickSocket] = ssl - orig_run(ssl) - Thread.current[:WEBrickSocket] = sock - ssl.close - else - orig_run(sock) - end - end - - private - - def set_ssl_context(ctx, config) - ctx.key = config[:SSLPrivateKey] - ctx.cert = config[:SSLCertificate] - ctx.client_ca = config[:SSLClientCA] - ctx.ca_file = config[:SSLCACertificateFile] - ctx.ca_path = config[:SSLCACertificatePath] - ctx.cert_store = config[:SSLCertificateStore] - ctx.verify_mode = config[:SSLVerifyClient] - ctx.verify_depth = config[:SSLVerifyDepth] - ctx.verify_callback = config[:SSLVerifyCallback] - ctx.timeout = config[:SSLTimeout] - ctx.options = config[:SSLOptions] - end - end end |