DMAAP-1714 - DR Making TLS Configurable 52/128252/7
authordavid.mcweeney <david.mcweeney@est.tech>
Wed, 16 Mar 2022 16:08:44 +0000 (16:08 +0000)
committerdavid.mcweeney <david.mcweeney@est.tech>
Mon, 4 Apr 2022 15:27:53 +0000 (16:27 +0100)
Change-Id: I0c3bc05182691c12c9d0f0b76d09f7dfea3e09eb
Signed-off-by: david.mcweeney <david.mcweeney@est.tech>
Issue-ID: DMAAP-1714

14 files changed:
csit/scripts/dmaap-datarouter/docker-compose/node.properties
csit/scripts/dmaap-datarouter/docker-compose/provserver.properties
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/NodeConfigManager.java
datarouter-node/src/main/java/org/onap/dmaap/datarouter/node/NodeServlet.java
datarouter-node/src/main/resources/node.properties
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeConfigManagerTest.java
datarouter-node/src/test/java/org/onap/dmaap/datarouter/node/NodeServletTest.java
datarouter-node/src/test/resources/node_test.properties
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/PublishServlet.java
datarouter-prov/src/main/java/org/onap/dmaap/datarouter/provisioning/utils/URLUtilities.java
datarouter-prov/src/main/resources/provserver.properties
datarouter-prov/src/test/java/org/onap/dmaap/datarouter/provisioning/SubscriptionServletTest.java
datarouter-prov/src/test/resources/h2Database.properties
datarouter-prov/src/test/resources/h2DatabaseTlsDisabled.properties [new file with mode: 0644]

index 58639cf..9f3ca40 100644 (file)
@@ -80,3 +80,6 @@ CadiEnabled = false
 #
 #    AAF Props file path
 AAFPropsFilePath = /opt/app/osaaf/local/org.onap.dmaap-dr.props
+
+#    https security required for publish request
+TlsEnabled = true
index b54868e..b38c3f5 100755 (executable)
@@ -52,4 +52,7 @@ org.onap.dmaap.datarouter.provserver.aaf.feed.type        = org.onap.dmaap-dr.fe
 org.onap.dmaap.datarouter.provserver.aaf.sub.type         = org.onap.dmaap-dr.sub
 org.onap.dmaap.datarouter.provserver.aaf.instance         = legacy
 org.onap.dmaap.datarouter.provserver.aaf.action.publish   = publish
-org.onap.dmaap.datarouter.provserver.aaf.action.subscribe = subscribe
\ No newline at end of file
+org.onap.dmaap.datarouter.provserver.aaf.action.subscribe = subscribe
+org.onap.dmaap.datarouter.provserver.tlsenabled           = true
+org.onap.dmaap.datarouter.nodeserver.https.port           = 8443
+org.onap.dmaap.datarouter.nodeserver.http.port            = 8080
\ No newline at end of file
index 5b5245d..3b95023 100644 (file)
@@ -102,6 +102,7 @@ public class NodeConfigManager implements DeliveryQueueHelper {
     private String aafType;
     private String aafInstance;
     private String aafAction;
+    private boolean tlsEnabled;
     private boolean cadiEnabled;
     private NodeAafPropsUtils nodeAafPropsUtils;
 
@@ -159,6 +160,8 @@ public class NodeConfigManager implements DeliveryQueueHelper {
         svcport = Integer.parseInt(drNodeProperties.getProperty("IntHttpsPort", "8443"));
         port = Integer.parseInt(drNodeProperties.getProperty("ExtHttpsPort", "443"));
         spooldir = drNodeProperties.getProperty("SpoolDir", "spool");
+        tlsEnabled = Boolean.parseBoolean(drNodeProperties.getProperty("TlsEnabled", "true"));
+
         File fdir = new File(spooldir + "/f");
         fdir.mkdirs();
         for (File junk : Objects.requireNonNull(fdir.listFiles())) {
@@ -811,6 +814,10 @@ public class NodeConfigManager implements DeliveryQueueHelper {
         return aafAction;
     }
 
+    protected boolean isTlsEnabled() {
+        return tlsEnabled;
+    }
+
     boolean getCadiEnabled() {
         return cadiEnabled;
     }
index 139c749..ee1f5b7 100644 (file)
@@ -549,7 +549,7 @@ public class NodeServlet extends HttpServlet {
             eelfLogger.info(EelfMsgs.EXIT);
             return null;
         }
-        if (!req.isSecure()) {
+        if (!req.isSecure() && config.isTlsEnabled()) {
             eelfLogger.error(
                     "NODE0104 Rejecting insecure PUT or DELETE of " + req.getPathInfo() + FROM + req
                             .getRemoteAddr());
index 1d7a5d4..f7c24fa 100644 (file)
@@ -85,3 +85,6 @@ CadiEnabled = false
 #
 #    AAF Props file path
 AAFPropsFilePath = /opt/app/osaaf/local/org.onap.dmaap-dr.props
+
+#    https security required for publish request
+TlsEnabled = true
index e64579e..82038fb 100644 (file)
@@ -112,6 +112,7 @@ public class NodeConfigManagerTest {
         Assert.assertEquals("publish", nodeConfigManager.getAafAction());
         Assert.assertFalse(nodeConfigManager.getCadiEnabled());
         Assert.assertFalse(nodeConfigManager.isShutdown());
+        Assert.assertTrue(nodeConfigManager.isTlsEnabled());
         Assert.assertTrue(nodeConfigManager.isConfigured());
         Assert.assertEquals("legacy", nodeConfigManager.getAafInstance("1"));
         Assert.assertNotNull(nodeConfigManager.getPublishId());
index 4340b01..f7e3d7c 100644 (file)
@@ -23,7 +23,6 @@
 package org.onap.dmaap.datarouter.node;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyObject;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.anyString;
@@ -144,8 +143,9 @@ public class NodeServletTest {
     }
 
     @Test
-    public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Secure_Then_Forbidden_Response_Is_Generated() throws Exception {
+    public void Given_Request_Is_HTTP_PUT_And_Request_Is_Not_Secure_And_TLS_Enabled_Then_Forbidden_Response_Is_Generated() throws Exception {
         when(request.isSecure()).thenReturn(false);
+        when(config.isTlsEnabled()).thenReturn(true);
         nodeServlet.doPut(request, response);
         verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), anyString());
         verifyEnteringExitCalled(listAppender);
@@ -284,6 +284,17 @@ public class NodeServletTest {
         verifyEnteringExitCalled(listAppender);
     }
 
+    @Test
+    public void Given_Request_Is_HTTP_DELETE_File_And_Request_Is_Not_Secure_But_TLS_Disabled_Then_Request_Succeeds() throws Exception {
+        when(request.isSecure()).thenReturn(false);
+        when(config.isTlsEnabled()).thenReturn(false);
+        when(request.getPathInfo()).thenReturn("/delete/1/dmaap-dr-node.1234567");
+        createFilesAndDirectories();
+        nodeServlet.doDelete(request, response);
+        verify(response).setStatus(eq(HttpServletResponse.SC_OK));
+        verifyEnteringExitCalled(listAppender);
+    }
+
     @Test
     public void Given_Request_Is_HTTP_DELETE_File_And_File_Does_Not_Exist_Then_Not_Found_Response_Is_Generated() throws IOException {
         when(request.getPathInfo()).thenReturn("/delete/1/nonExistingFile");
index 9359e8d..3c96ed2 100644 (file)
@@ -86,3 +86,6 @@ CadiEnabled = false
 #    AAF Props file path
 AAFPropsFilePath = src/test/resources/aaf/org.onap.dmaap-dr.props
 
+#    https security required for publish request 
+TlsEnabled = true
+
index 35205aa..949019d 100644 (file)
@@ -45,6 +45,7 @@ import org.onap.dmaap.datarouter.provisioning.utils.Poker;
 import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;\r
 import org.onap.dmaap.datarouter.provisioning.beans.IngressRoute;\r
 import org.onap.dmaap.datarouter.provisioning.eelf.EelfMsgs;\r
+import org.onap.dmaap.datarouter.provisioning.utils.URLUtilities;\r
 \r
 /**\r
  * This servlet handles redirects for the &lt;publishURL&gt; on the provisioning server, which is generated by the\r
@@ -158,9 +159,15 @@ public class PublishServlet extends BaseServlet {
                 } else {\r
                     // Generate new URL\r
                     String nextnode = getRedirectNode(feedid, req);\r
-                    nextnode = nextnode + ":" + ProvRunner.getProvProperties().getProperty(\r
-                        "org.onap.dmaap.datarouter.provserver.https.port", "8443");\r
-                    String newurl = "https://" + nextnode + "/publish" + req.getPathInfo();\r
+                    if (Boolean.parseBoolean(ProvRunner.getProvProperties()\r
+                        .getProperty("org.onap.dmaap.datarouter.provserver.tlsenabled", "true"))) {\r
+                        nextnode = nextnode + ":" + ProvRunner.getProvProperties().getProperty(\r
+                            "org.onap.dmaap.datarouter.nodeserver.https.port", "8443");\r
+                    } else {\r
+                        nextnode = nextnode + ":" + ProvRunner.getProvProperties().getProperty(\r
+                            "org.onap.dmaap.datarouter.nodeserver.http.port", "8080");\r
+                    }\r
+                    String newurl = URLUtilities.getUrlSecurityOption() + nextnode + "/publish" + req.getPathInfo();\r
                     String qs = req.getQueryString();\r
                     if (qs != null) {\r
                         newurl += "?" + qs;\r
index 2e00002..988b576 100644 (file)
@@ -28,8 +28,8 @@ import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;\r
 import java.net.InetAddress;\r
 import java.net.UnknownHostException;\r
-\r
 import org.onap.dmaap.datarouter.provisioning.BaseServlet;\r
+import org.onap.dmaap.datarouter.provisioning.ProvRunner;\r
 \r
 /**\r
  * Utility functions used to generate the different URLs used by the Data Router.\r
@@ -39,9 +39,7 @@ import org.onap.dmaap.datarouter.provisioning.BaseServlet;
  */\r
 public class URLUtilities {\r
 \r
-\r
     private static final EELFLogger utilsLogger = EELFManager.getInstance().getLogger("UtilsLog");\r
-    private static final String HTTPS = "https://";\r
     private static String otherPod;\r
 \r
     private URLUtilities() {\r
@@ -54,7 +52,7 @@ public class URLUtilities {
      * @return the URL\r
      */\r
     public static String generateFeedURL(int feedid) {\r
-        return HTTPS + BaseServlet.getProvName() + "/feed/" + feedid;\r
+        return getUrlSecurityOption() + BaseServlet.getProvName() + getAppropriateUrlPort() + "/feed/" + feedid;\r
     }\r
 \r
     /**\r
@@ -64,7 +62,7 @@ public class URLUtilities {
      * @return the URL\r
      */\r
     public static String generatePublishURL(int feedid) {\r
-        return HTTPS + BaseServlet.getProvName() + "/publish/" + feedid;\r
+        return getUrlSecurityOption() + BaseServlet.getProvName() + getAppropriateUrlPort() + "/publish/" + feedid;\r
     }\r
 \r
     /**\r
@@ -74,7 +72,7 @@ public class URLUtilities {
      * @return the URL\r
      */\r
     public static String generateSubscribeURL(int feedid) {\r
-        return HTTPS + BaseServlet.getProvName() + "/subscribe/" + feedid;\r
+        return getUrlSecurityOption() + BaseServlet.getProvName() + getAppropriateUrlPort() + "/subscribe/" + feedid;\r
     }\r
 \r
     /**\r
@@ -84,7 +82,7 @@ public class URLUtilities {
      * @return the URL\r
      */\r
     public static String generateFeedLogURL(int feedid) {\r
-        return HTTPS + BaseServlet.getProvName() + "/feedlog/" + feedid;\r
+        return getUrlSecurityOption() + BaseServlet.getProvName() + getAppropriateUrlPort() + "/feedlog/" + feedid;\r
     }\r
 \r
     /**\r
@@ -94,7 +92,7 @@ public class URLUtilities {
      * @return the URL\r
      */\r
     public static String generateSubscriptionURL(int subid) {\r
-        return HTTPS + BaseServlet.getProvName() + "/subs/" + subid;\r
+        return getUrlSecurityOption() + BaseServlet.getProvName() + getAppropriateUrlPort() + "/subs/" + subid;\r
     }\r
 \r
     /**\r
@@ -104,7 +102,7 @@ public class URLUtilities {
      * @return the URL\r
      */\r
     public static String generateSubLogURL(int subid) {\r
-        return HTTPS + BaseServlet.getProvName() + "/sublog/" + subid;\r
+        return getUrlSecurityOption() + BaseServlet.getProvName() + getAppropriateUrlPort() + "/sublog/" + subid;\r
     }\r
 \r
     /**\r
@@ -113,7 +111,7 @@ public class URLUtilities {
      * @return the URL\r
      */\r
     public static String generatePeerProvURL() {\r
-        return HTTPS + getPeerPodName() + "/internal/prov";\r
+        return getUrlSecurityOption() + getPeerPodName() + getAppropriateUrlPort() + "/internal/prov";\r
     }\r
 \r
     /**\r
@@ -128,7 +126,7 @@ public class URLUtilities {
             return "";\r
         }\r
 \r
-        return HTTPS + peerPodUrl + "/internal/drlogs/";\r
+        return getUrlSecurityOption() + peerPodUrl + getAppropriateUrlPort() + "/internal/drlogs/";\r
     }\r
 \r
     /**\r
@@ -154,4 +152,21 @@ public class URLUtilities {
         return otherPod;\r
     }\r
 \r
+    public static String getUrlSecurityOption() {\r
+        if (Boolean.parseBoolean(ProvRunner.getProvProperties()\r
+            .getProperty("org.onap.dmaap.datarouter.provserver.tlsenabled", "true"))) {\r
+            return "https://";\r
+        }\r
+        return "http://";\r
+    }\r
+\r
+    private static String getAppropriateUrlPort() {\r
+        if (Boolean.parseBoolean(ProvRunner.getProvProperties()\r
+            .getProperty("org.onap.dmaap.datarouter.provserver.tlsenabled", "true")))\r
+                return "";\r
+\r
+        return ":" + ProvRunner.getProvProperties()\r
+            .getProperty("org.onap.dmaap.datarouter.provserver.http.port", "8080");\r
+\r
+    }\r
 }\r
index ad9a19e..642088f 100755 (executable)
@@ -56,4 +56,8 @@ org.onap.dmaap.datarouter.provserver.aaf.feed.type        = org.onap.dmaap-dr.fe
 org.onap.dmaap.datarouter.provserver.aaf.sub.type         = org.onap.dmaap-dr.sub
 org.onap.dmaap.datarouter.provserver.aaf.instance         = legacy
 org.onap.dmaap.datarouter.provserver.aaf.action.publish   = publish
-org.onap.dmaap.datarouter.provserver.aaf.action.subscribe = subscribe
\ No newline at end of file
+org.onap.dmaap.datarouter.provserver.aaf.action.subscribe = subscribe
+
+org.onap.dmaap.datarouter.provserver.tlsenabled           = true
+org.onap.dmaap.datarouter.nodeserver.https.port           = 8443
+org.onap.dmaap.datarouter.nodeserver.http.port            = 8080
\ No newline at end of file
index d644df9..1f4fd53 100755 (executable)
  ******************************************************************************/
 package org.onap.dmaap.datarouter.provisioning;
 
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.contains;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
+
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.read.ListAppender;
 import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.jetbrains.annotations.NotNull;
 import org.json.JSONObject;
@@ -45,25 +63,6 @@ import org.onap.dmaap.datarouter.provisioning.utils.ProvDbUtils;
 import org.powermock.core.classloader.annotations.PowerMockIgnore;
 import org.powermock.modules.junit4.PowerMockRunner;
 
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.Persistence;
-import javax.servlet.ServletInputStream;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Set;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.contains;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.onap.dmaap.datarouter.provisioning.BaseServlet.BEHALF_HEADER;
-
 
 @RunWith(PowerMockRunner.class)
 @PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"})
@@ -89,7 +88,7 @@ public class SubscriptionServletTest extends DrServletTestBase {
         em = emf.createEntityManager();
         System.setProperty(
             "org.onap.dmaap.datarouter.provserver.properties",
-            "src/test/resources/h2Database.properties");
+            "src/test/resources/h2DatabaseTlsDisabled.properties");
     }
 
     @AfterClass
@@ -156,14 +155,6 @@ public class SubscriptionServletTest extends DrServletTestBase {
         verify(response).sendError(eq(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), anyString());
     }
 
-    @Test
-    public void Given_Request_Is_HTTP_DELETE_And_AAF_CADI_Is_Enabled_Without_Permissions_Then_Forbidden_Response_Is_Generated() throws Exception {
-        when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
-        when(request.getPathInfo()).thenReturn("/2");
-        subscriptionServlet.doDelete(request, response);
-        verify(response).sendError(eq(HttpServletResponse.SC_FORBIDDEN), contains("AAF disallows access"));
-    }
-
     @Test
     public void Given_Request_Is_HTTP_DELETE_And_AAF_CADI_Is_Enabled_With_Permissions_Then_A_NO_CONTENT_Response_Is_Generated() throws Exception {
         when(request.getHeader("Content-Type")).thenReturn("application/vnd.dmaap-dr.subscription; version=1.0");
index 6957ae1..9596871 100755 (executable)
@@ -31,3 +31,6 @@ org.onap.dmaap.datarouter.provserver.accesslog.dir         = unit-test-logs
 org.onap.dmaap.datarouter.provserver.spooldir              = src/test/resources
 org.onap.dmaap.datarouter.provserver.dbscripts             = src/test/resources
 org.onap.dmaap.datarouter.provserver.localhost             = 127.0.0.1
+org.onap.dmaap.datarouter.provserver.tlsenabled            = true
+org.onap.dmaap.datarouter.nodeserver.https.port            = 8443
+org.onap.dmaap.datarouter.nodeserver.http.port             = 8080
diff --git a/datarouter-prov/src/test/resources/h2DatabaseTlsDisabled.properties b/datarouter-prov/src/test/resources/h2DatabaseTlsDisabled.properties
new file mode 100644 (file)
index 0000000..05ab3a4
--- /dev/null
@@ -0,0 +1,36 @@
+#-------------------------------------------------------------------------------
+# ============LICENSE_START==================================================
+# * org.onap.dmaap
+# * ===========================================================================
+# * Copyright ? 2017 AT&T Intellectual Property. All rights reserved.
+# * ===========================================================================
+# * Licensed 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.
+# * ============LICENSE_END====================================================
+# *
+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+# *
+#-------------------------------------------------------------------------------
+
+# Database access
+org.onap.dmaap.datarouter.db.driver                        = org.h2.Driver
+org.onap.dmaap.datarouter.db.url                           = jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
+org.onap.dmaap.datarouter.provserver.isaddressauthenabled  = true
+org.onap.dmaap.datarouter.provserver.cadi.enabled          = true
+org.onap.dmaap.datarouter.provserver.https.relaxation      = false
+org.onap.dmaap.datarouter.provserver.accesslog.dir         = unit-test-logs
+org.onap.dmaap.datarouter.provserver.spooldir              = src/test/resources
+org.onap.dmaap.datarouter.provserver.dbscripts             = src/test/resources
+org.onap.dmaap.datarouter.provserver.localhost             = 127.0.0.1
+org.onap.dmaap.datarouter.provserver.tlsenabled            = false
+org.onap.dmaap.datarouter.nodeserver.https.port            = 8443
+org.onap.dmaap.datarouter.nodeserver.http.port             = 8080