aws-sigv2 1.0.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 +7 -0
- data/lib/aws-sigv2.rb +30 -0
- data/lib/aws-sigv2/credentials.rb +55 -0
- data/lib/aws-sigv2/signer.rb +212 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fdaba0dd004182fd2e09f59cabefa29b19fc9775
|
4
|
+
data.tar.gz: 38827852313c9f8715ea0fc1a7221c56762f76a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af8226eb8f02f5eb999a563c1eff3945b5a0efda7ee50ccfe5a093b443c9d04990a3323e659c19bfe62df5ba79314f460907cd28672946b00efb171dbc7190a4
|
7
|
+
data.tar.gz: 078a27ddef917c32c34625b8dfb707319bd5dbf7b75b8a557837826259ee190d1bdb108c8a2e069216a427f38f0f24d52fda4c9709b8f087a2df1d404e2a71a4
|
data/lib/aws-sigv2.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'aws-sigv2/credentials'
|
2
|
+
require_relative 'aws-sigv2/signer'
|
3
|
+
|
4
|
+
module Aws
|
5
|
+
# This is a legacy signer. You should AWS signature version
|
6
|
+
# 4 instead, as provided by the `aws-sigv4` gem.
|
7
|
+
#
|
8
|
+
# This exists primarily to support SimpleDB which does not
|
9
|
+
# accept version 4 signatures.
|
10
|
+
#
|
11
|
+
# ## Known Limitations
|
12
|
+
#
|
13
|
+
# * This signer is only compatible with AWS services that
|
14
|
+
# use the Query protocol. Only around 18 of the 80+
|
15
|
+
# AWS services use this protocol.
|
16
|
+
#
|
17
|
+
# * **This signer is not capable of producing a valid
|
18
|
+
# signature for Amazon S3.** It is not aware of
|
19
|
+
# S3 sub-resources and how to properly insert them
|
20
|
+
# into the URI path. Amazon S3 supports signature
|
21
|
+
# version 4 in every region, and so `aws-sigv4` should
|
22
|
+
# be used instead.
|
23
|
+
#
|
24
|
+
# * This signer does not provide a method to compute
|
25
|
+
# pre-signed URLs. This is available in the
|
26
|
+
# `aws-sigv4` gem.
|
27
|
+
#
|
28
|
+
module Sigv2
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Aws
|
2
|
+
module Sigv2
|
3
|
+
class Credentials
|
4
|
+
|
5
|
+
# @option options [required, String] :access_key_id
|
6
|
+
# @option options [required, String] :secret_access_key
|
7
|
+
# @option options [String, nil] :session_token (nil)
|
8
|
+
def initialize(options = {})
|
9
|
+
if options[:access_key_id] && options[:secret_access_key]
|
10
|
+
@access_key_id = options[:access_key_id]
|
11
|
+
@secret_access_key = options[:secret_access_key]
|
12
|
+
@session_token = options[:session_token]
|
13
|
+
else
|
14
|
+
msg = "expected both :access_key_id and :secret_access_key options"
|
15
|
+
raise ArgumentError, msg
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [String]
|
20
|
+
attr_reader :access_key_id
|
21
|
+
|
22
|
+
# @return [String]
|
23
|
+
attr_reader :secret_access_key
|
24
|
+
|
25
|
+
# @return [String, nil]
|
26
|
+
attr_reader :session_token
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
# The default credential provider class.
|
31
|
+
#
|
32
|
+
# StaticCredentialsProvider.new({
|
33
|
+
# access_key_id: 'akid',
|
34
|
+
# secret_access_key: 'secret',
|
35
|
+
# })
|
36
|
+
#
|
37
|
+
class StaticCredentialsProvider
|
38
|
+
|
39
|
+
# @option options [Credentials] :credentials
|
40
|
+
# @option options [String] :access_key_id
|
41
|
+
# @option options [String] :secret_access_key
|
42
|
+
# @option options [String] :session_token (nil)
|
43
|
+
def initialize(options = {})
|
44
|
+
@credentials = options[:credentials] ?
|
45
|
+
options[:credentials] :
|
46
|
+
Credentials.new(options)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Credentials]
|
50
|
+
attr_reader :credentials
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
require 'uri'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module Aws
|
7
|
+
module Sigv2
|
8
|
+
# @deprecated This signer is deprecated. You should use
|
9
|
+
# the `aws-sigv4` gem instead.
|
10
|
+
class Signer
|
11
|
+
|
12
|
+
# @overload initialize(access_key_id:, secret_access_key:, session_token:nil)
|
13
|
+
# @param [String] :access_key_id
|
14
|
+
# @param [String] :secret_access_key
|
15
|
+
# @param [String] :session_token (nil)
|
16
|
+
#
|
17
|
+
# @overload initialize(credentials:)
|
18
|
+
# @param [Credentials] :credentials
|
19
|
+
#
|
20
|
+
# @overload initialize(credentials_provider:)
|
21
|
+
# @param [#credentials] :credentials_provider An object that responds
|
22
|
+
# to `#credentials`, returning an object that responds to:
|
23
|
+
#
|
24
|
+
# * `#access_key_id`
|
25
|
+
# * `#secret_access_key`
|
26
|
+
# * `#session_token`
|
27
|
+
#
|
28
|
+
def initialize(options = {})
|
29
|
+
@credentials_provider = extract_credentials_provider(options)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [#credentials] Returns an object that responds
|
33
|
+
# to `#credentials` returning a {Credentials} object.
|
34
|
+
attr_reader :credentials_provider
|
35
|
+
|
36
|
+
# Computes a version 2 signature. The signature is returned as a hash
|
37
|
+
# of request parameters that should be applied to the HTTP request.
|
38
|
+
# The given request will not be modified.
|
39
|
+
#
|
40
|
+
# signature = signer.sign_request(
|
41
|
+
# http_method: 'POST',
|
42
|
+
# url: 'https://domain.com',
|
43
|
+
# params: {
|
44
|
+
# 'Param.Name' => 'Param.Value',
|
45
|
+
# }
|
46
|
+
# )
|
47
|
+
#
|
48
|
+
# # Returns a hash with the following keys:
|
49
|
+
# signature['AWSAccessKeyId']
|
50
|
+
# signature['SecurityToken'] # when using session credentials
|
51
|
+
# signature['Timestamp']
|
52
|
+
# signature['SignatureVersion']
|
53
|
+
# signature['SignatureMethod']
|
54
|
+
# signature['Signature']
|
55
|
+
#
|
56
|
+
# @param [Hash] request
|
57
|
+
#
|
58
|
+
# @option request [required, String] :http_method One of
|
59
|
+
# 'GET', 'HEAD', 'PUT', 'POST', 'PATCH', or 'DELETE'
|
60
|
+
#
|
61
|
+
# @option request [required, String, URI::HTTPS, URI::HTTP] :url
|
62
|
+
# The request URI. Must be a valid HTTP or HTTPS URI.
|
63
|
+
#
|
64
|
+
# @option request [optional, Hash] :params ({}) Request
|
65
|
+
# parameters to sign. This should be a hash with
|
66
|
+
# un-escaped parameter names and values. For "GET" style
|
67
|
+
# requests, this should be the querystring parameters.
|
68
|
+
# For "POST" style requests, this should be the form-url-encoded
|
69
|
+
# query parameters.
|
70
|
+
#
|
71
|
+
# @return [Hash] Returns a hash of un-escaped signature
|
72
|
+
# parameters. These must be applied to the HTTP request.
|
73
|
+
# If the request is a "GET" request, they should be applied
|
74
|
+
# to the querystring. If the request is "POST" then they
|
75
|
+
# should be added to the form-url-encoded HTTP request body.
|
76
|
+
#
|
77
|
+
def sign_request(request)
|
78
|
+
|
79
|
+
creds = @credentials_provider.credentials
|
80
|
+
|
81
|
+
http_method = extract_http_method(request)
|
82
|
+
url = extract_url(request)
|
83
|
+
params = request[:params] || {}
|
84
|
+
|
85
|
+
timestamp = params['Timestamp']
|
86
|
+
timestamp ||= Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
|
87
|
+
|
88
|
+
auth_params = {}
|
89
|
+
auth_params['AWSAccessKeyId'] = creds.access_key_id
|
90
|
+
auth_params['SecurityToken'] = creds.session_token if creds.session_token
|
91
|
+
auth_params['Timestamp'] = timestamp
|
92
|
+
auth_params['SignatureVersion'] = '2'
|
93
|
+
auth_params['SignatureMethod'] = 'HmacSHA256'
|
94
|
+
|
95
|
+
sts = string_to_sign(http_method, url, params.merge(auth_params))
|
96
|
+
|
97
|
+
auth_params['Signature'] = signature(sts, creds.secret_access_key)
|
98
|
+
auth_params
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
# @param [String] string_to_sign
|
104
|
+
# @param [String] secret_access_key
|
105
|
+
# @return [String<Base64>]
|
106
|
+
def signature(string_to_sign, secret_access_key)
|
107
|
+
Base64.encode64(
|
108
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'),
|
109
|
+
secret_access_key, string_to_sign)
|
110
|
+
).strip
|
111
|
+
end
|
112
|
+
|
113
|
+
# @param [String] http_method
|
114
|
+
# @param [URI::HTTP, URI::HTTPS] url
|
115
|
+
# @param [Hash] params
|
116
|
+
# @return [String]
|
117
|
+
def string_to_sign(http_method, url, params)
|
118
|
+
[
|
119
|
+
http_method,
|
120
|
+
host(url),
|
121
|
+
path(url),
|
122
|
+
param_list(params).join('&'),
|
123
|
+
].join("\n")
|
124
|
+
end
|
125
|
+
|
126
|
+
# @param [URI::HTTP, URI::HTTPS] url
|
127
|
+
# @return [String]
|
128
|
+
def host(url)
|
129
|
+
if
|
130
|
+
(url.scheme == 'http' && url.port != 80) ||
|
131
|
+
(url.scheme == 'https' && url.port != 443)
|
132
|
+
then
|
133
|
+
"#{url.host}:#{url.port}"
|
134
|
+
else
|
135
|
+
url.host
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# @param [URI::HTTP, URI::HTTPS] url
|
140
|
+
# @return [String]
|
141
|
+
def path(url)
|
142
|
+
if url.path == ''
|
143
|
+
'/'
|
144
|
+
else
|
145
|
+
uri_escape_path(url.path)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# @param [String] path
|
150
|
+
# @return [String]
|
151
|
+
def uri_escape_path(path)
|
152
|
+
path.gsub(/[^\/]+/) { |part| uri_escape(part) }
|
153
|
+
end
|
154
|
+
|
155
|
+
# @param [String] value
|
156
|
+
# @return [String]
|
157
|
+
def uri_escape(value)
|
158
|
+
if value.nil?
|
159
|
+
nil
|
160
|
+
else
|
161
|
+
CGI.escape(value.encode('UTF-8')).gsub('+', '%20').gsub('%7E', '~')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# @param [Hash] params
|
166
|
+
# @return [Array<String>]
|
167
|
+
def param_list(params)
|
168
|
+
params.keys.sort.inject([]) do |list, param_name|
|
169
|
+
if param_name == 'Signature'
|
170
|
+
list # do not sign the previous signature
|
171
|
+
else
|
172
|
+
list << "#{uri_escape(param_name)}=#{uri_escape(params[param_name])}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def extract_credentials_provider(options)
|
178
|
+
if options[:credentials_provider]
|
179
|
+
options[:credentials_provider]
|
180
|
+
elsif options.key?(:credentials) || options.key?(:access_key_id)
|
181
|
+
StaticCredentialsProvider.new(options)
|
182
|
+
else
|
183
|
+
raise ArgumentError, <<-MSG
|
184
|
+
missing credentials, provide credentials with one of the following options:
|
185
|
+
- :access_key_id and :secret_access_key
|
186
|
+
- :credentials
|
187
|
+
- :credentials_provider
|
188
|
+
MSG
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def extract_http_method(request)
|
193
|
+
if request[:http_method]
|
194
|
+
request[:http_method].upcase
|
195
|
+
else
|
196
|
+
msg = "missing required option :http_method"
|
197
|
+
raise ArgumentError, msg
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def extract_url(request)
|
202
|
+
if request[:url]
|
203
|
+
URI.parse(request[:url].to_s)
|
204
|
+
else
|
205
|
+
msg = "missing required option :url"
|
206
|
+
raise ArgumentError, msg
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aws-sigv2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Amazon Web Services
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-05 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Amazon Web Services Signature Version 2 signing ligrary. Generates sigv2
|
14
|
+
signature for HTTP requests.
|
15
|
+
email:
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/aws-sigv2.rb
|
21
|
+
- lib/aws-sigv2/credentials.rb
|
22
|
+
- lib/aws-sigv2/signer.rb
|
23
|
+
homepage: http://github.com/aws/aws-sdk-ruby
|
24
|
+
licenses:
|
25
|
+
- Apache-2.0
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.5.1
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: AWS Signature Version 2 library.
|
47
|
+
test_files: []
|