diff options
author | Alexander Pakulov <[email protected]> | 2019-06-24 17:36:31 -0700 |
---|---|---|
committer | Hiroshi SHIBATA <[email protected]> | 2019-07-31 07:47:01 +0800 |
commit | 38daeded66afb4a7beafa47d82625a4eb40c112b () | |
tree | 5ba34b8bacf3fc68657878fc3344808f38bcd3d9 /lib | |
parent | 688ccc96020258acb4c02a2f8c5ff6e5a0bbc966 (diff) |
[rubygems/rubygems] Upgrading S3 source signature to AWS SigV4
https://.com/rubygems/rubygems/commit/f289788ca5
-rw-r--r-- | lib/rubygems/remote_fetcher.rb | 96 |
1 files changed, 78 insertions, 18 deletions
@@ -343,31 +343,71 @@ class Gem::RemoteFetcher protected # we have our own signing code here to avoid a dependency on the aws-sdk gem # fortunately, a simple GET request isn't too complex to sign properly def sign_s3_url(uri, expiration = nil) require 'base64' require 'openssl' - 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', 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=#{id}&Expires=#{expiration}&Signature=#{signature}") - end - - def s3_expiration - (Time.now + 3600).to_i # one hour from now end BASE64_URI_TRANSLATE = { '+' => '%2B', '/' => '%2F', '=' => '%3D' }.freeze private def proxy_for(proxy, uri) Gem::Request.proxy_uri(proxy || Gem::Request.get_proxy_from_env(uri.scheme)) end @@ -379,7 +419,7 @@ class Gem::RemoteFetcher 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 @@ -388,11 +428,31 @@ class Gem::RemoteFetcher 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 |