mixlib-authentication 1.3.0.beta.0 → 1.3.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,9 +7,9 @@
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
9
9
  # You may obtain a copy of the License at
10
- #
10
+ #
11
11
  # http://www.apache.org/licenses/LICENSE-2.0
12
- #
12
+ #
13
13
  # Unless required by applicable law or agreed to in writing, software
14
14
  # distributed under the License is distributed on an "AS IS" BASIS,
15
15
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,62 +28,99 @@ module Mixlib
28
28
 
29
29
  module SignedHeaderAuth
30
30
 
31
- SUPPORTED_ALGORITHMS = ['sha1']
32
- SUPPORTED_VERSIONS = ['1.0', '1.1']
31
+ NULL_ARG = Object.new
32
+ SUPPORTED_ALGORITHMS = ['sha1'].freeze
33
+ SUPPORTED_VERSIONS = ['1.0', '1.1'].freeze
33
34
 
34
- # This is a module meant to be mixed in but can be used standalone
35
- # with the simple OpenStruct extended with the auth functions
36
- class << self
37
- def signing_object(args={ })
38
- SigningObject.new(args[:http_method], args[:path], args[:body], args[:host], args[:timestamp], args[:user_id], args[:file])
39
- end
35
+ DEFAULT_SIGN_ALGORITHM = 'sha1'.freeze
36
+ DEFAULT_PROTO_VERSION = '1.0'.freeze
37
+
38
+
39
+ # === signing_object
40
+ # This is the intended interface for signing requests with the
41
+ # Opscode/Chef signed header protocol. This wraps the constructor for a
42
+ # Struct that contains the relevant information about your request.
43
+ #
44
+ # ==== Signature Parameters:
45
+ # These parameters are used to generate the canonical representation of
46
+ # the request, which is then hashed and encrypted to generate the
47
+ # request's signature. These options are all required, with the exception
48
+ # of `:body` and `:file`, which are alternate ways to specify the request
49
+ # body (you must specify one of these).
50
+ # * `:http_method`: HTTP method as a lowercase symbol, e.g., `:get | :put | :post | :delete`
51
+ # * `:path`: The path part of the URI, e.g., `URI.parse(uri).path`
52
+ # * `:body`: An object representing the body of the request.
53
+ # Use an empty String for bodiless requests.
54
+ # * `:timestamp`: A String representing the time in any format understood
55
+ # by `Time.parse`. The server may reject the request if the timestamp is
56
+ # not close to the server's current time.
57
+ # * `:user_id`: The user or client name. This is used by the server to
58
+ # lookup the public key necessary to verify the signature.
59
+ # * `:file`: An IO object (must respond to `:read`) to be used as the
60
+ # request body.
61
+ # ==== Protocol Versioning Parameters:
62
+ # * `:proto_version`: The version of the signing protocol to use.
63
+ # Currently defaults to 1.0, but version 1.1 is also available.
64
+ # ==== Other Parameters:
65
+ # These parameters are accepted but not used in the computation of the signature.
66
+ # * `:host`: The host part of the URI
67
+ def self.signing_object(args={ })
68
+ SigningObject.new(args[:http_method], args[:path], args[:body], args[:host], args[:timestamp], args[:user_id], args[:file], args[:proto_version])
69
+ end
70
+
71
+ def algorithm
72
+ DEFAULT_SIGN_ALGORITHM
73
+ end
74
+
75
+ def proto_version
76
+ DEFAULT_PROTO_VERSION
40
77
  end
41
78
 
42
79
  # Build the canonicalized request based on the method, other headers, etc.
43
80
  # compute the signature from the request, using the looked-up user secret
44
81
  # ====Parameters
45
82
  # private_key<OpenSSL::PKey::RSA>:: user's RSA private key.
46
- def sign(private_key, algorithm='sha1', version='1.1')
83
+ def sign(private_key, sign_algorithm=algorithm, sign_version=proto_version)
47
84
  # Our multiline hash for authorization will be encoded in multiple header
48
85
  # lines - X-Ops-Authorization-1, ... (starts at 1, not 0!)
49
86
  header_hash = {
50
- "X-Ops-Sign" => "algorithm=#{algorithm};version=#{version};",
87
+ "X-Ops-Sign" => "algorithm=#{sign_algorithm};version=#{sign_version};",
51
88
  "X-Ops-Userid" => user_id,
52
89
  "X-Ops-Timestamp" => canonical_time,
53
90
  "X-Ops-Content-Hash" => hashed_body,
54
91
  }
55
92
 
