diff options
| author | bwarsaw | 2001-07-03 04:34:29 +0000 |
|---|---|---|
| committer | bwarsaw | 2001-07-03 04:34:29 +0000 |
| commit | 096b4c89b916052f60b9105dd59f04b072a2bf3b (patch) | |
| tree | a9171d48a188a3eeb326520602633032c79ebf49 /Mailman | |
| parent | c7ed6eb58c2881ba81a49502b233c3400c991d11 (diff) | |
| download | mailman-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.py | 76 |
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: |
