From 26b7de8ef77c5c8a0b696a49fe70f0ec5981ff25 Mon Sep 17 00:00:00 2001 From: geemus Date: Thu, 29 Nov 2012 16:25:37 -0600 Subject: [PATCH] [aws|dynamodb] port off of sts for credentials, now uses signature v4 --- lib/fog/aws/dynamodb.rb | 90 ++++++++++++-------------------------- lib/fog/aws/glacier.rb | 2 +- lib/fog/aws/signaturev4.rb | 2 +- 3 files changed, 30 insertions(+), 64 deletions(-) diff --git a/lib/fog/aws/dynamodb.rb b/lib/fog/aws/dynamodb.rb index 49f160c42..3bdf8a938 100644 --- a/lib/fog/aws/dynamodb.rb +++ b/lib/fog/aws/dynamodb.rb @@ -76,41 +76,30 @@ module Fog # * DynamoDB object with connection to aws def initialize(options={}) @use_iam_profile = options[:use_iam_profile] - #TODO check dynamodb stuff + @region = options[:region] || 'us-east-1' setup_credentials(options) - + @connection_options = options[:connection_options] || {} - - options[:region] ||= 'us-east-1' - @host = options[:host] || "dynamodb.#{options[:region]}.amazonaws.com" + + @host = options[:host] || "dynamodb.#{@region}.amazonaws.com" @path = options[:path] || '/' @persistent = options[:persistent] || false @port = options[:port] || '80' #443 @scheme = options[:scheme] || 'http' #'https' + @connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options) end private def setup_credentials(options) - if options[:aws_session_token] - @aws_access_key_id = options[:aws_access_key_id] - @aws_secret_access_key = options[:aws_secret_access_key] - @aws_session_token = options[:aws_session_token] - @aws_credentials_expire_at = options[:aws_credentials_expire_at] - else - sts = Fog::AWS::STS.new( - :aws_access_key_id => options[:aws_access_key_id], - :aws_secret_access_key => options[:aws_secret_access_key] - ) - session_data = sts.get_session_token.body + @aws_access_key_id = options[:aws_access_key_id] + @aws_secret_access_key = options[:aws_secret_access_key] + @aws_session_token = options[:aws_session_token] + @aws_credentials_expire_at = options[:aws_credentials_expire_at] - @aws_access_key_id = session_data['AccessKeyId'] - @aws_secret_access_key = session_data['SecretAccessKey'] - @aws_session_token = session_data['SessionToken'] - end - @hmac = Fog::HMAC.new('sha256', @aws_secret_access_key) + @signer = Fog::AWS::SignatureV4.new(@aws_access_key_id, @aws_secret_access_key, @region, 'dynamodb') end def reload @@ -119,25 +108,27 @@ module Fog def request(params) refresh_credentials_if_expired - idempotent = params.delete(:idempotent) - headers = { - 'Content-Type' => 'application/x-amz-json-1.0', - 'x-amz-date' => Fog::Time.now.to_date_header, - 'x-amz-security-token' => @aws_session_token - }.merge(params[:headers]) - - headers['x-amzn-authorization'] = signed_authorization_header(params, headers) - - response = @connection.request({ - :body => params[:body], - :expects => 200, - :headers => headers, - :host => @host, - :idempotent => idempotent, - :method => 'POST', + # defaults for all dynamodb requests + params.merge!({ + :expects => 200, + :host => @host, + :method => :post, + :path => '/' }) + # setup headers and sign with signature v4 + date = Fog::Time.now + params[:headers] = { + 'Content-Type' => 'application/x-amz-json-1.0', + 'Date' => date.to_iso8601_basic, + 'Host' => @host, + }.merge!(params[:headers]) + params[:headers]['x-amz-security-token'] = @aws_session_token if @aws_session_token + params[:headers]['Authorization'] = @signer.sign(params, date) + + response = @connection.request(params) + unless response.body.empty? response.body = Fog::JSON.decode(response.body) end @@ -145,31 +136,6 @@ module Fog response end - def signed_authorization_header(params, headers) - string_to_sign = "POST\n/\n\nhost:#{@host}:#{@port}\n" - - amz_headers, canonical_amz_headers = {}, '' - for key, value in headers - if key[0..5] == 'x-amz-' - amz_headers[key] = value - end - end - amz_headers = amz_headers.sort {|x, y| x[0] <=> y[0]} - for key, value in amz_headers - canonical_amz_headers << "#{key}:#{value}\n" - end - string_to_sign << canonical_amz_headers - string_to_sign << "\n" - string_to_sign << (params[:body] || '') - - string_to_sign = OpenSSL::Digest::SHA256.digest(string_to_sign) - - signed_string = @hmac.sign(string_to_sign) - signature = Base64.encode64(signed_string).chomp! - - "AWS3 AWSAccessKeyId=#{@aws_access_key_id},Algorithm=HmacSHA256,Signature=#{signature}" - end - end end end diff --git a/lib/fog/aws/glacier.rb b/lib/fog/aws/glacier.rb index 1c42794f9..f28712d12 100644 --- a/lib/fog/aws/glacier.rb +++ b/lib/fog/aws/glacier.rb @@ -169,4 +169,4 @@ module Fog end end end -end \ No newline at end of file +end diff --git a/lib/fog/aws/signaturev4.rb b/lib/fog/aws/signaturev4.rb index 911487cde..cdc9d4397 100644 --- a/lib/fog/aws/signaturev4.rb +++ b/lib/fog/aws/signaturev4.rb @@ -70,4 +70,4 @@ DATA end end -end \ No newline at end of file +end