You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2021/07/05 18:24:06 UTC

[directory-studio] branch master updated: Add more TLSv1.3 tests

This is an automated email from the ASF dual-hosted git repository.

seelmann pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/directory-studio.git


The following commit(s) were added to refs/heads/master by this push:
     new 9f92542  Add more TLSv1.3 tests
9f92542 is described below

commit 9f92542b3f5f4bd64ccf89ec6159f04c66eba17f
Author: Stefan Seelmann <ma...@stefan-seelmann.de>
AuthorDate: Mon Jul 5 20:23:52 2021 +0200

    Add more TLSv1.3 tests
---
 tests/test.integration.core/pom-first.xml          |   1 +
 .../core/DirectoryApiConnectionWrapperTest.java    | 169 ++++++++++++++++++++-
 .../studio/test/integration/junit5/TestData.java   |  55 +++++++
 .../test/integration/junit5/Fedora389ds.ldif       |   7 +
 .../test/integration/junit5/OpenLdapConfig.ldif    |  10 +-
 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 d7e2529..271d18e 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 6616b99..730e49d 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 0000000..29829f0
--- /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 3c76c87..d8d5bd0 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 1cf98b3..a2eb4da 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