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.
@@ -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
@@ -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: []