aws-sdk-core 3.126.0 → 3.127.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/VERSION +1 -1
- data/lib/aws-sdk-core/assume_role_credentials.rb +18 -0
- data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +5 -0
- data/lib/aws-sdk-core/ec2_metadata.rb +3 -2
- data/lib/aws-sdk-core/ecs_credentials.rb +4 -0
- data/lib/aws-sdk-core/instance_profile_credentials.rb +27 -8
- data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +340 -0
- data/lib/aws-sdk-core/plugins/http_checksum.rb +8 -1
- data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +1 -1
- data/lib/aws-sdk-core/plugins/signature_v4.rb +1 -1
- data/lib/aws-sdk-core/refreshing_credentials.rb +13 -2
- data/lib/aws-sdk-core/shared_config.rb +1 -6
- data/lib/aws-sdk-core/sso_credentials.rb +5 -0
- data/lib/aws-sdk-sso/client.rb +3 -1
- data/lib/aws-sdk-sso.rb +1 -1
- data/lib/aws-sdk-sts/client.rb +3 -1
- data/lib/aws-sdk-sts.rb +1 -1
- data/lib/seahorse/model/operation.rb +3 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 918c0204898bdad127acf619312dbce114cb19cc5c33e072548ac948c85c34a8
|
4
|
+
data.tar.gz: 79b434c6e925efbf6c8921a915aa20171a702cfd89bfd9caee27739017a46978
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51b4885b28f643ae32d0765fd5ca08f565cd60235c4d21e2b432710353afd1d25c957c7e0fd462c489263272f809b2dedbd4803eaa7b26266738bee764b5c2e4
|
7
|
+
data.tar.gz: dc8671e28caf0a7dcf0cef57ef25e35a8b6ed846d428e8c80aec1c6cb14b9b24e62705e231d497c917254202a4588ea8379b451457a2c6e2f292a66edf1df0cd
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
Unreleased Changes
|
2
2
|
------------------
|
3
3
|
|
4
|
+
3.127.0 (2022-02-24)
|
5
|
+
------------------
|
6
|
+
|
7
|
+
* Feature - Updated Aws::STS::Client with the latest API changes.
|
8
|
+
|
9
|
+
* Feature - Updated Aws::SSO::Client with the latest API changes.
|
10
|
+
|
11
|
+
* Feature - Support `HttpChecksum` trait for requests and responses.
|
12
|
+
|
13
|
+
3.126.2 (2022-02-16)
|
14
|
+
------------------
|
15
|
+
|
16
|
+
* Issue - Add a before_refresh callback to AssumeRoleCredentials (#2529).
|
17
|
+
* Issue - Raise a `NoSuchProfileError` when config and credentials files don't exist.
|
18
|
+
|
19
|
+
3.126.1 (2022-02-14)
|
20
|
+
------------------
|
21
|
+
|
22
|
+
* Issue - Set `create_time` on IMDS tokens before fetch to reduce chance of using expired tokens and retry failures due to using expired tokens.
|
23
|
+
|
4
24
|
3.126.0 (2022-02-03)
|
5
25
|
------------------
|
6
26
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.127.0
|
@@ -17,6 +17,11 @@ module Aws
|
|
17
17
|
#
|
18
18
|
# If you omit `:client` option, a new {STS::Client} object will be
|
19
19
|
# constructed.
|
20
|
+
#
|
21
|
+
# The AssumeRoleCredentials also provides a `before_refresh` callback
|
22
|
+
# that can be used to help manage refreshing tokens.
|
23
|
+
# `before_refresh` is called when AWS credentials are required and need
|
24
|
+
# to be refreshed and it is called with the AssumeRoleCredentials object.
|
20
25
|
class AssumeRoleCredentials
|
21
26
|
|
22
27
|
include CredentialProvider
|
@@ -28,6 +33,16 @@ module Aws
|
|
28
33
|
# @option options [Integer] :duration_seconds
|
29
34
|
# @option options [String] :external_id
|
30
35
|
# @option options [STS::Client] :client
|
36
|
+
# @option options [Callable] before_refresh Proc called before
|
37
|
+
# credentials are refreshed. Useful for updating tokens.
|
38
|
+
# `before_refresh` is called when AWS credentials are
|
39
|
+
# required and need to be refreshed. Tokens can be refreshed using
|
40
|
+
# the following example:
|
41
|
+
#
|
42
|
+
# before_refresh = Proc.new do |assume_role_credentials| do
|
43
|
+
# assume_role_credentials.assume_role_params['token_code'] = update_token
|
44
|
+
# end
|
45
|
+
#
|
31
46
|
def initialize(options = {})
|
32
47
|
client_opts = {}
|
33
48
|
@assume_role_params = {}
|
@@ -45,6 +60,9 @@ module Aws
|
|
45
60
|
# @return [STS::Client]
|
46
61
|
attr_reader :client
|
47
62
|
|
63
|
+
# @return [Hash]
|
64
|
+
attr_reader :assume_role_params
|
65
|
+
|
48
66
|
private
|
49
67
|
|
50
68
|
def refresh
|
@@ -39,6 +39,11 @@ module Aws
|
|
39
39
|
# encoded UUID is generated as the session name
|
40
40
|
#
|
41
41
|
# @option options [STS::Client] :client
|
42
|
+
#
|
43
|
+
# @option options [Callable] before_refresh Proc called before
|
44
|
+
# credentials are refreshed. `before_refresh` is called
|
45
|
+
# with an instance of this object when
|
46
|
+
# AWS credentials are required and need to be refreshed.
|
42
47
|
def initialize(options = {})
|
43
48
|
client_opts = {}
|
44
49
|
@assume_role_web_identity_params = {}
|
@@ -136,8 +136,9 @@ module Aws
|
|
136
136
|
|
137
137
|
def fetch_token
|
138
138
|
open_connection do |conn|
|
139
|
+
created_time = Time.now
|
139
140
|
token_value, token_ttl = http_put(conn, @token_ttl)
|
140
|
-
@token = Token.new(value: token_value, ttl: token_ttl)
|
141
|
+
@token = Token.new(value: token_value, ttl: token_ttl, created_time: created_time)
|
141
142
|
end
|
142
143
|
end
|
143
144
|
|
@@ -222,7 +223,7 @@ module Aws
|
|
222
223
|
def initialize(options = {})
|
223
224
|
@ttl = options[:ttl]
|
224
225
|
@value = options[:value]
|
225
|
-
@created_time = Time.now
|
226
|
+
@created_time = options[:created_time] || Time.now
|
226
227
|
end
|
227
228
|
|
228
229
|
# [String] Returns the token value.
|
@@ -43,6 +43,10 @@ module Aws
|
|
43
43
|
# @option options [IO] :http_debug_output (nil) HTTP wire
|
44
44
|
# traces are sent to this object. You can specify something
|
45
45
|
# like $stdout.
|
46
|
+
# @option options [Callable] before_refresh Proc called before
|
47
|
+
# credentials are refreshed. `before_refresh` is called
|
48
|
+
# with an instance of this object when
|
49
|
+
# AWS credentials are required and need to be refreshed.
|
46
50
|
def initialize options = {}
|
47
51
|
@retries = options[:retries] || 5
|
48
52
|
@ip_address = options[:ip_address] || '169.254.170.2'
|
@@ -63,6 +63,10 @@ module Aws
|
|
63
63
|
# @option options [Integer] :token_ttl Time-to-Live in seconds for EC2
|
64
64
|
# Metadata Token used for fetching Metadata Profile Credentials, defaults
|
65
65
|
# to 21600 seconds
|
66
|
+
# @option options [Callable] before_refresh Proc called before
|
67
|
+
# credentials are refreshed. `before_refresh` is called
|
68
|
+
# with an instance of this object when
|
69
|
+
# AWS credentials are required and need to be refreshed.
|
66
70
|
def initialize(options = {})
|
67
71
|
@retries = options[:retries] || 1
|
68
72
|
endpoint_mode = resolve_endpoint_mode(options)
|
@@ -153,10 +157,11 @@ module Aws
|
|
153
157
|
begin
|
154
158
|
retry_errors(NETWORK_ERRORS, max_retries: @retries) do
|
155
159
|
unless token_set?
|
160
|
+
created_time = Time.now
|
156
161
|
token_value, ttl = http_put(
|
157
162
|
conn, METADATA_TOKEN_PATH, @token_ttl
|
158
163
|
)
|
159
|
-
@token = Token.new(token_value, ttl) if token_value && ttl
|
164
|
+
@token = Token.new(token_value, ttl, created_time) if token_value && ttl
|
160
165
|
end
|
161
166
|
end
|
162
167
|
rescue *NETWORK_ERRORS
|
@@ -166,9 +171,17 @@ module Aws
|
|
166
171
|
end
|
167
172
|
|
168
173
|
token = @token.value if token_set?
|
169
|
-
|
170
|
-
|
171
|
-
|
174
|
+
|
175
|
+
begin
|
176
|
+
metadata = http_get(conn, METADATA_PATH_BASE, token)
|
177
|
+
profile_name = metadata.lines.first.strip
|
178
|
+
http_get(conn, METADATA_PATH_BASE + profile_name, token)
|
179
|
+
rescue TokenExpiredError
|
180
|
+
# Token has expired, reset it
|
181
|
+
# The next retry should fetch it
|
182
|
+
@token = nil
|
183
|
+
raise Non200Response
|
184
|
+
end
|
172
185
|
end
|
173
186
|
end
|
174
187
|
rescue
|
@@ -200,9 +213,15 @@ module Aws
|
|
200
213
|
headers = { 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}" }
|
201
214
|
headers['x-aws-ec2-metadata-token'] = token if token
|
202
215
|
response = connection.request(Net::HTTP::Get.new(path, headers))
|
203
|
-
raise Non200Response unless response.code.to_i == 200
|
204
216
|
|
205
|
-
response.
|
217
|
+
case response.code.to_i
|
218
|
+
when 200
|
219
|
+
response.body
|
220
|
+
when 401
|
221
|
+
raise TokenExpiredError
|
222
|
+
else
|
223
|
+
raise Non200Response
|
224
|
+
end
|
206
225
|
end
|
207
226
|
|
208
227
|
# PUT request fetch token with ttl
|
@@ -244,10 +263,10 @@ module Aws
|
|
244
263
|
# @api private
|
245
264
|
# Token used to fetch IMDS profile and credentials
|
246
265
|
class Token
|
247
|
-
def initialize(value, ttl)
|
266
|
+
def initialize(value, ttl, created_time = Time.now)
|
248
267
|
@ttl = ttl
|
249
268
|
@value = value
|
250
|
-
@created_time =
|
269
|
+
@created_time = created_time
|
251
270
|
end
|
252
271
|
|
253
272
|
# [String] token value
|
@@ -0,0 +1,340 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Plugins
|
5
|
+
# @api private
|
6
|
+
class ChecksumAlgorithm < Seahorse::Client::Plugin
|
7
|
+
CHUNK_SIZE = 1 * 1024 * 1024 # one MB
|
8
|
+
|
9
|
+
# determine the set of supported client side checksum algorithms
|
10
|
+
# CRC32c requires aws-crt (optional sdk dependency) for support
|
11
|
+
CLIENT_ALGORITHMS = begin
|
12
|
+
supported = %w[SHA256 SHA1 CRC32]
|
13
|
+
begin
|
14
|
+
require 'aws-crt'
|
15
|
+
supported << 'CRC32C'
|
16
|
+
rescue LoadError
|
17
|
+
end
|
18
|
+
supported
|
19
|
+
end.freeze
|
20
|
+
|
21
|
+
# priority order of checksum algorithms to validate responses against
|
22
|
+
# Remove any algorithms not supported by client (ie, depending on CRT availability)
|
23
|
+
CHECKSUM_ALGORITHM_PRIORITIES = %w[CRC32C SHA1 CRC32 SHA256] & CLIENT_ALGORITHMS
|
24
|
+
|
25
|
+
# byte size of checksums, used in computing the trailer length
|
26
|
+
CHECKSUM_SIZE = {
|
27
|
+
'CRC32' => 16,
|
28
|
+
'CRC32C' => 16,
|
29
|
+
'SHA1' => 36,
|
30
|
+
'SHA256' => 52
|
31
|
+
}
|
32
|
+
|
33
|
+
# Interface for computing digests on request/response bodies
|
34
|
+
# which may be files, strings or IO like objects
|
35
|
+
# Applies only to digest functions that produce 32 bit integer checksums
|
36
|
+
# (eg CRC32)
|
37
|
+
class Digest32
|
38
|
+
|
39
|
+
attr_reader :value
|
40
|
+
|
41
|
+
# @param [Object] digest_fn
|
42
|
+
def initialize(digest_fn)
|
43
|
+
@digest_fn = digest_fn
|
44
|
+
@value = 0
|
45
|
+
end
|
46
|
+
|
47
|
+
def update(chunk)
|
48
|
+
@value = @digest_fn.call(chunk, @value)
|
49
|
+
end
|
50
|
+
|
51
|
+
def base64digest
|
52
|
+
Base64.encode64([@value].pack('N')).chomp
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_handlers(handlers, _config)
|
57
|
+
handlers.add(OptionHandler, step: :initialize)
|
58
|
+
# priority set low to ensure checksum is computed AFTER the request is
|
59
|
+
# built but before it is signed
|
60
|
+
handlers.add(ChecksumHandler, priority: 15, step: :build)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def self.request_algorithm_selection(context)
|
66
|
+
return unless context.operation.http_checksum
|
67
|
+
|
68
|
+
input_member = context.operation.http_checksum['requestAlgorithmMember']
|
69
|
+
context.params[input_member.to_sym]&.upcase if input_member
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.request_validation_mode(context)
|
73
|
+
return unless context.operation.http_checksum
|
74
|
+
|
75
|
+
input_member = context.operation.http_checksum['requestValidationModeMember']
|
76
|
+
context.params[input_member.to_sym] if input_member
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.operation_response_algorithms(context)
|
80
|
+
return unless context.operation.http_checksum
|
81
|
+
|
82
|
+
context.operation.http_checksum['responseAlgorithms']
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
# @api private
|
87
|
+
class OptionHandler < Seahorse::Client::Handler
|
88
|
+
def call(context)
|
89
|
+
context[:http_checksum] ||= {}
|
90
|
+
|
91
|
+
# validate request configuration
|
92
|
+
if (request_input = ChecksumAlgorithm.request_algorithm_selection(context))
|
93
|
+
unless CLIENT_ALGORITHMS.include? request_input
|
94
|
+
if (request_input == 'CRC32C')
|
95
|
+
raise ArgumentError, "CRC32C requires crt support - install the aws-crt gem for support."
|
96
|
+
else
|
97
|
+
raise ArgumentError, "#{request_input} is not a supported checksum algorithm."
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# validate response configuration
|
103
|
+
if (ChecksumAlgorithm.request_validation_mode(context))
|
104
|
+
# Compute an ordered list as the union between priority supported and the
|
105
|
+
# operation's modeled response algorithms.
|
106
|
+
validation_list = CHECKSUM_ALGORITHM_PRIORITIES &
|
107
|
+
ChecksumAlgorithm.operation_response_algorithms(context)
|
108
|
+
context[:http_checksum][:validation_list] = validation_list
|
109
|
+
end
|
110
|
+
|
111
|
+
@handler.call(context)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# @api private
|
116
|
+
class ChecksumHandler < Seahorse::Client::Handler
|
117
|
+
|
118
|
+
def call(context)
|
119
|
+
if should_calculate_request_checksum?(context)
|
120
|
+
request_algorithm_input = ChecksumAlgorithm.request_algorithm_selection(context)
|
121
|
+
context[:checksum_algorithms] = request_algorithm_input
|
122
|
+
|
123
|
+
request_checksum_property = {
|
124
|
+
'algorithm' => request_algorithm_input,
|
125
|
+
'in' => checksum_request_in(context),
|
126
|
+
'name' => "x-amz-checksum-#{request_algorithm_input.downcase}"
|
127
|
+
}
|
128
|
+
|
129
|
+
calculate_request_checksum(context, request_checksum_property)
|
130
|
+
end
|
131
|
+
|
132
|
+
if should_verify_response_checksum?(context)
|
133
|
+
add_verify_response_checksum_handlers(context)
|
134
|
+
end
|
135
|
+
|
136
|
+
@handler.call(context)
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def should_calculate_request_checksum?(context)
|
142
|
+
context.operation.http_checksum &&
|
143
|
+
ChecksumAlgorithm.request_algorithm_selection(context)
|
144
|
+
end
|
145
|
+
|
146
|
+
def should_verify_response_checksum?(context)
|
147
|
+
context[:http_checksum][:validation_list] && !context[:http_checksum][:validation_list].empty?
|
148
|
+
end
|
149
|
+
|
150
|
+
def calculate_request_checksum(context, checksum_properties)
|
151
|
+
case checksum_properties['in']
|
152
|
+
when 'header'
|
153
|
+
header_name = checksum_properties['name']
|
154
|
+
body = context.http_request.body_contents
|
155
|
+
if body
|
156
|
+
context.http_request.headers[header_name] ||=
|
157
|
+
ChecksumAlgorithm.calculate_checksum(checksum_properties['algorithm'], body)
|
158
|
+
end
|
159
|
+
when 'trailer'
|
160
|
+
apply_request_trailer_checksum(context, checksum_properties)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def apply_request_trailer_checksum(context, checksum_properties)
|
165
|
+
location_name = checksum_properties['name']
|
166
|
+
|
167
|
+
# set required headers
|
168
|
+
headers = context.http_request.headers
|
169
|
+
headers['Content-Encoding'] = 'aws-chunked'
|
170
|
+
headers['X-Amz-Content-Sha256'] = 'STREAMING-UNSIGNED-PAYLOAD-TRAILER'
|
171
|
+
headers['X-Amz-Trailer'] = location_name
|
172
|
+
|
173
|
+
# We currently always compute the size in the modified body wrapper - allowing us
|
174
|
+
# to set the Content-Length header (set by content_length plugin).
|
175
|
+
# This means we cannot use Transfer-Encoding=chunked
|
176
|
+
|
177
|
+
if !context.http_request.body.respond_to?(:size)
|
178
|
+
raise Aws::Errors::ChecksumError, 'Could not determine length of the body'
|
179
|
+
end
|
180
|
+
headers['X-Amz-Decoded-Content-Length'] = context.http_request.body.size
|
181
|
+
|
182
|
+
context.http_request.body = AwsChunkedTrailerDigestIO.new(
|
183
|
+
context.http_request.body,
|
184
|
+
checksum_properties['algorithm'],
|
185
|
+
location_name
|
186
|
+
)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Add events to the http_response to verify the checksum as its read
|
190
|
+
# This prevents the body from being read multiple times
|
191
|
+
# verification is done only once a successful response has completed
|
192
|
+
def add_verify_response_checksum_handlers(context)
|
193
|
+
http_response = context.http_response
|
194
|
+
checksum_context = { }
|
195
|
+
http_response.on_headers do |_status, headers|
|
196
|
+
header_name, algorithm = response_header_to_verify(headers, context[:http_checksum][:validation_list])
|
197
|
+
if header_name
|
198
|
+
expected = headers[header_name]
|
199
|
+
|
200
|
+
unless context[:http_checksum][:skip_on_suffix] && /-[\d]+$/.match(expected)
|
201
|
+
checksum_context[:algorithm] = algorithm
|
202
|
+
checksum_context[:header_name] = header_name
|
203
|
+
checksum_context[:digest] = ChecksumAlgorithm.digest_for_algorithm(algorithm)
|
204
|
+
checksum_context[:expected] = expected
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
http_response.on_data do |chunk|
|
210
|
+
checksum_context[:digest].update(chunk) if checksum_context[:digest]
|
211
|
+
end
|
212
|
+
|
213
|
+
http_response.on_success do
|
214
|
+
if checksum_context[:digest] &&
|
215
|
+
(computed = checksum_context[:digest].base64digest)
|
216
|
+
|
217
|
+
if computed != checksum_context[:expected]
|
218
|
+
raise Aws::Errors::ChecksumError,
|
219
|
+
"Checksum validation failed on #{checksum_context[:header_name]} "\
|
220
|
+
"computed: #{computed}, expected: #{checksum_context[:expected]}"
|
221
|
+
end
|
222
|
+
|
223
|
+
context[:http_checksum][:validated] = checksum_context[:algorithm]
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# returns nil if no headers to verify
|
229
|
+
def response_header_to_verify(headers, validation_list)
|
230
|
+
validation_list.each do |algorithm|
|
231
|
+
header_name = "x-amz-checksum-#{algorithm}"
|
232
|
+
return [header_name, algorithm] if headers[header_name]
|
233
|
+
end
|
234
|
+
nil
|
235
|
+
end
|
236
|
+
|
237
|
+
# determine where (header vs trailer) a request checksum should be added
|
238
|
+
def checksum_request_in(context)
|
239
|
+
if context.operation['authtype'].eql?('v4-unsigned-body')
|
240
|
+
'trailer'
|
241
|
+
else
|
242
|
+
'header'
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
def self.calculate_checksum(algorithm, body)
|
249
|
+
digest = ChecksumAlgorithm.digest_for_algorithm(algorithm)
|
250
|
+
if body.respond_to?(:read)
|
251
|
+
ChecksumAlgorithm.update_in_chunks(digest, body)
|
252
|
+
else
|
253
|
+
digest.update(body)
|
254
|
+
end
|
255
|
+
digest.base64digest
|
256
|
+
end
|
257
|
+
|
258
|
+
def self.digest_for_algorithm(algorithm)
|
259
|
+
case algorithm
|
260
|
+
when 'CRC32'
|
261
|
+
Digest32.new(Zlib.method(:crc32))
|
262
|
+
when 'CRC32C'
|
263
|
+
# this will only be used if input algorithm is CRC32C AND client supports it (crt available)
|
264
|
+
Digest32.new(Aws::Crt::Checksums.method(:crc32c))
|
265
|
+
when 'SHA1'
|
266
|
+
Digest::SHA1.new
|
267
|
+
when 'SHA256'
|
268
|
+
Digest::SHA256.new
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# The trailer size (in bytes) is the overhead + the trailer name +
|
273
|
+
# the length of the base64 encoded checksum
|
274
|
+
def self.trailer_length(algorithm, location_name)
|
275
|
+
CHECKSUM_SIZE[algorithm] + location_name.size
|
276
|
+
end
|
277
|
+
|
278
|
+
def self.update_in_chunks(digest, io)
|
279
|
+
loop do
|
280
|
+
chunk = io.read(CHUNK_SIZE)
|
281
|
+
break unless chunk
|
282
|
+
digest.update(chunk)
|
283
|
+
end
|
284
|
+
io.rewind
|
285
|
+
end
|
286
|
+
|
287
|
+
# Wrapper for request body that implements application-layer
|
288
|
+
# chunking with Digest computed on chunks + added as a trailer
|
289
|
+
class AwsChunkedTrailerDigestIO
|
290
|
+
CHUNK_SIZE = 16384
|
291
|
+
|
292
|
+
def initialize(io, algorithm, location_name)
|
293
|
+
@io = io
|
294
|
+
@location_name = location_name
|
295
|
+
@algorithm = algorithm
|
296
|
+
@digest = ChecksumAlgorithm.digest_for_algorithm(algorithm)
|
297
|
+
@trailer_io = nil
|
298
|
+
end
|
299
|
+
|
300
|
+
# the size of the application layer aws-chunked + trailer body
|
301
|
+
def size
|
302
|
+
# compute the number of chunks
|
303
|
+
# a full chunk has 4 + 4 bytes overhead, a partial chunk is len.to_s(16).size + 4
|
304
|
+
orig_body_size = @io.size
|
305
|
+
n_full_chunks = orig_body_size / CHUNK_SIZE
|
306
|
+
partial_bytes = orig_body_size % CHUNK_SIZE
|
307
|
+
chunked_body_size = n_full_chunks * (CHUNK_SIZE + 8)
|
308
|
+
chunked_body_size += partial_bytes.to_s(16).size + partial_bytes + 4 unless partial_bytes.zero?
|
309
|
+
trailer_size = ChecksumAlgorithm.trailer_length(@algorithm, @location_name)
|
310
|
+
chunked_body_size + trailer_size
|
311
|
+
end
|
312
|
+
|
313
|
+
def rewind
|
314
|
+
@io.rewind
|
315
|
+
end
|
316
|
+
|
317
|
+
def read(length, buf)
|
318
|
+
# account for possible leftover bytes at the end, if we have trailer bytes, send them
|
319
|
+
if @trailer_io
|
320
|
+
return @trailer_io.read(length, buf)
|
321
|
+
end
|
322
|
+
|
323
|
+
chunk = @io.read(length)
|
324
|
+
if chunk
|
325
|
+
@digest.update(chunk)
|
326
|
+
application_chunked = "#{chunk.bytesize.to_s(16)}\r\n#{chunk}\r\n"
|
327
|
+
return StringIO.new(application_chunked).read(application_chunked.size, buf)
|
328
|
+
else
|
329
|
+
trailers = {}
|
330
|
+
trailers[@location_name] = @digest.base64digest
|
331
|
+
trailers = trailers.map { |k,v| "#{k}:#{v}"}.join("\r\n")
|
332
|
+
@trailer_io = StringIO.new("0\r\n#{trailers}\r\n\r\n")
|
333
|
+
chunk = @trailer_io.read(length, buf)
|
334
|
+
end
|
335
|
+
chunk
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
@@ -11,7 +11,8 @@ module Aws
|
|
11
11
|
CHUNK_SIZE = 1 * 1024 * 1024 # one MB
|
12
12
|
|
13
13
|
def call(context)
|
14
|
-
if context
|
14
|
+
if checksum_required?(context) &&
|
15
|
+
!context[:checksum_algorithms] # skip in favor of flexible checksum
|
15
16
|
body = context.http_request.body
|
16
17
|
context.http_request.headers['Content-Md5'] ||= md5(body)
|
17
18
|
end
|
@@ -20,6 +21,12 @@ module Aws
|
|
20
21
|
|
21
22
|
private
|
22
23
|
|
24
|
+
def checksum_required?(context)
|
25
|
+
context.operation.http_checksum_required ||
|
26
|
+
(context.operation.http_checksum &&
|
27
|
+
context.operation.http_checksum['requestChecksumRequired'])
|
28
|
+
end
|
29
|
+
|
23
30
|
# @param [File, Tempfile, IO#read, String] value
|
24
31
|
# @return [String<MD5>]
|
25
32
|
def md5(value)
|
@@ -134,7 +134,7 @@ module Aws
|
|
134
134
|
def apply_authtype(context)
|
135
135
|
if context.operation['authtype'].eql?('v4-unsigned-body') &&
|
136
136
|
context.http_request.endpoint.scheme.eql?('https')
|
137
|
-
context.http_request.headers['X-Amz-Content-Sha256']
|
137
|
+
context.http_request.headers['X-Amz-Content-Sha256'] ||= 'UNSIGNED-PAYLOAD'
|
138
138
|
end
|
139
139
|
context
|
140
140
|
end
|
@@ -19,6 +19,9 @@ module Aws
|
|
19
19
|
|
20
20
|
def initialize(options = {})
|
21
21
|
@mutex = Mutex.new
|
22
|
+
@before_refresh = options.delete(:before_refresh) if Hash === options
|
23
|
+
|
24
|
+
@before_refresh.call(self) if @before_refresh
|
22
25
|
refresh
|
23
26
|
end
|
24
27
|
|
@@ -37,7 +40,11 @@ module Aws
|
|
37
40
|
# Refresh credentials.
|
38
41
|
# @return [void]
|
39
42
|
def refresh!
|
40
|
-
@mutex.synchronize
|
43
|
+
@mutex.synchronize do
|
44
|
+
@before_refresh.call(self) if @before_refresh
|
45
|
+
|
46
|
+
refresh
|
47
|
+
end
|
41
48
|
end
|
42
49
|
|
43
50
|
private
|
@@ -47,7 +54,11 @@ module Aws
|
|
47
54
|
def refresh_if_near_expiration
|
48
55
|
if near_expiration?
|
49
56
|
@mutex.synchronize do
|
50
|
-
|
57
|
+
if near_expiration?
|
58
|
+
@before_refresh.call(self) if @before_refresh
|
59
|
+
|
60
|
+
refresh
|
61
|
+
end
|
51
62
|
end
|
52
63
|
end
|
53
64
|
end
|
@@ -100,7 +100,7 @@ module Aws
|
|
100
100
|
# or `nil` if no valid credentials were found.
|
101
101
|
def credentials(opts = {})
|
102
102
|
p = opts[:profile] || @profile_name
|
103
|
-
validate_profile_exists(p)
|
103
|
+
validate_profile_exists(p)
|
104
104
|
if (credentials = credentials_from_shared(p, opts))
|
105
105
|
credentials
|
106
106
|
elsif (credentials = credentials_from_config(p, opts))
|
@@ -195,11 +195,6 @@ module Aws
|
|
195
195
|
value
|
196
196
|
end
|
197
197
|
|
198
|
-
def credentials_present?
|
199
|
-
(@parsed_credentials && !@parsed_credentials.empty?) ||
|
200
|
-
(@parsed_config && !@parsed_config.empty?)
|
201
|
-
end
|
202
|
-
|
203
198
|
def assume_role_from_profile(cfg, profile, opts, chain_config)
|
204
199
|
if cfg && prof_cfg = cfg[profile]
|
205
200
|
opts[:source_profile] ||= prof_cfg['source_profile']
|
@@ -63,6 +63,11 @@ module Aws
|
|
63
63
|
#
|
64
64
|
# @option options [SSO::Client] :client Optional `SSO::Client`. If not
|
65
65
|
# provided, a client will be constructed.
|
66
|
+
#
|
67
|
+
# @option options [Callable] before_refresh Proc called before
|
68
|
+
# credentials are refreshed. `before_refresh` is called
|
69
|
+
# with an instance of this object when
|
70
|
+
# AWS credentials are required and need to be refreshed.
|
66
71
|
def initialize(options = {})
|
67
72
|
|
68
73
|
missing_keys = SSO_REQUIRED_OPTS.select { |k| options[k].nil? }
|
data/lib/aws-sdk-sso/client.rb
CHANGED
@@ -27,6 +27,7 @@ require 'aws-sdk-core/plugins/client_metrics_plugin.rb'
|
|
27
27
|
require 'aws-sdk-core/plugins/client_metrics_send_plugin.rb'
|
28
28
|
require 'aws-sdk-core/plugins/transfer_encoding.rb'
|
29
29
|
require 'aws-sdk-core/plugins/http_checksum.rb'
|
30
|
+
require 'aws-sdk-core/plugins/checksum_algorithm.rb'
|
30
31
|
require 'aws-sdk-core/plugins/defaults_mode.rb'
|
31
32
|
require 'aws-sdk-core/plugins/recursion_detection.rb'
|
32
33
|
require 'aws-sdk-core/plugins/signature_v4.rb'
|
@@ -75,6 +76,7 @@ module Aws::SSO
|
|
75
76
|
add_plugin(Aws::Plugins::ClientMetricsSendPlugin)
|
76
77
|
add_plugin(Aws::Plugins::TransferEncoding)
|
77
78
|
add_plugin(Aws::Plugins::HttpChecksum)
|
79
|
+
add_plugin(Aws::Plugins::ChecksumAlgorithm)
|
78
80
|
add_plugin(Aws::Plugins::DefaultsMode)
|
79
81
|
add_plugin(Aws::Plugins::RecursionDetection)
|
80
82
|
add_plugin(Aws::Plugins::SignatureV4)
|
@@ -543,7 +545,7 @@ module Aws::SSO
|
|
543
545
|
params: params,
|
544
546
|
config: config)
|
545
547
|
context[:gem_name] = 'aws-sdk-core'
|
546
|
-
context[:gem_version] = '3.
|
548
|
+
context[:gem_version] = '3.127.0'
|
547
549
|
Seahorse::Client::Request.new(handlers, context)
|
548
550
|
end
|
549
551
|
|
data/lib/aws-sdk-sso.rb
CHANGED
data/lib/aws-sdk-sts/client.rb
CHANGED
@@ -27,6 +27,7 @@ require 'aws-sdk-core/plugins/client_metrics_plugin.rb'
|
|
27
27
|
require 'aws-sdk-core/plugins/client_metrics_send_plugin.rb'
|
28
28
|
require 'aws-sdk-core/plugins/transfer_encoding.rb'
|
29
29
|
require 'aws-sdk-core/plugins/http_checksum.rb'
|
30
|
+
require 'aws-sdk-core/plugins/checksum_algorithm.rb'
|
30
31
|
require 'aws-sdk-core/plugins/defaults_mode.rb'
|
31
32
|
require 'aws-sdk-core/plugins/recursion_detection.rb'
|
32
33
|
require 'aws-sdk-core/plugins/signature_v4.rb'
|
@@ -76,6 +77,7 @@ module Aws::STS
|
|
76
77
|
add_plugin(Aws::Plugins::ClientMetricsSendPlugin)
|
77
78
|
add_plugin(Aws::Plugins::TransferEncoding)
|
78
79
|
add_plugin(Aws::Plugins::HttpChecksum)
|
80
|
+
add_plugin(Aws::Plugins::ChecksumAlgorithm)
|
79
81
|
add_plugin(Aws::Plugins::DefaultsMode)
|
80
82
|
add_plugin(Aws::Plugins::RecursionDetection)
|
81
83
|
add_plugin(Aws::Plugins::SignatureV4)
|
@@ -2286,7 +2288,7 @@ module Aws::STS
|
|
2286
2288
|
params: params,
|
2287
2289
|
config: config)
|
2288
2290
|
context[:gem_name] = 'aws-sdk-core'
|
2289
|
-
context[:gem_version] = '3.
|
2291
|
+
context[:gem_version] = '3.127.0'
|
2290
2292
|
Seahorse::Client::Request.new(handlers, context)
|
2291
2293
|
end
|
2292
2294
|
|
data/lib/aws-sdk-sts.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-sdk-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.127.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amazon Web Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jmespath
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- lib/aws-sdk-core/plugins/apig_authorizer_token.rb
|
140
140
|
- lib/aws-sdk-core/plugins/apig_credentials_configuration.rb
|
141
141
|
- lib/aws-sdk-core/plugins/apig_user_agent.rb
|
142
|
+
- lib/aws-sdk-core/plugins/checksum_algorithm.rb
|
142
143
|
- lib/aws-sdk-core/plugins/client_metrics_plugin.rb
|
143
144
|
- lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb
|
144
145
|
- lib/aws-sdk-core/plugins/credentials_configuration.rb
|