Issue #6021 - PoC for resolvePath within XmlConfiguration

Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
Joakim Erdfelt 2021-03-02 14:40:36 -06:00
parent d9eefc9231
commit 613e0ecd54
No known key found for this signature in database
GPG Key ID: 2D0E1FB8FE4B68B4
20 changed files with 155 additions and 49 deletions

View File

@ -40,12 +40,10 @@
<Arg>
<New id="webappprovider" class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName">
<Property>
<Name>jetty.deploy.monitoredPath</Name>
<Default>
<Property name="jetty.base" default="." />/<Property name="jetty.deploy.monitoredDir" default="webapps"/>
</Default>
</Property>
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.deploy.monitoredDir" default="webapps" /></Arg>
</Call>
</Set>
<Set name="defaultsDescriptor">
<Property>

View File

@ -7,12 +7,10 @@
<Arg>
<New class="org.eclipse.jetty.deploy.bindings.GlobalWebappConfigBinding">
<Set name="jettyXml">
<Property>
<Name>jetty.deploy.webappCommonConfig</Name>
<Default>
<Property name="jetty.base"/>/etc/webapp-common.xml
</Default>
</Property>
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.deploy.webappCommonConfig"/>/etc/webapp-common.xml</Arg>
</Call>
</Set>
</New>
</Arg>

View File

@ -6,7 +6,7 @@
<Arg>
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/hawtio</Set>
<Set name="war"><Property name="jetty.base" default="."/>/lib/hawtio/hawtio.war</Set>
<Set name="war"><Property name="jetty.base"/>/lib/hawtio/hawtio.war</Set>
<Set name="extractWAR">true</Set>
<Set name="copyWebDir">false</Set>
<Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>

View File

@ -20,7 +20,7 @@
<Arg>
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/jamon</Set>
<Set name="war"><Property name="jetty.base" default="."/>/lib/jamon/jamon.war</Set>
<Set name="war"><Property name="jetty.base"/>/lib/jamon/jamon.war</Set>
<Set name="extractWAR">true</Set>
<Set name="copyWebDir">false</Set>
<Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>

View File

@ -6,7 +6,7 @@
<Arg>
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/jolokia</Set>
<Set name="war"><Property name="jetty.base" default="."/>/lib/jolokia/jolokia.war</Set>
<Set name="war"><Property name="jetty.base"/>/lib/jolokia/jolokia.war</Set>
<Set name="extractWAR">true</Set>
<Set name="copyWebDir">false</Set>
<Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>

View File

@ -39,7 +39,7 @@
<New id="cacheMgr" class="org.infinispan.manager.DefaultCacheManager">
<Arg>
<Property name="jetty.base" default="."/>/etc/infinispan.xml
<Property name="jetty.base"/>/etc/infinispan.xml
</Arg>
<Get id="defaultConfig" name="defaultCacheConfiguration"/>
</New>

View File

@ -7,7 +7,7 @@
<!-- Get a reference to the default local cache. -->
<!-- ===================================================================== -->
<New id="cacheMgr" class="org.infinispan.manager.DefaultCacheManager">
<Arg><Property name="jetty.base" default="."/>/etc/infinispan.xml</Arg>
<Arg><Property name="jetty.base"/>/etc/infinispan.xml</Arg>
<Get id="cache" name="cache"></Get>
</New>

View File

@ -24,9 +24,9 @@
<New id="properties" class="java.util.Properties">
<Call name="load">
<Arg>
<New class="java.io.FileInputStream">
<Arg><Property name="jetty.base" default="."/>/resources/hotrod-client.properties</Arg>
</New>
<New class="java.io.FileInputStream">
<Arg><Property name="jetty.base"/>/resources/hotrod-client.properties</Arg>
</New>
</Arg>
</Call>
<Call name="put">

View File

@ -19,7 +19,7 @@
<Arg>my.proto</Arg>
<Arg>
<New class="java.io.File">
<Arg><Property name="jetty.base" default="."/>/etc/my.proto</Arg>
<Arg><Property name="jetty.base"/>/etc/my.proto</Arg>
</New>
</Arg>
</Call>

View File

@ -10,7 +10,7 @@
<Call name="load">
<Arg>
<New class="java.io.FileInputStream">
<Arg><Property name="jetty.base" default="."/>/resources/hotrod-client.properties</Arg>
<Arg><Property name="jetty.base"/>/resources/hotrod-client.properties</Arg>
</New>
</Arg>
</Call>

View File

@ -10,7 +10,12 @@
<!-- ======================================================== -->
<Call class="java.lang.System" name="setProperty">
<Arg>java.security.auth.login.config</Arg>
<Arg><Property name="jetty.base" default="." />/<Property name="jetty.jaas.login.conf" default="etc/login.conf"/></Arg>
<Arg>
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.jaas.login.conf" default="etc/login.conf" /></Arg>
</Call>
</Arg>
</Call>
</Configure>

