/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive.ssl;
import java.net.InetAddress;
import org.ldaptive.CompareOperation;
import org.ldaptive.CompareRequest;
import org.ldaptive.Connection;
import org.ldaptive.ConnectionConfig;
import org.ldaptive.DefaultConnectionFactory;
import org.ldaptive.LdapAttribute;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
/**
* Unit test for default hostname verification behavior.
*
* @author Middleware Services
*/
public class HostnameVerifierConnectionTest
{
/** @throws Exception On test failure. */
@BeforeClass(groups = {"ssl-hostname"})
public void setProperties()
throws Exception
{
System.setProperty("javax.net.ssl.trustStore", "target/test-classes/ldaptive.truststore");
System.setProperty("javax.net.ssl.trustStoreType", "BKS");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
}
/** @throws Exception On test failure. */
@AfterClass(groups = {"ssl-hostname"})
public void clearProperties()
throws Exception
{
System.clearProperty("javax.net.ssl.trustStore");
System.clearProperty("javax.net.ssl.trustStoreType");
System.clearProperty("javax.net.ssl.trustStorePassword");
}
/**
* @param host to connect to
*
* @throws Exception On test failure.
*/
@Parameters("ldapTestHost")
@Test(groups = {"ssl-hostname"})
public void connectStartTLS(final String host)
throws Exception
{
// attempting to use startTLS by IP address should fail
ConnectionConfig cc = new ConnectionConfig(convertUrlToIp(host));
cc.setUseStartTLS(true);
Connection conn = DefaultConnectionFactory.getConnection(cc);
try {
conn.open();
AssertJUnit.fail("Should have thrown Exception, no exception thrown");
} catch (Exception e) {
AssertJUnit.assertNotNull(e);
} finally {
conn.close();
}
// attempting to use startTLS by hostname address should succeed
cc = new ConnectionConfig(host);
cc.setUseStartTLS(true);
conn = DefaultConnectionFactory.getConnection(cc);
try {
conn.open();
} finally {
conn.close();
}
}
/**
* @param host to connect to
*
* @throws Exception On test failure.
*/
@Parameters("ldapSslTestHost")
@Test(groups = {"ssl-hostname"})
public void connectSSL(final String host)
throws Exception
{
// attempting to use LDAPS by IP address should fail
ConnectionConfig cc = new ConnectionConfig(convertUrlToIp(host));
cc.setUseSSL(true);
Connection conn = DefaultConnectionFactory.getConnection(cc);
try {
conn.open();
// some providers won't perform the handshake until an operation is
// executed
final CompareOperation op = new CompareOperation(conn);
op.execute(new CompareRequest("", new LdapAttribute("objectClass", "top")));
AssertJUnit.fail("Should have thrown Exception, no exception thrown");
} catch (Exception e) {
AssertJUnit.assertNotNull(e);
} finally {
conn.close();
}
// attempting to use LDAPS by hostname address should succeed
cc = new ConnectionConfig(host);
cc.setUseSSL(true);
conn = DefaultConnectionFactory.getConnection(cc);
try {
conn.open();
} finally {
conn.close();
}
}
/**
* Converts a DNS based url string to an IP based string.
*
* @param host url to convert
*
* @return url with IP address
*
* @throws Exception if the ip address cannot be determined
*/
private String convertUrlToIp(final String host)
throws Exception
{
// convert the hostname into an ip address
String ipHost = null;
if (host.indexOf(":") < host.lastIndexOf(":")) {
ipHost = host.substring("ldap://".length(), host.lastIndexOf(":"));
} else {
ipHost = host.substring("ldap://".length());
}
final InetAddress ip = InetAddress.getByName(ipHost);
ipHost = "ldap://" + ip.getHostAddress();
if (host.indexOf(":") < host.lastIndexOf(":")) {
ipHost = ipHost + ":" + host.substring(host.lastIndexOf(":") + 1);
}
return ipHost;
}
}