def _sign_url(self, credentials, path): """ Create properly formatted and pre-signed URL using supplied credentials See http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/ rest-signature.html Also see boto/auth.py::QuerySignatureV2AuthHandler """ host_url = urlparse.urlparse(cfg.CONF.heat_waitcondition_server_url) # Note the WSGI spec apparently means that the webob request we end up # prcessing in the CFN API (ec2token.py) has an unquoted path, so we # need to calculate the signature with the path component unquoted, but # ensure the actual URL contains the quoted version... unquoted_path = urllib.unquote(host_url.path + path) request = { 'host': host_url.netloc.lower(), 'verb': 'PUT', 'path': unquoted_path, 'params': { 'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'AWSAccessKeyId': credentials.access, 'Timestamp': self.created_time.strftime("%Y-%m-%dT%H:%M:%SZ") } } # Sign the request signer = Ec2Signer(credentials.secret) request['params']['Signature'] = signer.generate(request) qs = urllib.urlencode(request['params']) url = "%s%s?%s" % (cfg.CONF.heat_waitcondition_server_url.lower(), path, qs) return url
def test_generate_v4_port(self): """ Test v4 generator with host:port format """ # Create a new signer object with the AWS example key secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY' signer = Ec2Signer(secret) body_hash = ('b6359072c78d70ebee1e81adcbab4f0' '1bf2c23245fa365ef83fe8f1f955085e2') auth_str = ('AWS4-HMAC-SHA256 ' 'Credential=AKIAIOSFODNN7EXAMPLE/20110909/' 'us-east-1/iam/aws4_request,' 'SignedHeaders=content-type;host;x-amz-date,') headers = {'Content-type': 'application/x-www-form-urlencoded; charset=utf-8', 'X-Amz-Date': '20110909T233600Z', 'Host': 'foo:8000', 'Authorization': auth_str} # Note the example in the AWS docs is inconsistent, previous # examples specify no query string, but the final POST example # does, apparently incorrectly since an empty parameter list # aligns all steps and the final signature with the examples params = {} credentials = {'host': 'foo:8000', 'verb': 'POST', 'path': '/', 'params': params, 'headers': headers, 'body_hash': body_hash} signature = signer.generate(credentials) expected = ('26dd92ea79aaa49f533d13b1055acdc' 'd7d7321460d64621f96cc79c4f4d4ab2b') self.assertEqual(signature, expected)
def test_generate_v4(self): """ Test v4 generator with data from AWS docs example, see: http://docs.aws.amazon.com/general/latest/gr/ sigv4-create-canonical-request.html and http://docs.aws.amazon.com/general/latest/gr/ sigv4-signed-request-examples.html """ # Create a new signer object with the AWS example key secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY' signer = Ec2Signer(secret) body_hash = ('b6359072c78d70ebee1e81adcbab4f0' '1bf2c23245fa365ef83fe8f1f955085e2') auth_str = ('AWS4-HMAC-SHA256 ' 'Credential=AKIAIOSFODNN7EXAMPLE/20110909/' 'us-east-1/iam/aws4_request,' 'SignedHeaders=content-type;host;x-amz-date,') headers = { 'Content-type': 'application/x-www-form-urlencoded; charset=utf-8', 'X-Amz-Date': '20110909T233600Z', 'Host': 'iam.amazonaws.com', 'Authorization': auth_str } # Note the example in the AWS docs is inconsistent, previous # examples specify no query string, but the final POST example # does, apparently incorrectly since an empty parameter list # aligns all steps and the final signature with the examples params = {} credentials = { 'host': 'iam.amazonaws.com', 'verb': 'POST', 'path': '/', 'params': params, 'headers': headers, 'body_hash': body_hash } signature = signer.generate(credentials) expected = ('ced6826de92d2bdeed8f846f0bf508e8' '559e98e4b0199114b84c54174deb456c') self.assertEqual(signature, expected)
def test_generate_v4_port_strip(self): """ Test v4 generator with host:port format, but for an old (<2.9.3) version of boto, where the port should be stripped to match boto behavior """ # Create a new signer object with the AWS example key secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY' signer = Ec2Signer(secret) body_hash = ('b6359072c78d70ebee1e81adcbab4f0' '1bf2c23245fa365ef83fe8f1f955085e2') auth_str = ('AWS4-HMAC-SHA256 ' 'Credential=AKIAIOSFODNN7EXAMPLE/20110909/' 'us-east-1/iam/aws4_request,' 'SignedHeaders=content-type;host;x-amz-date,') headers = {'Content-type': 'application/x-www-form-urlencoded; charset=utf-8', 'X-Amz-Date': '20110909T233600Z', 'Host': 'foo:8000', 'Authorization': auth_str, 'User-Agent': 'Boto/2.9.2 (linux2)'} # Note the example in the AWS docs is inconsistent, previous # examples specify no query string, but the final POST example # does, apparently incorrectly since an empty parameter list # aligns all steps and the final signature with the examples params = {} credentials = {'host': 'foo:8000', 'verb': 'POST', 'path': '/', 'params': params, 'headers': headers, 'body_hash': body_hash} signature = signer.generate(credentials) expected = ('9a4b2276a5039ada3b90f72ea8ec1745' '14b92b909fb106b22ad910c5d75a54f4') self.assertEqual(expected, signature)
def setUp(self): super(Ec2SignerTest, self).setUp() self.access = '966afbde20b84200ae4e62e09acf46b2' self.secret = '89cdf9e94e2643cab35b8b8ac5a51f83' self.signer = Ec2Signer(self.secret)