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.common.ldap.LdapUtils;
|
||||
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.user.UserMapper;
|
||||
|
@ -100,7 +101,7 @@ public class LdapBindAuthenticator
|
|||
|
||||
String filter = "(&(objectClass=" + mapper.getUserObjectClass() + ")" + ( mapper.getUserFilter() != null
|
||||
? 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() );
|
||||
|
||||
|
|
|
@ -137,6 +137,17 @@ public class LdapBindAuthenticatorTest
|
|||
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
|
||||
@Test
|
||||
public void testAuthenticationFromCache()
|
||||
|
|
|
@ -34,6 +34,28 @@ import javax.naming.ldap.Rdn;
|
|||
*/
|
||||
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()
|
||||
{
|
||||
// no op
|
||||
|
@ -172,4 +194,38 @@ public final class LdapUtils
|
|||
}
|
||||
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.
|
||||
*/
|
||||
|
||||
import org.apache.archiva.redback.common.ldap.LdapUtils;
|
||||
import org.apache.archiva.redback.common.ldap.user.UserMapper;
|
||||
import org.apache.archiva.redback.users.AbstractUserQuery;
|
||||
|
||||
|
@ -49,13 +50,13 @@ public class LdapUserQuery
|
|||
String filter = "";
|
||||
if (this.getEmail() != null )
|
||||
{
|
||||
filter += "(" + mapper.getEmailAddressAttribute() + "=" + this.getEmail() + ")";
|
||||
filter += "(" + mapper.getEmailAddressAttribute() + "=" + LdapUtils.encodeFilterValue( this.getEmail() ) + ")";
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
public void testWithManyUsers()
|
||||
throws Exception
|
||||
|
|
Loading…
Reference in New Issue