diff options
author | Stefan Seelmann <mail@stefan-seelmann.de> | 2021-06-04 20:49:56 +0300 |
---|---|---|
committer | Stefan Seelmann <mail@stefan-seelmann.de> | 2021-06-04 20:49:56 +0300 |
commit | b53667ab3b87afcfcd6f1b1df90d733636cfc888 (patch) | |
tree | 5f27e7df11f98fc3fa5a8bcf7f2ede10c3583be9 /tests | |
parent | 8c758465c5a3e96e921e2b0083f85d025e16799f (diff) |
DIRSTUDIO-1219: Ensure StartTLS on connect
* Call startTls() right after connect()
* Change icon and label to indicate that connection is secured
* Remove unused SASL Plain mechanism and cleanup related code
* Add several test scenarios
Diffstat (limited to 'tests')
10 files changed, 821 insertions, 271 deletions
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java index 6ebf8fcf3..49000f2a5 100644 --- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java +++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java @@ -44,6 +44,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.net.ConnectException; import java.nio.channels.UnresolvedAddressException; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -66,6 +67,8 @@ import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyReq //import org.apache.directory.api.ldap.extras.extended.startTransaction.StartTransactionResponse; import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIRequest; import org.apache.directory.api.ldap.extras.extended.whoAmI.WhoAmIResponse; +import org.apache.directory.api.ldap.model.constants.SaslQoP; +import org.apache.directory.api.ldap.model.constants.SaslSecurityStrength; import org.apache.directory.api.ldap.model.entry.DefaultAttribute; import org.apache.directory.api.ldap.model.entry.DefaultEntry; import org.apache.directory.api.ldap.model.entry.DefaultModification; @@ -73,6 +76,7 @@ import org.apache.directory.api.ldap.model.entry.Entry; import org.apache.directory.api.ldap.model.entry.Modification; import org.apache.directory.api.ldap.model.entry.ModificationOperation; import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException; +import org.apache.directory.api.ldap.model.exception.LdapAuthenticationNotSupportedException; import org.apache.directory.api.ldap.model.exception.LdapException; import org.apache.directory.api.ldap.model.exception.LdapLoopDetectedException; import org.apache.directory.api.ldap.model.message.ExtendedResponse; @@ -88,6 +92,7 @@ import org.apache.directory.studio.connection.core.ConnectionCorePlugin; import org.apache.directory.studio.connection.core.ConnectionParameter; import org.apache.directory.studio.connection.core.ConnectionParameter.AuthenticationMethod; import org.apache.directory.studio.connection.core.ConnectionParameter.EncryptionMethod; +import org.apache.directory.studio.connection.core.ICertificateHandler.TrustLevel; import org.apache.directory.studio.connection.core.IReferralHandler; import org.apache.directory.studio.connection.core.event.ConnectionEventRegistry; import org.apache.directory.studio.connection.core.io.ConnectionWrapper; @@ -99,9 +104,9 @@ import org.apache.directory.studio.ldapbrowser.core.jobs.InitializeRootDSERunnab import org.apache.directory.studio.ldapbrowser.core.model.impl.BrowserConnection; import org.apache.directory.studio.test.integration.junit5.LdapServerType; import org.apache.directory.studio.test.integration.junit5.LdapServersSource; +import org.apache.directory.studio.test.integration.junit5.LdapServersSource.Mode; import org.apache.directory.studio.test.integration.junit5.SkipTestIfLdapServerIsNotAvailableInterceptor; import org.apache.directory.studio.test.integration.junit5.TestLdapServer; -import org.apache.directory.studio.test.integration.junit5.LdapServersSource.Mode; import org.apache.mina.util.AvailablePortFinder; import org.eclipse.core.runtime.NullProgressMonitor; import org.junit.jupiter.api.AfterAll; @@ -128,6 +133,7 @@ public class DirectoryApiConnectionWrapperTest public static void suspendEventFiringInCurrentThread() { ConnectionEventRegistry.suspendEventFiringInCurrentThread(); + ConnectionCorePlugin.getDefault().setCertificateHandler( null ); } @@ -149,29 +155,76 @@ public class DirectoryApiConnectionWrapperTest /** - * Tests connecting to the server. + * Tests connecting to the server without encryption. */ @ParameterizedTest - @LdapServersSource - public void testConnect( TestLdapServer ldapServer ) + @LdapServersSource(mode = Mode.All) + public void testConnectPlain( TestLdapServer ldapServer ) { StudioProgressMonitor monitor = getProgressMonitor(); - ConnectionParameter connectionParameter = new ConnectionParameter( null, ldapServer.getHost(), - ldapServer.getPort(), EncryptionMethod.NONE, AuthenticationMethod.NONE, null, null, null, true, null, - 30000L ); - Connection connection = new Connection( connectionParameter ); - ConnectionWrapper connectionWrapper = connection.getConnectionWrapper(); + getConnection( monitor, ldapServer, null, null ); assertFalse( connectionWrapper.isConnected() ); - connectionWrapper.connect( monitor ); + X509Certificate[] certificates = connectionWrapper.connect( monitor ); assertTrue( connectionWrapper.isConnected() ); + assertFalse( connectionWrapper.isSecured() ); assertNull( monitor.getException() ); + assertNull( certificates ); connectionWrapper.disconnect(); assertFalse( connectionWrapper.isConnected() ); + } + - // TODO: SSL, StartTLS + /** + * Tests connecting to the server using ldaps:// encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testConnectLdaps( TestLdapServer ldapServer ) + { + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, null, null ); + connection.setPort( ldapServer.getPortSSL() ); + connection.setEncryptionMethod( EncryptionMethod.LDAPS ); + acceptAllCertificates(); + + assertFalse( connectionWrapper.isConnected() ); + + X509Certificate[] certificates = connectionWrapper.connect( monitor ); + assertTrue( connectionWrapper.isConnected() ); + assertTrue( connectionWrapper.isSecured() ); + assertNull( monitor.getException() ); + assertNotNull( certificates ); + + connectionWrapper.disconnect(); + assertFalse( connectionWrapper.isConnected() ); + } + + + /** + * Tests connecting to the server using StartTLS encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testConnectStartTls( TestLdapServer ldapServer ) + { + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, null, null ); + connection.setEncryptionMethod( EncryptionMethod.START_TLS ); + acceptAllCertificates(); + + assertFalse( connectionWrapper.isConnected() ); + + X509Certificate[] certificates = connectionWrapper.connect( monitor ); + assertTrue( connectionWrapper.isConnected() ); + assertTrue( connectionWrapper.isSecured() ); + assertNull( monitor.getException() ); + assertNotNull( certificates ); + + connectionWrapper.disconnect(); + assertFalse( connectionWrapper.isConnected() ); } @@ -179,21 +232,16 @@ public class DirectoryApiConnectionWrapperTest * Test failed connections to the server. */ @ParameterizedTest - @LdapServersSource + @LdapServersSource(mode = Mode.All) public void testConnectFailures( TestLdapServer ldapServer ) { StudioProgressMonitor monitor = null; - ConnectionParameter connectionParameter = null; Connection connection = null; - ConnectionWrapper connectionWrapper = null; // invalid port monitor = getProgressMonitor(); - connectionParameter = new ConnectionParameter( null, ldapServer.getHost(), - AvailablePortFinder.getNextAvailable(), EncryptionMethod.NONE, AuthenticationMethod.NONE, null, null, null, - true, null, 30000L ); - connection = new Connection( connectionParameter ); - connectionWrapper = connection.getConnectionWrapper(); + connection = getConnection( monitor, ldapServer, null, null ); + connection.setPort( AvailablePortFinder.getNextAvailable() ); connectionWrapper.connect( monitor ); assertFalse( connectionWrapper.isConnected() ); assertNotNull( monitor.getException() ); @@ -205,10 +253,8 @@ public class DirectoryApiConnectionWrapperTest // unknown host monitor = getProgressMonitor(); - connectionParameter = new ConnectionParameter( null, "555.555.555.555", ldapServer.getPort(), - EncryptionMethod.NONE, AuthenticationMethod.NONE, null, null, null, true, null, 30000L ); - connection = new Connection( connectionParameter ); - connectionWrapper = connection.getConnectionWrapper(); + connection = getConnection( monitor, ldapServer, null, null ); + connection.setHost( "555.555.555.555" ); connectionWrapper.connect( monitor ); assertFalse( connectionWrapper.isConnected() ); assertNotNull( monitor.getException() ); @@ -217,30 +263,222 @@ public class DirectoryApiConnectionWrapperTest assertTrue( monitor.getException().getCause() instanceof InvalidConnectionException ); assertNotNull( monitor.getException().getCause().getCause() ); assertTrue( monitor.getException().getCause().getCause() instanceof UnresolvedAddressException ); + } + + + /** + * Test binding to the server using simple auth and no encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testSimpleBindPlain( TestLdapServer ldapServer ) + { + ldapServer.setConfidentialityRequired( false ); + StudioProgressMonitor monitor = getProgressMonitor(); + getConnection( monitor, ldapServer, ldapServer.getAdminDn(), ldapServer.getAdminPassword() ); + + assertFalse( connectionWrapper.isConnected() ); + + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + assertTrue( connectionWrapper.isConnected() ); + assertFalse( connectionWrapper.isSecured() ); + assertNull( monitor.getException() ); - // TODO: SSL, StartTLS + connectionWrapper.unbind(); + connectionWrapper.disconnect(); + assertFalse( connectionWrapper.isConnected() ); } /** - * Test binding to the server. + * Test binding to the server using simple auth and no encryption should fail if the server requires confidentially. */ @ParameterizedTest - @LdapServersSource - public void testBind( TestLdapServer ldapServer ) + @LdapServersSource(mode = Mode.All) + public void testSimpleBindPlainConfidentiallyRequired( TestLdapServer ldapServer ) { + ldapServer.setConfidentialityRequired( true ); StudioProgressMonitor monitor = getProgressMonitor(); - ConnectionParameter connectionParameter = new ConnectionParameter( null, ldapServer.getHost(), - ldapServer.getPort(), EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, ldapServer.getAdminDn(), - ldapServer.getAdminPassword(), null, true, null, 30000L ); - Connection connection = new Connection( connectionParameter ); - ConnectionWrapper connectionWrapper = connection.getConnectionWrapper(); + getConnection( monitor, ldapServer, ldapServer.getAdminDn(), ldapServer.getAdminPassword() ); + + assertFalse( connectionWrapper.isConnected() ); + + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + + assertFalse( connectionWrapper.isConnected() ); + assertFalse( connectionWrapper.isSecured() ); + assertNotNull( monitor.getException() ); + assertTrue( monitor.getException() instanceof StudioLdapException ); + assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 13 - confidentialityRequired]" ) ); + assertNotNull( monitor.getException().getCause() ); + assertTrue( monitor.getException().getCause() instanceof LdapAuthenticationNotSupportedException ); + } + + + /** + * Test binding to the server using simple auth and ldaps:// encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testSimpleBindLdaps( TestLdapServer ldapServer ) + { + ldapServer.setConfidentialityRequired( true ); + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, ldapServer.getAdminDn(), + ldapServer.getAdminPassword() ); + connection.setPort( ldapServer.getPortSSL() ); + connection.setEncryptionMethod( EncryptionMethod.LDAPS ); + acceptAllCertificates(); + + assertFalse( connectionWrapper.isConnected() ); + + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + assertTrue( connectionWrapper.isConnected() ); + assertTrue( connectionWrapper.isSecured() ); + assertNull( monitor.getException() ); + + connectionWrapper.unbind(); + connectionWrapper.disconnect(); + assertFalse( connectionWrapper.isConnected() ); + } + + + /** + * Test binding to the server using simple auth and StartTLS encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testSimpleBindStartTls( TestLdapServer ldapServer ) + { + ldapServer.setConfidentialityRequired( true ); + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, ldapServer.getAdminDn(), + ldapServer.getAdminPassword() ); + connection.setEncryptionMethod( EncryptionMethod.START_TLS ); + acceptAllCertificates(); + + assertFalse( connectionWrapper.isConnected() ); + + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + assertTrue( connectionWrapper.isConnected() ); + assertTrue( connectionWrapper.isSecured() ); + assertNull( monitor.getException() ); + + connectionWrapper.unbind(); + connectionWrapper.disconnect(); + assertFalse( connectionWrapper.isConnected() ); + } + + + /** + * Test binding to the server using SASL and no encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds) + public void testSaslBindPlain( TestLdapServer ldapServer ) + { + ldapServer.setConfidentialityRequired( false ); + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, "user.1", "password" ); + connection.setAuthMethod( AuthenticationMethod.SASL_DIGEST_MD5 ); + + assertFalse( connectionWrapper.isConnected() ); + + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + + assertTrue( connectionWrapper.isConnected() ); + assertFalse( connectionWrapper.isSecured() ); + assertNull( monitor.getException() ); + + connectionWrapper.unbind(); + connectionWrapper.disconnect(); + assertFalse( connectionWrapper.isConnected() ); + } + + + /** + * Test binding to the server using SASL and no encryption should fail if the server requires confidentially. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds) + public void testSaslBindPlainConfidentiallyRequired( TestLdapServer ldapServer ) + { + ldapServer.setConfidentialityRequired( true ); + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, "user.1", "password" ); + connection.setAuthMethod( AuthenticationMethod.SASL_DIGEST_MD5 ); + + assertFalse( connectionWrapper.isConnected() ); + + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + + assertFalse( connectionWrapper.isConnected() ); + assertFalse( connectionWrapper.isSecured() ); + assertNotNull( monitor.getException() ); + assertTrue( monitor.getException() instanceof StudioLdapException ); + assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 13 - confidentialityRequired]" ) ); + assertNotNull( monitor.getException().getCause() ); + assertTrue( monitor.getException().getCause() instanceof LdapAuthenticationNotSupportedException ); + } + + + /** + * Test binding to the server using SASL and ldaps:// encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds) + public void testSaslBindLdaps( TestLdapServer ldapServer ) + { + ldapServer.setConfidentialityRequired( true ); + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, "user.1", "password" ); + connection.setPort( ldapServer.getPortSSL() ); + connection.setEncryptionMethod( EncryptionMethod.LDAPS ); + connection.setAuthMethod( AuthenticationMethod.SASL_DIGEST_MD5 ); + acceptAllCertificates(); + + assertFalse( connectionWrapper.isConnected() ); + + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + + assertTrue( connectionWrapper.isConnected() ); + assertTrue( connectionWrapper.isSecured() ); + assertNull( monitor.getException() ); + + connectionWrapper.unbind(); + connectionWrapper.disconnect(); + assertFalse( connectionWrapper.isConnected() ); + } + + + /** + * Test binding to the server using SASL and StartTLS encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds) + public void testSaslBindStartTls( TestLdapServer ldapServer ) + { + ldapServer.setConfidentialityRequired( true ); + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, "user.1", "password" ); + connection.setEncryptionMethod( EncryptionMethod.START_TLS ); + connection.setAuthMethod( AuthenticationMethod.SASL_DIGEST_MD5 ); + acceptAllCertificates(); assertFalse( connectionWrapper.isConnected() ); connectionWrapper.connect( monitor ); connectionWrapper.bind( monitor ); + assertTrue( connectionWrapper.isConnected() ); + assertTrue( connectionWrapper.isSecured() ); assertNull( monitor.getException() ); connectionWrapper.unbind(); @@ -257,17 +495,10 @@ public class DirectoryApiConnectionWrapperTest public void testBindFailures( TestLdapServer ldapServer ) { StudioProgressMonitor monitor = null; - ConnectionParameter connectionParameter = null; - Connection connection = null; - ConnectionWrapper connectionWrapper = null; // simple auth with invalid user monitor = getProgressMonitor(); - connectionParameter = new ConnectionParameter( null, ldapServer.getHost(), ldapServer.getPort(), - EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, "cn=invalid," + USERS_DN, "invalid", null, true, - null, 30000L ); - connection = new Connection( connectionParameter ); - connectionWrapper = connection.getConnectionWrapper(); + getConnection( monitor, ldapServer, "cn=invalid," + USERS_DN, "invalid" ); connectionWrapper.connect( monitor ); connectionWrapper.bind( monitor ); assertFalse( connectionWrapper.isConnected() ); @@ -283,11 +514,7 @@ public class DirectoryApiConnectionWrapperTest // simple auth with invalid password monitor = getProgressMonitor(); - connectionParameter = new ConnectionParameter( null, ldapServer.getHost(), ldapServer.getPort(), - EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, ldapServer.getAdminDn(), "invalid", null, true, null, - 30000L ); - connection = new Connection( connectionParameter ); - connectionWrapper = connection.getConnectionWrapper(); + getConnection( monitor, ldapServer, ldapServer.getAdminDn(), "invalid" ); connectionWrapper.connect( monitor ); connectionWrapper.bind( monitor ); assertFalse( connectionWrapper.isConnected() ); @@ -1055,58 +1282,57 @@ public class DirectoryApiConnectionWrapperTest } - protected ConnectionWrapper getConnectionWrapper( StudioProgressMonitor monitor, TestLdapServer ldapServer, - String dn, String password ) + protected void acceptAllCertificates() { - // simple auth without principal and credential - ConnectionParameter connectionParameter = new ConnectionParameter( null, ldapServer.getHost(), - ldapServer.getPort(), EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, dn, password, null, false, null, - 30000L ); + ConnectionCorePlugin.getDefault().setCertificateHandler( ( host, certChain, failCauses ) -> { + return TrustLevel.Permanent; + } ); + } - Connection connection = new Connection( connectionParameter ); - connectionWrapper = connection.getConnectionWrapper(); - connectionWrapper.connect( monitor ); - connectionWrapper.bind( monitor ); + protected ConnectionWrapper getConnectionWrapper( StudioProgressMonitor monitor, TestLdapServer ldapServer ) + { + return getConnectionWrapper( monitor, ldapServer, ldapServer.getAdminDn(), + ldapServer.getAdminPassword() ); + } - assertTrue( connectionWrapper.isConnected() ); - IReferralHandler referralHandler = referralUrls -> { - return connection; - }; - ConnectionCorePlugin.getDefault().setReferralHandler( referralHandler ); + protected ConnectionWrapper getConnectionWrapper( StudioProgressMonitor monitor, TestLdapServer ldapServer, + String dn, String password ) + { + getConnection( monitor, ldapServer, dn, password ); + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); assertTrue( connectionWrapper.isConnected() ); assertNull( monitor.getException() ); return connectionWrapper; + } - protected ConnectionWrapper getConnectionWrapper( StudioProgressMonitor monitor, TestLdapServer ldapServer ) + protected Connection getConnection( StudioProgressMonitor monitor, TestLdapServer ldapServer, + String dn, String password ) { // simple auth without principal and credential ConnectionParameter connectionParameter = new ConnectionParameter( null, ldapServer.getHost(), - ldapServer.getPort(), EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, ldapServer.getAdminDn(), - ldapServer.getAdminPassword(), null, false, null, 30000L ); + ldapServer.getPort(), EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, dn, password, null, false, null, + 30000L ); + connectionParameter.setSaslQop( SaslQoP.AUTH_CONF ); + connectionParameter.setSaslSecurityStrength( SaslSecurityStrength.HIGH ); + connectionParameter.setSaslMutualAuthentication( true ); Connection connection = new Connection( connectionParameter ); - connectionWrapper = connection.getConnectionWrapper(); - connectionWrapper.connect( monitor ); - connectionWrapper.bind( monitor ); - - assertTrue( connectionWrapper.isConnected() ); - IReferralHandler referralHandler = referralUrls -> { return connection; }; ConnectionCorePlugin.getDefault().setReferralHandler( referralHandler ); - assertTrue( connectionWrapper.isConnected() ); - assertNull( monitor.getException() ); + connectionWrapper = connection.getConnectionWrapper(); - return connectionWrapper; + return connection; } } diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/ApacheDirectoryServer.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/ApacheDirectoryServer.java index ade8ddffe..c93a9454d 100644 --- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/ApacheDirectoryServer.java +++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/ApacheDirectoryServer.java @@ -86,7 +86,7 @@ public class ApacheDirectoryServer extends TestLdapServer service.setInterceptors( service.getInterceptors().stream() .filter( i -> !i.getName().equals( "ConfigurableHashingInterceptor" ) ) .collect( Collectors.toList() ) ); - System.out.println( service.getInterceptors() ); + service.setAllowAnonymousAccess( true ); server = new LdapServer(); server.setDirectoryService( service ); @@ -97,6 +97,7 @@ public class ApacheDirectoryServer extends TestLdapServer server.addTransports( ldaps ); server.addSaslMechanismHandler( "SIMPLE", new SimpleMechanismHandler() ); + server.addSaslMechanismHandler( "CRAM-MD5", new CramMd5MechanismHandler() ); server.addSaslMechanismHandler( "DIGEST-MD5", new DigestMd5MechanismHandler() ); server.setSaslRealms( Collections.singletonList( "EXAMPLE.ORG" ) ); server.setSaslHost( getHost() ); @@ -153,6 +154,13 @@ public class ApacheDirectoryServer extends TestLdapServer } + @Override + public void setConfidentialityRequired( boolean confidentialityRequired ) + { + server.setConfidentialityRequired( confidentialityRequired ); + } + + private ApacheDirectoryServer( int port, int portSSL ) { super( LdapServerType.ApacheDS, LOCALHOST, port, portSSL, "uid=admin,ou=system", "secret" ); diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Fedora389dsLdapServer.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Fedora389dsLdapServer.java index b856ee563..7f8a0ac57 100644 --- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Fedora389dsLdapServer.java +++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Fedora389dsLdapServer.java @@ -23,6 +23,10 @@ package org.apache.directory.studio.test.integration.junit5; import static org.apache.directory.studio.test.integration.junit5.Constants.LOCALHOST; +import org.apache.directory.api.ldap.model.entry.DefaultModification; +import org.apache.directory.api.ldap.model.entry.Modification; +import org.apache.directory.api.ldap.model.entry.ModificationOperation; + /** * An 389ds implementation of a test LDAP server. @@ -52,4 +56,15 @@ public class Fedora389dsLdapServer extends TestLdapServer FEDORA_389DS_ADMIN_DN, FEDORA_389DS_ADMIN_PASSWORD ); } + + @Override + public void setConfidentialityRequired( boolean confidentialityRequired ) + { + withAdminConnection( connection -> { + Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, + "nsslapd-require-secure-binds", confidentialityRequired ? "on" : "off" ); + connection.modify( "cn=config", modification ); + } ); + + } } diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/OpenLdapServer.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/OpenLdapServer.java index 23c64951a..69b80cbdb 100644 --- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/OpenLdapServer.java +++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/OpenLdapServer.java @@ -23,10 +23,13 @@ package org.apache.directory.studio.test.integration.junit5; import static org.apache.directory.studio.test.integration.junit5.Constants.LOCALHOST; +import org.apache.directory.api.ldap.model.entry.DefaultModification; import org.apache.directory.api.ldap.model.entry.Modification; +import org.apache.directory.api.ldap.model.entry.ModificationOperation; +import org.apache.directory.api.ldap.model.exception.LdapNoSuchAttributeException; import org.apache.directory.api.ldap.model.ldif.LdifEntry; import org.apache.directory.api.ldap.model.ldif.LdifReader; -import org.apache.directory.ldap.client.api.LdapNetworkConnection; +import org.apache.directory.ldap.client.api.LdapConnection; /** @@ -63,7 +66,7 @@ public class OpenLdapServer extends TestLdapServer { super.prepare(); - try ( LdapNetworkConnection connection = new LdapNetworkConnection( OPENLDAP_HOST, OPENLDAP_PORT ); + try ( LdapConnection connection = openConnection(); LdifReader ldifReader = new LdifReader( TestFixture.class.getResourceAsStream( "OpenLdapConfig.ldif" ) ) ) { connection.bind( OPENLDAP_CONFIG_DN, OPENLDAP_CONFIG_PASSWORD ); @@ -81,4 +84,25 @@ public class OpenLdapServer extends TestLdapServer } } + + @Override + public void setConfidentialityRequired( boolean confidentialityRequired ) + { + try ( LdapConnection connection = openConnection() ) + { + connection.bind( OPENLDAP_CONFIG_DN, OPENLDAP_CONFIG_PASSWORD ); + Modification modification = new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, + "olcSecurity", confidentialityRequired ? "ssf=256 tls=256" : "ssf=0 tls=0" ); + connection.modify( "cn=config", modification ); + } + catch ( LdapNoSuchAttributeException e ) + { + // ignore + } + catch ( Exception e ) + { + throw new RuntimeException( "Unexpected exception: " + e, e ); + } + } + } diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestLdapServer.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestLdapServer.java index 9caa587f3..f0fe345e3 100644 --- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestLdapServer.java +++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestLdapServer.java @@ -26,7 +26,9 @@ import org.apache.directory.api.ldap.model.exception.LdapException; import org.apache.directory.api.ldap.model.ldif.LdifEntry; import org.apache.directory.api.ldap.model.ldif.LdifReader; import org.apache.directory.ldap.client.api.LdapConnection; +import org.apache.directory.ldap.client.api.LdapConnectionConfig; import org.apache.directory.ldap.client.api.LdapNetworkConnection; +import org.apache.directory.ldap.client.api.NoVerificationTrustManager; import org.apache.directory.ldap.client.api.exception.InvalidConnectionException; @@ -83,13 +85,25 @@ public abstract class TestLdapServer public LdapConnection openAdminConnection() throws LdapException { - LdapConnection connection = new LdapNetworkConnection( host, port ); - connection.connect(); + LdapConnection connection = openConnection(); connection.bind( adminDn, adminPassword ); return connection; } + public LdapConnection openConnection() throws LdapException + { + LdapConnectionConfig config = new LdapConnectionConfig(); + config.setLdapHost( host ); + config.setLdapPort( port ); + config.setUseTls( true ); + config.setTrustManagers( new NoVerificationTrustManager() ); + LdapConnection connection = new LdapNetworkConnection( config ); + connection.connect(); + return connection; + } + + public void withAdminConnection( LdapConnectionConsumer consumer ) { try ( LdapConnection connection = openAdminConnection() ) @@ -129,6 +143,7 @@ public abstract class TestLdapServer TestFixture.createContextEntry( this ); TestFixture.cleanup( this ); TestFixture.importData( this ); + setConfidentialityRequired( false ); String serverSpecificLdif = getType().name() + ".ldif"; if ( TestFixture.class.getResource( serverSpecificLdif ) != null ) @@ -200,6 +215,9 @@ public abstract class TestLdapServer } + public abstract void setConfidentialityRequired( boolean confidentialityRequired ); + + @Override public String toString() { diff --git a/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/OpenLdapConfig.ldif b/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/OpenLdapConfig.ldif index 9fe06a588..158317fa6 100644 --- a/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/OpenLdapConfig.ldif +++ b/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/OpenLdapConfig.ldif @@ -36,8 +36,9 @@ dn: cn=config changetype: modify replace: olcAuthzRegexp olcAuthzRegexp: uid=([^,]*),cn=digest-md5,cn=auth uid=$1,ou=users,dc=example,dc=org +olcAuthzRegexp: uid=([^,]*),cn=cram-md5,cn=auth uid=$1,ou=users,dc=example,dc=org - replace: olcSaslSecProps -olcSaslSecProps: noplain,noanonymous,minssf=128 +olcSaslSecProps: noplain,noanonymous,minssf=0 - diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/AbstractTestBase.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/AbstractTestBase.java index b59294baf..817847ff2 100644 --- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/AbstractTestBase.java +++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/AbstractTestBase.java @@ -23,6 +23,7 @@ package org.apache.directory.studio.test.integration.ui; import static org.apache.directory.studio.test.integration.junit5.TestFixture.CONTEXT_DN; import static org.apache.directory.studio.test.integration.junit5.TestFixture.REFERRALS_DN; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -30,6 +31,7 @@ import java.util.List; import org.apache.commons.lang3.ArrayUtils; import org.apache.directory.api.ldap.model.name.Dn; import org.apache.directory.api.ldap.model.name.Rdn; +import org.apache.directory.studio.connection.core.ConnectionCorePlugin; import org.apache.directory.studio.test.integration.junit5.SkipTestIfLdapServerIsNotAvailableInterceptor; import org.apache.directory.studio.test.integration.junit5.TestLdapServer; import org.apache.directory.studio.test.integration.ui.bots.ApacheDSServersViewBot; @@ -76,6 +78,20 @@ public class AbstractTestBase @AfterEach final void tearDownBase() throws Exception { + // clear custom trust stores + X509Certificate[] permanentCertificates = ConnectionCorePlugin.getDefault().getPermanentTrustStoreManager() + .getCertificates(); + for ( X509Certificate certificate : permanentCertificates ) + { + ConnectionCorePlugin.getDefault().getPermanentTrustStoreManager().removeCertificate( certificate ); + } + X509Certificate[] temporaryCertificates = ConnectionCorePlugin.getDefault().getSessionTrustStoreManager() + .getCertificates(); + for ( X509Certificate certificate : temporaryCertificates ) + { + ConnectionCorePlugin.getDefault().getSessionTrustStoreManager().removeCertificate( certificate ); + } + connectionsViewBot.deleteTestConnections(); serversViewBot.deleteTestServers(); Assertions.genericTearDownAssertions(); diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/CertificateValidationTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/CertificateValidationTest.java index a78b757e0..54b555c43 100644 --- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/CertificateValidationTest.java +++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/CertificateValidationTest.java @@ -107,20 +107,6 @@ public class CertificateValidationTest extends AbstractTestBase @AfterEach public void tearDown() throws Exception { - // delete custom trust stores - X509Certificate[] permanentCertificates = ConnectionCorePlugin.getDefault().getPermanentTrustStoreManager() - .getCertificates(); - for ( X509Certificate certificate : permanentCertificates ) - { - ConnectionCorePlugin.getDefault().getPermanentTrustStoreManager().removeCertificate( certificate ); - } - X509Certificate[] temporaryCertificates = ConnectionCorePlugin.getDefault().getSessionTrustStoreManager() - .getCertificates(); - for ( X509Certificate certificate : temporaryCertificates ) - { - ConnectionCorePlugin.getDefault().getSessionTrustStoreManager().removeCertificate( certificate ); - } - // delete custom Java key store settings System.clearProperty( "javax.net.ssl.trustStore" ); System.clearProperty( "javax.net.ssl.trustStorePassword" ); diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/NewConnectionWizardTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/NewConnectionWizardTest.java index 93df03f20..2fcba8540 100644 --- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/NewConnectionWizardTest.java +++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/NewConnectionWizardTest.java @@ -21,7 +21,6 @@ package org.apache.directory.studio.test.integration.ui; -import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -40,11 +39,13 @@ import org.apache.directory.studio.connection.core.Connection; import org.apache.directory.studio.connection.core.ConnectionCorePlugin; import org.apache.directory.studio.connection.core.ConnectionManager; import org.apache.directory.studio.connection.core.ConnectionParameter.AuthenticationMethod; -import org.apache.directory.studio.test.integration.junit5.Constants; +import org.apache.directory.studio.connection.core.ConnectionParameter.EncryptionMethod; import org.apache.directory.studio.test.integration.junit5.LdapServerType; import org.apache.directory.studio.test.integration.junit5.LdapServersSource; import org.apache.directory.studio.test.integration.junit5.LdapServersSource.Mode; import org.apache.directory.studio.test.integration.junit5.TestLdapServer; +import org.apache.directory.studio.test.integration.ui.bots.CertificateTrustDialogBot; +import org.apache.directory.studio.test.integration.ui.bots.ErrorDialogBot; import org.apache.directory.studio.test.integration.ui.bots.NewConnectionWizardBot; import org.apache.mina.util.AvailablePortFinder; import org.junit.jupiter.api.BeforeEach; @@ -342,18 +343,57 @@ public class NewConnectionWizardTest extends AbstractTestBase } - /** - * Creates a new connection using the new connection wizard. - */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionNoEncryptionNoAuthOK( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.NONE ); + + wizardBot.selectNoAuthentication(); + + finishAndAssertConnection( server, EncryptionMethod.NONE, AuthenticationMethod.NONE, "", "" ); + } + + @ParameterizedTest @LdapServersSource - public void testCreateConnection( TestLdapServer server ) + public void testCreateConnectionNoEncryptionNoAuthInvalidHostname( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.NONE ); + + wizardBot.clickBackButton(); + String hostname = getInvalidHostName(); + wizardBot.typeHost( hostname ); + wizardBot.clickNextButton(); + wizardBot.selectNoAuthentication(); + + finishAndAssertConnectionError( hostname ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionNoEncryptionSimpleAuthOK( TestLdapServer server ) throws UnknownHostException { // enter connection parameter wizardBot.typeConnectionName( getConnectionName() ); wizardBot.typeHost( server.getHost() ); wizardBot.typePort( server.getPort() ); + // click "Check Network Parameter" button + String result = wizardBot.clickCheckNetworkParameterButton(); + assertNull( result, "Expected OK" ); + + // enter IPv4 address as host + wizardBot.typeHost( InetAddress.getByName( server.getHost() ).getHostAddress() ); + + // click "Check Network Parameter" button + result = wizardBot.clickCheckNetworkParameterButton(); + assertNull( result, "Expected OK" ); + + // enter hostname as host again + wizardBot.typeHost( server.getHost() ); + // jump to auth page wizardBot.clickNextButton(); @@ -361,261 +401,470 @@ public class NewConnectionWizardTest extends AbstractTestBase wizardBot.typeUser( server.getAdminDn() ); wizardBot.typePassword( server.getAdminPassword() ); - // finish dialog - wizardBot.clickFinishButton( true ); - connectionsViewBot.waitForConnection( getConnectionName() ); - - // ensure connection was created - ConnectionManager connectionManager = ConnectionCorePlugin.getDefault().getConnectionManager(); - assertNotNull( connectionManager.getConnections() ); - assertEquals( 1, connectionManager.getConnections().length ); - Connection connection = connectionManager.getConnections()[0]; - assertEquals( getConnectionName(), connection.getName() ); - assertEquals( server.getHost(), connection.getHost() ); - assertEquals( server.getPort(), connection.getPort() ); - assertEquals( AuthenticationMethod.SIMPLE, connection.getAuthMethod() ); - assertEquals( server.getAdminDn(), connection.getBindPrincipal() ); - assertEquals( server.getAdminPassword(), connection.getBindPassword() ); - - // ensure connection is visible in Connections view - assertEquals( 1, connectionsViewBot.getCount() ); + // click "Check Network Parameter" button + result = wizardBot.clickCheckAuthenticationButton(); + assertNull( result, "Expected OK" ); - // close connection - connectionsViewBot.closeSelectedConnections(); + finishAndAssertConnection( server, EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, + server.getAdminDn(), server.getAdminPassword() ); } - /** - * Tests the "Check Network Parameter" button. - */ @ParameterizedTest - @LdapServersSource - public void testCheckNetworkParameterButtonOK( TestLdapServer server ) throws UnknownHostException + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionNoEncryptionSimpleAuthConfidentialityRequired( TestLdapServer server ) + { - // enter connection parameter with host name - wizardBot.typeConnectionName( getConnectionName() ); - wizardBot.typeHost( server.getHost() ); - wizardBot.typePort( server.getPort() ); + setConnectionParameters( server, EncryptionMethod.NONE ); - // click "Check Network Parameter" button - String result1 = wizardBot.clickCheckNetworkParameterButton(); - assertNull( result1, "Expected OK" ); + wizardBot.selectSimpleAuthentication(); + wizardBot.typeUser( server.getAdminDn() ); + wizardBot.typePassword( server.getAdminPassword() ); - // enter connection parameter with IPv4 address - wizardBot.typeHost( InetAddress.getByName( server.getHost() ).getHostAddress() ); - wizardBot.typePort( server.getPort() ); + server.setConfidentialityRequired( true ); - // click "Check Network Parameter" button - String result2 = wizardBot.clickCheckNetworkParameterButton(); - assertNull( result2, "Expected OK" ); - - // - // Don't know why this doesn't work with SWTBot. - // When testing manually it works. - // - // // enter connection parameter with IPv6 address - // wizardBot.typeHost( "[::1]" ); - // wizardBot.typePort( ldapService.getPort() ); - // - // // click "Check Network Parameter" button - // String result3 = wizardBot.clickCheckNetworkParameterButton(); - // assertNull( "Expected OK", result3 ); + String result = wizardBot.clickCheckAuthenticationButton(); + assertThat( result, containsString( "[LDAP result code 13 - confidentialityRequired]" ) ); + + finishAndAssertConnectionError( "[LDAP result code 13 - confidentialityRequired]" ); - wizardBot.clickCancelButton(); } - /** - * Tests the "Check Network Parameter" button. - */ - @Test - public void testCheckNetworkParameterButtonNotOK() + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds, reason = "SASL not configured for 389ds") + public void testCreateConnectionNoEncryptionSaslCramMd5OK( TestLdapServer server ) { - // enter connection parameter with invalid port - wizardBot.typeConnectionName( getConnectionName() ); - wizardBot.typeHost( Constants.LOCALHOST ); - wizardBot.typePort( AvailablePortFinder.getNextAvailable( 1024 ) ); - - // click "Check Network Parameter" button and get the result - String result1 = wizardBot.clickCheckNetworkParameterButton(); - assertNotNull( result1 ); - // LDAP API: Connection refused - // JNDI: The connection failed - assertThat( result1, - anyOf( containsString( "Connection refused" ), containsString( "The connection failed" ) ) ); - - // enter connection parameter with invalid host name - String hostname = "qwertzuiop.asdfghjkl.yxcvbnm"; - wizardBot.typeHost( hostname ); - wizardBot.typePort( 389 ); + setConnectionParameters( server, EncryptionMethod.NONE ); - // click "Check Network Parameter" button and get the result - String result2 = wizardBot.clickCheckNetworkParameterButton(); - assertNotNull( "Expected Error", result2 ); - // LDAP API: could not be resolved - // JNDI: The connection failed - assertThat( result2, - anyOf( containsString( "could not be resolved" ), containsString( "The connection failed" ) ) ); - assertThat( "Unknown host name must occur in error message", result2, containsString( hostname ) ); - - // disabled this test because it does not work properly - // as it depends from the network connection settings. - // // enter connection parameter with non-routed IP address - // String ipAddress = "10.11.12.13"; - // wizardBot.typeHost( ipAddress ); - // wizardBot.typePort( ldapServer.getPort() ); - // - // // click "Check Network Parameter" button and get the result - // String result3 = wizardBot.clickCheckNetworkParameterButton(); - // assertNotNull( "Expected Error", result3 ); - // assertTrue( "'No route to host' or 'Network is unreachable' message must occur in error message", // - // result3.contains( "No route to host" ) || result3.contains( "Network is unreachable" ) ); - // assertTrue( "IP address must occur in error message", result3.contains( ipAddress ) ); + wizardBot.selectCramMD5Authentication(); + wizardBot.typeUser( "user.1" ); + wizardBot.typePassword( "password" ); + wizardBot.selectQualityOfProtection( SaslQoP.AUTH ); + wizardBot.selectProtectionStrength( SaslSecurityStrength.HIGH ); - wizardBot.clickCancelButton(); + String result = wizardBot.clickCheckAuthenticationButton(); + assertNull( result, "Expected OK" ); + + finishAndAssertConnection( server, EncryptionMethod.NONE, AuthenticationMethod.SASL_CRAM_MD5, + "user.1", "password" ); } - /** - * Tests the "Check Authentication" button. - */ @ParameterizedTest - @LdapServersSource - public void testCheckAuthenticationButtonSimpleAuthOK( TestLdapServer server ) + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds, reason = "SASL not configured for 389ds") + public void testCreateConnectionNoEncryptionSaslDigestMd5OK( TestLdapServer server ) { - // enter connection parameter - wizardBot.typeConnectionName( getConnectionName() ); - wizardBot.typeHost( server.getHost() ); - wizardBot.typePort( server.getPort() ); - wizardBot.clickNextButton(); + setConnectionParameters( server, EncryptionMethod.NONE ); - // enter correct authentication parameter - wizardBot.typeUser( server.getAdminDn() ); - wizardBot.typePassword( server.getAdminPassword() ); + wizardBot.selectDigestMD5Authentication(); + wizardBot.typeUser( "user.1" ); + wizardBot.typePassword( "password" ); + if ( server.getType() == LdapServerType.ApacheDS ) + { + wizardBot.typeRealm( "EXAMPLE.ORG" ); + } + wizardBot.selectQualityOfProtection( SaslQoP.AUTH ); + wizardBot.selectProtectionStrength( SaslSecurityStrength.HIGH ); - // click "Check Network Parameter" button String result = wizardBot.clickCheckAuthenticationButton(); assertNull( result, "Expected OK" ); - wizardBot.clickCancelButton(); + finishAndAssertConnection( server, EncryptionMethod.NONE, AuthenticationMethod.SASL_DIGEST_MD5, + "user.1", "password" ); } - /** - * Tests the "Check Authentication" button. - */ @ParameterizedTest - @LdapServersSource - public void testCheckAuthenticationButtonSimpleAuthNotOK( TestLdapServer server ) + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds, reason = "SASL not configured for 389ds") + public void testCreateConnectionNoEncryptionSaslDigestMd5ConfidentialityRequired( TestLdapServer server ) { - // enter connection parameter - wizardBot.typeConnectionName( getConnectionName() ); - wizardBot.typeHost( server.getHost() ); - wizardBot.typePort( server.getPort() ); - wizardBot.clickNextButton(); + setConnectionParameters( server, EncryptionMethod.NONE ); + + wizardBot.selectDigestMD5Authentication(); + wizardBot.typeUser( "user.1" ); + wizardBot.typePassword( "password" ); + wizardBot.selectQualityOfProtection( SaslQoP.AUTH ); + wizardBot.selectProtectionStrength( SaslSecurityStrength.HIGH ); + + server.setConfidentialityRequired( true ); + + finishAndAssertConnectionError( "[LDAP result code 13 - confidentialityRequired]" ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionLdapsEncryptionNoAuthOK( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.LDAPS ); + + wizardBot.selectNoAuthentication(); + + finishAndAssertConnection( server, EncryptionMethod.LDAPS, AuthenticationMethod.NONE, "", "" ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionLdapsEncryptionSimpleAuthOK( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.LDAPS ); - // enter incorrect authentication parameter wizardBot.typeUser( server.getAdminDn() ); - wizardBot.typePassword( "secret45" ); + wizardBot.typePassword( server.getAdminPassword() ); + + finishAndAssertConnection( server, EncryptionMethod.LDAPS, AuthenticationMethod.SIMPLE, + server.getAdminDn(), server.getAdminPassword() ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionLdapsEncryptionSimpleAuthInvalidCredentials( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.LDAPS ); + + wizardBot.selectSimpleAuthentication(); + wizardBot.typeUser( "cn=invalid" ); + wizardBot.typePassword( "invalid" ); - // click "Check Network Parameter" button String result = wizardBot.clickCheckAuthenticationButton(); - assertNotNull( result ); assertThat( result, containsString( "[LDAP result code 49 - invalidCredentials]" ) ); - wizardBot.clickCancelButton(); + finishAndAssertConnectionError( "[LDAP result code 49 - invalidCredentials]" ); } - /** - * Tests the "Check Authentication" button. - */ @ParameterizedTest - @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds) - public void testCheckAuthenticationButtonDigestMD5OK( TestLdapServer server ) + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds, reason = "SASL not configured for 389ds") + public void testCreateConnectionLdapsEncryptionSaslDigestMd5Ok( TestLdapServer server ) { - // enter connection parameter - wizardBot.typeConnectionName( getConnectionName() ); - wizardBot.typeHost( server.getHost() ); - wizardBot.typePort( server.getPort() ); - wizardBot.clickNextButton(); + setConnectionParameters( server, EncryptionMethod.LDAPS ); - // enter correct authentication parameter wizardBot.selectDigestMD5Authentication(); - wizardBot.typeUser( "user.8" ); + wizardBot.typeUser( "user.1" ); wizardBot.typePassword( "password" ); if ( server.getType() == LdapServerType.ApacheDS ) { wizardBot.typeRealm( "EXAMPLE.ORG" ); } - wizardBot.selectQualityOfProtection( SaslQoP.AUTH_CONF ); + wizardBot.selectQualityOfProtection( SaslQoP.AUTH ); + wizardBot.selectProtectionStrength( SaslSecurityStrength.HIGH ); + + finishAndAssertConnection( server, EncryptionMethod.LDAPS, AuthenticationMethod.SASL_DIGEST_MD5, + "user.1", "password" ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds, reason = "SASL not configured for 389ds") + public void testCreateConnectionLdapsEncryptionSaslDigestMd5InvalidCredentials( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.LDAPS ); + + wizardBot.selectDigestMD5Authentication(); + wizardBot.typeUser( "user.1" ); + wizardBot.typePassword( "invalid" ); + if ( server.getType() == LdapServerType.ApacheDS ) + { + wizardBot.typeRealm( "EXAMPLE.ORG" ); + } + wizardBot.selectQualityOfProtection( SaslQoP.AUTH ); wizardBot.selectProtectionStrength( SaslSecurityStrength.HIGH ); - // click "Check Network Parameter" button String result = wizardBot.clickCheckAuthenticationButton(); - assertNull( result, "Expected OK" ); + assertThat( result, containsString( "[LDAP result code 49 - invalidCredentials]" ) ); - wizardBot.clickCancelButton(); + finishAndAssertConnectionError( "[LDAP result code 49 - invalidCredentials]" ); } - /** - * Tests the "Check Authentication" button. - */ @ParameterizedTest - @LdapServersSource(only = LdapServerType.OpenLdap) - public void testCheckAuthenticationButtonDigestMD5OKTooWeek( TestLdapServer server ) + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds, reason = "SASL not configured for 389ds") + public void testCreateConnectionLdapsEncryptionSaslDigestMd5InvalidRealm( TestLdapServer server ) { - // enter connection parameter - wizardBot.typeConnectionName( getConnectionName() ); - wizardBot.typeHost( server.getHost() ); - wizardBot.typePort( server.getPort() ); - wizardBot.clickNextButton(); + setConnectionParameters( server, EncryptionMethod.LDAPS ); - // enter correct authentication parameter wizardBot.selectDigestMD5Authentication(); - wizardBot.typeUser( "user.8" ); + wizardBot.typeUser( "user.1" ); wizardBot.typePassword( "password" ); + wizardBot.typeRealm( "APACHE.ORG" ); wizardBot.selectQualityOfProtection( SaslQoP.AUTH ); - wizardBot.selectProtectionStrength( SaslSecurityStrength.LOW ); + wizardBot.selectProtectionStrength( SaslSecurityStrength.HIGH ); - // click "Check Network Parameter" button String result = wizardBot.clickCheckAuthenticationButton(); - assertThat( result, containsString( "DIGEST-MD5: No common protection layer between client and server" ) ); + assertThat( result, containsString( "[LDAP result code" ) ); - wizardBot.clickCancelButton(); + finishAndAssertConnectionError( "[LDAP result code" ); } - /** - * Tests the "Check Authentication" button. - */ @ParameterizedTest - @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds) - public void testCheckAuthenticationButtonDigestMD5NotOKWrongPassword( TestLdapServer server ) + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionStartTlsEncryptionNoAuthOK( TestLdapServer server ) { - // enter connection parameter - wizardBot.typeConnectionName( getConnectionName() ); - wizardBot.typeHost( server.getHost() ); - wizardBot.typePort( server.getPort() ); - wizardBot.clickNextButton(); + setConnectionParameters( server, EncryptionMethod.START_TLS ); + + wizardBot.selectNoAuthentication(); + + finishAndAssertConnection( server, EncryptionMethod.START_TLS, AuthenticationMethod.NONE, "", "" ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionStartTlsEncryptionSimpleAuthOK( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.START_TLS ); + + wizardBot.typeUser( server.getAdminDn() ); + wizardBot.typePassword( server.getAdminPassword() ); + + finishAndAssertConnection( server, EncryptionMethod.START_TLS, AuthenticationMethod.SIMPLE, + server.getAdminDn(), server.getAdminPassword() ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCreateConnectionStartTlsEncryptionSimpleAuthInvalidCredentials( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.START_TLS ); + + wizardBot.selectSimpleAuthentication(); + wizardBot.typeUser( "cn=invalid" ); + wizardBot.typePassword( "invalid" ); + + String result = wizardBot.clickCheckAuthenticationButton(); + assertThat( result, containsString( "[LDAP result code 49 - invalidCredentials]" ) ); + + finishAndAssertConnectionError( "[LDAP result code 49 - invalidCredentials]" ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds, reason = "SASL not configured for 389ds") + public void testCreateConnectionStartTlsEncryptionSaslDigestMd5OK( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.START_TLS ); - // enter correct authentication parameter wizardBot.selectDigestMD5Authentication(); - wizardBot.typeUser( "user.8" ); - wizardBot.typePassword( "wrong" ); + wizardBot.typeUser( "user.1" ); + wizardBot.typePassword( "password" ); if ( server.getType() == LdapServerType.ApacheDS ) { wizardBot.typeRealm( "EXAMPLE.ORG" ); } - wizardBot.selectQualityOfProtection( SaslQoP.AUTH_CONF ); + wizardBot.selectQualityOfProtection( SaslQoP.AUTH ); + wizardBot.selectProtectionStrength( SaslSecurityStrength.HIGH ); + + finishAndAssertConnection( server, EncryptionMethod.START_TLS, AuthenticationMethod.SASL_DIGEST_MD5, + "user.1", "password" ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.Fedora389ds, reason = "SASL not configured for 389ds") + public void testCreateConnectionStartTlsEncryptionSaslDigestMd5InvalidCredentials( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.START_TLS ); + + wizardBot.selectDigestMD5Authentication(); + wizardBot.typeUser( "user.1" ); + wizardBot.typePassword( "invalid" ); + if ( server.getType() == LdapServerType.ApacheDS ) + { + wizardBot.typeRealm( "EXAMPLE.ORG" ); + } + wizardBot.selectQualityOfProtection( SaslQoP.AUTH ); wizardBot.selectProtectionStrength( SaslSecurityStrength.HIGH ); - // click "Check Network Parameter" button String result = wizardBot.clickCheckAuthenticationButton(); assertThat( result, containsString( "[LDAP result code 49 - invalidCredentials]" ) ); + finishAndAssertConnectionError( "[LDAP result code 49 - invalidCredentials]" ); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCheckNetworkParameterButtonNoEncryptionNotOk( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.NONE ); + wizardBot.clickBackButton(); + + // Invalid port + wizardBot.typePort( getInvalidPort() ); + String result = wizardBot.clickCheckNetworkParameterButton(); + assertThat( result, containsString( "The connection failed" ) ); + + // Invalid host + String hostname = getInvalidHostName(); + wizardBot.typeHost( hostname ); + result = wizardBot.clickCheckNetworkParameterButton(); + assertThat( result, containsString( "The connection failed" ) ); + assertThat( "Unknown host name must occur in error message", result, containsString( hostname ) ); + + wizardBot.clickCancelButton(); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCheckNetworkParameterButtonLdapsEncryptionNotOk( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.LDAPS ); + wizardBot.clickBackButton(); + + // Invalid port + wizardBot.typePort( getInvalidPort() ); + String result = wizardBot.clickCheckNetworkParameterButton(); + assertThat( result, containsString( "The connection failed" ) ); + + // Non ldaps port + wizardBot.typePort( server.getPort() ); + result = wizardBot.clickCheckNetworkParameterButton(); + assertThat( result, containsString( "The connection failed" ) ); + + // Invalid host + String hostname = getInvalidHostName(); + wizardBot.typeHost( hostname ); + result = wizardBot.clickCheckNetworkParameterButton(); + assertThat( result, containsString( "The connection failed" ) ); + assertThat( "Unknown host name must occur in error message", result, containsString( hostname ) ); + + wizardBot.clickCancelButton(); + } + + + @ParameterizedTest + @LdapServersSource(mode = Mode.All) + public void testCheckNetworkParameterButtonStartTlsEncryptionNotOk( TestLdapServer server ) + { + setConnectionParameters( server, EncryptionMethod.START_TLS ); + wizardBot.clickBackButton(); + + // Invalid port + wizardBot.typePort( getInvalidPort() ); + String result = wizardBot.clickCheckNetworkParameterButton(); + assertThat( result, containsString( "The connection failed" ) ); + + // Ldaps port + wizardBot.typePort( server.getPortSSL() ); + result = wizardBot.clickCheckNetworkParameterButton(); + assertThat( result, containsString( "The connection failed" ) ); + + // Invalid host + String hostname = getInvalidHostName(); + wizardBot.typeHost( hostname ); + result = wizardBot.clickCheckNetworkParameterButton(); + assertThat( result, containsString( "The connection failed" ) ); + assertThat( "Unknown host name must occur in error message", result, containsString( hostname ) ); + wizardBot.clickCancelButton(); } + + private void setConnectionParameters( TestLdapServer server, EncryptionMethod encryptionMethod ) + { + wizardBot.typeConnectionName( getConnectionName() ); + wizardBot.typeHost( server.getHost() ); + wizardBot.typePort( encryptionMethod == EncryptionMethod.LDAPS ? server.getPortSSL() : server.getPort() ); + + if ( encryptionMethod == EncryptionMethod.LDAPS ) + { + wizardBot.selectLdapsEncryption(); + } + if ( encryptionMethod == EncryptionMethod.START_TLS ) + { + wizardBot.selectStartTlsEncryption(); + } + + if ( encryptionMethod != EncryptionMethod.NONE ) + { + server.setConfidentialityRequired( true ); + CertificateTrustDialogBot trustDialog = wizardBot + .clickCheckNetworkParameterButtonExpectingCertificateTrustDialog(); + trustDialog.selectTrustPermanent(); + trustDialog.clickOkButton(); + bot.button( "OK" ).click(); + } + + wizardBot.clickNextButton(); + } + + + private void finishAndAssertConnection( TestLdapServer server, EncryptionMethod encryptionMethod, + AuthenticationMethod authenticationMethod, String user, String password ) + { + wizardBot.clickFinishButton( true ); + + connectionsViewBot.waitForConnection( getConnectionName() ); + + // ensure connection was created + ConnectionManager connectionManager = ConnectionCorePlugin.getDefault().getConnectionManager(); + assertNotNull( connectionManager.getConnections() ); + assertEquals( 1, connectionManager.getConnections().length ); + Connection connection = connectionManager.getConnections()[0]; + assertEquals( getConnectionName(), connection.getName() ); + assertEquals( server.getHost(), connection.getHost() ); + assertEquals( encryptionMethod == EncryptionMethod.LDAPS ? server.getPortSSL() : server.getPort(), + connection.getPort() ); + assertEquals( user, connection.getBindPrincipal() ); + assertEquals( password, connection.getBindPassword() ); + assertEquals( authenticationMethod, connection.getAuthMethod() ); + assertTrue( connection.getConnectionWrapper().isConnected() ); + if ( encryptionMethod == EncryptionMethod.NONE ) + { + assertFalse( connection.getConnectionWrapper().isSecured() ); + } + else + { + assertTrue( connection.getConnectionWrapper().isSecured() ); + } + + // ensure connection is visible in Connections view + assertEquals( 1, connectionsViewBot.getCount() ); + + // close connection + connectionsViewBot.closeSelectedConnections(); + } + + + private void finishAndAssertConnectionError( String errorText ) + { + ErrorDialogBot errorBot = wizardBot.clickFinishButtonExpectingError(); + + String errorMessage = errorBot.getErrorMessage(); + String errorDetails = errorBot.getErrorDetails(); + assertNotNull( errorMessage ); + assertNotNull( errorDetails ); + assertThat( errorDetails, containsString( errorText ) ); + errorBot.clickOkButton(); + + ConnectionManager connectionManager = ConnectionCorePlugin.getDefault().getConnectionManager(); + assertNotNull( connectionManager.getConnections() ); + assertEquals( 1, connectionManager.getConnections().length ); + Connection connection = connectionManager.getConnections()[0]; + assertEquals( getConnectionName(), connection.getName() ); + assertFalse( connection.getConnectionWrapper().isConnected() ); + assertFalse( connection.getConnectionWrapper().isSecured() ); + + // ensure connection is visible in Connections view + assertEquals( 1, connectionsViewBot.getCount() ); + } + + + private int getInvalidPort() + { + return AvailablePortFinder.getNextAvailable( 1025 ); + } + + + private static String getInvalidHostName() + { + return "qwertzuiop.asdfghjkl.yxcvbnm"; + } + } diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/WizardBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/WizardBot.java index 28b8a5fb8..332bd9177 100644 --- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/WizardBot.java +++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/WizardBot.java @@ -94,6 +94,13 @@ public abstract class WizardBot extends DialogBot } + public ErrorDialogBot clickFinishButtonExpectingError() + { + String shellText = BotUtils.shell( () -> clickFinishButton(), "Error", "Problem Occurred" ).getText(); + return new ErrorDialogBot( shellText ); + } + + public boolean existsCategory( String category ) { TreeBot treeBot = new TreeBot( bot.tree() ); |