[Zope-dev] Membership and latest LoginManager
Dan L. Pierson
dan@sol.control.com
13 Nov 2000 13:37:05 -0500
I've been trying to get Membership 0.7.6 working with
LoginManager-0-8-8b1 (and it's associated ZPatterns) under Zope 2.2.2
on RedHat 6.2. After probing around it seems that there is a problem
storing member passwords. The following trace from print statements
inserted in PersistentUserSource illustrates the problem:
==================================================================
using crypt
encodePassword( testing , scheme=' CRYPT ', salt= U3 ) ==>
{CRYPT}U35nKDwqMBaD2addUser
setting password for aral to "{CRYPT}U35nKDwqMBaD2"
password = "{CRYPT}R0nzSkU8huehY"
setting again with direct assignment
password = "{CRYPT}U35nKDwqMBaD2"
authenticateUser(self, aral , testing )
comparePassword( testing , {CRYPT}U35nKDwqMBaD2 )
using crypt
encodePassword( testing , scheme=' CRYPT ', salt= U3 ) ==>
{CRYPT}U35nKDwqMBaD2
comparePassword ==> {CRYPT}U35nKDwqMBaD2 == {CRYPT}U35nKDwqMBaD2
passwords matched
==================================================================
Source bits with print statements follows at the end of this article.
The problem seems to be that:
...manage_changeProperties(password = new_value)
doesn't change the password correctly, but
...password = new_value
works.
Does anyone know what's really going on here?
Modified from PersistentUserSource.py:PersistentUserSource:
def authenticateUser(self,user,password,request):
name = user.getUserName()
ok=0
print 'authenticateUser(self,',name,',',password,')'
if self.cacheGetAuth(name, password):
return 1
if hasattr(self, 'userAuthenticate'):
old_au = setuid(self.REQUEST, _LoggingInUser)
try:
ok = self.userAuthenticate(
self, request, user=user, password=password)
if ok:
print 'self authenticated'
finally:
setuid(self.REQUEST, old_au)
else:
# Why does the following always return '{CRYPT}R0nzSkU8huehY' ???
encpw = user.propertysheets.SystemProperties.password
print 'comparePassword(',password,',',encpw,')'
ok = self.comparePassword(password, encpw)
if ok:
print 'passwords matched'
if ok:
self.cacheSetAuth(name, password)
return ok
def addUser(self, userid, password, roles, domains):
user = self.newItem(userid)
user.propertysheets.RestrictedProperties.manage_changeProperties(roles = roles)
user.propertysheets.SystemProperties.manage_changeProperties(domains = domains)
epass=self.encodePassword(password)
# This always sets the password to '{CRYPT}R0nzSkU8huehY' !!!
print 'addUser setting password for %s to "%s"' % (userid, epass)
user.propertysheets.SystemProperties.manage_changeProperties(password = epass)
print ' password = "%s"' % user.propertysheets.SystemProperties.password
# This works - what is broken with the manage_changeProperties call?
print 'setting again with direct assignment'
user.propertysheets.SystemProperties.password = epass
print ' password = "%s"' % user.propertysheets.SystemProperties.password
return user
Modified from LoginManager/UserSources.py:BasicUserSource
def encodePassword(self, text, scheme='CRYPT', salt=None):
"""Encode a password"""
if scheme == 'CRYPT' and crypt is not None:
print ' using crypt'
if salt is None:
salt = whrandom.randint(0, 2**12-1)
salt = saltdict[salt >> 6] + saltdict[salt & 0x3f]
pw = '{CRYPT}' + crypt.crypt(text, salt)
elif scheme == 'SHA':
pw = '{SHA}' + binascii.b2a_base64(sha.sha(text).digest())[:-1]
elif scheme == 'SSHA':
if salt is None:
# XXX random salt selection could be much better...
salt = hex(whrandom.randint(0, sys.maxint-1))[2:]
salt = sha.sha(salt).digest()
ssha = sha.sha(text + salt).digest()+salt
pw = '{SSHA}' + binascii.b2a_base64(ssha)[:-1]
else:
pw = text
print "encodePassword(",text,", scheme='",scheme,"', salt=",salt,") ==> ",pw
return pw
def comparePassword(self, text, pw):
"""Check if password matches"""
salt = self.extractSalt(pw)
if pw[0] == '{':
scheme = split(pw[1:], '}', 1)[0]
else:
scheme = ''
text = self.encodePassword(text, scheme, salt)
print 'comparePassword ==>',text,'==',pw
return (text == pw)