Merge remote-tracking branch 'origin/jetty-9.4.x' into jetty-10.0.x

Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
Joakim Erdfelt 2020-08-12 16:04:06 -05:00
commit 00f4859e33
No known key found for this signature in database
GPG Key ID: 2D0E1FB8FE4B68B4
3 changed files with 41 additions and 18 deletions

View File

@ -227,15 +227,15 @@ public class PathResource extends Resource
Path absPath = path;
try
{
absPath = path.toAbsolutePath();
absPath = path.toRealPath(NO_FOLLOW_LINKS);
}
catch (IOError ioError)
catch (IOError | IOException e)
{
// Not able to resolve absolute path from provided path
// Not able to resolve real/canonical path from provided path
// This could be due to a glob reference, or a reference
// to a path that doesn't exist (yet)
if (LOG.isDebugEnabled())
LOG.debug("Unable to get absolute path for {}", path, ioError);
LOG.debug("Unable to get real/canonical path for {}", path, e);
}
// cleanup any lingering relative path nonsense (like "/./" and "/../")

View File

@ -27,6 +27,7 @@ import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.resource.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -49,11 +50,22 @@ public class KeyStoreScanner extends ContainerLifeCycle implements Scanner.Discr
this.sslContextFactory = sslContextFactory;
try
{
keystoreFile = sslContextFactory.getKeyStoreResource().getFile();
if (keystoreFile == null || !keystoreFile.exists())
Resource keystoreResource = sslContextFactory.getKeyStoreResource();
File monitoredFile = keystoreResource.getFile();
if (monitoredFile == null || !monitoredFile.exists())
throw new IllegalArgumentException("keystore file does not exist");
if (keystoreFile.isDirectory())
if (monitoredFile.isDirectory())
throw new IllegalArgumentException("expected keystore file not directory");
if (keystoreResource.getAlias() != null)
{
// this resource has an alias, use the alias, as that's what's returned in the Scanner
monitoredFile = new File(keystoreResource.getAlias());
}
keystoreFile = monitoredFile;
if (LOG.isDebugEnabled())
LOG.debug("Monitored Keystore File: {}", monitoredFile);
}
catch (IOException e)
{
@ -122,7 +134,8 @@ public class KeyStoreScanner extends ContainerLifeCycle implements Scanner.Discr
try
{
sslContextFactory.reload(scf -> {});
sslContextFactory.reload(scf ->
{});
}
catch (Throwable t)
{

View File

@ -21,6 +21,7 @@ package org.eclipse.jetty.test;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
@ -47,11 +48,14 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.condition.OS.WINDOWS;
@ExtendWith(WorkDirExtension.class)
public class KeyStoreScannerTest
@ -161,7 +165,8 @@ public class KeyStoreScannerTest
// Delete the keystore.
try (StacklessLogging ignored = new StacklessLogging(KeyStoreScanner.class))
{
useKeystore(null);
Path keystorePath = keystoreDir.resolve("keystore");
assertTrue(Files.deleteIfExists(keystorePath));
keystoreScanner.scan();
}
@ -176,6 +181,7 @@ public class KeyStoreScannerTest
}
@Test
@DisabledOnOs(WINDOWS) // does not support symbolic link
public void testReloadChangingSymbolicLink() throws Exception
{
Path keystorePath = keystoreDir.resolve("symlinkKeystore");
@ -202,13 +208,19 @@ public class KeyStoreScannerTest
}
@Test
@DisabledOnOs(WINDOWS) // does not support symbolic link
public void testReloadChangingTargetOfSymbolicLink() throws Exception
{
Path keystoreLink = keystoreDir.resolve("symlinkKeystore");
Path oldKeystoreSrc = MavenTestingUtils.getTestResourcePathFile("oldKeystore");
Path newKeystoreSrc = MavenTestingUtils.getTestResourcePathFile("newKeystore");
Path target = keystoreDir.resolve("keystore");
start(sslContextFactory ->
{
Path keystorePath = keystoreDir.resolve("symlinkKeystore");
Files.createSymbolicLink(keystorePath, useKeystore("oldKeystore"));
sslContextFactory.setKeyStorePath(keystorePath.toString());
Files.copy(oldKeystoreSrc, target);
Files.createSymbolicLink(keystoreLink, target);
sslContextFactory.setKeyStorePath(keystoreLink.toString());
sslContextFactory.setKeyStorePassword("storepwd");
sslContextFactory.setKeyManagerPassword("keypwd");
});
@ -218,7 +230,8 @@ public class KeyStoreScannerTest
assertThat(getExpiryYear(cert1), is(2015));
// Change the target file of the symlink to the newKeystore which has a later expiry date.
useKeystore("newKeystore");
Files.copy(newKeystoreSrc, target, StandardCopyOption.REPLACE_EXISTING);
System.err.println("### Triggering scan");
keystoreScanner.scan();
// The scanner should have detected the updated keystore, expiry should be renewed.
@ -232,11 +245,7 @@ public class KeyStoreScannerTest
if (Files.exists(keystorePath))
Files.delete(keystorePath);
if (keystore == null)
return null;
Files.copy(MavenTestingUtils.getTestResourceFile(keystore).toPath(), keystorePath);
keystorePath.toFile().deleteOnExit();
Files.copy(MavenTestingUtils.getTestResourcePath(keystore), keystorePath);
if (!Files.exists(keystorePath))
throw new IllegalStateException("keystore file was not created");
@ -260,6 +269,7 @@ public class KeyStoreScannerTest
HttpsURLConnection connection = (HttpsURLConnection)serverUrl.openConnection();
connection.setHostnameVerifier((a, b) -> true);
connection.setRequestProperty("Connection", "close");
connection.connect();
Certificate[] certs = connection.getServerCertificates();
connection.disconnect();