You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2022/04/22 17:28:28 UTC

[tika] branch TIKA-3719 updated: TIKA-3719 -- add configuration to require two way tls and unit tests.

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

tallison pushed a commit to branch TIKA-3719
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/TIKA-3719 by this push:
     new e45071b25 TIKA-3719 -- add configuration to require two way tls and unit tests.
e45071b25 is described below

commit e45071b251b5823a23f904bde2cc8a9a26ac6de9
Author: tallison <ta...@apache.org>
AuthorDate: Fri Apr 22 13:28:14 2022 -0400

    TIKA-3719 -- add configuration to require two way tls and unit tests.
---
 .../apache/tika/server/core/TikaServerProcess.java |   5 +
 .../org/apache/tika/server/core/TlsConfig.java     |  24 ++++-
 .../server/core/TikaServerIntegrationTest.java     | 107 +++++++++++++++++----
 ...=> tika-config-server-tls-one-way-template.xml} |   5 +-
 ...=> tika-config-server-tls-two-way-template.xml} |   2 +
 5 files changed, 122 insertions(+), 21 deletions(-)

diff --git a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TikaServerProcess.java b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TikaServerProcess.java
index d75da900b..ea25dda93 100644
--- a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TikaServerProcess.java
+++ b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TikaServerProcess.java
@@ -38,6 +38,7 @@ import org.apache.commons.cli.Options;
 import org.apache.cxf.binding.BindingFactoryManager;
 import org.apache.cxf.configuration.jsse.TLSParameterJaxBUtils;
 import org.apache.cxf.configuration.jsse.TLSServerParameters;
+import org.apache.cxf.configuration.security.ClientAuthentication;
 import org.apache.cxf.configuration.security.KeyManagersType;
 import org.apache.cxf.configuration.security.KeyStoreType;
 import org.apache.cxf.configuration.security.TrustManagersType;
@@ -301,6 +302,10 @@ public class TikaServerProcess {
             tmt.setKeyStore(trustKeyStore);
             parameters.setTrustManagers(TLSParameterJaxBUtils.getTrustManagers(tmt, true));
         }
+        ClientAuthentication clientAuthentication = new ClientAuthentication();
+        clientAuthentication.setRequired(tlsConfig.isClientAuthenticationRequired());
+        clientAuthentication.setWant(tlsConfig.isClientAuthenticationWanted());
+        parameters.setClientAuthentication(clientAuthentication);
         return parameters;
     }
 
diff --git a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TlsConfig.java b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TlsConfig.java
index 20ad36bc0..f2d47e6f4 100644
--- a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TlsConfig.java
+++ b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TlsConfig.java
@@ -36,6 +36,10 @@ public class TlsConfig implements Initializable {
     private String trustStorePassword = null;
     private String trustStoreFile = null;
 
+    private boolean clientAuthenticationWanted = false;
+
+    private boolean clientAuthenticationRequired = false;
+
     public boolean isActive() {
         return active;
     }
@@ -127,6 +131,22 @@ public class TlsConfig implements Initializable {
         }
     }
 
