diff options
author | Christopher Brown <cb@opscode.com> | 2009-11-04 11:06:03 -0800 |
---|---|---|
committer | Christopher Brown <cb@opscode.com> | 2009-11-04 11:06:03 -0800 |
commit | 5de2fd9a6410eec7fb353d56d960a63bdeb9d8f7 (patch) | |
tree | 850f964c86b15807b3f7ec90177843941a26fc6b /lib/mixlib | |
parent | b5074922bfc716b681abb7d0bd122eea8190d005 (diff) | |
parent | c38ca86e2e79737f5bb7c67b83f15a2dec61a2ea (diff) | |
download | mixlib-authentication-5de2fd9a6410eec7fb353d56d960a63bdeb9d8f7.tar.gz |
Merge branch 'PL-316'
Diffstat (limited to 'lib/mixlib')
-rw-r--r-- | lib/mixlib/authentication/signatureverification.rb | 28 | ||||
-rw-r--r-- | lib/mixlib/authentication/signedheaderauth.rb | 22 |
2 files changed, 39 insertions, 11 deletions
diff --git a/lib/mixlib/authentication/signatureverification.rb b/lib/mixlib/authentication/signatureverification.rb index 73a2309..b6802e2 100644 --- a/lib/mixlib/authentication/signatureverification.rb +++ b/lib/mixlib/authentication/signatureverification.rb @@ -50,19 +50,39 @@ module Mixlib @signing_description = headers[:x_ops_sign].chomp @user_id = headers[:x_ops_userid].chomp @timestamp = headers[:x_ops_timestamp].chomp - @request_signature = headers[:authorization].chomp.gsub!(/\n\t/,"\n") @host = headers[:host].chomp @content_hash = headers[:x_ops_content_hash].chomp @user_secret = user_lookup - - file_param = request.params["file"] + # The authorization header is a Base64-encoded version of an RSA signature. + # The client sent it on multiple header lines, starting at index 1 - + # X-Ops-Authorization-1, X-Ops-Authorization-2, etc. Pull them out and + # concatenate. + @request_signature = "" + header_idx = 1 + while (header_idx == 1 || !header_value.nil?) + header_name = "X-Ops-Authorization-#{header_idx}" + header_sym = header_name.downcase.to_sym + header_value = headers[header_sym] + if !header_value.nil? + @request_signature += "\n" if @request_signature.length > 0 + @request_signature += header_value.strip + end + header_idx += 1 + end + + # Any file that's included in the request is hashed if it's there. Otherwise, + # we hash the body. Look for files by looking for objects that respond to + # the read call. + file_param = request.params.values.find { |value| value.respond_to?(:read) } @hashed_body = if file_param Mixlib::Authentication::Log.debug "Digesting file_param: '#{file_param.inspect}'" if file_param.respond_to?(:has_key?) tempfile = file_param[:tempfile] digester.hash_file(tempfile) + elsif file_param.respond_to?(:read) + digester.hash_file(file_param) else digester.hash_body(file_param) end @@ -72,7 +92,7 @@ module Mixlib digester.hash_body(body) end - Mixlib::Authentication::Log.debug "Authenticating user : #{user_id}, User secret is: #{@user_secret}, Request signature is :\n#{@request_signature}, Hashed Body is #{@hashed_body}" + Mixlib::Authentication::Log.debug "Authenticating user : #{user_id}, User secret is : #{@user_secret}, Request signature is :\n#{@request_signature}, Auth HTTP header is :\n#{headers[:authorization]}, Hashed Body is : #{@hashed_body}" #BUGBUG Not doing anything with the signing description yet [cb] parse_signing_description diff --git a/lib/mixlib/authentication/signedheaderauth.rb b/lib/mixlib/authentication/signedheaderauth.rb index 87c596a..4d72a4a 100644 --- a/lib/mixlib/authentication/signedheaderauth.rb +++ b/lib/mixlib/authentication/signedheaderauth.rb @@ -39,11 +39,11 @@ module Mixlib end end - # Build the canonicalized request based on the method, other headers, etc. + # Build the canonicalized request based on the method, other headers, etc. # compute the signature from the request, using the looked-up user secret # ====Parameters - # private_key<String>:: user's RSA private key. - def sign(private_key) + # private_key<OpenSSL::PKey::RSA>:: user's RSA private key. + def sign(private_key) digester = Mixlib::Authentication::Digester.new @hashed_body = if self.file digester.hash_file(self.file) @@ -51,18 +51,26 @@ module Mixlib digester.hash_body(self.body) end - signature = Base64.encode64(private_key.private_encrypt(canonicalize_request)).chomp.gsub!(/\n/,"\n\t") - header_hash = { + header_hash = { "X-Ops-Sign" => SIGNING_DESCRIPTION, "X-Ops-Userid" => user_id, "X-Ops-Timestamp" => canonical_time, "X-Ops-Content-Hash" =>@hashed_body, - "Authorization" => signature, } + + # Our multiline hash for authorization will be encoded in multiple header + # lines - X-Ops-Authorization-1, ... (starts at 1, not 0!) + signature = Base64.encode64(private_key.private_encrypt(canonicalize_request)).chomp + signature_lines = signature.split(/\n/) + signature_lines.each_index do |idx| + key = "X-Ops-Authorization-#{idx + 1}" + header_hash[key] = signature_lines[idx] + end + Mixlib::Authentication::Log.debug "Header hash: #{header_hash.inspect}" header_hash - end + end # Build the canonicalized time based on utc & iso8601 # |