/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions Copyright [year] [name of copyright owner]".
*
* Copyright 2006-2008 Sun Microsystems, Inc.
* Portions Copyright 2014-2016 ForgeRock AS.
*/
package org.opends.server.tools;
import static org.opends.server.util.CollectionUtils.*;
import static org.testng.Assert.*;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.forgerock.opendj.ldap.ByteString;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.SASLMechanismHandler;
import org.opends.server.controls.PasswordPolicyRequestControl;
import org.opends.server.core.DirectoryServer;
import org.opends.server.extensions.AnonymousSASLMechanismHandler;
import org.opends.server.types.Control;
import org.opends.server.types.LDAPException;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.forgerock.opendj.cli.ClientException;
/** A set of test cases for the LDAP authentication handler. */
public class LDAPAuthenticationHandlerTestCase
extends ToolsTestCase
{
private String hostname;
/**
* Ensures that the Directory Server is running.
*
* @throws Exception If an unexpected problem occurs.
*/
@BeforeClass
public void startServer()
throws Exception
{
TestCaseUtils.startServer();
getFQDN();
}
/**
* Retrieves the names of the supported SASL mechanisms.
*
* @return The names of the supported SASL mechanisms.
*/
@DataProvider(name = "saslMechanisms")
public Object[][] getSASLMechanisms()
{
return new Object[][]
{
new Object[] { "ANONYMOUS" },
new Object[] { "CRAM-MD5" },
new Object[] { "DIGEST-MD5" },
new Object[] { "EXTERNAL" },
new Object[] { "GSSAPI" },
new Object[] { "PLAIN" }
};
}
/**
* Tests the getSupportedSASLMechanisms method.
*
* @param saslMechanismName The name of the mechanism to ensure is in the
* returned list.
*/
@Test(dataProvider = "saslMechanisms")
public void testGetSupportedSASLMechanisms(String saslMechanismName)
{
String[] supportedMechanisms =
LDAPAuthenticationHandler.getSupportedSASLMechanisms();
assertNotNull(supportedMechanisms);
assertEquals(supportedMechanisms.length, 6);
assertTrue(Arrays.asList(supportedMechanisms).contains(saslMechanismName));
}
/**
* Tests the getSASLProperties method.
*
* @param saslMechanismName The name for which to retrieve the applicable properties.
*/
@Test(dataProvider = "saslMechanisms")
public void testGetSASLProperties(String saslMechanismName)
{
assertNotNull(LDAPAuthenticationHandler.getSASLProperties(saslMechanismName));
}
/** Tests the getSASLProperties method with an unsupported mechanism name. */
@Test
public void testGetSASLPropertiesInvalid()
{
assertNull(LDAPAuthenticationHandler.getSASLProperties("unsupportedMechanism"));
}
/**
* Tests the doSimpleBind method with a valid DN and password and
* with no request controls.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSimpleBindWithValidDNAndPWNoControls()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"), ByteString.valueOfUtf8("password"),
requestControls, responseControls);
}
}
/**
* Tests the doSimpleBind method with a null DN and password and
* no request controls.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSimpleBindWithNullDNAndPWNoControls()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, null, null, requestControls, responseControls);
}
}
/**
* Tests the doSimpleBind method with an empty DN and password
* and no request controls.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSimpleBindWithEmptyDNAndPWNoControls()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, ByteString.empty(), ByteString.empty(), requestControls, responseControls);
}
}
/**
* Tests the doSimpleBind method with an valid DN but no
* password.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSimpleBindWithDNButNoPassword()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"),
ByteString.empty(), requestControls,
responseControls);
}
}
/**
* Tests the doSimpleBind method with an valid DN but an invalid
* password.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSimpleBindWithDNButInvalidPassword()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"),
ByteString.valueOfUtf8("wrongPassword"),
requestControls, responseControls);
}
}
/**
* Tests the doSimpleBind method with the password policy
* request control.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSimpleBindWithPasswordPolicyControl()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
requestControls.add(new PasswordPolicyRequestControl());
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"), ByteString.valueOfUtf8("password"),
requestControls, responseControls);
}
}
/**
* Tests the doSASLBind method with a null mechanism.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindNullMechanism()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
Map> saslProperties = new LinkedHashMap<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSASLBind(null, null, null, saslProperties, requestControls, responseControls);
}
}
/**
* Tests the doSASLBind method with an empty mechanism.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindEmptyMechanism()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
Map> saslProperties = new LinkedHashMap<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSASLBind(null, null, "", saslProperties, requestControls, responseControls);
}
}
/**
* Tests the doSASLBind method with an invalid mechanism.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindInvalidMechanism()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
Map> saslProperties = new LinkedHashMap<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSASLBind(null, null, "invalid", saslProperties,
requestControls, responseControls);
}
}
/**
* Tests the doSASLBind method for the case in which ANONYMOUS
* authentication is disabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindAnonymousDisabled()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("trace", newArrayList("testDoSASLBindAnonymousDisabled"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
anonymous(authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method for the case in which ANONYMOUS
* authentication is enabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindAnonymous()
throws Exception
{
AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
handler.initializeSASLMechanismHandler(null);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("trace", newArrayList("testDoSASLBindAnonymous"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
anonymous(authHandler, saslProperties);
}
handler.finalizeSASLMechanismHandler();
}
/**
* Tests the doSASLBind method for the case in which ANONYMOUS
* authentication is enabled in the server and there is no trace information.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindAnonymousNoTrace()
throws Exception
{
AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
handler.initializeSASLMechanismHandler(null);
Map> saslProperties = new LinkedHashMap<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
anonymous(authHandler, saslProperties);
}
handler.finalizeSASLMechanismHandler();
}
/**
* Tests the doSASLBind method for the case in which ANONYMOUS
* authentication is enabled in the server and multiple trace values are
* provided.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindAnonymousMultivaluedTrace()
throws Exception
{
AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
handler.initializeSASLMechanismHandler(null);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("trace",
newArrayList("testDoSASLBindAnonymousMultivaluedTrace", "aSecondTraceStringWhichIsInvalid"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
anonymous(authHandler, saslProperties);
}
finally
{
handler.finalizeSASLMechanismHandler();
}
}
/**
* Tests the doSASLBind method for the case in which ANONYMOUS
* authentication is enabled in the server and an invalid SASL property is
* provided.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindAnonymousInvalidProperty()
throws Exception
{
AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
handler.initializeSASLMechanismHandler(null);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("invalid", newArrayList("testDoSASLBindAnonymousInvalidProperty"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
anonymous(authHandler, saslProperties);
}
finally
{
handler.finalizeSASLMechanismHandler();
}
}
/**
* Tests the doSASLBind method for the case in which ANONYMOUS
* authentication is enabled in the server and the request includes the
* password policy request control.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindAnonymousWithPasswordPolicyControl()
throws Exception
{
AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
handler.initializeSASLMechanismHandler(null);
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
requestControls.add(new PasswordPolicyRequestControl());
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("trace", newArrayList("testDoSASLBindAnonymous"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSASLBind(ByteString.empty(), ByteString.empty(), "ANONYMOUS", saslProperties, requestControls,
responseControls);
}
handler.finalizeSASLMechanismHandler();
}
/**
* Tests the doSASLBind method for the case in which CRAM-MD5
* authentication is disabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindCRAMMD5Disabled()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
SASLMechanismHandler> cramMD5Handler =
DirectoryServer.getSASLMechanismHandler("CRAM-MD5");
DirectoryServer.deregisterSASLMechanismHandler("CRAM-MD5");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try
{
cramMd5SaslBind(saslProperties);
}
finally
{
DirectoryServer.registerSASLMechanismHandler("CRAM-MD5", cramMD5Handler);
}
}
/**
* Tests the doSASLBind method for the case in which CRAM-MD5
* authentication is enabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindCRAMMD5()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
cramMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method using CRAM-MD5 for the case in
* which an authID was provided that doesn't map to any user.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindCRAMMD5InvalidAuthID()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
cramMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method using CRAM-MD5 for the case in
* which an empty authID was provided.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindCRAMMD5EmptyAuthID()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList(""));
cramMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method using CRAM-MD5 for the case in
* which the provided password was incorrect.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindCRAMMD5InvalidPassword()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
doSASLBind("CRAM-MD5", "invalidPassword", authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method using CRAM-MD5 for the case in
* which the specified user doesn't have a reversible password.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindCRAMMD5NoReversiblePassword()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
cramMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method using CRAM-MD5 for the case in
* which the provided SASL properties were null.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindCRAMMD5NullProperties()
throws Exception
{
Map> saslProperties = null;
cramMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method using CRAM-MD5 for the case in
* which the provided SASL properties were empty.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindCRAMMD5EmptyProperties()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
cramMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method using CRAM-MD5 for the case in
* which multiple authID values were provided
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindCRAMMD5MultipleAuthIDs()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test", "u:test.user"));
cramMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method using CRAM-MD5 for the case in
* which an invalid SASL property was provided.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindCRAMMD5InvalidSASLProperty()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("invalid", newArrayList("foo"));
cramMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which CRAM-MD5
* authentication is enabled in the server and the password policy request
* control is used.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindCRAMMD5WithPasswordPolicyControl()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
requestControls.add(new PasswordPolicyRequestControl());
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSASLBind(ByteString.empty(), ByteString.valueOfUtf8("password"), "CRAM-MD5", saslProperties,
requestControls, responseControls);
}
}
/**
* Tests the doSASLBind method for the case in which DIGEST-MD5
* authentication is disabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindDigestMD5Disabled()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
SASLMechanismHandler> digestMD5Handler =
DirectoryServer.getSASLMechanismHandler("DIGEST-MD5");
DirectoryServer.deregisterSASLMechanismHandler("DIGEST-MD5");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("realm", newArrayList("o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
digestMD5(authHandler, saslProperties);
}
finally
{
DirectoryServer.registerSASLMechanismHandler("DIGEST-MD5", digestMD5Handler);
}
}
/**
* Tests the doSASLBind method for the case in which DIGEST-MD5
* authentication is enabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindDigestMD5()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
digestMD5(authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method for the case in which DIGEST-MD5
* authentication is enabled in the server and an authz ID was provided.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindDigestMD5WithAuthzID()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
digestMD5(authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties are null.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5NullProperties()
throws Exception
{
Map> saslProperties = null;
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties are empty.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5EmptyProperties()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain an invalid property.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5InvalidProperty()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("invalid", newArrayList("foo"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain multiple values for the authID property.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5MultipleAuthIDs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
List propList = newArrayList("dn:uid=test.user,o=test");
propList.add("u:test.user");
saslProperties.put("authid", propList);
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain an empty authID.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5MEmptyAuthID()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList(""));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain multiple values for the realm property.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5MultipleRealms()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("realm", newArrayList("o=test", "dc=example,dc=com"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain a valid quality of protection.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindDigestMD5ValidQoP()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("qop", newArrayList("auth"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
digestMD5(authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain the unsupported integrity quality of
* protection.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5UnsupportedQoPAuthInt()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("realm", newArrayList("o=test"));
saslProperties.put("qop", newArrayList("auth-int"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain the unsupported confidentiality quality
* of protection.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5UnsupportedQoPAuthConf()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("realm", newArrayList("o=test"));
saslProperties.put("qop", newArrayList("auth-conf"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain an invalid quality of protection.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5InvalidQoP()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("realm", newArrayList("o=test"));
saslProperties.put("qop", newArrayList("invalid"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain multiple quality of protection values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5MultipleQoPs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("realm", newArrayList("o=test"));
saslProperties.put("qop", newArrayList("auth", "auth-int", "auth-conf"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain multiple digest URIs.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5MultipleDigestURIs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("realm", newArrayList("o=test"));
saslProperties.put("digest-uri", newArrayList("ldap/value1", "ldap/value2"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain multiple authorization IDs.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindDigestMD5MultipleAuthzIDs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("realm", newArrayList("o=test"));
saslProperties.put("authzid", newArrayList("dn:uid=test.user,o=test", "u:test.user"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain an invalid auth ID in the DN form.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindDigestMD5InvalidAuthDN()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:invalid"));
saslProperties.put("realm", newArrayList("o=test"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the
* DIGEST-MD5 SASL properties contain an auth ID that doesn't map to any user.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindDigestMD5NonExistentAuthID()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:nosuchuser"));
saslProperties.put("realm", newArrayList("o=test"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which an invalid
* password was provided.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindDigestMD5InvalidPassword()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:nosuchuser"));
saslProperties.put("realm", newArrayList("o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
doSASLBind("DIGEST-MD5", "wrongPassword", authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method for the case in which the target
* user does not have a reversible password.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindDigestMD5NoReversiblePassword()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:nosuchuser"));
saslProperties.put("realm", newArrayList("o=test"));
digestMd5SaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which DIGEST-MD5
* authentication is enabled in the server and the password policy request
* control is included.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindDigestMD5WithPasswordPolicyControl()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
requestControls.add(new PasswordPolicyRequestControl());
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
authHandler.doSASLBind(ByteString.empty(), ByteString.valueOfUtf8("password"), "DIGEST-MD5", saslProperties,
requestControls, responseControls);
}
}
/**
* Tests the doSASLBind method for the case in which EXTERNAL
* authentication is not enabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindExternalDisabled()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: cn=Test User,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User");
SASLMechanismHandler> externalHandler =
DirectoryServer.getSASLMechanismHandler("EXTERNAL");
DirectoryServer.deregisterSASLMechanismHandler("EXTERNAL");
String keyStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.keystore";
String trustStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.truststore";
SSLConnectionFactory factory = new SSLConnectionFactory();
factory.init(false, keyStorePath, "password", "client-cert",
trustStorePath, "password");
Map> saslProperties = new LinkedHashMap<>();
try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
doSASLBind("EXTERNAL", null, authHandler, saslProperties);
}
finally
{
DirectoryServer.registerSASLMechanismHandler("EXTERNAL", externalHandler);
}
}
/**
* Tests the doSASLBind method for the case in which EXTERNAL
* authentication is enabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindExternal()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: cn=Test User,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User");
String keyStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.keystore";
String trustStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.truststore";
SSLConnectionFactory factory = new SSLConnectionFactory();
factory.init(false, keyStorePath, "password", "client-cert", trustStorePath,
"password");
try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
{
Map> saslProperties = new LinkedHashMap<>();
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
doSASLBind("EXTERNAL", null, authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method for the case in the EXTERNAL SASL
* properties were not empty.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindExternalInvalidProperties()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: cn=Test User,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User");
SASLMechanismHandler> externalHandler =
DirectoryServer.getSASLMechanismHandler("EXTERNAL");
DirectoryServer.deregisterSASLMechanismHandler("EXTERNAL");
String keyStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.keystore";
String trustStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.truststore";
SSLConnectionFactory factory = new SSLConnectionFactory();
factory.init(false, keyStorePath, "password", "client-cert", trustStorePath,
"password");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("invalid", newArrayList("foo"));
try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
doSASLBind("EXTERNAL", null, authHandler, saslProperties);
}
finally
{
DirectoryServer.registerSASLMechanismHandler("EXTERNAL", externalHandler);
}
}
/**
* Tests the doSASLBind method for the case in which EXTERNAL
* authentication is enabled in the server and the password policy request
* control is included.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindExternalWithPasswordPolicy()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: cn=Test User,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User");
String keyStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.keystore";
String trustStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.truststore";
SSLConnectionFactory factory = new SSLConnectionFactory();
factory.init(false, keyStorePath, "password", "client-cert", trustStorePath,
"password");
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
requestControls.add(new PasswordPolicyRequestControl());
Map> saslProperties = new LinkedHashMap<>();
try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
doSASLBind("EXTERNAL", null, authHandler, saslProperties);
authHandler.doSASLBind(ByteString.empty(), null, "EXTERNAL", saslProperties, requestControls, responseControls);
}
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties list was null.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPINullProperties()
throws Exception
{
Map> saslProperties = null;
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties list was empty.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIEmptyProperties()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
gssapiSaslBind(saslProperties);
}
private Socket newSocket() throws UnknownHostException, IOException
{
final Socket socket=new Socket();
socket.setReuseAddress(true);
socket.connect(new InetSocketAddress("127.0.0.1",TestCaseUtils.getServerLdapPort()));
return socket;
}
private LDAPAuthenticationHandler newLDAPAuthenticationHandler(Socket s, String hostName2) throws IOException
{
LDAPReader r = new LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
AtomicInteger messageID = new AtomicInteger(1);
return new LDAPAuthenticationHandler(r, w, hostName2, messageID);
}
private void anonymous(LDAPAuthenticationHandler authHandler, Map> saslProperties)
throws ClientException, LDAPException
{
doSASLBind("ANONYMOUS", "", authHandler, saslProperties);
}
private void gssapi(LDAPAuthenticationHandler authHandler, Map> saslProperties)
throws ClientException, LDAPException
{
doSASLBind("GSSAPI", "", authHandler, saslProperties);
}
private void cramMD5(LDAPAuthenticationHandler authHandler, Map> saslProperties)
throws ClientException, LDAPException
{
doSASLBind("CRAM-MD5", "password", authHandler, saslProperties);
}
private void plain(LDAPAuthenticationHandler authHandler, Map> saslProperties)
throws ClientException, LDAPException
{
doSASLBind("PLAIN", "password", authHandler, saslProperties);
}
private void digestMD5(LDAPAuthenticationHandler authHandler, Map> saslProperties)
throws ClientException, LDAPException
{
doSASLBind("DIGEST-MD5", "password", authHandler, saslProperties);
}
private void doSASLBind(String mechanism, String bindPassword, LDAPAuthenticationHandler authHandler,
Map> saslProperties) throws ClientException, LDAPException
{
ByteString bindPwd = bindPassword != null ? ByteString.valueOfUtf8(bindPassword) : null;
authHandler.doSASLBind(ByteString.empty(), bindPwd, mechanism, saslProperties,
new ArrayList(), new ArrayList());
}
private void plainSaslBind(Map> saslProperties) throws Exception
{
try (Socket s = newSocket())
{
plain(newLDAPAuthenticationHandler(s, "127.0.0.1"), saslProperties);
}
}
private void cramMd5SaslBind(Map> saslProperties) throws Exception
{
try (Socket s = newSocket())
{
cramMD5(newLDAPAuthenticationHandler(s, "127.0.0.1"), saslProperties);
}
}
private void digestMd5SaslBind(Map> saslProperties) throws Exception
{
try (Socket s = newSocket())
{
digestMD5(newLDAPAuthenticationHandler(s, "127.0.0.1"), saslProperties);
}
}
private void gssapiSaslBind(Map> saslProperties) throws Exception
{
try (Socket s = newSocket())
{
gssapi(newLDAPAuthenticationHandler(s, "127.0.0.1"), saslProperties);
}
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has a zero-length auth ID value.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIEmptyAuthID()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList(""));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has multiple authID values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIMultipleAuthIDs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user", "dn:uid=test.user,o=test"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has multiple authzID values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIMultipleAuthzIDs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user"));
saslProperties.put("authzid", newArrayList("u:test.user", "dn:uid=test.user,o=test"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has multiple KDC values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIMultipleKDCs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user"));
saslProperties.put("kdc", newArrayList("kdc1", "kdc2"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has multiple quality of protection values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIMultipleQoPs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user"));
saslProperties.put("qop", newArrayList("auth", "auth-int", "auth-conf"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has an unsupported quality of protection value of
* auth-int.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIUnsupportedQoPAuthInt()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user"));
saslProperties.put("qop", newArrayList("auth-int"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has an unsupported quality of protection value of
* auth-conf.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIUnsupportedQoPAuthConf()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user"));
saslProperties.put("qop", newArrayList("auth-conf"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has an invalid quality of protection value.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIInvalidQoP()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user"));
saslProperties.put("qop", newArrayList("invalid"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has multiple realm values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIMultipleRealms()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user"));
saslProperties.put("realm", newArrayList("realm1", "realm2"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties has an invalid property.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPIInvalidProperty()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("u:test.user"));
saslProperties.put("invalid", newArrayList("foo"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for GSSAPI authentication when the
* provided properties isn't empty but doesn't contain an auth ID.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindGSSAPINoAuthID()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("qop", newArrayList("auth"));
gssapiSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which PLAIN
* authentication is disabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindPlainDisabled()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
SASLMechanismHandler> plainHandler =
DirectoryServer.getSASLMechanismHandler("PLAIN");
DirectoryServer.deregisterSASLMechanismHandler("PLAIN");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
plain(authHandler, saslProperties);
}
finally
{
DirectoryServer.registerSASLMechanismHandler("PLAIN", plainHandler);
}
}
/**
* Tests the doSASLBind method for the case in which PLAIN
* authentication is enabled in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindPlain()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
plain(authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method for the case in which the PLAIN
* SASL properties are null.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindPlainNullProperties()
throws Exception
{
Map> saslProperties = null;
plainSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the PLAIN
* SASL properties are empty.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindPlainEmptyProperties()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
plainSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the PLAIN
* SASL properties have multiple auth ID values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindPlainMultipleAuthIDs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test", "u:test.user"));
plainSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the PLAIN
* SASL properties have multiple auth ID values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindPlainZeroLengthAuthID()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList(""));
plainSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the PLAIN
* SASL properties have multiple authzID values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindPlainMultipleAuthzIDs()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("authzid", newArrayList("dn:uid=test.user,o=test", "u:test.user"));
plainSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the PLAIN
* SASL properties contains an invalid property.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindPlainInvalidProperty()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
saslProperties.put("invalid", newArrayList("foo"));
plainSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for the case in which the PLAIN
* SASL properties does not contain an auth ID.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = ClientException.class)
public void testDoSASLBindPlainNoAuthID()
throws Exception
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authzid", newArrayList("dn:uid=test.user,o=test"));
plainSaslBind(saslProperties);
}
/**
* Tests the doSASLBind method for PLAIN authentication in which
* the target user does not exist in the server.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindPlainNonExistentUser()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
try (Socket s = newSocket())
{
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=does.not.exist,o=test"));
plain(newLDAPAuthenticationHandler(s, "127.0.0.1"), saslProperties);
}
}
/**
* Tests the doSASLBind method for PLAIN authentication in which the wrong password
* has been provided for the target user.
*
* @throws Exception
* If an unexpected problem occurs.
*/
@Test(expectedExceptions = LDAPException.class)
public void testDoSASLBindPlainWrongPassword()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=does.not.exist,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
doSASLBind("PLAIN", "wrongPassword", authHandler, saslProperties);
}
}
/**
* Tests the doSASLBind method for the case in which PLAIN
* authentication is enabled in the server and the password policy request
* control is included.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testDoSASLBindPlainWithPasswordPolicy()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
requestControls.add(new PasswordPolicyRequestControl());
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSASLBind(ByteString.empty(), ByteString.valueOfUtf8("password"), "PLAIN", saslProperties,
requestControls, responseControls);
}
}
/**
* Tests the requestAuthorizationIdentity method for an
* unauthenticated client connection.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentityUnauthenticated()
throws Exception
{
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
assertNull(authHandler.requestAuthorizationIdentity());
}
}
/**
* Tests the requestAuthorizationIdentity method for a a client
* connection after a simple anonymous bind.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentitySimpleAnonymous()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, ByteString.empty(), ByteString.empty(), requestControls, responseControls);
assertNull(authHandler.requestAuthorizationIdentity());
}
}
/**
* Tests the requestAuthorizationIdentity method for a a client
* connection after a simple bind as a root user.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentitySimpleRootUser()
throws Exception
{
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, ByteString.valueOfUtf8("cn=Directory Manager"), ByteString.valueOfUtf8("password"),
requestControls, responseControls);
assertNotNull(authHandler.requestAuthorizationIdentity());
}
}
/**
* Tests the requestAuthorizationIdentity method for a a client
* connection after a simple bind as a normal user.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentitySimpleTestUser()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
List requestControls = new ArrayList<>();
List responseControls = new ArrayList<>();
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
authHandler.doSimpleBind(3, ByteString.valueOfUtf8("uid=test.user,o=test"), ByteString.valueOfUtf8("password"),
requestControls, responseControls);
assertNotNull(authHandler.requestAuthorizationIdentity());
}
}
/**
* Tests the requestAuthorizationIdentity method for a a client
* connection after a SASL ANONYMOUS bind.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentitySASLAnonymous()
throws Exception
{
AnonymousSASLMechanismHandler handler = new AnonymousSASLMechanismHandler();
handler.initializeSASLMechanismHandler(null);
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("trace", newArrayList("testDoSASLBindAnonymous"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
anonymous(authHandler, saslProperties);
assertNull(authHandler.requestAuthorizationIdentity());
}
handler.finalizeSASLMechanismHandler();
}
/**
* Tests the requestAuthorizationIdentity method for a a client
* connection after a CRAM-MD5 bind.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentityCRAMMD5()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
cramMD5(authHandler, saslProperties);
assertNotNull(authHandler.requestAuthorizationIdentity());
}
}
/**
* Tests the requestAuthorizationIdentity method for a a client
* connection after a DIGEST-MD5 bind.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentityDigestMD5()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, hostname);
digestMD5(authHandler, saslProperties);
assertNotNull(authHandler.requestAuthorizationIdentity());
}
}
/**
* Tests the requestAuthorizationIdentity method for a a client
* connection after an EXTERNAL bind.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentityExternal()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: cn=Test User,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User");
String keyStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.keystore";
String trustStorePath = DirectoryServer.getInstanceRoot() + File.separator +
"config" + File.separator + "client.truststore";
SSLConnectionFactory factory = new SSLConnectionFactory();
factory.init(false, keyStorePath, "password", "client-cert", trustStorePath,
"password");
Map> saslProperties = new LinkedHashMap<>();
try (Socket s = factory.createSocket("127.0.0.1", TestCaseUtils.getServerLdapsPort()))
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
doSASLBind("EXTERNAL", null, authHandler, saslProperties);
assertNotNull(authHandler.requestAuthorizationIdentity());
}
}
/**
* Tests the requestAuthorizationIdentity method for a a client
* connection after a PLAIN bind.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
public void testRequestAuthorizationIdentityPlain()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
Map> saslProperties = new LinkedHashMap<>();
saslProperties.put("authid", newArrayList("dn:uid=test.user,o=test"));
try (Socket s = newSocket())
{
LDAPAuthenticationHandler authHandler = newLDAPAuthenticationHandler(s, "127.0.0.1");
plain(authHandler, saslProperties);
assertNotNull(authHandler.requestAuthorizationIdentity());
}
}
private void getFQDN() {
try {
this.hostname = InetAddress.getLocalHost().getCanonicalHostName();
} catch(UnknownHostException ex) {
this.hostname = "127.0.0.1";
}
}
}