+    public boolean isClientAuthenticationWanted() {
+        return clientAuthenticationWanted;
+    }
+
+    public void setClientAuthenticationWanted(boolean clientAuthenticationWanted) {
+        this.clientAuthenticationWanted = clientAuthenticationWanted;
+    }
+
+    public boolean isClientAuthenticationRequired() {
+        return clientAuthenticationRequired;
+    }
+
+    public void setClientAuthenticationRequired(boolean clientAuthenticationRequired) {
+        this.clientAuthenticationRequired = clientAuthenticationRequired;
+    }
+
     @Override
     public String toString() {
         return "TlsConfig{" + "active=" + active + ", passwordsAESEncrypted=" +
@@ -134,7 +154,9 @@ public class TlsConfig implements Initializable {
                 ", keyStorePassword='" + keyStorePassword + '\'' + ", keyStoreFile='" +
                 keyStoreFile + '\'' + ", trustStoreType='" + trustStoreType + '\'' +
                 ", trustStorePassword='" + trustStorePassword + '\'' + ", trustStoreFile='" +
-                trustStoreFile + '\'' + '}';
+                trustStoreFile + '\'' + ", clientAuthenticationWanted=" +
+                clientAuthenticationWanted + ", isClientAuthenticationRequired=" +
+                clientAuthenticationRequired + '}';
     }
 
     public boolean hasTrustStore() {
diff --git a/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/TikaServerIntegrationTest.java b/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/TikaServerIntegrationTest.java
index bf6b5a2e1..603c5a668 100644
--- a/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/TikaServerIntegrationTest.java
+++ b/tika-server/tika-server-core/src/test/java/org/apache/tika/server/core/TikaServerIntegrationTest.java
@@ -63,27 +63,36 @@ import org.apache.tika.utils.ProcessUtils;
 public class TikaServerIntegrationTest extends IntegrationTestBase {
 
     private static final Logger LOG = LoggerFactory.getLogger(TikaServerIntegrationTest.class);
-    private static Path SSL;
-    private static Path TIKA_SSL_CONFIG;
+    private static Path TLS_KEYS;
+    private static Path TIKA_TLS_ONE_WAY_CONFIG;
+    private static Path TIKA_TLS_TWO_WAY_CONFIG;
     @BeforeAll
     public static void setUpSSL() throws Exception {
-        SSL =
+        TLS_KEYS =
                 Paths.get(TikaServerIntegrationTest.class.getResource("/ssl-keys").toURI());
-        String xml = IOUtils.resourceToString("/configs/tika-config-server-tls-template.xml",
+
+        String xml = IOUtils.resourceToString(
+                "/configs/tika-config-server-tls-two-way-template.xml",
                 UTF_8);
-        xml = xml.replaceAll("\\$\\{SSL_KEYS\\}", SSL.toAbsolutePath().toString());
+        xml = xml.replaceAll("\\$\\{SSL_KEYS\\}", TLS_KEYS.toAbsolutePath().toString());
+
+        TIKA_TLS_TWO_WAY_CONFIG = Files.createTempFile("tika-config-tls-", ".xml");
+        Files.write(TIKA_TLS_TWO_WAY_CONFIG, xml.getBytes(UTF_8));
+
+        xml = IOUtils.resourceToString(
+                "/configs/tika-config-server-tls-one-way-template.xml",
+                UTF_8);
+        xml = xml.replaceAll("\\$\\{SSL_KEYS\\}", TLS_KEYS.toAbsolutePath().toString());
+
+        TIKA_TLS_ONE_WAY_CONFIG = Files.createTempFile("tika-config-tls-", ".xml");
+        Files.write(TIKA_TLS_ONE_WAY_CONFIG, xml.getBytes(UTF_8));
 
-        TIKA_SSL_CONFIG = Files.createTempFile("tika-config-tls-", ".xml");
-        try {
-            Files.write(TIKA_SSL_CONFIG, xml.getBytes(UTF_8));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
     }
 
     @AfterAll
     public static void cleanUpSSL() throws IOException {
-        Files.delete(TIKA_SSL_CONFIG);
+        Files.delete(TIKA_TLS_TWO_WAY_CONFIG);
+        Files.delete(TIKA_TLS_ONE_WAY_CONFIG);
     }
 
     @Test
@@ -322,20 +331,20 @@ public class TikaServerIntegrationTest extends IntegrationTestBase {
     }
 
     @Test
-    public void testTLS() throws Exception {
+    public void test1WayTLS() throws Exception {
         startProcess(
                 new String[]{"-config",
-                        ProcessUtils.escapeCommandLine(TIKA_SSL_CONFIG.toAbsolutePath().toString())});
+                        ProcessUtils.escapeCommandLine(TIKA_TLS_ONE_WAY_CONFIG.toAbsolutePath().toString())});
 
         String httpsEndpoint = "https://localhost:" + INTEGRATION_TEST_PORT;
         WebClient webClient = WebClient.create(httpsEndpoint);
-        configureTLS(webClient);
+        configure1WayTLS(webClient);
 
         awaitServerStartup(webClient);
 
         webClient.close();
         webClient = WebClient.create(httpsEndpoint + RMETA_PATH);
-        configureTLS(webClient);
+        configure1WayTLS(webClient);
 
         Response response = webClient.accept("application/json")
                 .put(ClassLoader.getSystemResourceAsStream(TEST_HELLO_WORLD));
@@ -357,8 +366,55 @@ public class TikaServerIntegrationTest extends IntegrationTestBase {
             assertContains("javax.net.ssl.SSLHandshakeException", e.getMessage());
         }
     }
+    @Test
+    public void test2WayTLS() throws Exception {
+        startProcess(
+                new String[]{"-config",
+                        ProcessUtils.escapeCommandLine(TIKA_TLS_TWO_WAY_CONFIG.toAbsolutePath().toString())});
+
+        String httpsEndpoint = "https://localhost:" + INTEGRATION_TEST_PORT;
+        WebClient webClient = WebClient.create(httpsEndpoint);
+        configure2WayTLS(webClient);
+
+        awaitServerStartup(webClient);
+
+        webClient.close();
+        webClient = WebClient.create(httpsEndpoint + RMETA_PATH);
+        configure2WayTLS(webClient);
+
+        Response response = webClient.accept("application/json")
+                .put(ClassLoader.getSystemResourceAsStream(TEST_HELLO_WORLD));
+        Reader reader = new InputStreamReader((InputStream) response.getEntity(), UTF_8);
+
+        List<Metadata> metadataList = JsonMetadataList.fromJson(reader);
+        assertEquals(1, metadataList.size());
+        assertEquals("Nikolai Lobachevsky", metadataList.get(0).get("author"));
+        assertContains("hello world", metadataList.get(0).get("X-TIKA:content"));
+
+        //now test that no tls config fails
+        webClient = WebClient.create(httpsEndpoint + RMETA_PATH);
+
+        try {
+            response = webClient.accept("application/json").put(
+                    ClassLoader.getSystemResourceAsStream(TEST_HELLO_WORLD));
+            fail("bad, bad, bad. this should have failed!");
+        } catch (Exception e) {
+            assertContains("javax.net.ssl.SSLHandshakeException", e.getMessage());
+        }
+
+        //now test that 1 way fails
+        webClient = WebClient.create(httpsEndpoint + RMETA_PATH);
+        configure1WayTLS(webClient);
+        try {
+            response = webClient.accept("application/json").put(
+                    ClassLoader.getSystemResourceAsStream(TEST_HELLO_WORLD));
+            fail("bad, bad, bad. this should have failed!");
+        } catch (Exception e) {
+            assertContains("readHandshakeRecord", e.getMessage());
+        }
+    }
 
-    private void configureTLS(WebClient webClient) throws GeneralSecurityException, IOException {
+    private void configure2WayTLS(WebClient webClient) throws GeneralSecurityException, IOException {
         HTTPConduit conduit = WebClient.getConfig(webClient)
                 .getHttpConduit();
         KeyStoreType keystore = new KeyStoreType();
@@ -384,6 +440,23 @@ public class TikaServerIntegrationTest extends IntegrationTestBase {
 
     }
 
+    private void configure1WayTLS(WebClient webClient) throws GeneralSecurityException,
+            IOException {
+        HTTPConduit conduit = WebClient.getConfig(webClient)
+                .getHttpConduit();
+        TLSClientParameters parameters = new TLSClientParameters();
+
+        KeyStoreType trustKeyStore = new KeyStoreType();
+        trustKeyStore.setType("PKCS12");
+        trustKeyStore.setPassword("tika-secret");
+        trustKeyStore.setFile(getSSL("tika-client-truststore.p12"));
+
+        TrustManagersType tmt = new TrustManagersType();
+        tmt.setKeyStore(trustKeyStore);
+        parameters.setTrustManagers(TLSParameterJaxBUtils.getTrustManagers(tmt, true));
+        conduit.setTlsClientParameters(parameters);
+    }
+
     @Test
     @Disabled("This works, but prints too much junk to the console.  " +
             "Figure out how to gobble/redirect.")
diff --git a/tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-template.xml b/tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-one-way-template.xml
similarity index 88%
copy from tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-template.xml
copy to tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-one-way-template.xml
index 861a0c616..f90acc859 100644
--- a/tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-template.xml
+++ b/tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-one-way-template.xml
@@ -35,9 +35,8 @@
         <keyStoreType>PKCS12</keyStoreType>
         <keyStorePassword>tika-secret</keyStorePassword>
         <keyStoreFile>${SSL_KEYS}/tika-server-keystore.p12</keyStoreFile>
-        <trustStoreType>PKCS12</trustStoreType>
-        <trustStorePassword>tika-secret</trustStorePassword>
-        <trustStoreFile>${SSL_KEYS}/tika-server-truststore.p12</trustStoreFile>
+        <clientAuthenticationWanted>false</clientAuthenticationWanted>
+        <clientAuthenticationRequired>false</clientAuthenticationRequired>
       </params>
     </tlsConfig>
   </server>
diff --git a/tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-template.xml b/tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-two-way-template.xml
similarity index 92%
rename from tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-template.xml
rename to tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-two-way-template.xml
index 861a0c616..7a8b5dc94 100644
--- a/tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-template.xml
+++ b/tika-server/tika-server-core/src/test/resources/configs/tika-config-server-tls-two-way-template.xml
@@ -38,6 +38,8 @@
         <trustStoreType>PKCS12</trustStoreType>
         <trustStorePassword>tika-secret</trustStorePassword>
         <trustStoreFile>${SSL_KEYS}/tika-server-truststore.p12</trustStoreFile>
+        <clientAuthenticationWanted>true</clientAuthenticationWanted>
+        <clientAuthenticationRequired>true</clientAuthenticationRequired>
       </params>
     </tlsConfig>
   </server>