summaryrefslogtreecommitdiff
path: root/Mailman
diff options
context:
space:
mode:
authorbwarsaw2001-07-03 04:34:29 +0000
committerbwarsaw2001-07-03 04:34:29 +0000
commit096b4c89b916052f60b9105dd59f04b072a2bf3b (patch)
treea9171d48a188a3eeb326520602633032c79ebf49 /Mailman
parentc7ed6eb58c2881ba81a49502b233c3400c991d11 (diff)
downloadmailman-096b4c89b916052f60b9105dd59f04b072a2bf3b.tar.gz
mailman-096b4c89b916052f60b9105dd59f04b072a2bf3b.tar.zst
mailman-096b4c89b916052f60b9105dd59f04b072a2bf3b.zip
ConfirmUserPassword(): Obsolete; removed.
AuthContextInfo(): Allow `user' argument to be optional; default to None. Authenticate(): Re-install backwards compatibility for pre-MM2.1 list passwords. For AuthListAdmin context only, if the sha check fails, fallback to crypt (if the crypt module could be imported) and md5 checks. If either of the latter two matches, assume that the list password is "old style" and auto-upgrade it to the sha password, based on the matching plain text response. This way, MM2.0.x list passwords won't just be broken upon an upgrade.
Diffstat (limited to 'Mailman')
-rw-r--r--Mailman/SecurityManager.py76
1 files changed, 49 insertions, 27 deletions
diff --git a/Mailman/SecurityManager.py b/Mailman/SecurityManager.py
index f4cfc64aa..5b1efb66f 100644
--- a/Mailman/SecurityManager.py
+++ b/Mailman/SecurityManager.py
@@ -59,11 +59,13 @@ try:
import crypt
except ImportError:
crypt = None
+import md5
-from Mailman import Errors
+from Mailman import mm_cfg
from Mailman import Utils
+from Mailman import Errors
from Mailman import Cookie
-from Mailman import mm_cfg
+from Mailman.Logging.Syslog import syslog
@@ -76,7 +78,7 @@ class SecurityManager:
# Non configurable
self.passwords = {}
- def AuthContextInfo(self, authcontext, user):
+ def AuthContextInfo(self, authcontext, user=None):
# authcontext may be one of AuthUser, AuthListModerator,
# AuthListAdmin, AuthSiteAdmin. Not supported is the AuthCreator
# context.
@@ -135,19 +137,55 @@ class SecurityManager:
ok = Utils.check_global_password(response)
if ok:
return mm_cfg.AuthSiteAdmin
- else:
+ elif ac == mm_cfg.AuthListAdmin:
# The password for the list admin and list moderator are not
# kept as plain text, but instead as an sha hexdigest. The
# response being passed in is plain text, so we need to
- # digestify it first.
- if ac in (mm_cfg.AuthListAdmin, mm_cfg.AuthListModerator):
- chkresponse = sha.new(response).hexdigest()
- else:
- chkresponse = response
-
+ # digestify it first. Note however, that for backwards
+ # compatibility reasons, we'll also check the admin response
+ # against the crypted and md5'd passwords, and if they match,
+ # we'll auto-migrate the passwords to sha.
+ key, secret = self.AuthContextInfo(ac)
+ if secret is None:
+ continue
+ sharesponse = sha.new(response).hexdigest()
+ upgrade = ok = 0
+ if sharesponse == secret:
+ ok = 1
+ elif md5.new(response).digest() == secret:
+ ok = 1
+ upgrade = 1
+ elif crypt and crypt.crypt(response, secret[:2]) == secret:
+ ok = 1
+ upgrade = 1
+ if upgrade:
+ save_and_unlock = 0
+ if not self.Locked():
+ self.Lock()
+ save_and_unlock = 1
+ try:
+ self.password = sharesponse
+ if save_and_unlock:
+ self.Save()
+ finally:
+ if save_and_unlock:
+ self.Unlock()
+ if ok:
+ return ac
+ elif ac == mm_cfg.AuthListModerator:
+ # The list moderator password must be sha'd
+ key, secret = self.AuthContextInfo(ac)
+ if secret and sha.new(response).hexdigest() == secret:
+ return ac
+ elif ac == mm_cfg.AuthUser:
+ # The user's passwords are kept in plain text
key, secret = self.AuthContextInfo(ac, user)
- if secret is not None and chkresponse == secret:
+ if secret and response == secret:
return ac
+ else:
+ # What is this context???
+ syslog('error', 'Bad authcontext: %s', ac)
+ raise ValueError, 'Bad authcontext: %s' % ac
return mm_cfg.UnAuthorized
def WebAuthenticate(self, authcontexts, response, user=None):
@@ -269,22 +307,6 @@ class SecurityManager:
# Authenticated!
return 1
- def ConfirmUserPassword(self, user, pw):
- """True if password is valid for site, list admin, or specific user."""
- if self.ValidAdminPassword(pw):
- return 1
- if user is None:
- raise Errors.MMBadUserError
- addr = self.FindUser(user)
- if addr is None:
- raise Errors.MMNotAMemberError
- storedpw = self.passwords.get(addr)
- if storedpw is None:
- raise Errors.MMBadUserError
- if storedpw <> pw:
- raise Errors.MMBadPasswordError
- return 1
-
def ChangeUserPassword(self, user, newpw, confirm):
addr = self.FindUser(user)
if not addr: