comparison roundup/hyperdb.py @ 4480:1613754d2646

Fix first part of Password handling security issue2550688 (thanks Joseph Myers for reporting and Eli Collins for fixing) Small change against original patch: We still accept plaintext passwords (in known_schemes) when parsing encrypted password (e.g. from database). This way existing databases with plaintext passwords continue to work (I don't know of any, this would need patching on the users side) and all regression tests pass.
author Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
date Thu, 14 Apr 2011 12:24:59 +0000
parents 34dce76bb202
children 9bbf3758c16a
comparison
equal deleted inserted replaced
4479:0bdcb1e7f7ce 4480:1613754d2646
70 class Password(_Type): 70 class Password(_Type):
71 """An object designating a Password property.""" 71 """An object designating a Password property."""
72 def from_raw(self, value, **kw): 72 def from_raw(self, value, **kw):
73 if not value: 73 if not value:
74 return None 74 return None
75 m = password.Password.pwre.match(value) 75 try:
76 if m: 76 return password.Password(encrypted=value, strict=True)
77 # password is being given to us encrypted 77 except password.PasswordValueError, message:
78 p = password.Password() 78 raise HyperdbValueError, \
79 p.scheme = m.group(1) 79 _('property %s: %s')%(kw['propname'], message)
80 if p.scheme not in 'SHA crypt plaintext'.split(): 80
81 raise HyperdbValueError, \
82 ('property %s: unknown encryption scheme %r') %\
83 (kw['propname'], p.scheme)
84 p.password = m.group(2)
85 value = p
86 else:
87 try:
88 value = password.Password(value)
89 except password.PasswordValueError, message:
90 raise HyperdbValueError, \
91 _('property %s: %s')%(kw['propname'], message)
92 return value
93 def sort_repr (self, cls, val, name): 81 def sort_repr (self, cls, val, name):
94 if not val: 82 if not val:
95 return val 83 return val
96 return str(val) 84 return str(val)
97 85
1305 elif isinstance(prop, Date): 1293 elif isinstance(prop, Date):
1306 value = date.Date(value) 1294 value = date.Date(value)
1307 elif isinstance(prop, Interval): 1295 elif isinstance(prop, Interval):
1308 value = date.Interval(value) 1296 value = date.Interval(value)
1309 elif isinstance(prop, Password): 1297 elif isinstance(prop, Password):
1310 pwd = password.Password() 1298 value = password.Password(encrypted=value)
1311 pwd.unpack(value)
1312 value = pwd
1313 params[propname] = value 1299 params[propname] = value
1314 elif action == 'create' and params: 1300 elif action == 'create' and params:
1315 # old tracker with data stored in the create! 1301 # old tracker with data stored in the create!
1316 params = {} 1302 params = {}
1317 r.append((nodeid, date.Date(jdate), user, action, params)) 1303 r.append((nodeid, date.Date(jdate), user, action, params))
1335 node = self.db.getnode(self.classname, nodeid) 1321 node = self.db.getnode(self.classname, nodeid)
1336 return iter_roles(node['roles']) 1322 return iter_roles(node['roles'])
1337 1323
1338 def has_role(self, nodeid, *roles): 1324 def has_role(self, nodeid, *roles):
1339 '''See if this node has any roles that appear in roles. 1325 '''See if this node has any roles that appear in roles.
1340 1326
1341 For convenience reasons we take a list. 1327 For convenience reasons we take a list.
1342 In standard schemas only a user has a roles property but 1328 In standard schemas only a user has a roles property but
1343 this may be different in customized schemas. 1329 this may be different in customized schemas.
1344 ''' 1330 '''
1345 roles = dict.fromkeys ([r.strip().lower() for r in roles]) 1331 roles = dict.fromkeys ([r.strip().lower() for r in roles])

Roundup Issue Tracker: http://roundup-tracker.org/