40
37
LOG = logging.getLogger(__name__)
42
ISO_TIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
43
39
MAX_PASSWORD_LENGTH = 4096
46
def import_class(import_str):
47
"""Returns a class from a string including module and class."""
48
mod_str, _sep, class_str = import_str.rpartition('.')
51
return getattr(sys.modules[mod_str], class_str)
52
except (ImportError, ValueError, AttributeError), exc:
53
LOG.debug('Inner Exception: %s', exc)
57
def import_object(import_str, *args, **kw):
58
"""Returns an object including a module or module and class."""
60
__import__(import_str)
61
return sys.modules[import_str]
63
cls = import_class(import_str)
64
return cls(*args, **kw)
67
def find_config(config_path):
68
"""Find a configuration file using the given hint.
70
:param config_path: Full or relative path to the config.
71
:returns: Full path of the config, if it exists.
74
possible_locations = [
76
os.path.join('etc', 'keystone', config_path),
77
os.path.join('etc', config_path),
78
os.path.join(config_path),
79
'/etc/keystone/%s' % config_path,
82
for path in possible_locations:
83
if os.path.exists(path):
84
return os.path.abspath(path)
86
raise Exception('Config not found: %s', os.path.abspath(config_path))
89
42
def read_cached_file(filename, cache_info, reload_func=None):
90
43
"""Read from a file if it has been modified.
114
67
return super(SmarterEncoder, self).default(obj)
117
class Ec2Signer(object):
118
"""Hacked up code from boto/connection.py"""
120
def __init__(self, secret_key):
121
secret_key = secret_key.encode()
122
self.hmac = hmac.new(secret_key, digestmod=hashlib.sha1)
124
self.hmac_256 = hmac.new(secret_key, digestmod=hashlib.sha256)
126
def generate(self, credentials):
127
"""Generate auth string according to what SignatureVersion is given."""
128
if credentials['params']['SignatureVersion'] == '0':
129
return self._calc_signature_0(credentials['params'])
130
if credentials['params']['SignatureVersion'] == '1':
131
return self._calc_signature_1(credentials['params'])
132
if credentials['params']['SignatureVersion'] == '2':
133
return self._calc_signature_2(credentials['params'],
137
raise Exception('Unknown Signature Version: %s' %
138
credentials['params']['SignatureVersion'])
141
def _get_utf8_value(value):
142
"""Get the UTF8-encoded version of a value."""
143
if not isinstance(value, str) and not isinstance(value, unicode):
145
if isinstance(value, unicode):
146
return value.encode('utf-8')
150
def _calc_signature_0(self, params):
151
"""Generate AWS signature version 0 string."""
152
s = params['Action'] + params['Timestamp']
154
return base64.b64encode(self.hmac.digest())
156
def _calc_signature_1(self, params):
157
"""Generate AWS signature version 1 string."""
159
keys.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))
161
self.hmac.update(key)
162
val = self._get_utf8_value(params[key])
163
self.hmac.update(val)
164
return base64.b64encode(self.hmac.digest())
166
def _calc_signature_2(self, params, verb, server_string, path):
167
"""Generate AWS signature version 2 string."""
168
LOG.debug('using _calc_signature_2')
169
string_to_sign = '%s\n%s\n%s\n' % (verb, server_string, path)
171
current_hmac = self.hmac_256
172
params['SignatureMethod'] = 'HmacSHA256'
174
current_hmac = self.hmac
175
params['SignatureMethod'] = 'HmacSHA1'
180
val = self._get_utf8_value(params[key])
181
val = urllib.quote(val, safe='-_~')
182
pairs.append(urllib.quote(key, safe='') + '=' + val)
184
LOG.debug('query string: %s', qs)
186
LOG.debug('string_to_sign: %s', string_to_sign)
187
current_hmac.update(string_to_sign)
188
b64 = base64.b64encode(current_hmac.digest())
189
LOG.debug('len(b64)=%d', len(b64))
190
LOG.debug('base64 encoded digest: %s', b64)
194
70
def trunc_password(password):
195
71
"""Truncate passwords to the MAX_PASSWORD_LENGTH."""
196
if len(password) > MAX_PASSWORD_LENGTH:
197
return password[:MAX_PASSWORD_LENGTH]
73
if len(password) > MAX_PASSWORD_LENGTH:
74
return password[:MAX_PASSWORD_LENGTH]
78
raise exception.ValidationError(attribute='string', target='password')
81
def hash_user_password(user):
82
"""Hash a user dict's password without modifying the passed-in dict"""
84
password = user['password']
88
return dict(user, password=hash_password(password))
91
def hash_ldap_user_password(user):
92
"""Hash a user dict's password without modifying the passed-in dict"""
94
password = user['password']
98
return dict(user, password=ldap_hash_password(password))
202
101
def hash_password(password):
318
206
b = ord(known[i]) if i < k_len else 0
320
208
return (p_len == k_len) & (result == 0)
211
def hash_signed_token(signed_text):
212
hash_ = hashlib.md5()
213
hash_.update(signed_text)
214
return hash_.hexdigest()
217
def setup_remote_pydev_debug():
218
if CONF.pydev_debug_host and CONF.pydev_debug_port:
219
error_msg = ('Error setting up the debug environment. Verify that the'
220
' option --debug-url has the format <host>:<port> and '
221
'that a debugger processes is listening on that port.')
225
from pydevd import pydevd
229
pydevd.settrace(CONF.pydev_debug_host,
230
port=CONF.pydev_debug_port,
235
LOG.exception(_(error_msg))
239
class LimitingReader(object):
240
"""Reader to limit the size of an incoming request."""
241
def __init__(self, data, limit):
243
:param data: Underlying data object
244
:param limit: maximum number of bytes the reader should allow
251
for chunk in self.data:
252
self.bytes_read += len(chunk)
253
if self.bytes_read > self.limit:
254
raise exception.RequestTooLarge()
259
result = self.data.read(i)
260
self.bytes_read += len(result)
261
if self.bytes_read > self.limit:
262
raise exception.RequestTooLarge()
266
result = self.data.read()
267
self.bytes_read += len(result)
268
if self.bytes_read > self.limit:
269
raise exception.RequestTooLarge()