56
- string_to_sign = canonicalize_request(algorithm, version)
93
+ string_to_sign = canonicalize_request(sign_algorithm, sign_version)
57
94
  signature = Base64.encode64(private_key.private_encrypt(string_to_sign)).chomp
58
95
  signature_lines = signature.split(/\n/)
59
96
  signature_lines.each_index do |idx|
60
97
  key = "X-Ops-Authorization-#{idx + 1}"
61
98
  header_hash[key] = signature_lines[idx]
62
99
  end
63
-
100
+
64
101
  Mixlib::Authentication::Log.debug "String to sign: '#{string_to_sign}'\nHeader hash: #{header_hash.inspect}"
65
-
102
+
66
103
  header_hash
67
104
  end
68
-
105
+
69
106
  # Build the canonicalized time based on utc & iso8601
70
- #
107
+ #
71
108
  # ====Parameters
72
- #
109
+ #
73
110
  def canonical_time
74
111
  Time.parse(timestamp).utc.iso8601
75
112
  end
76
-
113
+
77
114
  # Build the canonicalized path, which collapses multiple slashes (/) and
78
115
  # removes a trailing slash unless the path is only "/"
79
- #
116
+ #
80
117
  # ====Parameters
81
- #
118
+ #
82
119
  def canonical_path
83
120
  p = path.gsub(/\/+/,'/')
84
121
  p.length > 1 ? p.chomp('/') : p
85
122
  end
86
-
123
+
87
124
  def hashed_body
88
125
  # Hash the file object if it was passed in, otherwise hash based on
89
126
  # the body.
@@ -92,27 +129,33 @@ module Mixlib
92
129
  # body in the case of a file being include.
93
130
  @hashed_body ||= (self.file && self.file.respond_to?(:read)) ? digester.hash_file(self.file) : digester.hash_string(self.body)
94
131
  end
95
-
132
+
96
133
  # Takes HTTP request method & headers and creates a canonical form
97
134
  # to create the signature
98
- #
135
+ #
99
136
  # ====Parameters
100
- #
101
- #
102
- def canonicalize_request(algorithm='sha1', version='1.1')
103
- raise AuthenticationError, "Bad algorithm '#{algorithm}' or version '#{version}'" unless SUPPORTED_ALGORITHMS.include?(algorithm) && SUPPORTED_VERSIONS.include?(version)
104
-
105
- canonical_x_ops_user_id = case
106
- when version == "1.1"
107
- digester.hash_string(user_id)
108
- when version == "1.0"
109
- user_id
110
- else
111
- user_id
112
- end
137
+ #
138
+ #
139
+ def canonicalize_request(sign_algorithm=algorithm, sign_version=proto_version)
140
+ unless SUPPORTED_ALGORITHMS.include?(sign_algorithm) && SUPPORTED_VERSIONS.include?(sign_version)
141
+ raise AuthenticationError, "Bad algorithm '#{sign_algorithm}' (allowed: #{SUPPORTED_ALGORITHMS.inspect}) or version '#{sign_version}' (allowed: #{SUPPORTED_VERSIONS.inspect})"
142
+ end
143
+
144
+ canonical_x_ops_user_id = canonicalize_user_id(user_id, sign_version)
113
145
  "Method:#{http_method.to_s.upcase}\nHashed Path:#{digester.hash_string(canonical_path)}\nX-Ops-Content-Hash:#{hashed_body}\nX-Ops-Timestamp:#{canonical_time}\nX-Ops-UserId:#{canonical_x_ops_user_id}"
114
146
  end
115
-
147
+
148
+ def canonicalize_user_id(user_id, proto_version)
149
+ case proto_version
150
+ when "1.1"
151
+ digester.hash_string(user_id)
152
+ when "1.0"
153
+ user_id
154
+ else
155
+ user_id
156
+ end
157
+ end
158
+
116
159
  # Parses signature version information, algorithm used, etc.
117
160
  #
118
161
  # ====Parameters
@@ -126,17 +169,25 @@ module Mixlib
126
169
  Mixlib::Authentication::Log.debug "Parsed signing description: #{parts.inspect}"
127
170
  parts
128
171
  end
129
-
172
+
130
173
  def digester
131
174
  Mixlib::Authentication::Digester
132
175
  end
133
-
134
- private :canonical_time, :canonical_path, :parse_signing_description, :digester
135
-
176
+
177
+ private :canonical_time, :canonical_path, :parse_signing_description, :digester, :canonicalize_user_id
178
+
136
179
  end
137
180
 
