From d22c3fb19eb2619021b37cb117c54d4cf55eda5c Mon Sep 17 00:00:00 2001 From: kolaente Date: Mon, 27 Jan 2025 15:22:28 +0100 Subject: [PATCH] feat(auth): make ldap user filter configurable --- pkg/config/config.go | 15 ++++++++------- pkg/modules/auth/ldap/ldap.go | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 59e69ff05..d54e8a256 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -78,13 +78,14 @@ const ( AuthOpenIDEnabled Key = `auth.openid.enabled` AuthOpenIDProviders Key = `auth.openid.providers` - AuthLdapEnabled Key = `auth.ldap.enabled` - AuthLdapHost Key = `auth.ldap.host` - AuthLdapPort Key = `auth.ldap.port` - AuthLdapBaseDN Key = `auth.ldap.basedn` - AuthLdapUseTLS Key = `auth.ldap.usetls` - AuthLdapVerifyTLS Key = `auth.ldap.verifytls` - AuthLdapBindDN Key = `auth.ldap.binddn` + AuthLdapEnabled Key = `auth.ldap.enabled` + AuthLdapHost Key = `auth.ldap.host` + AuthLdapPort Key = `auth.ldap.port` + AuthLdapBaseDN Key = `auth.ldap.basedn` + AuthLdapUserFilter Key = `auth.ldap.userfilter` + AuthLdapUseTLS Key = `auth.ldap.usetls` + AuthLdapVerifyTLS Key = `auth.ldap.verifytls` + AuthLdapBindDN Key = `auth.ldap.binddn` // #nosec G101 AuthLdapBindPassword Key = `auth.ldap.bindpassword` AuthLdapAttributeUsername Key = `auth.ldap.attribute.username` diff --git a/pkg/modules/auth/ldap/ldap.go b/pkg/modules/auth/ldap/ldap.go index d7c933ac1..01b1178ff 100644 --- a/pkg/modules/auth/ldap/ldap.go +++ b/pkg/modules/auth/ldap/ldap.go @@ -56,6 +56,18 @@ func ConnectAndBindToLDAPDirectory() (l *ldap.Conn, err error) { return } +// Adjusted from https://github.com/go-gitea/gitea/blob/6ca91f555ab9778310ac46cbbe33849c59286793/services/auth/source/ldap/source_search.go#L34 +func sanitizedUserQuery(username string) (string, bool) { + // See http://tools.ietf.org/search/rfc4515 + badCharacters := "\x00()*\\" + if strings.ContainsAny(username, badCharacters) { + log.Debugf("'%s' contains invalid query characters. Aborting.", username) + return "", false + } + + return fmt.Sprintf(config.AuthLdapUserFilter.GetString(), username), true +} + func AuthenticateUserInLDAP(s *xorm.Session, username, password string) (u *user.User, err error) { if password == "" || username == "" { return nil, user.ErrNoUsernamePassword{} @@ -70,10 +82,16 @@ func AuthenticateUserInLDAP(s *xorm.Session, username, password string) (u *user log.Debugf("Connected to LDAP server") + userFilter, ok := sanitizedUserQuery(username) + if !ok { + log.Debugf("Could not sanitize username %s", username) + return nil, user.ErrWrongUsernameOrPassword{} + } + searchRequest := ldap.NewSearchRequest( config.AuthLdapBaseDN.GetString(), ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, - fmt.Sprintf("(&(objectClass=inetOrgPerson)(uid=%s))", username), + userFilter, []string{ "dn", config.AuthLdapAttributeUsername.GetString(),