Skip to content

Commit c034ea8

Browse files
authored
Handle validation for Composite URIs without parens (#2004) (#2013)
Parentheses are optional when creating composite and nested URIs so this updates the validation to handle missing parens as well. Follow on to #1847 (cherry picked from commit cf00060)
1 parent c28f59b commit c034ea8

3 files changed

Lines changed: 92 additions & 12 deletions

File tree

activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -574,26 +574,39 @@ private static void validateAllowedUrl(String uriString) throws URISyntaxExcepti
574574
// Validate the URI does not contain a denied transport scheme
575575
private static void validateAllowedUri(URI uri, int depth) throws URISyntaxException {
576576
// Don't allow more than 5 nested URIs to prevent blowing the stack
577-
// If we are greater than 4 then this is the 5th level of composite
578-
if (depth > 4) {
577+
if (depth > 5) {
579578
throw new IllegalArgumentException("URI can't contain more than 5 nested composite URIs");
580579
}
581580

582581
// First check the main URI scheme
583582
validateAllowedScheme(uri.getScheme());
584583

585-
// If composite, iterate and check each of the composite URIs
586-
if (URISupport.isCompositeURI(uri)) {
587-
URISupport.CompositeData data = URISupport.parseComposite(uri);
584+
// We need to check if the URI is composite and/or contains nested URIs
585+
// The utility method URISupport#isCompositeURI is not good enough here
586+
// because it misses if there are no parentheses and also is primarily meant
587+
// for checking comma separated URIs and not nested URIs.
588+
//
589+
// The best way to handle all cases is to use the same logic that the transports
590+
// use to process the URIs and that is to simply attempt to parse it and check each
591+
// of the parsed components. This wll correctly handle the case when there
592+
// are parentheses and also when the parentheses are skipped.
593+
final URISupport.CompositeData data;
594+
try {
595+
data = URISupport.parseComposite(uri);
596+
} catch (URISyntaxException e) {
597+
// If this is not a valid URI then we can stop checking
598+
// This can happen when parsing a nested URI and at the last portion
599+
return;
600+
}
601+
602+
if (data.getComponents() != null) {
588603
depth++;
589604
for (URI component : data.getComponents()) {
590-
// Each URI could be a nested composite URI so call validateAllowedUri()
591-
// to validate it. This check if composite first so we don't add to
592-
// the recursive stack depth if there's a lot of URIs that are not composite
593-
if (URISupport.isCompositeURI(component)) {
605+
// Each URI could be a nested and/or composite URI so call validateAllowedUri()
606+
// to validate it. If the scheme is null then the original URI is not composite
607+
// or nested so we can skip the check, and we are finished.
608+
if (component.getScheme() != null) {
594609
validateAllowedUri(component, depth);
595-
} else {
596-
validateAllowedScheme(component.getScheme());
597610
}
598611
}
599612
}

activemq-unit-tests/src/test/java/org/apache/activemq/broker/jmx/MBeanTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,6 +2086,14 @@ protected void testAddTransportConnectorBlockedBrokerView(String scheme) throws
20862086
assertEquals("Transport scheme '" + scheme + "' is not allowed", e.getMessage());
20872087
}
20882088

2089+
try {
2090+
// verify any composite URI is blocked as well without parens
2091+
brokerView.addConnector("static:tcp://0.0.0.0:0," + scheme + "://" + brokerName);
2092+
fail("Should have failed trying to add connector with scheme: " + scheme);
2093+
} catch (IllegalArgumentException e) {
2094+
assertEquals("Transport scheme '" + scheme + "' is not allowed", e.getMessage());
2095+
}
2096+
20892097
try {
20902098
// verify nested composite URI is blocked
20912099
brokerView.addConnector("static:(static:(static:(" + scheme + "://localhost)))");
@@ -2108,6 +2116,15 @@ public void testNestedAddTransportConnector() throws Exception {
21082116
} catch (IllegalArgumentException e) {
21092117
assertEquals("URI can't contain more than 5 nested composite URIs", e.getMessage());
21102118
}
2119+
2120+
try {
2121+
// verify nested composite URI with more than 5 levels is blocked without parens
2122+
brokerView.addConnector(
2123+
"static:static:static:static:static:static:tcp://localhost:0");
2124+
fail("Should have failed trying to add vm connector bridge");
2125+
} catch (IllegalArgumentException e) {
2126+
assertEquals("URI can't contain more than 5 nested composite URIs", e.getMessage());
2127+
}
21112128
}
21122129

21132130
}

activemq-unit-tests/src/test/java/org/apache/activemq/jmx/JmxCreateNCTest.java

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,31 @@ public void testBridgeRegistration() throws Exception {
8282
assertEquals("NC", nc.getName());
8383
}
8484

85+
@Test
86+
public void testTransportSchemeBridgeAllowed() throws Exception {
87+
// Test composite network connector uri
88+
String name = proxy.addNetworkConnector("static:(tcp://localhost,amqp://localhost)");
89+
proxy.removeNetworkConnector(name);
90+
91+
// Test composite with missing parens
92+
name = proxy.addNetworkConnector("static:amqp://localhost,tcp://127.0.0.1:0");
93+
proxy.removeNetworkConnector(name);
94+
95+
// verify direct connector as well
96+
name = proxy.addNetworkConnector("static:stomp://localhost");
97+
proxy.removeNetworkConnector(name);
98+
99+
// verify nested composite URI
100+
name = proxy.addNetworkConnector(
101+
"static:(static:(static:(tcp+ssl://localhost:0,auto+nio+ssl://localhost)))");
102+
proxy.removeNetworkConnector(name);
103+
104+
// verify nested composite URI is not blocked when not using parens
105+
name = proxy.addNetworkConnector(
106+
"static:static:static:123://localhost:0,auto+nio+ssl://localhost");
107+
proxy.removeNetworkConnector(name);
108+
}
109+
85110
@Test
86111
public void testTransportSchemeBridgeBlocked() throws Exception {
87112
for (String deniedScheme : DENIED_TRANSPORT_SCHEMES) {
@@ -99,6 +124,14 @@ protected void testTransportSchemeBridgeBlocked(String scheme) throws Exception
99124
assertEquals("Transport scheme '" + scheme + "' is not allowed", e.getMessage());
100125
}
101126

127+
// Test composite with missing parens
128+
try {
129+
proxy.addNetworkConnector("static:" + scheme + "://localhost,tcp://127.0.0.1:0");
130+
fail("Should have failed trying to add connector bridge with scheme: " + scheme);
131+
} catch (IllegalArgumentException e) {
132+
assertEquals("Transport scheme '" + scheme + "' is not allowed", e.getMessage());
133+
}
134+
102135
// verify direct connector as well
103136
try {
104137
proxy.addNetworkConnector(scheme + "://localhost");
@@ -114,6 +147,14 @@ protected void testTransportSchemeBridgeBlocked(String scheme) throws Exception
114147
} catch (IllegalArgumentException e) {
115148
assertEquals("Transport scheme '" + scheme + "' is not allowed", e.getMessage());
116149
}
150+
151+
try {
152+
// verify nested composite URI is blocked when not using parens
153+
proxy.addNetworkConnector("static:static:static:tcp://localhost:0," + scheme + "://localhost");
154+
fail("Should have failed trying to add connector bridge with scheme: " + scheme);
155+
} catch (IllegalArgumentException e) {
156+
assertEquals("Transport scheme '" + scheme + "' is not allowed", e.getMessage());
157+
}
117158
}
118159

119160
@Test
@@ -124,12 +165,21 @@ public void testAddNetworkConnectorMaxComposite() throws Exception {
124165

125166
try {
126167
// verify nested composite URI with more than 5 levels is blocked. This has 6 nested
127-
// (not including first wrapper url
168+
// (not including first wrapper url)
128169
proxy.addNetworkConnector(
129170
"static:(static:(static:(static:(static:(static:(tcp://localhost:0))))))");
130171
fail("Should have failed trying to add more than 5 connector bridges");
131172
} catch (IllegalArgumentException e) {
132173
assertEquals("URI can't contain more than 5 nested composite URIs", e.getMessage());
133174
}
175+
176+
try {
177+
// verify nested composite URI with more than 5 levels is blocked without parens
178+
proxy.addNetworkConnector(
179+
"static:static:static:static:static:static:tcp://localhost:0");
180+
fail("Should have failed trying to add more than 5 connector bridges");
181+
} catch (IllegalArgumentException e) {
182+
assertEquals("URI can't contain more than 5 nested composite URIs", e.getMessage());
183+
}
134184
}
135185
}

0 commit comments

Comments
 (0)