aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rubygems/remote_fetcher.rb
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-19 23:07:48 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-19 23:07:48 +0000
commit064bf602e0f42a925f470c219962e3a430bc5ca8 (patch)
tree908b5285fcb003da1dafd069cb6f174d203c9205 /lib/rubygems/remote_fetcher.rb
parent83ed985182c5bbaba2c2a3c32bf1a4ecb6c0edde (diff)
downloadruby-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.rb48
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