138
- class SigningObject < Struct.new(:http_method, :path, :body, :host, :timestamp, :user_id, :file)
181
+ # === SigningObject
182
+ # A Struct-based value object that contains the necessary information to
183
+ # generate a request signature. `SignedHeaderAuth.signing_object()`
184
+ # provides a more convenient interface to the constructor.
185
+ class SigningObject < Struct.new(:http_method, :path, :body, :host, :timestamp, :user_id, :file, :proto_version)
139
186
  include SignedHeaderAuth
187
+
188
+ def proto_version
189
+ (self[:proto_version] or DEFAULT_PROTO_VERSION).to_s
190
+ end
140
191
  end
141
192
 
142
193
  end
@@ -8,9 +8,9 @@
8
8
  # Licensed under the Apache License, Version 2.0 (the "License");
9
9
  # you may not use this file except in compliance with the License.
10
10
  # You may obtain a copy of the License at
11
- #
11
+ #
12
12
  # http://www.apache.org/licenses/LICENSE-2.0
13
- #
13
+ #
14
14
  # Unless required by applicable law or agreed to in writing, software
15
15
  # distributed under the License is distributed on an "AS IS" BASIS,
16
16
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -68,28 +68,42 @@ end
68
68
 
69
69
  describe "Mixlib::Authentication::SignedHeaderAuth" do
70
70
 
71
- it "should generate the correct string to sign and signature, version 1.0" do
72
-
73
- algorithm = 'sha1'
74
- version = '1.0'
75
- V1_0_SIGNING_OBJECT.canonicalize_request(algorithm, version).should == V1_0_CANONICAL_REQUEST
71
+ # NOTE: Version 1.0 will be the default until Chef 11 is released.
72
+
73
+ it "should generate the correct string to sign and signature, version 1.0 (default)" do
74
+
75
+ V1_0_SIGNING_OBJECT.canonicalize_request.should == V1_0_CANONICAL_REQUEST
76
76
 
77
77
  # If you need to regenerate the constants in this test spec, print out
78
- # the results of res.inspect and copy them as appropriate into the
78
+ # the results of res.inspect and copy them as appropriate into the
79
79
  # the constants in this file.
80
- V1_0_SIGNING_OBJECT.sign(PRIVATE_KEY, algorithm, version).should == EXPECTED_SIGN_RESULT_V1_0
80
+ V1_0_SIGNING_OBJECT.sign(PRIVATE_KEY).should == EXPECTED_SIGN_RESULT_V1_0
81
81
  end
82
82
 
83
83
  it "should generate the correct string to sign and signature, version 1.1" do
84
-
84
+ V1_1_SIGNING_OBJECT.proto_version.should == "1.1"
85
85
  V1_1_SIGNING_OBJECT.canonicalize_request.should == V1_1_CANONICAL_REQUEST
86
86
 
87
87
  # If you need to regenerate the constants in this test spec, print out
88
- # the results of res.inspect and copy them as appropriate into the
88
+ # the results of res.inspect and copy them as appropriate into the
89
89
  # the constants in this file.
90
90
  V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY).should == EXPECTED_SIGN_RESULT_V1_1
91
91
  end
92
92
 
93
+ it "should generate the correct string to sign and signature for non-default proto version when used as a mixin" do
94
+ algorithm = 'sha1'
95
+ version = '1.1'
96
+
97
+ V1_1_SIGNING_OBJECT.proto_version = "1.0"
98
+ V1_1_SIGNING_OBJECT.proto_version.should == "1.0"
99
+ V1_1_SIGNING_OBJECT.canonicalize_request(algorithm, version).should == V1_1_CANONICAL_REQUEST
100
+
101
+ # If you need to regenerate the constants in this test spec, print out
102
+ # the results of res.inspect and copy them as appropriate into the
103
+ # the constants in this file.
104
+ V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, algorithm, version).should == EXPECTED_SIGN_RESULT_V1_1
105
+ end
106
+
93
107
  it "should not choke when signing a request for a long user id with version 1.1" do
94
108
  lambda { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, 'sha1', '1.1') }.should_not raise_error
95
109
  end
@@ -109,7 +123,7 @@ describe "Mixlib::Authentication::SignedHeaderAuth" do
109
123
  end
110
124
 
111
125
  describe "Mixlib::Authentication::SignatureVerification" do
112
-
126
+
113
127
  before(:each) do
114
128
  @user_private_key = PRIVATE_KEY
115
129
  end
@@ -231,7 +245,7 @@ PATH = "/organizations/clownco"
231
245
  HASHED_CANONICAL_PATH = "YtBWDn1blGGuFIuKksdwXzHU9oE=" # Base64.encode64(Digest::SHA1.digest("/organizations/clownco")).chomp
232
246
 
