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 <[email protected]>
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 <[email protected]>
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) {