1515# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717#
18- # $Id: password.py,v 1.5 2002-09-10 00:18:20 richard Exp $
18+ # $Id: password.py,v 1.6 2002-09-26 07:39:21 richard Exp $
1919
2020__doc__ = """
2121Password handling (encoding, decoding).
2222"""
2323
24- import sha , re
24+ import sha , re , string
25+ try :
26+ import crypt :
27+ except :
28+ crypt = None
29+ pass
2530
26- def encodePassword (plaintext , scheme ):
31+ def encodePassword (plaintext , scheme , other = None ):
2732 '''Encrypt the plaintext password.
2833 '''
2934 if scheme == 'SHA' :
3035 s = sha .sha (plaintext ).hexdigest ()
36+ elif scheme == 'crypt' and crypt is not None :
37+ if other is not None :
38+ salt = other [:2 ]
39+ else :
40+ saltchars = './0123456789' + string .letters
41+ salt = random .choice (saltchars ) + random .choice (saltchars )
42+ s = crypt .crypt (plaintext , salt )
3143 elif scheme == 'plaintext' :
32- pass
44+ s = plaintext
3345 else :
3446 raise ValueError , 'Unknown encryption scheme "%s"' % scheme
3547 return s
@@ -60,8 +72,10 @@ class Password:
6072 default_scheme = 'SHA' # new encryptions use this scheme
6173 pwre = re .compile (r'{(\w+)}(.+)' )
6274
63- def __init__ (self , plaintext = None ):
75+ def __init__ (self , plaintext = None , scheme = None ):
6476 '''Call setPassword if plaintext is not None.'''
77+ if scheme is None :
78+ scheme = self .default_scheme
6579 if plaintext is not None :
6680 self .password = encodePassword (plaintext , self .default_scheme )
6781 self .scheme = self .default_scheme
@@ -82,22 +96,25 @@ def unpack(self, encrypted):
8296 self .password = encodePassword (encrypted , self .default_scheme )
8397 self .scheme = self .default_scheme
8498
85- def setPassword (self , plaintext ):
99+ def setPassword (self , plaintext , scheme = None ):
86100 '''Sets encrypts plaintext.'''
87- self .password = encodePassword (plaintext , self .scheme )
101+ if scheme is None :
102+ scheme = self .default_scheme
103+ self .password = encodePassword (plaintext , scheme )
88104
89105 def __cmp__ (self , other ):
90106 '''Compare this password against another password.'''
91107 # check to see if we're comparing instances
92108 if isinstance (other , Password ):
93109 if self .scheme != other .scheme :
94- return
110+ return cmp ( self . scheme , other . scheme )
95111 return cmp (self .password , other .password )
96112
97113 # assume password is plaintext
98114 if self .password is None :
99115 raise ValueError , 'Password not set'
100- return cmp (self .password , encodePassword (other , self .scheme ))
116+ return cmp (self .password , encodePassword (other , self .scheme ,
117+ self .password ))
101118
102119 def __str__ (self ):
103120 '''Stringify the encrypted password for database storage.'''
@@ -106,12 +123,20 @@ def __str__(self):
106123 return '{%s}%s' % (self .scheme , self .password )
107124
108125def test ():
126+ # SHA
109127 p = Password ('sekrit' )
110128 assert p == 'sekrit'
111129 assert p != 'not sekrit'
112130 assert 'sekrit' == p
113131 assert 'not sekrit' != p
114132
133+ # crypt
134+ p = Password ('sekrit' , 'crypt' )
135+ assert p == 'sekrit'
136+ assert p != 'not sekrit'
137+ assert 'sekrit' == p
138+ assert 'not sekrit' != p
139+
115140if __name__ == '__main__' :
116141 test ()
117142
0 commit comments