View File

@ -3,7 +3,12 @@
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call class="org.eclipse.jetty.keystore.KeystoreGenerator" name="generateTestKeystore">
<Arg><Property name="jetty.base" default="." />/<Property name="jetty.sslContext.keyStorePath" default="etc/keystore.p12" /></Arg>
<Arg>
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.sslContext.keyStorePath" default="etc/keystore.p12" /></Arg>
</Call>
</Arg>
<Arg><Property name="jetty.sslContext.keyStorePassword" /></Arg>
</Call>
</Configure>

View File

@ -27,6 +27,3 @@ jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/bouncycastle/
jetty.sslContext.keyStorePath?=etc/test-keystore.p12
jetty.sslContext.keyStoreType?=PKCS12
jetty.sslContext.keyStorePassword?=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
jetty.sslContext.trustStorePath?=etc/test-keystore.p12
jetty.sslContext.trustStoreType?=PKCS12
jetty.sslContext.keyStorePassword?=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4

View File

@ -7,7 +7,7 @@
<Arg>
<Ref refid="wac" />
</Arg>
<Arg><Property name="jetty.base" default="."/>/etc/maven.props</Arg>
<Arg><Property name="jetty.base"/>/etc/maven.props</Arg>
<Arg>
<Ref refid="Server" />
</Arg>

View File

@ -31,9 +31,9 @@
<!-- ============================================================= -->
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
<Set name="Provider"><SystemProperty name="jetty.sslContext.provider"/></Set>
<Set name="KeyStorePath"><Property name="jetty.base" default="."/>/<Property name="jetty.sslContext.keyStorePath" default="etc/keystore.p12"/></Set>
<Set name="KeyStorePath"><Property name="jetty.base"/>/<Property name="jetty.sslContext.keyStorePath" default="etc/keystore.p12"/></Set>
<Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set>
<Set name="TrustStorePath"><Property name="jetty.base" default="."/>/<Property name="jetty.sslContext.trustStorePath" default="etc/keystore.p12"/></Set>
<Set name="TrustStorePath"><Property name="jetty.base"/>/<Property name="jetty.sslContext.trustStorePath" default="etc/keystore.p12"/></Set>
<Set name="TrustStorePassword"><Property name="jetty.sslContext.trustStorePassword" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set>
<Set name="NeedClientAuth" property="jetty.sslContext.needClientAuth"/>
<Set name="WantClientAuth" property="jetty.sslContext.wantClientAuth"/>

View File

@ -15,11 +15,12 @@
<!-- Writer -->
<Arg>
<New class="org.eclipse.jetty.server.AsyncRequestLogWriter">
<Arg><Property name="jetty.base" default="." />/<Property>
<Name>jetty.requestlog.filePath</Name>
<Default><Property name="jetty.requestlog.dir" default="logs"/>/yyyy_mm_dd.request.log</Default>
</Property></Arg>
<Arg/>
<Arg>
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.requestlog.dir" default="logs" />/yyyy_mm_dd.request.log</Arg>
</Call>
</Arg>
<Set name="filenameDateFormat"><Property name="jetty.requestlog.filenameDateFormat" default="yyyy_MM_dd"/></Set>
<Set name="retainDays"><Property name="jetty.requestlog.retainDays" default="90"/></Set>

View File

@ -6,22 +6,20 @@
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
<Set name="Provider" property="jetty.sslContext.provider" />
<Set name="KeyStorePath">
<Property name="jetty.sslContext.keyStoreAbsolutePath">
<Default>
<Property name="jetty.base" default="." />/<Property name="jetty.sslContext.keyStorePath" deprecated="jetty.keystore" default="etc/keystore"/>
</Default>
</Property>
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.sslContext.keyStorePath" deprecated="jetty.sslContext.keyStoreAbsolutePath,jetty.keystore" default="etc/keystore.p12" /></Arg>
</Call>
</Set>
<Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" /></Set>
<Set name="KeyStoreType" property="jetty.sslContext.keyStoreType" />
<Set name="KeyStoreProvider" property="jetty.sslContext.keyStoreProvider" />
<Set name="KeyManagerPassword"><Property name="jetty.sslContext.keyManagerPassword" /></Set>
<Set name="TrustStorePath">
<Property name="jetty.sslContext.trustStoreAbsolutePath">
<Default>
<Property name="jetty.base" default="." />/<Property name="jetty.sslContext.trustStorePath" deprecated="jetty.truststore" default="etc/keystore"/>
</Default>
</Property>
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.sslContext.trustStorePath" deprecated="jetty.sslContext.trustStoreAbsolutePath,jetty.truststore" /></Arg>
</Call>
</Set>
<Set name="TrustStorePassword" property="jetty.sslContext.trustStorePassword" />
<Set name="TrustStoreType" property="jetty.sslContext.trustStoreType" />

View File

