diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/security/SkipSslLdapSocketFactoryTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/security/SkipSslLdapSocketFactoryTest.java new file mode 100644 index 00000000000..d923425a077 --- /dev/null +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/security/SkipSslLdapSocketFactoryTest.java @@ -0,0 +1,17 @@ +package org.cloudfoundry.identity.uaa.security; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SkipSslLdapSocketFactoryTest { + + @Test + void testDefaultInstanceIsSkipSslLdapSocketFactory() { + Object ldapFactory = SkipSslLdapSocketFactory.getDefault(); + assertNotNull(ldapFactory); + assertTrue(ldapFactory instanceof SkipSslLdapSocketFactory); + assertTrue(SkipSslLdapSocketFactory.getDefault() instanceof SkipSslLdapSocketFactory); + } +} diff --git a/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/LdapSkipCertificateMockMvcTests.java b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/LdapSkipCertificateMockMvcTests.java new file mode 100644 index 00000000000..ced228d446a --- /dev/null +++ b/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/ldap/LdapSkipCertificateMockMvcTests.java @@ -0,0 +1,127 @@ +package org.cloudfoundry.identity.uaa.mock.ldap; + +import org.cloudfoundry.identity.uaa.DefaultTestContext; +import org.cloudfoundry.identity.uaa.constants.OriginKeys; +import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; +import org.cloudfoundry.identity.uaa.provider.LdapIdentityProviderDefinition; +import org.cloudfoundry.identity.uaa.test.InMemoryLdapServer; +import org.cloudfoundry.identity.uaa.util.SetServerNameRequestPostProcessor; +import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.util.FileSystemUtils; +import org.springframework.web.context.WebApplicationContext; + +import java.io.File; + +import static org.cloudfoundry.identity.uaa.constants.OriginKeys.LDAP; +import static org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils.CookieCsrfPostProcessor.cookieCsrf; +import static org.cloudfoundry.identity.uaa.provider.LdapIdentityProviderDefinition.LDAP_TLS_NONE; +import static org.springframework.http.MediaType.TEXT_HTML_VALUE; +import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@DefaultTestContext +@ExtendWith(InMemoryLdapServer.LdapTrustStoreExtension.class) +class LdapSkipCertificateMockMvcTests { + private static final int LDAP_VALID_LDAP_PORT = 33390; + private static final int LDAP_EXPIRED_LDAP_PORT = LDAP_VALID_LDAP_PORT + 1; + private static final int LDAP_VALID_LDAPS_PORT = 33637; + private static final int LDAP_EXPIRED_LDAPS_PORT = LDAP_VALID_LDAPS_PORT + 1; + + private static File LDAP_ROOT_DIRECTORY_EXPIRED; + private static InMemoryLdapServer expiredLdapCertServer; + private MockMvcUtils.IdentityZoneCreationResult trustedCertZone; + private MockMvcUtils.IdentityZoneCreationResult trustedButExpiredCertZone; + + private RandomValueStringGenerator gen = new RandomValueStringGenerator(8); + + private MockMvc mockMvc; + + @BeforeAll + static void startLdapsServers() { + ClassLoader classLoader = LdapSkipCertificateMockMvcTests.class.getClassLoader(); + + File expiredKeystore = new File(classLoader.getResource("certs/expired-self-signed-ldap-cert.jks").getFile()); + RandomValueStringGenerator generator = new RandomValueStringGenerator(); + LDAP_ROOT_DIRECTORY_EXPIRED = new File(System.getProperty("java.io.tmpdir"), generator.generate()); + + expiredLdapCertServer = InMemoryLdapServer.startLdapWithTls(LDAP_EXPIRED_LDAP_PORT, LDAP_EXPIRED_LDAPS_PORT, expiredKeystore); + } + + @AfterAll + static void stopLdapsServers() { + expiredLdapCertServer.stop(); + FileSystemUtils.deleteRecursively(LDAP_ROOT_DIRECTORY_EXPIRED); + } + + @BeforeEach + void setUp(@Autowired WebApplicationContext webApplicationContext, @Autowired MockMvc mockMvc) throws Exception { + this.mockMvc = mockMvc; + + trustedCertZone = MockMvcUtils.createOtherIdentityZoneAndReturnResult( + gen.generate(), + mockMvc, + webApplicationContext, + null, IdentityZoneHolder.getCurrentZoneId()); + + LdapIdentityProviderDefinition definition = LdapIdentityProviderDefinition.searchAndBindMapGroupToScopes( + expiredLdapCertServer.getLdapSBaseUrl(), + "cn=admin,ou=Users,dc=test,dc=com", + "adminsecret", + "dc=test,dc=com", + "cn={0}", + "ou=scopes,dc=test,dc=com", + "member={0}", + "mail", + null, + false, + true, + true, + 10, + true + ); + definition.setTlsConfiguration(LDAP_TLS_NONE); + + MockMvcUtils.createIdentityProvider(mockMvc, trustedCertZone, OriginKeys.LDAP, definition); + trustedButExpiredCertZone = MockMvcUtils.createOtherIdentityZoneAndReturnResult( + gen.generate(), + mockMvc, + webApplicationContext, + null, IdentityZoneHolder.getCurrentZoneId()); + definition.setBaseUrl(expiredLdapCertServer.getLdapSBaseUrl()); + MockMvcUtils.createIdentityProvider(mockMvc, trustedButExpiredCertZone, OriginKeys.LDAP, definition); + } + + @Test + void testIgnoreServerCertificate() throws Exception { + mockMvc.perform(post("/login.do").accept(TEXT_HTML_VALUE) + .with(cookieCsrf()) + .with(new SetServerNameRequestPostProcessor(trustedCertZone.getIdentityZone().getSubdomain() + ".localhost")) + .param("username", "marissa2") + .param("password", LDAP)) + .andExpect(status().isFound()) + .andExpect(redirectedUrl("/")) + .andExpect(authenticated()); + } + + @Test + void testIgnoreExpiredServerCertificate() throws Exception { + mockMvc.perform(post("/login.do").accept(TEXT_HTML_VALUE) + .with(cookieCsrf()) + .with(new SetServerNameRequestPostProcessor(trustedButExpiredCertZone.getIdentityZone().getSubdomain() + ".localhost")) + .param("username", "marissa2") + .param("password", LDAP)) + .andExpect(status().isFound()) + .andExpect(redirectedUrl("/")) + .andExpect(authenticated()); + } +}