Improving LDAP filters by escaping characters
This commit is contained in:
parent
8f6ca402c4
commit
ef075525c8
|
@ -20,6 +20,7 @@ package org.apache.archiva.redback.authentication.ldap;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.apache.archiva.redback.authentication.AbstractAuthenticator;
|
import org.apache.archiva.redback.authentication.AbstractAuthenticator;
|
||||||
|
import org.apache.archiva.redback.common.ldap.LdapUtils;
|
||||||
import org.apache.archiva.redback.common.ldap.connection.DefaultLdapConnection;
|
import org.apache.archiva.redback.common.ldap.connection.DefaultLdapConnection;
|
||||||
import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
|
import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
|
||||||
import org.apache.archiva.redback.common.ldap.user.UserMapper;
|
import org.apache.archiva.redback.common.ldap.user.UserMapper;
|
||||||
|
@ -100,7 +101,7 @@ public class LdapBindAuthenticator
|
||||||
|
|
||||||
String filter = "(&(objectClass=" + mapper.getUserObjectClass() + ")" + ( mapper.getUserFilter() != null
|
String filter = "(&(objectClass=" + mapper.getUserObjectClass() + ")" + ( mapper.getUserFilter() != null
|
||||||
? mapper.getUserFilter()
|
? mapper.getUserFilter()
|
||||||
: "" ) + "(" + mapper.getUserIdAttribute() + "=" + source.getUsername() + "))";
|
: "" ) + "(" + mapper.getUserIdAttribute() + "=" + LdapUtils.encodeFilterValue( source.getUsername() ) + "))";
|
||||||
|
|
||||||
log.debug( "Searching for users with filter: '{}' from base dn: {}", filter, mapper.getUserBaseDn() );
|
log.debug( "Searching for users with filter: '{}' from base dn: {}", filter, mapper.getUserBaseDn() );
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,17 @@ public class LdapBindAuthenticatorTest
|
||||||
assertTrue( result.isAuthenticated() );
|
assertTrue( result.isAuthenticated() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuthenticationWithInvalidChar()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
PasswordBasedAuthenticationDataSource authDs = new PasswordBasedAuthenticationDataSource();
|
||||||
|
authDs.setPrincipal( "jesse)(mail=foo" );
|
||||||
|
authDs.setPassword( passwordEncoder.encodePassword( "foo" ) );
|
||||||
|
AuthenticationResult result = authnr.authenticate( authDs );
|
||||||
|
assertFalse( result.isAuthenticated() );
|
||||||
|
}
|
||||||
|
|
||||||
// REDBACK-289/MRM-1488
|
// REDBACK-289/MRM-1488
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationFromCache()
|
public void testAuthenticationFromCache()
|
||||||
|
|
|
@ -34,6 +34,28 @@ import javax.naming.ldap.Rdn;
|
||||||
*/
|
*/
|
||||||
public final class LdapUtils
|
public final class LdapUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1];
|
||||||
|
|
||||||
|
|
||||||
|
// Characters that must be escaped in a user filter
|
||||||
|
static {
|
||||||
|
|
||||||
|
// Filter encoding table -------------------------------------
|
||||||
|
// fill with char itself
|
||||||
|
for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) {
|
||||||
|
FILTER_ESCAPE_TABLE[c] = String.valueOf(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// escapes (RFC2254)
|
||||||
|
FILTER_ESCAPE_TABLE['*'] = "\\2a";
|
||||||
|
FILTER_ESCAPE_TABLE['('] = "\\28";
|
||||||
|
FILTER_ESCAPE_TABLE[')'] = "\\29";
|
||||||
|
FILTER_ESCAPE_TABLE['\\'] = "\\5c";
|
||||||
|
FILTER_ESCAPE_TABLE[0] = "\\00";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private LdapUtils()
|
private LdapUtils()
|
||||||
{
|
{
|
||||||
// no op
|
// no op
|
||||||
|
@ -172,4 +194,38 @@ public final class LdapUtils
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape a value for use in a filter.
|
||||||
|
* This method is copied from the spring framework class org.springframework.security.ldap.authentication.LdapEncoder
|
||||||
|
*
|
||||||
|
* @param value the value to escape.
|
||||||
|
* @return a properly escaped representation of the supplied value.
|
||||||
|
*/
|
||||||
|
public static String encodeFilterValue(String value) {
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make buffer roomy
|
||||||
|
StringBuilder encodedValue = new StringBuilder(value.length() * 2);
|
||||||
|
|
||||||
|
int length = value.length();
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
|
||||||
|
char c = value.charAt(i);
|
||||||
|
|
||||||
|
if (c < FILTER_ESCAPE_TABLE.length) {
|
||||||
|
encodedValue.append(FILTER_ESCAPE_TABLE[c]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// default: add the char
|
||||||
|
encodedValue.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return encodedValue.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.archiva.redback.users.ldap;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import org.apache.archiva.redback.common.ldap.LdapUtils;
|
||||||
import org.apache.archiva.redback.common.ldap.user.UserMapper;
|
import org.apache.archiva.redback.common.ldap.user.UserMapper;
|
||||||
import org.apache.archiva.redback.users.AbstractUserQuery;
|
import org.apache.archiva.redback.users.AbstractUserQuery;
|
||||||
|
|
||||||
|
@ -49,13 +50,13 @@ public class LdapUserQuery
|
||||||
String filter = "";
|
String filter = "";
|
||||||
if (this.getEmail() != null )
|
if (this.getEmail() != null )
|
||||||
{
|
{
|
||||||
filter += "(" + mapper.getEmailAddressAttribute() + "=" + this.getEmail() + ")";
|
filter += "(" + mapper.getEmailAddressAttribute() + "=" + LdapUtils.encodeFilterValue( this.getEmail() ) + ")";
|
||||||
}
|
}
|
||||||
if ( this.getFullName() != null )
|
if ( this.getFullName() != null )
|
||||||
{
|
{
|
||||||
filter += "(" + mapper.getUserFullNameAttribute() + "=" + this.getFullName() + ")";
|
filter += "(" + mapper.getUserFullNameAttribute() + "=" + LdapUtils.encodeFilterValue( this.getFullName() ) + ")";
|
||||||
}
|
}
|
||||||
filter += "(" + mapper.getUserIdAttribute() + "=" + ( this.getUsername() != null ? this.getUsername() : "*" ) + ")";
|
filter += "(" + mapper.getUserIdAttribute() + "=" + ( this.getUsername() != null ? LdapUtils.encodeFilterValue( this.getUsername() ) : "*" ) + ")";
|
||||||
|
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,6 +233,21 @@ public class LdapUserManagerTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserWithInvalidChars()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
userManager.findUser( "jesse)(mail=jesse@apache.org" );
|
||||||
|
fail( "UserNotFoundException should be thrown, if invalid filter chars are in the username" );
|
||||||
|
}
|
||||||
|
catch ( UserNotFoundException e )
|
||||||
|
{
|
||||||
|
// cool it works !
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWithManyUsers()
|
public void testWithManyUsers()
|
||||||
throws Exception
|
throws Exception
|
||||||
|
|
Loading…
Reference in New Issue