diff options
Diffstat (limited to 'lib/rubygems/remote_fetcher.rb')
-rw-r--r-- | lib/rubygems/remote_fetcher.rb | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/lib/rubygems/remote_fetcher.rb b/lib/rubygems/remote_fetcher.rb index a829268f39..940523f246 100644 --- a/lib/rubygems/remote_fetcher.rb +++ b/lib/rubygems/remote_fetcher.rb @@ -384,17 +384,15 @@ class Gem::RemoteFetcher require 'base64' require 'openssl' - unless uri.user && uri.password - raise FetchError.new("credentials needed in s3 source, like s3://key:secret@bucket-name/", uri.to_s) - end + id, secret = s3_source_auth uri expiration ||= s3_expiration canonical_path = "/#{uri.host}#{uri.path}" payload = "GET\n\n\n#{expiration}\n#{canonical_path}" - digest = OpenSSL::HMAC.digest('sha1', uri.password, payload) + digest = OpenSSL::HMAC.digest('sha1', secret, payload) # URI.escape is deprecated, and there isn't yet a replacement that does quite what we want signature = Base64.encode64(digest).gsub("\n", '').gsub(/[\+\/=]/) { |c| BASE64_URI_TRANSLATE[c] } - URI.parse("https://#{uri.host}.s3.amazonaws.com#{uri.path}?AWSAccessKeyId=#{uri.user}&Expires=#{expiration}&Signature=#{signature}") + URI.parse("https://#{uri.host}.s3.amazonaws.com#{uri.path}?AWSAccessKeyId=#{id}&Expires=#{expiration}&Signature=#{signature}") end def s3_expiration @@ -414,4 +412,21 @@ class Gem::RemoteFetcher @pools[proxy] ||= Gem::Request::ConnectionPools.new proxy, @cert_files end end + + def s3_source_auth(uri) + return [uri.user, uri.password] if uri.user && uri.password + + s3_source = Gem.configuration[:s3_source] || Gem.configuration['s3_source'] + host = uri.host + raise FetchError.new("no s3_source key exists in .gemrc", "s3://#{host}") unless s3_source + + auth = s3_source[host] || s3_source[host.to_sym] + raise FetchError.new("no key for host #{host} in s3_source in .gemrc", "s3://#{host}") unless auth + + id = auth[:id] || auth['id'] + secret = auth[:secret] || auth['secret'] + raise FetchError.new("s3_source for #{host} missing id or secret", "s3://#{host}") unless id and secret + + [id, secret] + end end |