Changeset - fefd7279e798
[Not reviewed]
stable
0 2 0
Mads Kiilerich - 8 years ago 2018-01-15 00:34:13
mads@kiilerich.com
login: fix crash when entering non-ASCII password for login (Issue #300)

Avoid errors like
UnicodeEncodeError: 'ascii' codec can't encode characters in position X: ordinal not in range(128)
when the user enters non-ASCII passwords for existing internal accounts in the
login prompt.

The password forms have "always" rejected non-ASCII passwords with
Invalid characters (non-ASCII) in password
2 files changed with 12 insertions and 0 deletions:
0 comments (0 inline, 0 general)
kallithea/lib/auth.py
Show inline comments
 
@@ -113,24 +113,29 @@ class KallitheaCrypto(object):
 
                            % __platform__)
 

	
 
    @classmethod
 
    def hash_check(cls, password, hashed):
 
        """
 
        Checks matching password with it's hashed value, runs different
 
        implementation based on platform it runs on
 

	
 
        :param password: password
 
        :param hashed: password in hashed form
 
        """
 

	
 
        try:
 
            password = str(password)
 
        except UnicodeEncodeError:
 
            log.warning('rejecting non-ascii password')
 
            return False
 
        if is_windows:
 
            return hashlib.sha256(password).hexdigest() == hashed
 
        elif is_unix:
 
            import bcrypt
 
            return bcrypt.hashpw(password, hashed) == hashed
 
        else:
 
            raise Exception('Unknown or unsupported platform %s' \
 
                            % __platform__)
 

	
 

	
 
def get_crypt_password(password):
 
    return KallitheaCrypto.hash_string(password)
kallithea/tests/functional/test_login.py
Show inline comments
 
@@ -124,24 +124,31 @@ class TestLoginController(TestController
 
                                  'password': 'as'})
 
        self.assertEqual(response.status, '200 OK')
 

	
 
        response.mustcontain('Enter 3 characters or more')
 

	
 
    def test_login_wrong_username_password(self):
 
        response = self.app.post(url(controller='login', action='index'),
 
                                 {'username': 'error',
 
                                  'password': 'test12'})
 

	
 
        response.mustcontain('Invalid username or password')
 

	
 
    def test_login_non_ascii(self):
 
        response = self.app.post(url(controller='login', action='index'),
 
                                 {'username': TEST_USER_REGULAR_LOGIN,
 
                                  'password': 'blåbærgrød'})
 

	
 
        response.mustcontain('>Invalid username or password<')
 

	
 
    # verify that get arguments are correctly passed along login redirection
 

	
 
    @parameterized.expand([
 
        ({'foo':'one', 'bar':'two'}, (('foo', 'one'), ('bar', 'two'))),
 
        ({'blue': u'blå'.encode('utf-8'), 'green':u'grøn'},
 
             (('blue', u'blå'.encode('utf-8')), ('green', u'grøn'.encode('utf-8')))),
 
    ])
 
    def test_redirection_to_login_form_preserves_get_args(self, args, args_encoded):
 
        with fixture.anon_access(False):
 
            response = self.app.get(url(controller='summary', action='index',
 
                                        repo_name=HG_REPO,
 
                                        **args))
0 comments (0 inline, 0 general)