diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-19 23:07:48 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-19 23:07:48 +0000 |
commit | 064bf602e0f42a925f470c219962e3a430bc5ca8 (patch) | |
tree | 908b5285fcb003da1dafd069cb6f174d203c9205 /lib/rubygems/remote_fetcher.rb | |
parent | 83ed985182c5bbaba2c2a3c32bf1a4ecb6c0edde (diff) | |
download | ruby-064bf602e0f42a925f470c219962e3a430bc5ca8.tar.gz |
* lib/rubygems: Update to RubyGems 1.8.23 which contains security
fixes:
RubyGems now disallows redirection from HTTPS to HTTP.
RubyGems now verifies SSL connections.
See https://github.com/rubygems/rubygems/blob/1.8/History.txt for
changes since 1.8.22.
* test/rubygems: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35404 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/rubygems/remote_fetcher.rb')
-rw-r--r-- | lib/rubygems/remote_fetcher.rb | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb index 9363052052..6650711235 100644 --- a/lib/rubygems/remote_fetcher.rb +++ b/lib/rubygems/remote_fetcher.rb @@ -8,6 +8,8 @@ require 'uri' class Gem::RemoteFetcher + BuiltinSSLCerts = File.expand_path("./ssl_certs/*.pem", File.dirname(__FILE__)) + include Gem::UserInteraction ## @@ -210,6 +212,11 @@ class Gem::RemoteFetcher raise FetchError.new('too many redirects', uri) if depth > 10 location = URI.parse response['Location'] + + if https?(uri) && !https?(location) + raise FetchError.new("redirecting to non-https resource: #{location}", uri) + end + fetch_http(location, last_modified, head, depth + 1) else raise FetchError.new("bad response #{response.message} #{response.code}", uri) @@ -312,19 +319,46 @@ class Gem::RemoteFetcher @connections[connection_id] ||= Net::HTTP.new(*net_http_args) connection = @connections[connection_id] - if uri.scheme == 'https' and not connection.started? then - require 'net/https' - connection.use_ssl = true - connection.verify_mode = OpenSSL::SSL::VERIFY_NONE + if https?(uri) and !connection.started? then + configure_connection_for_https(connection) end connection.start unless connection.started? connection - rescue Errno::EHOSTDOWN => e + rescue OpenSSL::SSL::SSLError, Errno::EHOSTDOWN => e raise FetchError.new(e.message, uri) end + def configure_connection_for_https(connection) + require 'net/https' + + connection.use_ssl = true + connection.verify_mode = + Gem.configuration.ssl_verify_mode || OpenSSL::SSL::VERIFY_PEER + + store = OpenSSL::X509::Store.new + + if Gem.configuration.ssl_ca_cert + if File.directory? Gem.configuration.ssl_ca_cert + store.add_path Gem.configuration.ssl_ca_cert + else + store.add_file Gem.configuration.ssl_ca_cert + end + else + store.set_default_paths + add_rubygems_trusted_certs(store) + end + + connection.cert_store = store + end + + def add_rubygems_trusted_certs(store) + Dir.glob(BuiltinSSLCerts).each do |ssl_cert_file| + store.add_file ssl_cert_file + end + end + def correct_for_windows_path(path) if path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':' path = path[1..-1] @@ -465,5 +499,9 @@ class Gem::RemoteFetcher ua end + def https?(uri) + uri.scheme.downcase == 'https' + end + end |