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):
self.assertEqual(r.status_code, 200)
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):
r = self.client.post(path=url_for('session.login'),
data={'loginname': 'nouser', 'password': self.test_data.get('user').get('password')},
......
......@@ -4,7 +4,7 @@ import hashlib
from flask import current_app, request, abort, session
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
from uffd.ldapalchemy import LDAPMapper, LDAPCommitError # pylint: disable=unused-import
......@@ -74,7 +74,7 @@ def test_user_bind(bind_dn, bind_pw):
conn = connect_and_bind_to_ldap(server, bind_dn, bind_pw)
if not conn:
return False
except (LDAPBindError, LDAPPasswordIsMandatoryError, LDAPInvalidDnError):
except (LDAPBindError, LDAPPasswordIsMandatoryError, LDAPInvalidDnError, LDAPSASLPrepError):
return False
conn.search(conn.user, encode_filter(current_app.config["LDAP_USER_SEARCH_FILTER"]))
......
......@@ -9,7 +9,7 @@ from uffd.database import db
from uffd.csrf import csrf_protect
from uffd.secure_redirect import secure_local_redirect
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.session.models import DeviceLoginInitiation, DeviceLoginConfirmation
......@@ -46,7 +46,7 @@ def login_get_user(loginname, password):
session['user_pw'] = password
try:
ldap.get_connection()
except (LDAPBindError, LDAPPasswordIsMandatoryError):
except (LDAPBindError, LDAPPasswordIsMandatoryError, LDAPSASLPrepError):
session.clear()
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