diff --git a/uffd/ldap/__init__.py b/uffd/ldap/__init__.py index b420a489f3ff84a9c0484b6854dea620a5e231a8..0ba10c72f766f8344737250c7584b151f949660f 100644 --- a/uffd/ldap/__init__.py +++ b/uffd/ldap/__init__.py @@ -1,4 +1,4 @@ from .ldap import bp as ldap_bp -from .ldap import get_conn, user_conn, escape_filter_chars, uid_to_dn, loginname_to_dn, get_next_uid +from .ldap import get_conn, user_conn, escape_filter_chars, uid_to_dn, loginname_to_dn, get_next_uid, loginname_is_safe bp = [ldap_bp] diff --git a/uffd/ldap/ldap.py b/uffd/ldap/ldap.py index e1ddaf191d623398d03f580f36f3a607d1b822db..2d6d9c32f4c769e48bff5f77d42309e55da263fc 100644 --- a/uffd/ldap/ldap.py +++ b/uffd/ldap/ldap.py @@ -1,6 +1,7 @@ +import string + from flask import Blueprint, current_app from ldap3.utils.conv import escape_filter_chars -from ldap3.utils.dn import escape_rdn from ldap3.core.exceptions import LDAPBindError from ldap3 import Server, Connection, ALL, ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES @@ -17,9 +18,11 @@ def fix_connection(conn): def service_conn(): server = Server(current_app.config["LDAP_SERVICE_URL"], get_info=ALL) - return Connection(server, current_app.config["LDAP_SERVICE_BIND_DN"], current_app.config["LDAP_SERVICE_BIND_PASSWORD"], auto_bind=True) + return fix_connection(Connection(server, current_app.config["LDAP_SERVICE_BIND_DN"], current_app.config["LDAP_SERVICE_BIND_PASSWORD"], auto_bind=True)) def user_conn(loginname, password): + if not loginname_is_safe(loginname): + return False server = Server(current_app.config["LDAP_SERVICE_URL"], get_info=ALL) try: return fix_connection(Connection(server, loginname_to_dn(loginname), password, auto_bind=True)) @@ -27,8 +30,7 @@ def user_conn(loginname, password): return False def get_conn(): - conn = service_conn() - return fix_connection(conn) + return service_conn() def uid_to_dn(uid): conn = get_conn() @@ -38,7 +40,18 @@ def uid_to_dn(uid): return conn.entries[0].entry_dn def loginname_to_dn(loginname): - return 'uid={},{}'.format(escape_rdn(loginname), current_app.config["LDAP_BASE_USER"]) + if loginname_is_safe(loginname): + return 'uid={},{}'.format(loginname, current_app.config["LDAP_BASE_USER"]) + else: + raise Exception('unsafe login name') + +def loginname_is_safe(value): + if len(value) > 32 or len(value) < 1: + return False + for char in value: + if not char in string.ascii_lowercase + string.digits + '_': + return False + return True def get_next_uid(): conn = get_conn() diff --git a/uffd/user/models.py b/uffd/user/models.py index 69dcf005b597a2fe4022d682ce996901e19d66a9..f55ffe6681352ee5f8a215ac15b3bd2848dd26c2 100644 --- a/uffd/user/models.py +++ b/uffd/user/models.py @@ -1,5 +1,3 @@ -import string - from ldap3 import MODIFY_REPLACE, HASHED_SALTED_SHA512 from ldap3.utils.hashed import hashed from flask import current_app @@ -90,11 +88,8 @@ class User(): return False def set_loginname(self, value): - if len(value) > 32 or len(value) < 1: + if not ldap.loginname_is_safe(value): return False - for char in value: - if not char in string.ascii_lowercase + string.digits + '_': - return False self.loginname = value return True