Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: boto/auth.py

Issue 8386013: Merging in latest boto. (Closed) Base URL: svn://svn.chromium.org/boto
Patch Set: Redoing vendor drop by deleting and then merging. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « boto/__init__.py ('k') | boto/cacerts/__init__.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2010 Google Inc. 1 # Copyright 2010 Google Inc.
2 # Copyright (c) 2011 Mitch Garnaat http://garnaat.org/ 2 # Copyright (c) 2011 Mitch Garnaat http://garnaat.org/
3 # Copyright (c) 2011, Eucalyptus Systems, Inc. 3 # Copyright (c) 2011, Eucalyptus Systems, Inc.
4 # 4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a 5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the 6 # copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including 7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish, dis- 8 # without limitation the rights to use, copy, modify, merge, publish, dis-
9 # tribute, sublicense, and/or sell copies of the Software, and to permit 9 # tribute, sublicense, and/or sell copies of the Software, and to permit
10 # persons to whom the Software is furnished to do so, subject to the fol- 10 # persons to whom the Software is furnished to do so, subject to the fol-
(...skipping 16 matching lines...) Expand all
27 """ 27 """
28 28
29 import base64 29 import base64
30 import boto 30 import boto
31 import boto.auth_handler 31 import boto.auth_handler
32 import boto.exception 32 import boto.exception
33 import boto.plugin 33 import boto.plugin
34 import boto.utils 34 import boto.utils
35 import hmac 35 import hmac
36 import sys 36 import sys
37 import time
38 import urllib 37 import urllib
38 from email.utils import formatdate
39 39
40 from boto.auth_handler import AuthHandler 40 from boto.auth_handler import AuthHandler
41 from boto.exception import BotoClientError 41 from boto.exception import BotoClientError
42 # 42 #
43 # the following is necessary because of the incompatibilities 43 # the following is necessary because of the incompatibilities
44 # between Python 2.4, 2.5, and 2.6 as well as the fact that some 44 # between Python 2.4, 2.5, and 2.6 as well as the fact that some
45 # people running 2.4 have installed hashlib as a separate module 45 # people running 2.4 have installed hashlib as a separate module
46 # this fix was provided by boto user mccormix. 46 # this fix was provided by boto user mccormix.
47 # see: http://code.google.com/p/boto/issues/detail?id=172 47 # see: http://code.google.com/p/boto/issues/detail?id=172
48 # for more details. 48 # for more details.
(...skipping 21 matching lines...) Expand all
70 70
71 class HmacKeys(object): 71 class HmacKeys(object):
72 """Key based Auth handler helper.""" 72 """Key based Auth handler helper."""
73 73
74 def __init__(self, host, config, provider): 74 def __init__(self, host, config, provider):
75 if provider.access_key is None or provider.secret_key is None: 75 if provider.access_key is None or provider.secret_key is None:
76 raise boto.auth_handler.NotReadyToAuthenticate() 76 raise boto.auth_handler.NotReadyToAuthenticate()
77 self._provider = provider 77 self._provider = provider
78 self._hmac = hmac.new(self._provider.secret_key, digestmod=sha) 78 self._hmac = hmac.new(self._provider.secret_key, digestmod=sha)
79 if sha256: 79 if sha256:
80 self._hmac_256 = hmac.new(self._provider.secret_key, digestmod=sha25 6) 80 self._hmac_256 = hmac.new(self._provider.secret_key,
81 digestmod=sha256)
81 else: 82 else:
82 self._hmac_256 = None 83 self._hmac_256 = None
83 84
84 def algorithm(self): 85 def algorithm(self):
85 if self._hmac_256: 86 if self._hmac_256:
86 return 'HmacSHA256' 87 return 'HmacSHA256'
87 else: 88 else:
88 return 'HmacSHA1' 89 return 'HmacSHA1'
89 90
90 def sign_string(self, string_to_sign): 91 def sign_string(self, string_to_sign):
(...skipping 13 matching lines...) Expand all
104 def __init__(self, host, config, provider): 105 def __init__(self, host, config, provider):
105 AuthHandler.__init__(self, host, config, provider) 106 AuthHandler.__init__(self, host, config, provider)
106 HmacKeys.__init__(self, host, config, provider) 107 HmacKeys.__init__(self, host, config, provider)
107 self._hmac_256 = None 108 self._hmac_256 = None
108 109
109 def add_auth(self, http_request, **kwargs): 110 def add_auth(self, http_request, **kwargs):
110 headers = http_request.headers 111 headers = http_request.headers
111 method = http_request.method 112 method = http_request.method
112 auth_path = http_request.auth_path 113 auth_path = http_request.auth_path
113 if not headers.has_key('Date'): 114 if not headers.has_key('Date'):
114 headers['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", 115 headers['Date'] = formatdate(usegmt=True)
115 time.gmtime())
116 116
117 if self._provider.security_token:
118 key = self._provider.security_token_header
119 headers[key] = self._provider.security_token
117 c_string = boto.utils.canonical_string(method, auth_path, headers, 120 c_string = boto.utils.canonical_string(method, auth_path, headers,
118 None, self._provider) 121 None, self._provider)
119 b64_hmac = self.sign_string(c_string) 122 b64_hmac = self.sign_string(c_string)
120 auth_hdr = self._provider.auth_header 123 auth_hdr = self._provider.auth_header
121 headers['Authorization'] = ("%s %s:%s" % 124 headers['Authorization'] = ("%s %s:%s" %
122 (auth_hdr, 125 (auth_hdr,
123 self._provider.access_key, b64_hmac)) 126 self._provider.access_key, b64_hmac))
124 127
125 class HmacAuthV2Handler(AuthHandler, HmacKeys): 128 class HmacAuthV2Handler(AuthHandler, HmacKeys):
126 """ 129 """
127 Implements the simplified HMAC authorization used by CloudFront. 130 Implements the simplified HMAC authorization used by CloudFront.
128 """ 131 """
129 capability = ['hmac-v2', 'cloudfront'] 132 capability = ['hmac-v2', 'cloudfront']
130 133
131 def __init__(self, host, config, provider): 134 def __init__(self, host, config, provider):
132 AuthHandler.__init__(self, host, config, provider) 135 AuthHandler.__init__(self, host, config, provider)
133 HmacKeys.__init__(self, host, config, provider) 136 HmacKeys.__init__(self, host, config, provider)
134 self._hmac_256 = None 137 self._hmac_256 = None
135 138
136 def add_auth(self, http_request, **kwargs): 139 def add_auth(self, http_request, **kwargs):
137 headers = http_request.headers 140 headers = http_request.headers
138 if not headers.has_key('Date'): 141 if not headers.has_key('Date'):
139 headers['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", 142 headers['Date'] = formatdate(usegmt=True)
140 time.gmtime())
141 143
142 b64_hmac = self.sign_string(headers['Date']) 144 b64_hmac = self.sign_string(headers['Date'])
143 auth_hdr = self._provider.auth_header 145 auth_hdr = self._provider.auth_header
144 headers['Authorization'] = ("%s %s:%s" % 146 headers['Authorization'] = ("%s %s:%s" %
145 (auth_hdr, 147 (auth_hdr,
146 self._provider.access_key, b64_hmac)) 148 self._provider.access_key, b64_hmac))
147 149
148 class HmacAuthV3Handler(AuthHandler, HmacKeys): 150 class HmacAuthV3Handler(AuthHandler, HmacKeys):
149 """Implements the new Version 3 HMAC authorization used by Route53.""" 151 """Implements the new Version 3 HMAC authorization used by Route53."""
150 152
151 capability = ['hmac-v3', 'route53', 'ses'] 153 capability = ['hmac-v3', 'route53', 'ses']
152 154
153 def __init__(self, host, config, provider): 155 def __init__(self, host, config, provider):
154 AuthHandler.__init__(self, host, config, provider) 156 AuthHandler.__init__(self, host, config, provider)
155 HmacKeys.__init__(self, host, config, provider) 157 HmacKeys.__init__(self, host, config, provider)
156 158
157 def add_auth(self, http_request, **kwargs): 159 def add_auth(self, http_request, **kwargs):
158 headers = http_request.headers 160 headers = http_request.headers
159 if not headers.has_key('Date'): 161 if not headers.has_key('Date'):
160 headers['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT", 162 headers['Date'] = formatdate(usegmt=True)
161 time.gmtime())
162 163
163 b64_hmac = self.sign_string(headers['Date']) 164 b64_hmac = self.sign_string(headers['Date'])
164 s = "AWS3-HTTPS AWSAccessKeyId=%s," % self._provider.access_key 165 s = "AWS3-HTTPS AWSAccessKeyId=%s," % self._provider.access_key
165 s += "Algorithm=%s,Signature=%s" % (self.algorithm(), b64_hmac) 166 s += "Algorithm=%s,Signature=%s" % (self.algorithm(), b64_hmac)
166 headers['X-Amzn-Authorization'] = s 167 headers['X-Amzn-Authorization'] = s
167 168
168 class QuerySignatureHelper(HmacKeys): 169 class QuerySignatureHelper(HmacKeys):
169 """Helper for Query signature based Auth handler. 170 """Helper for Query signature based Auth handler.
170 171
171 Concrete sub class need to implement _calc_sigature method. 172 Concrete sub class need to implement _calc_sigature method.
172 """ 173 """
173 174
174 def add_auth(self, http_request, **kwargs): 175 def add_auth(self, http_request, **kwargs):
175 headers = http_request.headers 176 headers = http_request.headers
176 params = http_request.params 177 params = http_request.params
177 params['AWSAccessKeyId'] = self._provider.access_key 178 params['AWSAccessKeyId'] = self._provider.access_key
178 params['SignatureVersion'] = self.SignatureVersion 179 params['SignatureVersion'] = self.SignatureVersion
179 params['Timestamp'] = boto.utils.get_ts() 180 params['Timestamp'] = boto.utils.get_ts()
180 qs, signature = self._calc_signature( 181 qs, signature = self._calc_signature(
181 http_request.params, http_request.method, 182 http_request.params, http_request.method,
182 http_request.path, http_request.host) 183 http_request.auth_path, http_request.host)
183 boto.log.debug('query_string: %s Signature: %s' % (qs, signature)) 184 boto.log.debug('query_string: %s Signature: %s' % (qs, signature))
184 if http_request.method == 'POST': 185 if http_request.method == 'POST':
185 headers['Content-Type'] = 'application/x-www-form-urlencoded; charse t=UTF-8' 186 headers['Content-Type'] = 'application/x-www-form-urlencoded; charse t=UTF-8'
186 http_request.body = qs + '&Signature=' + urllib.quote(signature) 187 http_request.body = qs + '&Signature=' + urllib.quote(signature)
188 http_request.headers['Content-Length'] = str(len(http_request.body))
187 else: 189 else:
188 http_request.body = '' 190 http_request.body = ''
189 http_request.path = (http_request.path + '?' + qs + '&Signature=' + urllib.quote(signature)) 191 # if this is a retried request, the qs from the previous try will
190 # Now that query params are part of the path, clear the 'params' field 192 # already be there, we need to get rid of that and rebuild it
191 # in request. 193 http_request.path = http_request.path.split('?')[0]
192 http_request.params = {} 194 http_request.path = (http_request.path + '?' + qs +
195 '&Signature=' + urllib.quote(signature))
193 196
194 class QuerySignatureV0AuthHandler(QuerySignatureHelper, AuthHandler): 197 class QuerySignatureV0AuthHandler(QuerySignatureHelper, AuthHandler):
195 """Class SQS query signature based Auth handler.""" 198 """Provides Signature V0 Signing"""
196 199
197 SignatureVersion = 0 200 SignatureVersion = 0
198 capability = ['sign-v0'] 201 capability = ['sign-v0']
199 202
200 def _calc_signature(self, params, *args): 203 def _calc_signature(self, params, *args):
201 boto.log.debug('using _calc_signature_0') 204 boto.log.debug('using _calc_signature_0')
202 hmac = self._hmac.copy() 205 hmac = self._hmac.copy()
203 s = params['Action'] + params['Timestamp'] 206 s = params['Action'] + params['Timestamp']
204 hmac.update(s) 207 hmac.update(s)
205 keys = params.keys() 208 keys = params.keys()
206 keys.sort(cmp = lambda x, y: cmp(x.lower(), y.lower())) 209 keys.sort(cmp = lambda x, y: cmp(x.lower(), y.lower()))
207 pairs = [] 210 pairs = []
208 for key in keys: 211 for key in keys:
209 val = bot.utils.get_utf8_value(params[key]) 212 val = boto.utils.get_utf8_value(params[key])
210 pairs.append(key + '=' + urllib.quote(val)) 213 pairs.append(key + '=' + urllib.quote(val))
211 qs = '&'.join(pairs) 214 qs = '&'.join(pairs)
212 return (qs, base64.b64encode(hmac.digest())) 215 return (qs, base64.b64encode(hmac.digest()))
213 216
214 class QuerySignatureV1AuthHandler(QuerySignatureHelper, AuthHandler): 217 class QuerySignatureV1AuthHandler(QuerySignatureHelper, AuthHandler):
215 """ 218 """
216 Provides Query Signature V1 Authentication. 219 Provides Query Signature V1 Authentication.
217 """ 220 """
218 221
219 SignatureVersion = 1 222 SignatureVersion = 1
(...skipping 11 matching lines...) Expand all
231 hmac.update(val) 234 hmac.update(val)
232 pairs.append(key + '=' + urllib.quote(val)) 235 pairs.append(key + '=' + urllib.quote(val))
233 qs = '&'.join(pairs) 236 qs = '&'.join(pairs)
234 return (qs, base64.b64encode(hmac.digest())) 237 return (qs, base64.b64encode(hmac.digest()))
235 238
236 class QuerySignatureV2AuthHandler(QuerySignatureHelper, AuthHandler): 239 class QuerySignatureV2AuthHandler(QuerySignatureHelper, AuthHandler):
237 """Provides Query Signature V2 Authentication.""" 240 """Provides Query Signature V2 Authentication."""
238 241
239 SignatureVersion = 2 242 SignatureVersion = 2
240 capability = ['sign-v2', 'ec2', 'ec2', 'emr', 'fps', 'ecs', 243 capability = ['sign-v2', 'ec2', 'ec2', 'emr', 'fps', 'ecs',
241 'sdb', 'iam', 'rds', 'sns', 'sqs'] 244 'sdb', 'iam', 'rds', 'sns', 'sqs', 'cloudformation']
242 245
243 def _calc_signature(self, params, verb, path, server_name): 246 def _calc_signature(self, params, verb, path, server_name):
244 boto.log.debug('using _calc_signature_2') 247 boto.log.debug('using _calc_signature_2')
245 string_to_sign = '%s\n%s\n%s\n' % (verb, server_name.lower(), path) 248 string_to_sign = '%s\n%s\n%s\n' % (verb, server_name.lower(), path)
246 if self._hmac_256: 249 if self._hmac_256:
247 hmac = self._hmac_256.copy() 250 hmac = self._hmac_256.copy()
248 params['SignatureMethod'] = 'HmacSHA256' 251 params['SignatureMethod'] = 'HmacSHA256'
249 else: 252 else:
250 hmac = self._hmac.copy() 253 hmac = self._hmac.copy()
251 params['SignatureMethod'] = 'HmacSHA1' 254 params['SignatureMethod'] = 'HmacSHA1'
255 if self._provider.security_token:
256 params['SecurityToken'] = self._provider.security_token
252 keys = params.keys() 257 keys = params.keys()
253 keys.sort() 258 keys.sort()
254 pairs = [] 259 pairs = []
255 for key in keys: 260 for key in keys:
256 val = boto.utils.get_utf8_value(params[key]) 261 val = boto.utils.get_utf8_value(params[key])
257 pairs.append(urllib.quote(key, safe='') + '=' + 262 pairs.append(urllib.quote(key, safe='') + '=' +
258 urllib.quote(val, safe='-_~')) 263 urllib.quote(val, safe='-_~'))
259 qs = '&'.join(pairs) 264 qs = '&'.join(pairs)
260 boto.log.debug('query string: %s' % qs) 265 boto.log.debug('query string: %s' % qs)
261 string_to_sign += qs 266 string_to_sign += qs
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 try: 301 try:
297 ready_handlers.append(handler(host, config, provider)) 302 ready_handlers.append(handler(host, config, provider))
298 except boto.auth_handler.NotReadyToAuthenticate: 303 except boto.auth_handler.NotReadyToAuthenticate:
299 pass 304 pass
300 305
301 if not ready_handlers: 306 if not ready_handlers:
302 checked_handlers = auth_handlers 307 checked_handlers = auth_handlers
303 names = [handler.__name__ for handler in checked_handlers] 308 names = [handler.__name__ for handler in checked_handlers]
304 raise boto.exception.NoAuthHandlerFound( 309 raise boto.exception.NoAuthHandlerFound(
305 'No handler was ready to authenticate. %d handlers were checked.' 310 'No handler was ready to authenticate. %d handlers were checked.'
306 ' %s ' % (len(names), str(names))) 311 ' %s '
312 'Check your credentials' % (len(names), str(names)))
307 313
308 if len(ready_handlers) > 1: 314 if len(ready_handlers) > 1:
309 # NOTE: Even though it would be nice to accept more than one handler 315 # NOTE: Even though it would be nice to accept more than one handler
310 # by using one of the many ready handlers, we are never sure that each 316 # by using one of the many ready handlers, we are never sure that each
311 # of them are referring to the same storage account. Since we cannot 317 # of them are referring to the same storage account. Since we cannot
312 # easily guarantee that, it is always safe to fail, rather than operate 318 # easily guarantee that, it is always safe to fail, rather than operate
313 # on the wrong account. 319 # on the wrong account.
314 names = [handler.__class__.__name__ for handler in ready_handlers] 320 names = [handler.__class__.__name__ for handler in ready_handlers]
315 raise boto.exception.TooManyAuthHandlerReadyToAuthenticate( 321 raise boto.exception.TooManyAuthHandlerReadyToAuthenticate(
316 '%d AuthHandlers ready to authenticate, ' 322 '%d AuthHandlers %s ready to authenticate for requested_capabilit y '
317 'only 1 expected: %s' % (len(names), str(names))) 323 '%s, only 1 expected. This happens if you import multiple '
324 'pluging.Plugin implementations that declare support for the '
325 'requested_capability.' % (len(names), str(names),
326 requested_capability))
318 327
319 return ready_handlers[0] 328 return ready_handlers[0]
OLDNEW
« no previous file with comments | « boto/__init__.py ('k') | boto/cacerts/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698