Skip to content

Commit 24a179c

Browse files
author
Richard Jones
committed
added "crypt" password encoding...
...and ability to set password with already encrypted password through roundup-admin
1 parent 0c2edfd commit 24a179c

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

roundup/admin.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1717
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1818
#
19-
# $Id: admin.py,v 1.32 2002-09-24 01:36:04 richard Exp $
19+
# $Id: admin.py,v 1.33 2002-09-26 07:39:21 richard Exp $
2020

2121
import sys, os, getpass, getopt, re, UserDict, shlex, shutil
2222
try:
@@ -397,7 +397,7 @@ def do_get(self, args):
397397
return 0
398398

399399

400-
def do_set(self, args):
400+
def do_set(self, args, pwre = re.compile(r'{(\w+)}(.+)')):
401401
'''Usage: set [items] property=value property=value ...
402402
Set the given properties of one or more items(s).
403403
@@ -447,7 +447,15 @@ def do_set(self, args):
447447
elif isinstance(proptype, hyperdb.String):
448448
continue
449449
elif isinstance(proptype, hyperdb.Password):
450-
props[key] = password.Password(value)
450+
m = pwre.match(value)
451+
if m:
452+
# password is being given to us encrypted
453+
p = password.Password()
454+
p.scheme = m.group(1)
455+
p.password = m.group(2)
456+
props[key] = p
457+
else:
458+
props[key] = password.Password(value)
451459
elif isinstance(proptype, hyperdb.Date):
452460
try:
453461
props[key] = date.Date(value)
@@ -469,6 +477,7 @@ def do_set(self, args):
469477
try:
470478
apply(cl.set, (itemid, ), props)
471479
except (TypeError, IndexError, ValueError), message:
480+
import traceback; traceback.print_exc()
472481
raise UsageError, message
473482
return 0
474483

roundup/password.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,33 @@
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__ = """
2121
Password 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

108125
def 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+
115140
if __name__ == '__main__':
116141
test()
117142

0 commit comments

Comments
 (0)