diff options
author | bwarsaw <> | 2004-12-30 20:49:31 +0000 |
---|---|---|
committer | bwarsaw <> | 2004-12-30 20:49:31 +0000 |
commit | 292e9a631ebec94138bd4f3b1f5a1a9faea9cb38 (patch) | |
tree | 1a48bcb9e9fbcce81a636e0af2f97ee57cf7f82c /Mailman | |
parent | bef8ca35019a13a4973086e7bf60d52e815763da (diff) | |
download | mailman2-292e9a631ebec94138bd4f3b1f5a1a9faea9cb38.tar.gz mailman2-292e9a631ebec94138bd4f3b1f5a1a9faea9cb38.tar.xz mailman2-292e9a631ebec94138bd4f3b1f5a1a9faea9cb38.zip |
From the NEWS file:
- Added the ability for Mailman generated passwords (both member and list
admin) to be more cryptographically secure. See new configuration
variables USER_FRIENDLY_PASSWORDS, MEMBER_PASSWORD_LENGTH, and
ADMIN_PASSWORD_LENGTH. Also added a new bin/withlist script called
reset_pw which can be used to reset all member passwords. Passwords
generated by Mailman are now 8 characters by default for members, and 10
characters for list administrators.
Diffstat (limited to 'Mailman')
-rw-r--r-- | Mailman/Cgi/create.py | 3 | ||||
-rw-r--r-- | Mailman/Defaults.py.in | 15 | ||||
-rw-r--r-- | Mailman/Utils.py | 51 |
3 files changed, 62 insertions, 7 deletions
diff --git a/Mailman/Cgi/create.py b/Mailman/Cgi/create.py index 09e4790c..a67614cf 100644 --- a/Mailman/Cgi/create.py +++ b/Mailman/Cgi/create.py @@ -125,7 +125,8 @@ def process_request(doc, cgidata): blank if you want Mailman to autogenerate the list passwords.''')) return - password = confirm = Utils.MakeRandomPassword(length=8) + password = confirm = Utils.MakeRandomPassword( + mm_cfg.ADMIN_PASSWORD_LENGTH) else: if password <> confirm: request_creation(doc, cgidata, diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in index 3c7ecfdb..ca1fcd65 100644 --- a/Mailman/Defaults.py.in +++ b/Mailman/Defaults.py.in @@ -787,6 +787,21 @@ ADMIN_CATEGORIES = [ # list's config variable default_member_moderation. DEFAULT_NEW_MEMBER_OPTIONS = 256 +# Specify the type of passwords to use, when Mailman generates the passwords +# itself, as would be the case for membership requests where the user did not +# fill in a password, or during list creation, when auto-generation of admin +# passwords was selected. +# +# Set this value to Yes for classic Mailman user-friendly(er) passwords. +# These generate semi-pronounceable passwords which are easier to remember. +# Set this value to No to use more cryptographically secure, but harder to +# remember, passwords -- if your operating system and Python version support +# the necessary feature (specifically that /dev/urandom be available). +USER_FRIENDLY_PASSWORDS = Yes +# This value specifies the default lengths of member and list admin passwords +MEMBER_PASSWORD_LENGTH = 8 +ADMIN_PASSWORD_LENGTH = 10 + ##### diff --git a/Mailman/Utils.py b/Mailman/Utils.py index 03575998..a6e07e10 100644 --- a/Mailman/Utils.py +++ b/Mailman/Utils.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2003 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2004 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -27,12 +27,13 @@ from __future__ import nested_scopes import os import re -import random -import urlparse +import cgi import sha -import errno import time -import cgi +import errno +import base64 +import random +import urlparse import htmlentitydefs import email.Header import email.Iterators @@ -298,12 +299,50 @@ for v in _vowels: _syllables.append(v+c) del c, v -def MakeRandomPassword(length=6): +def UserFriendly_MakeRandomPassword(length): syls = [] while len(syls) * 2 < length: syls.append(random.choice(_syllables)) return EMPTYSTRING.join(syls)[:length] + +def Secure_MakeRandomPassword(length): + bytesread = 0 + bytes = [] + fd = None + try: + while bytesread < length: + try: + # Python 2.4 has this on available systems. + newbytes = os.urandom(length - bytesread) + except (AttributeError, NotImplementedError): + if fd is None: + try: + fd = os.open('/dev/urandom', os.O_RDONLY) + except OSError, e: + if e.errno <> errno.ENOENT: + raise + # We have no available source of cryptographically + # secure random characters. Log an error and fallback + # to the user friendly passwords. + return UserFriendly_MakeRandomPassword(length) + newbytes = os.read(fd, length - bytesread) + bytes.append(newbytes) + bytesread += len(newbytes) + s = base64.encodestring(EMPTYSTRING.join(bytes)) + # base64 will expand the string by 4/3rds + return s.replace('\n', '')[:length] + finally: + if fd is not None: + os.close(fd) + + +def MakeRandomPassword(length=mm_cfg.MEMBER_PASSWORD_LENGTH): + if mm_cfg.USER_FRIENDLY_PASSWORDS: + return UserFriendly_MakeRandomPassword(length) + return Secure_MakeRandomPassword(length) + + def GetRandomSeed(): chr1 = int(random.random() * 52) chr2 = int(random.random() * 52) |