Skip to content
Snippets Groups Projects
Commit 3f6a67ea authored by Julian's avatar Julian
Browse files

Catch LDAPSASLPrepError on login

Ldap3 raises LDAPSASLPrepError on bind if the password contains characters
forbidden by SASLPrep (string preperation/normalization algorithm for user
names and passwords). Examples are carriage return ("\r") or newline ("\n")
characters. See #100.
parent 9d2a7289
No related branches found
No related tags found
1 merge request!65Catch LDAPSASLPrepError on login (regression test for #100)
Pipeline #7537 passed
...@@ -87,6 +87,14 @@ class TestSession(UffdTestCase): ...@@ -87,6 +87,14 @@ class TestSession(UffdTestCase):
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
self.assertLoggedOut() self.assertLoggedOut()
# Regression test for #100 (uncatched LDAPSASLPrepError)
def test_saslprep_invalid_password(self):
r = self.client.post(path=url_for('session.login'),
data={'loginname': self.test_data.get('user').get('loginname'), 'password': 'wrongpassword\n'}, follow_redirects=True)
dump('login_saslprep_invalid_password', r)
self.assertEqual(r.status_code, 200)
self.assertLoggedOut()
def test_wrong_user(self): def test_wrong_user(self):
r = self.client.post(path=url_for('session.login'), r = self.client.post(path=url_for('session.login'),
data={'loginname': 'nouser', 'password': self.test_data.get('user').get('password')}, data={'loginname': 'nouser', 'password': self.test_data.get('user').get('password')},
......
...@@ -4,7 +4,7 @@ import hashlib ...@@ -4,7 +4,7 @@ import hashlib
from flask import current_app, request, abort, session from flask import current_app, request, abort, session
import ldap3 import ldap3
from ldap3.core.exceptions import LDAPBindError, LDAPPasswordIsMandatoryError, LDAPInvalidDnError from ldap3.core.exceptions import LDAPBindError, LDAPPasswordIsMandatoryError, LDAPInvalidDnError, LDAPSASLPrepError
# We import LDAPCommitError only because it is imported from us by other files. It is not needed here # We import LDAPCommitError only because it is imported from us by other files. It is not needed here
from uffd.ldapalchemy import LDAPMapper, LDAPCommitError # pylint: disable=unused-import from uffd.ldapalchemy import LDAPMapper, LDAPCommitError # pylint: disable=unused-import
...@@ -74,7 +74,7 @@ def test_user_bind(bind_dn, bind_pw): ...@@ -74,7 +74,7 @@ def test_user_bind(bind_dn, bind_pw):
conn = connect_and_bind_to_ldap(server, bind_dn, bind_pw) conn = connect_and_bind_to_ldap(server, bind_dn, bind_pw)
if not conn: if not conn:
return False return False
except (LDAPBindError, LDAPPasswordIsMandatoryError, LDAPInvalidDnError): except (LDAPBindError, LDAPPasswordIsMandatoryError, LDAPInvalidDnError, LDAPSASLPrepError):
return False return False
conn.search(conn.user, encode_filter(current_app.config["LDAP_USER_SEARCH_FILTER"])) conn.search(conn.user, encode_filter(current_app.config["LDAP_USER_SEARCH_FILTER"]))
......
...@@ -9,7 +9,7 @@ from uffd.database import db ...@@ -9,7 +9,7 @@ from uffd.database import db
from uffd.csrf import csrf_protect from uffd.csrf import csrf_protect
from uffd.secure_redirect import secure_local_redirect from uffd.secure_redirect import secure_local_redirect
from uffd.user.models import User from uffd.user.models import User
from uffd.ldap import ldap, test_user_bind, LDAPInvalidDnError, LDAPBindError, LDAPPasswordIsMandatoryError from uffd.ldap import ldap, test_user_bind, LDAPInvalidDnError, LDAPBindError, LDAPPasswordIsMandatoryError, LDAPSASLPrepError
from uffd.ratelimit import Ratelimit, host_ratelimit, format_delay from uffd.ratelimit import Ratelimit, host_ratelimit, format_delay
from uffd.session.models import DeviceLoginInitiation, DeviceLoginConfirmation from uffd.session.models import DeviceLoginInitiation, DeviceLoginConfirmation
...@@ -46,7 +46,7 @@ def login_get_user(loginname, password): ...@@ -46,7 +46,7 @@ def login_get_user(loginname, password):
session['user_pw'] = password session['user_pw'] = password
try: try:
ldap.get_connection() ldap.get_connection()
except (LDAPBindError, LDAPPasswordIsMandatoryError): except (LDAPBindError, LDAPPasswordIsMandatoryError, LDAPSASLPrepError):
session.clear() session.clear()
return None return None
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment