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

mattyb149 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 1f7aeb9002 NIFI-13823 Corrected Certificate Generation for Web Proxy 
Host Property
1f7aeb9002 is described below

commit 1f7aeb9002aa1a74734c394006eeb0088484da80
Author: exceptionfactory <exceptionfact...@apache.org>
AuthorDate: Wed Oct 2 16:20:36 2024 -0500

    NIFI-13823 Corrected Certificate Generation for Web Proxy Host Property
    
    - Added processing to split on comma separator and remove optional port 
number
    
    Signed-off-by: Matt Burgess <mattyb...@apache.org>
    
    This closes #9339
---
 .../SecurityApplicationPropertyHandler.java        | 32 +++++++++++++++--
 .../SecurityApplicationPropertyHandlerTest.java    | 42 ++++++++++++++++++++++
 2 files changed, 71 insertions(+), 3 deletions(-)

diff --git 
a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/property/SecurityApplicationPropertyHandler.java
 
b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/property/SecurityApplicationPropertyHandler.java
index 173d252340..ea84b4dcf6 100644
--- 
a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/property/SecurityApplicationPropertyHandler.java
+++ 
b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/property/SecurityApplicationPropertyHandler.java
@@ -47,10 +47,14 @@ import java.time.LocalDate;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.HexFormat;
 import java.util.List;
 import java.util.Objects;
 import java.util.Properties;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Standard implementation for application security generates Key Pair and 
Certificate when not configured
@@ -74,6 +78,12 @@ public class SecurityApplicationPropertyHandler implements 
ApplicationPropertyHa
 
     private static final String PROPERTY_SEPARATOR = "=";
 
+    private static final Pattern HOST_PORT_PATTERN = 
Pattern.compile("^([\\w-.]{1,63}):?\\d{0,5}$");
+
+    private static final int HOST_GROUP = 1;
+
+    private static final Pattern HOST_PORT_GROUP_SEPARATOR = 
Pattern.compile("\\s*,\\s*");
+
     private final Logger logger;
 
     public SecurityApplicationPropertyHandler(final Logger logger) {
@@ -236,9 +246,8 @@ public class SecurityApplicationPropertyHandler implements 
ApplicationPropertyHa
             subjectAlternativeNames.add(localHostName);
 
             final String proxyHost = 
applicationProperties.getProperty(SecurityProperty.WEB_PROXY_HOST.getName());
-            if (!isBlank(proxyHost)) {
-                subjectAlternativeNames.add(proxyHost);
-            }
+            final Set<String> proxyHostNames = getHosts(proxyHost);
+            subjectAlternativeNames.addAll(proxyHostNames);
 
             return subjectAlternativeNames;
         } catch (final UnknownHostException e) {
@@ -288,6 +297,23 @@ public class SecurityApplicationPropertyHandler implements 
ApplicationPropertyHa
         }
     }
 
+    private Set<String> getHosts(final String property) {
+        final Set<String> hosts = new HashSet<>();
+
+        if (property != null) {
+            final String[] hostPortGroups = 
HOST_PORT_GROUP_SEPARATOR.split(property);
+            for (final String hostPortGroup : hostPortGroups) {
+                final Matcher hostPortMatcher = 
HOST_PORT_PATTERN.matcher(hostPortGroup);
+                if (hostPortMatcher.matches()) {
+                    final String host = hostPortMatcher.group(HOST_GROUP);
+                    hosts.add(host);
+                }
+            }
+        }
+
+        return hosts;
+    }
+
     private boolean isBlank(final String propertyValue) {
         return propertyValue == null || propertyValue.isBlank();
     }
diff --git 
a/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/property/SecurityApplicationPropertyHandlerTest.java
 
b/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/property/SecurityApplicationPropertyHandlerTest.java
index c41e2226e1..e038356702 100644
--- 
a/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/property/SecurityApplicationPropertyHandlerTest.java
+++ 
b/nifi-bootstrap/src/test/java/org/apache/nifi/bootstrap/property/SecurityApplicationPropertyHandlerTest.java
@@ -31,10 +31,16 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
+import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Properties;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -53,6 +59,16 @@ class SecurityApplicationPropertyHandlerTest {
 
     private static final String TRUSTSTORE_FILE = "truststore.p12";
 
+    private static final int DNS_NAME_TYPE = 2;
+
+    private static final String FIRST_PROXY_HOST = "nifi.apache.org";
+
+    private static final int FIRST_PROXY_HOST_PORT = 443;
+
+    private static final String SECOND_PROXY_HOST = "nifi.local";
+
+    private static final String WEB_PROXY_HOST_PROPERTY = 
"%s:%d,%s".formatted(FIRST_PROXY_HOST, FIRST_PROXY_HOST_PORT, 
SECOND_PROXY_HOST);
+
     private static final Logger logger = 
LoggerFactory.getLogger(SecurityApplicationPropertyHandlerTest.class);
 
     @TempDir
@@ -68,6 +84,7 @@ class SecurityApplicationPropertyHandlerTest {
     @Test
     void testHandlePropertiesSuccess() throws IOException, 
GeneralSecurityException {
         final Properties sourceProperties = getSourceProperties();
+        
sourceProperties.setProperty(SecurityProperty.WEB_PROXY_HOST.getName(), 
WEB_PROXY_HOST_PROPERTY);
 
         final Path propertiesPath = writeProperties(sourceProperties);
 
@@ -155,6 +172,31 @@ class SecurityApplicationPropertyHandlerTest {
         assertNotNull(certificate);
         assertEquals(SecurityApplicationPropertyHandler.CERTIFICATE_ISSUER, 
certificate.getIssuerX500Principal());
         assertEquals(SecurityApplicationPropertyHandler.CERTIFICATE_ISSUER, 
certificate.getSubjectX500Principal());
+
+        assertSubjectAlternativeNamesFound(certificate);
+    }
+
+    private void assertSubjectAlternativeNamesFound(final X509Certificate 
certificate) throws CertificateParsingException {
+        final Collection<List<?>> subjectAlternativeNames = 
certificate.getSubjectAlternativeNames();
+
+        assertFalse(subjectAlternativeNames.isEmpty());
+
+        final List<String> alternativeNames = new ArrayList<>();
+
+        for (final List<?> subjectAlternativeName : subjectAlternativeNames) {
+            final Iterator<?> generalNameValue = 
subjectAlternativeName.iterator();
+            assertTrue(generalNameValue.hasNext());
+
+            final Object generalName = generalNameValue.next();
+            assertEquals(DNS_NAME_TYPE, generalName);
+
+            assertTrue(generalNameValue.hasNext());
+            final Object alternativeName = generalNameValue.next();
+            alternativeNames.add(alternativeName.toString());
+        }
+
+        assertTrue(alternativeNames.contains(FIRST_PROXY_HOST), "Web Proxy 
Host [%s] not found".formatted(FIRST_PROXY_HOST));
+        assertTrue(alternativeNames.contains(SECOND_PROXY_HOST), "Web Proxy 
Host [%s] not found".formatted(SECOND_PROXY_HOST));
     }
 
     private void assertStoreCreated(final Properties properties, final 
SecurityProperty securityProperty) {

Reply via email to