@ -708,13 +708,20 @@ public abstract class SslContextFactory extends AbstractLifeCycle implements Dum
*/
public void setTrustStorePath(String trustStorePath)
{
try
if (StringUtil.isEmpty(trustStorePath))
{
_trustStoreResource = Resource.newResource(trustStorePath);
_trustStoreResource = null;
}
catch (Exception e)
else
{
throw new IllegalArgumentException(e);
try
{
_trustStoreResource = Resource.newResource(trustStorePath);
}
catch (Exception e)
{
throw new IllegalArgumentException(e);
}
}
}

View File

@ -28,6 +28,7 @@ import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.AccessController;
@ -331,6 +332,29 @@ public class XmlConfiguration
{
}
/**
* Utility method to resolve a provided path against a base directory.
*
* @param baseDir the base directory
* @param destPath the destination path (can be relative or absolute, syntax depends on OS + FileSystem in use)
* @return String to resolved and normalized path, or null if baseDir or destPath is empty.
*/
public static String resolvePath(String baseDir, String destPath)
{
if (StringUtil.isEmpty(baseDir) || StringUtil.isEmpty(destPath))
return null;
Path base = Paths.get(baseDir);
if (!Files.exists(base))
{
// Add warning to debug output
LOG.debug("Configured baseDir={} does not exist", baseDir);
}
return base.resolve(destPath).normalize().toString();
}
private static class JettyXmlConfiguration implements ConfigurationProcessor
{
XmlParser.Node _root;

View File

@ -15,6 +15,7 @@ package org.eclipse.jetty.xml;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
@ -31,10 +32,12 @@ import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jetty.logging.JettyLevel;
import org.eclipse.jetty.logging.JettyLogger;
import org.eclipse.jetty.logging.StdErrAppender;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
@ -48,6 +51,7 @@ import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -1588,6 +1592,75 @@ public class XmlConfigurationTest
assertEquals(6, warnings.size());
}
public static Stream<Arguments> resolvePathCases()
{
return Stream.of(
// Not configured, default (in xml) is used.
Arguments.of(null, "/var/lib/jetty-base/etc/keystore.p12"),
// Configured using normal relative path
Arguments.of("alt/keystore", "/var/lib/jetty-base/alt/keystore"),
// Configured using navigated path segments
Arguments.of("../corp/etc/keystore", "/var/lib/corp/etc/keystore"),
// Configured using absolute path
Arguments.of("/opt/jetty/etc/keystore", "/opt/jetty/etc/keystore")
);
}
@ParameterizedTest
@MethodSource("resolvePathCases")
public void testCallResolvePath(String configValue, String expectedPath) throws Exception
{
Path war = MavenTestingUtils.getTargetPath("no.war");
XmlConfiguration configuration =
asXmlConfiguration(
"<Configure class=\"org.eclipse.jetty.xml.TestConfiguration\">" +
" <Set name=\"TestString\">" +
" <Call name=\"resolvePath\" class=\"org.eclipse.jetty.xml.XmlConfiguration\">" +
" <Arg><Property name=\"jetty.base\"/></Arg>" +
" <Arg><Property name=\"jetty.sslContext.keyStorePath\" default=\"etc/keystore.p12\" /></Arg>" +
" </Call>" +
" </Set>" +
"</Configure>");
configuration.setJettyStandardIdsAndProperties(null, Resource.newResource(war));
configuration.getProperties().put("jetty.base", "/var/lib/jetty-base");
if (configValue != null)
configuration.getProperties().put("jetty.sslContext.keyStorePath", configValue);
TestConfiguration tc = new TestConfiguration();
configuration.configure(tc);
assertThat(tc.getTestString(), is(expectedPath));
}
@Test
public void testResolvePathRelative()
{
Path testPath = MavenTestingUtils.getTargetTestingPath("testResolvePathRelative");
FS.ensureDirExists(testPath);
String resolved = XmlConfiguration.resolvePath(testPath.toString(), "etc/keystore");
assertEquals(testPath.toString() + File.separator + "etc/keystore", resolved);
}
@Test
public void testResolvePathAbsolute()
{
Path testPath = MavenTestingUtils.getTargetTestingPath("testResolvePathRelative");
FS.ensureDirExists(testPath);
String resolved = XmlConfiguration.resolvePath(testPath.toString(), "/tmp/etc/keystore");
assertEquals("/tmp/etc/keystore", resolved);
}
@Test
public void testResolvePathInvalidBase()
{
Path testPath = MavenTestingUtils.getTargetTestingPath("testResolvePathRelative");
FS.ensureDeleted(testPath);
Path baseDir = testPath.resolve("bogus");
String resolved = XmlConfiguration.resolvePath(baseDir.toString(), "etc/keystore");
assertNull(resolved, "Should be null as baseDir does not exist");
}
private ByteArrayOutputStream captureLoggingBytes(ThrowableAction action) throws Exception
{
Logger slf4jLogger = LoggerFactory.getLogger(XmlConfiguration.class);