233
247
  V1_0_ARGS = {
234
- :body => BODY,
248
+ :body => BODY,
235
249
  :user_id => USER_ID,
236
250
  :http_method => :post,
237
251
  :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time.
@@ -240,16 +254,17 @@ V1_0_ARGS = {
240
254
  }
241
255
 
242
256
  V1_1_ARGS = {
243
- :body => BODY,
257
+ :body => BODY,
244
258
  :user_id => USER_ID,
245
259
  :http_method => :post,
246
260
  :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time.
247
261
  :file => MockFile.new,
248
- :path => PATH
262
+ :path => PATH,
263
+ :proto_version => 1.1
249
264
  }
250
265
 
251
266
  LONG_PATH_LONG_USER_ARGS = {
252
- :body => BODY,
267
+ :body => BODY,
253
268
  :user_id => "A" * 200,
254
269
  :http_method => :put,
255
270
  :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time.
@@ -263,10 +278,10 @@ REQUESTING_ACTOR_ID = "c0f8a68c52bffa1020222a56b23cccfa"
263
278
  X_OPS_CONTENT_HASH = "DFteJZPVv6WKdQmMqZUQUumUyRs="
264
279
  X_OPS_AUTHORIZATION_LINES_V1_0 = [
265
280
  "jVHrNniWzpbez/eGWjFnO6lINRIuKOg40ZTIQudcFe47Z9e/HvrszfVXlKG4",
266
- "NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc",
267
- "3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O",
268
- "IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy",
269
- "9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0",
281
+ "NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc",
282
+ "3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O",
283
+ "IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy",
284
+ "9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0",
270
285
  "utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w=="
271
286
  ]
272
287
 
@@ -311,51 +326,51 @@ EXPECTED_SIGN_RESULT_V1_1 = {
311
326
  OTHER_HEADERS = {
312
327
  # An arbitrary sampling of non-HTTP_* headers are in here to
313
328
  # exercise that code path.
314
- "REMOTE_ADDR"=>"127.0.0.1",
315
- "PATH_INFO"=>"/organizations/local-test-org/cookbooks",
316
- "REQUEST_PATH"=>"/organizations/local-test-org/cookbooks",
329
+ "REMOTE_ADDR"=>"127.0.0.1",
330
+ "PATH_INFO"=>"/organizations/local-test-org/cookbooks",
331
+ "REQUEST_PATH"=>"/organizations/local-test-org/cookbooks",
317
332
  "CONTENT_TYPE"=>"multipart/form-data; boundary=----RubyMultipartClient6792ZZZZZ",
318
- "CONTENT_LENGTH"=>"394",
333
+ "CONTENT_LENGTH"=>"394",
319
334
  }
320
335
 
321
336
  # This is what will be in request.params for the Merb case.
322
337
  MERB_REQUEST_PARAMS = {
323
- "name"=>"zsh", "action"=>"create", "controller"=>"chef_server_api/cookbooks",
338
+ "name"=>"zsh", "action"=>"create", "controller"=>"chef_server_api/cookbooks",
324
339
  "organization_id"=>"local-test-org", "requesting_actor_id"=>REQUESTING_ACTOR_ID,
325
340
  }
326
341
 
327
342
  # Tis is what will be in request.env for the Merb case.
328
343
  MERB_HEADERS_V1_1 = {
329
344
  # These are used by signatureverification.
330
- "HTTP_HOST"=>"127.0.0.1",
345
+ "HTTP_HOST"=>"127.0.0.1",
331
346
  "HTTP_X_OPS_SIGN"=>"algorithm=sha1;version=1.1;",
332
- "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386",
333
- "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601,
334
- "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH,
335
- "HTTP_X_OPS_USERID"=>USER_ID,
336
- "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES[0],
337
- "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES[1],
338
- "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES[2],
339
- "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES[3],
340
- "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES[4],
341
- "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES[5],
347
+ "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386",
348
+ "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601,
349
+ "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH,
350
+ "HTTP_X_OPS_USERID"=>USER_ID,
351
+ "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES[0],
352
+ "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES[1],
353
+ "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES[2],
354
+ "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES[3],
355
+ "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES[4],
356
+ "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES[5],
342
357
  }.merge(OTHER_HEADERS)
343
358
 
344
359
  # Tis is what will be in request.env for the Merb case.
345
360
  MERB_HEADERS_V1_0 = {
346
361
  # These are used by signatureverification.
347
- "HTTP_HOST"=>"127.0.0.1",
362
+ "HTTP_HOST"=>"127.0.0.1",
348
363
  "HTTP_X_OPS_SIGN"=>"version=1.0",
349
- "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386",
350
- "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601,
351
- "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH,
352
- "HTTP_X_OPS_USERID"=>USER_ID,
353
- "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES_V1_0[0],
354
- "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES_V1_0[1],
355
- "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES_V1_0[2],
356
- "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES_V1_0[3],
357
- "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES_V1_0[4],
358
- "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES_V1_0[5],
364
+ "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386",
365
+ "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601,
366
+ "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH,
367
+ "HTTP_X_OPS_USERID"=>USER_ID,
368
+ "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES_V1_0[0],
369
+ "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES_V1_0[1],
370
+ "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES_V1_0[2],
371
+ "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES_V1_0[3],
372
+ "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES_V1_0[4],
373
+ "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES_V1_0[5],
359
374
  }.merge(OTHER_HEADERS)
360
375
 
361
376
  PASSENGER_REQUEST_PARAMS = {
@@ -367,34 +382,34 @@ PASSENGER_REQUEST_PARAMS = {
367
382
 
368
383
  PASSENGER_HEADERS_V1_1 = {
369
384
  # These are used by signatureverification.
370
- "HTTP_HOST"=>"127.0.0.1",
385
+ "HTTP_HOST"=>"127.0.0.1",
371
386
  "HTTP_X_OPS_SIGN"=>"algorithm=sha1;version=1.1;",
372
- "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386",
373
- "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601,
374
- "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH,
375
- "HTTP_X_OPS_USERID"=>USER_ID,
376
- "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES[0],
377
- "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES[1],
378
- "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES[2],
379
- "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES[3],
380
- "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES[4],
381
- "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES[5],
387
+ "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386",
388
+ "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601,
389
+ "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH,
390
+ "HTTP_X_OPS_USERID"=>USER_ID,
391
+ "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES[0],
392
+ "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES[1],
393
+ "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES[2],
394
+ "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES[3],
395
+ "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES[4],
396
+ "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES[5],
382
397
  }.merge(OTHER_HEADERS)
383
398
 
384
399
  PASSENGER_HEADERS_V1_0 = {
385
400
  # These are used by signatureverification.
386
- "HTTP_HOST"=>"127.0.0.1",
401
+ "HTTP_HOST"=>"127.0.0.1",
387
402
  "HTTP_X_OPS_SIGN"=>"version=1.0",
388
- "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386",
389
- "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601,
390
- "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH,
391
- "HTTP_X_OPS_USERID"=>USER_ID,
392
- "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES_V1_0[0],
393
- "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES_V1_0[1],
394
- "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES_V1_0[2],
395
- "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES_V1_0[3],
396
- "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES_V1_0[4],
397
- "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES_V1_0[5],
403
+ "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386",
404
+ "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601,
405
+ "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH,
406
+ "HTTP_X_OPS_USERID"=>USER_ID,
407
+ "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES_V1_0[0],
408
+ "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES_V1_0[1],
409
+ "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES_V1_0[2],
410
+ "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES_V1_0[3],
411
+ "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES_V1_0[4],
412
+ "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES_V1_0[5],
398
413
  }.merge(OTHER_HEADERS)
399
414
 
400
415
  # generated with
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-authentication
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196403
4
+ hash: -2745496134
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 1
8
8
  - 3
9
9
  - 0
10
10
  - beta
11
- - 0
12
- version: 1.3.0.beta.0
11
+ - 1
12
+ version: 1.3.0.beta.1
13
13
  platform: ruby
14
14
  authors:
15
15
  - Opscode, Inc.
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2012-06-05 00:00:00 Z
20
+ date: 2012-08-03 00:00:00 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  name: mixlib-log
@@ -49,13 +49,13 @@ files:
49
49
  - Rakefile
50
50
  - NOTICE
51
51
  - lib/mixlib/authentication.rb
52
- - lib/mixlib/authentication/signatureverification.rb
52
+ - lib/mixlib/authentication/http_authentication_request.rb
53
53
  - lib/mixlib/authentication/signedheaderauth.rb
54
+ - lib/mixlib/authentication/signatureverification.rb
54
55
  - lib/mixlib/authentication/digester.rb
55
- - lib/mixlib/authentication/http_authentication_request.rb
56
56
  - spec/spec_helper.rb
57
- - spec/mixlib/authentication/mixlib_authentication_spec.rb
58
57
  - spec/mixlib/authentication/http_authentication_request_spec.rb
58
+ - spec/mixlib/authentication/mixlib_authentication_spec.rb
59
59
  homepage: http://www.opscode.com
60
60
  licenses: []
61
61