changeset 2435:5742ec1cbb37

merge main
author Johannes Berg <johannes AT sipsolutions DOT net>
date Fri, 20 Jul 2007 10:06:35 +0200
parents b4aa8a40f754 (current diff) 738c0c3d001c (diff)
children c8a3a74953f6
files
diffstat 5 files changed, 64 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/newaccount.py	Fri Jul 20 10:02:19 2007 +0200
+++ b/MoinMoin/action/newaccount.py	Fri Jul 20 10:06:35 2007 +0200
@@ -43,6 +43,12 @@
     password = form.get('password', [''])[0]
     password2 = form.get('password2', [''])[0]
 
+    pw_checker = request.cfg.password_checker
+    if pw_checker:
+        pw_error = pw_checker(theuser.name, password)
+        if pw_error:
+            return _("Password not acceptable: %s") % pw_error
+
     # Check if password is given and matches with password repeat
     if password != password2:
         return _("Passwords don't match!")
--- a/MoinMoin/config/multiconfig.py	Fri Jul 20 10:02:19 2007 +0200
+++ b/MoinMoin/config/multiconfig.py	Fri Jul 20 10:06:35 2007 +0200
@@ -433,6 +433,51 @@
         'view':        ({}, _("View"), "view"),
         }
 
+
+    def password_checker(username, password):
+        """ Check if a password is secure enough.
+            First (and in any case), we use a built-in check to get rid of the
+            worst passwords. If there is cracklib installed, we use it for
+            additional checks.
+            If you don't want to check passwords, use password_checker = None.
+
+            @return: None if there is no problem with the password,
+                     some string with an error msg, if the password is problematic.
+        """
+        try:
+            # in any case, do a very simple built-in check to avoid the worst passwords
+            if len(password) < 6:
+                raise ValueError("Password too short!")
+
+            username_lower = username.lower()
+            password_lower = password.lower()
+            if username in password or password in username or \
+               username_lower in password_lower or password_lower in username_lower:
+                raise ValueError("Password too easy (containment)")
+
+            keyboards = (ur"`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./", # US kbd
+                        ) # add more keyboards!
+            for kbd in keyboards:
+                rev_kbd = kbd[::-1]
+                if password in kbd or password in rev_kbd or \
+                   password_lower in kbd or password_lower in rev_kbd:
+                    raise ValueError("Password too easy (kbd sequence)")
+            try:
+                # to use advanced checking, you need to install python-crack,
+                # cracklib-runtime (dict processing) and do not forget to
+                # initialize the crack dicts!
+                import crack
+                # instead of some "old password" we give the username to check
+                # whether the password is too similar to the username
+                crack.VeryFascistCheck(password, username) # raises ValueError on bad passwords
+            except ImportError:
+                pass
+            return None
+        except ValueError, err:
+            return str(err)
+
+    password_checker = staticmethod(password_checker)
+
     quicklinks_default = [] # preload user quicklinks with this page list
     refresh = None # (minimum_delay, type), e.g.: (2, 'internal')
     rss_cache = 60 # suggested caching time for RecentChanges RSS, in seconds
--- a/MoinMoin/userprefs/changepass.py	Fri Jul 20 10:02:19 2007 +0200
+++ b/MoinMoin/userprefs/changepass.py	Fri Jul 20 10:06:35 2007 +0200
@@ -35,12 +35,13 @@
 
     def handle_form(self):
         _ = self._
-        form = self.request.form
+        request = self.request
+        form = request.form
 
         if form.has_key('cancel'):
             return
 
-        if self.request.request_method != 'POST':
+        if request.request_method != 'POST':
             return
 
         password = form.get('password', [''])[0]
@@ -50,6 +51,12 @@
         if password != password2:
             return _("Passwords don't match!")
 
+        pw_checker = request.cfg.password_checker
+        if pw_checker:
+            pw_error = pw_checker(request.user.name, password)
+            if pw_error:
+                return _("Password not acceptable: %s") % pw_error
+
         # Encode password
         if password and not password.startswith('{SHA}'):
             try:
--- a/MoinMoin/userprefs/prefs.py	Fri Jul 20 10:02:19 2007 +0200
+++ b/MoinMoin/userprefs/prefs.py	Fri Jul 20 10:06:35 2007 +0200
@@ -103,7 +103,7 @@
 
         if not 'jid' in theuser.auth_attribs:
             # try to get the jid
-            jid = wikiutil.clean_input(form.get('jid', "")[0]).strip()
+            jid = wikiutil.clean_input(form.get('jid', [''])[0]).strip()
 
             jid_changed = theuser.jid != jid
             previous_jid = theuser.jid
--- a/docs/CHANGES	Fri Jul 20 10:02:19 2007 +0200
+++ b/docs/CHANGES	Fri Jul 20 10:06:35 2007 +0200
@@ -42,6 +42,9 @@
     * new authentication plugin system
     * new preferences plugin system, see MoinMoin/userprefs/__init__.py
     * new notification system with an optional jabber notification bot
+    * cfg.password_checker (default: use some simple builtin checks for too
+      easy passwords and, if available, python-crack).
+      Use password_checker = None to disable password checking.
 
   Bugfixes:
     * ...