aws-sigv2 1.0.0

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