diff options
author | Stefan Seelmann <mail@stefan-seelmann.de> | 2021-07-05 21:23:52 +0300 |
---|---|---|
committer | Stefan Seelmann <mail@stefan-seelmann.de> | 2021-07-05 21:23:52 +0300 |
commit | 9f92542b3f5f4bd64ccf89ec6159f04c66eba17f (patch) | |
tree | 14d434c41c51d4bb7e2ac920ff84ac7b1810466b | |
parent | 85bd670c33c57e4009da4fe784b6c3d21b4e8c14 (diff) |
Add more TLSv1.3 tests
5 files changed, 237 insertions, 5 deletions
diff --git a/tests/test.integration.core/pom-first.xml b/tests/test.integration.core/pom-first.xml index d7e25297f..271d18e7f 100644 --- a/tests/test.integration.core/pom-first.xml +++ b/tests/test.integration.core/pom-first.xml @@ -85,6 +85,7 @@ javax.annotation</Require-Bundle> <Import-Package>org.apache.commons.codec.digest, + org.apache.commons.lang3, org.apache.http.conn.ssl, org.bouncycastle.asn1, org.bouncycastle.asn1.x509, 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 6616b9963..730e49d82 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 @@ -22,6 +22,7 @@ package org.apache.directory.studio.test.integration.core; import static org.apache.directory.studio.test.integration.junit5.TestFixture.CONTEXT_DN; +import static org.apache.directory.studio.test.integration.junit5.TestFixture.MISC111_DN; import static org.apache.directory.studio.test.integration.junit5.TestFixture.MISC_DN; import static org.apache.directory.studio.test.integration.junit5.TestFixture.REFERRALS_DN; import static org.apache.directory.studio.test.integration.junit5.TestFixture.REFERRAL_LOOP_1_DN; @@ -44,8 +45,9 @@ 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.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; @@ -60,6 +62,7 @@ import javax.naming.directory.SearchControls; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; +import org.apache.commons.lang3.RandomStringUtils; import org.apache.directory.api.ldap.codec.api.LdapApiService; import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory; //import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionRequest; @@ -71,6 +74,7 @@ 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.constants.SchemaConstants; 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; @@ -109,6 +113,7 @@ 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.TestData; import org.apache.directory.studio.test.integration.junit5.TestFixture; import org.apache.directory.studio.test.integration.junit5.TestLdapServer; import org.apache.mina.util.AvailablePortFinder; @@ -842,6 +847,167 @@ public class DirectoryApiConnectionWrapperTest /** + * Executes load tests without encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.ApacheDS, reason = "JDBM JAR defines wrong OSGi imports") + public void loadTestPlain( TestLdapServer ldapServer ) throws Exception + { + ldapServer.setConfidentialityRequired( false ); + StudioProgressMonitor monitor = getProgressMonitor(); + getConnection( monitor, ldapServer, ldapServer.getAdminDn(), ldapServer.getAdminPassword() ); + + loadTest( ldapServer ); + } + + + /** + * Executes load test with ldaps:// encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.ApacheDS, reason = "JDBM JAR defines wrong OSGi imports") + public void loadTestLdaps( TestLdapServer ldapServer ) throws Exception + { + ldapServer.setConfidentialityRequired( true ); + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, ldapServer.getAdminDn(), + ldapServer.getAdminPassword() ); + connection.setPort( ldapServer.getPortSSL() ); + connection.setEncryptionMethod( EncryptionMethod.LDAPS ); + acceptAllCertificates(); + + loadTest( ldapServer ); + loadTest( ldapServer ); + + assertEquals( "TLSv1.3", connectionWrapper.getSslSession().getProtocol() ); + } + + + /** + * Executes load test with StartTLS encryption. + */ + @ParameterizedTest + @LdapServersSource(mode = Mode.All, except = LdapServerType.ApacheDS, reason = "JDBM JAR defines wrong OSGi imports") + public void loadTestStartTls( TestLdapServer ldapServer ) throws Exception + { + ldapServer.setConfidentialityRequired( true ); + StudioProgressMonitor monitor = getProgressMonitor(); + Connection connection = getConnection( monitor, ldapServer, ldapServer.getAdminDn(), + ldapServer.getAdminPassword() ); + connection.setEncryptionMethod( EncryptionMethod.START_TLS ); + acceptAllCertificates(); + + loadTest( ldapServer ); + loadTest( ldapServer ); + + assertEquals( "TLSv1.3", connectionWrapper.getSslSession().getProtocol() ); + } + + + /** + * Executes various search and modify operations with small and large payloads. + */ + private void loadTest( TestLdapServer ldapServer ) throws LdapException + { + int num = 500; + + StudioProgressMonitor monitor = getProgressMonitor(); + + // connect and bind + for ( int i = 1; i <= 20; i++ ) + { + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + connectionWrapper.unbind(); + assertNull( monitor.getException() ); + } + connectionWrapper.connect( monitor ); + connectionWrapper.bind( monitor ); + assertNull( monitor.getException() ); + + // lookup Root DSE + Entry rootDSE = lookup( "", monitor ); + assertNull( monitor.getException() ); + assertTrue( rootDSE.containsAttribute( "namingContexts", "subschemaSubentry" ) ); + String subschemaSubentryDn = rootDSE.get( "subschemaSubentry" ).getString(); + + // lookup schema + Entry schema = lookup( subschemaSubentryDn, monitor ); + assertNull( monitor.getException() ); + assertTrue( schema.containsAttribute( "objectClasses", "attributeTypes" ) ); + + // create entries with some large attributes + for ( int i = 1; i <= num; i++ ) + { + String dn = "uid=user." + i + "," + MISC111_DN; + Entry entry = new DefaultEntry( dn, "objectClass: inetOrgPerson", "sn: " + i, "cn: " + i, + "uid: user." + i ); + if ( i % 50 == 0 ) + { + entry.add( "description", RandomStringUtils.randomAscii( 10000 ) ); + entry.add( "jpegPhoto", TestData.jpegImage( 100000 ) ); + } + connectionWrapper.createEntry( entry, null, monitor, null ); + assertNull( monitor.getException() ); + } + + // modify entries + for ( int i = 1; i <= num; i++ ) + { + Dn dn = new Dn( "uid=user." + i + "," + MISC111_DN ); + Collection<Modification> modifications = Arrays.asList( + new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, "description", + RandomStringUtils.randomAscii( 20 ) ), + new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, "userPassword", + RandomStringUtils.randomAscii( 20 ) ) ); + connectionWrapper.modifyEntry( dn, modifications, null, monitor, null ); + assertNull( monitor.getException() ); + } + + try + { + Thread.sleep( 5000L ); + } + catch ( InterruptedException e ) + { + } + + // search entries + StudioSearchResultEnumeration result = connectionWrapper.search( MISC111_DN.getName(), + TestFixture.OBJECT_CLASS_ALL_FILTER, new SearchControls(), AliasDereferencingMethod.NEVER, + ReferralHandlingMethod.IGNORE, null, monitor, null ); + List<Dn> dns = consume( result, sr -> sr.getDn() ); + assertEquals( num, dns.size() ); + assertNull( monitor.getException() ); + + // delete entries + for ( int i = 1; i <= num; i++ ) + { + Dn dn = new Dn( "uid=user." + i + "," + MISC111_DN ); + connectionWrapper.deleteEntry( dn, null, monitor, null ); + assertNull( monitor.getException() ); + } + + assertNull( monitor.getException() ); + } + + + private Entry lookup( String dn, StudioProgressMonitor monitor ) throws LdapException + { + SearchControls searchControls = new SearchControls(); + searchControls.setSearchScope( SearchControls.OBJECT_SCOPE ); + searchControls.setReturningAttributes( SchemaConstants.ALL_ATTRIBUTES_ARRAY ); + StudioSearchResultEnumeration result = connectionWrapper.search( dn, + TestFixture.OBJECT_CLASS_ALL_FILTER, searchControls, AliasDereferencingMethod.NEVER, + ReferralHandlingMethod.IGNORE, null, + monitor, null ); + List<Entry> entries = consume( result, sr -> sr.getEntry() ); + assertEquals( 1, entries.size() ); + return entries.get( 0 ); + } + + + /** * Test searching. */ @ParameterizedTest @@ -1051,6 +1217,7 @@ public class DirectoryApiConnectionWrapperTest protected <T> List<T> consume( StudioSearchResultEnumeration result, Function<StudioSearchResult, T> fn ) throws LdapException { + assertNotNull( result ); List<T> list = new ArrayList<>(); while ( result.hasMore() ) { diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestData.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestData.java new file mode 100644 index 000000000..29829f06c --- /dev/null +++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestData.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.directory.studio.test.integration.junit5; + + +import java.nio.charset.StandardCharsets; + +import org.apache.commons.lang3.RandomStringUtils; + + +/** + * Utility to generate test data. + */ +public class TestData +{ + + public static byte[] jpegImage( int size ) + { + byte[] jpegImage = RandomStringUtils.randomAscii( size ).getBytes( StandardCharsets.UTF_8 ); + System.arraycopy( new byte[] + { + ( byte ) 0xFF, + ( byte ) 0xD8, + ( byte ) 0XFF, + ( byte ) 0XE0, + ( byte ) 0X00, + ( byte ) 0X00, + 'J', + 'F', + 'I', + 'F', + ( byte ) 0X00 }, + 0, jpegImage, 0, 11 ); + return jpegImage; + } + +} diff --git a/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/Fedora389ds.ldif b/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/Fedora389ds.ldif index 3c76c87eb..d8d5bd049 100644 --- a/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/Fedora389ds.ldif +++ b/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/Fedora389ds.ldif @@ -15,6 +15,13 @@ # specific language governing permissions and limitations # under the License. # + +dn: ou=misc,dc=example,dc=org +changetype: modify +add: aci +aci: (targetattr="*")(version 3.0; aci "allow hnelson all access"; allow(all) userdn="ldap:///uid=hnelson,ou=misc,dc=example,dc=org";) +- + dn: cn=config changetype: modify replace: passwordStorageScheme 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 1cf98b3dd..a2eb4da88 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 @@ -18,19 +18,21 @@ dn: olcDatabase={-1}frontend,cn=config changetype: modify replace: olcAccess -olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external - ,cn=auth manage by * break +olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break olcAccess: {1}to dn.exact="" by * read # Forbid user.8 to read the schema, used in SchemaBrowserTest olcAccess: {2}to dn.base="cn=Subschema" by dn.exact="uid=user.8,ou=users,dc=example,dc=org" none by * read - +replace: olcSizeLimit +olcSizeLimit: 2000 +- dn: olcDatabase={1}mdb,cn=config changetype: modify replace: olcAccess olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break -olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by dn="cn=a dmin,dc=example,dc=org" write by anonymous auth by * none -olcAccess: {2}to * by self read by dn="cn=admin,dc=example,dc=org" write by anonymous auth by * none +olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by dn="cn=admin,dc=example,dc=org" write by dn="uid=hnelson,cn=gssapi,cn=auth" write by anonymous auth by * none +olcAccess: {2}to * by self read by dn="cn=admin,dc=example,dc=org" write by dn="uid=hnelson,cn=gssapi,cn=auth" write by anonymous auth by * none - dn: cn=config |