aws-sigv2 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|