From 1da18a3f40a45a5896c1a409024bf46ec1e4b7da Mon Sep 17 00:00:00 2001 From: Bryan Rosander Date: Mon, 11 Jul 2016 14:57:27 -0400 Subject: [PATCH] NIFI-2222 - Fixing SslContextFactory Properties set by keyStorePasswd and keyPasswd This closes #632 Signed-off-by: James Wing --- .../apache/nifi/web/server/JettyServer.java | 12 +-- .../nifi/web/server/JettyServerTest.java | 88 +++++++++++++++++++ 2 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java index 82792206b0..02e3867a6f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java @@ -600,7 +600,11 @@ public class JettyServer implements NiFiServer { private SslContextFactory createSslContextFactory() { final SslContextFactory contextFactory = new SslContextFactory(); + configureSslContextFactory(contextFactory, props); + return contextFactory; + } + protected static void configureSslContextFactory(SslContextFactory contextFactory, NiFiProperties props) { // require client auth when not supporting login, Kerberos service, or anonymous access if (props.isClientAuthRequiredForRestApi()) { contextFactory.setNeedClientAuth(true); @@ -621,11 +625,11 @@ public class JettyServer implements NiFiServer { if (StringUtils.isNotBlank(keystorePassword)) { // if no key password was provided, then assume the keystore password is the same as the key password. final String defaultKeyPassword = (StringUtils.isBlank(keyPassword)) ? keystorePassword : keyPassword; - contextFactory.setKeyManagerPassword(keystorePassword); - contextFactory.setKeyStorePassword(defaultKeyPassword); + contextFactory.setKeyStorePassword(keystorePassword); + contextFactory.setKeyManagerPassword(defaultKeyPassword); } else if (StringUtils.isNotBlank(keyPassword)) { // since no keystore password was provided, there will be no keystore integrity check - contextFactory.setKeyStorePassword(keyPassword); + contextFactory.setKeyManagerPassword(keyPassword); } // truststore properties @@ -638,8 +642,6 @@ public class JettyServer implements NiFiServer { if (StringUtils.isNotBlank(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD))) { contextFactory.setTrustStorePassword(props.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD)); } - - return contextFactory; } @Override diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java new file mode 100644 index 0000000000..314e331626 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java @@ -0,0 +1,88 @@ +/* + * 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.nifi.web.server; + +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.apache.nifi.util.NiFiProperties; +import org.junit.Test; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +public class JettyServerTest { + @Test + public void testConfigureSslContextFactoryWithKeystorePasswordAndKeyPassword() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + // Expect that if we set both passwords, KeyStore password is used for KeyStore, Key password is used for Key Manager + String testKeystorePassword = "testKeystorePassword"; + String testKeyPassword = "testKeyPassword"; + + NiFiProperties nifiProperties = createNifiProperties(); + SslContextFactory contextFactory = mock(SslContextFactory.class); + + nifiProperties.setProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD, testKeystorePassword); + nifiProperties.setProperty(NiFiProperties.SECURITY_KEY_PASSWD, testKeyPassword); + + JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + + verify(contextFactory).setKeyStorePassword(testKeystorePassword); + verify(contextFactory).setKeyManagerPassword(testKeyPassword); + } + + @Test + public void testConfigureSslContextFactoryWithKeyPassword() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + // Expect that with no KeyStore password, we will only need to set Key Manager Password + String testKeyPassword = "testKeyPassword"; + + NiFiProperties nifiProperties = createNifiProperties(); + SslContextFactory contextFactory = mock(SslContextFactory.class); + + nifiProperties.setProperty(NiFiProperties.SECURITY_KEY_PASSWD, testKeyPassword); + + JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + + verify(contextFactory).setKeyManagerPassword(testKeyPassword); + verify(contextFactory, never()).setKeyStorePassword(anyString()); + } + + @Test + public void testConfigureSslContextFactoryWithKeystorePassword() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + // Expect that with no KeyPassword, we use the same one from the KeyStore + String testKeystorePassword = "testKeystorePassword"; + + NiFiProperties nifiProperties = createNifiProperties(); + SslContextFactory contextFactory = mock(SslContextFactory.class); + + nifiProperties.setProperty(NiFiProperties.SECURITY_KEYSTORE_PASSWD, testKeystorePassword); + + JettyServer.configureSslContextFactory(contextFactory, nifiProperties); + + verify(contextFactory).setKeyStorePassword(testKeystorePassword); + verify(contextFactory).setKeyManagerPassword(testKeystorePassword); + } + + private NiFiProperties createNifiProperties() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + Constructor constructor = NiFiProperties.class.getDeclaredConstructor(); + constructor.setAccessible(true); + return constructor.newInstance(); + } +}