Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'.

This commit is contained in:
Simone Bordet 2020-01-17 09:02:14 +01:00
commit 65d50258b7
17 changed files with 205 additions and 145 deletions

View File

@ -196,7 +196,7 @@ public abstract class AbstractHttpClientServerTest
private void configure(SslContextFactory ssl)
{
Path keystorePath = MavenTestingUtils.getTestResourcePath("keystore.jks");
Path keystorePath = MavenTestingUtils.getTestResourcePath("keystore.p12");
ssl.setKeyStorePath(keystorePath.toString());
ssl.setKeyStorePassword("storepwd");
}

View File

@ -62,7 +62,7 @@ public class HostnameVerificationTest
server = new Server(serverThreads);
SslContextFactory.Server serverSslContextFactory = new SslContextFactory.Server();
serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.p12");
serverSslContextFactory.setKeyStorePassword("storepwd");
connector = new ServerConnector(server, serverSslContextFactory);
server.addConnector(connector);
@ -78,7 +78,7 @@ public class HostnameVerificationTest
server.start();
// The keystore contains a hostname which doesn't match localhost
clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.p12");
clientSslContextFactory.setKeyStorePassword("storepwd");
ClientConnector clientConnector = new ClientConnector();

View File

@ -127,7 +127,7 @@ public class HttpClientTLSTest
private void configureSslContextFactory(SslContextFactory sslContextFactory)
{
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12");
sslContextFactory.setKeyStorePassword("storepwd");
}

View File

@ -204,7 +204,7 @@ public class Socks4ProxyTest
{
// The client keystore contains the trustedCertEntry for the
// self-signed server certificate, so it acts as a truststore.
ssl.setTrustStorePath("src/test/resources/client_keystore.jks");
ssl.setTrustStorePath("src/test/resources/client_keystore.p12");
ssl.setTrustStorePassword("storepwd");
// Disable TLS hostname verification, but
// enable application hostname verification.
@ -238,7 +238,7 @@ public class Socks4ProxyTest
// Wrap the socket with TLS.
SslContextFactory.Server serverTLS = new SslContextFactory.Server();
serverTLS.setKeyStorePath("src/test/resources/keystore.jks");
serverTLS.setKeyStorePath("src/test/resources/keystore.p12");
serverTLS.setKeyStorePassword("storepwd");
serverTLS.start();
SSLContext sslContext = serverTLS.getSslContext();

View File

@ -52,7 +52,7 @@ public class TLSServerConnectionCloseTest
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
sslContextFactory.setEndpointIdentificationAlgorithm(null);
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12");
sslContextFactory.setKeyStorePassword("storepwd");
clientConnector.setSslContextFactory(sslContextFactory);

View File

@ -87,7 +87,7 @@ public class NeedWantClientAuthTest
private SslContextFactory.Server createServerSslContextFactory()
{
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
sslContextFactory.setKeyStorePath("src/test/resources/keystore.p12");
sslContextFactory.setKeyStorePassword("storepwd");
return sslContextFactory;
}
@ -146,7 +146,7 @@ public class NeedWantClientAuthTest
});
SslContextFactory.Client clientSSL = new SslContextFactory.Client(true);
clientSSL.setKeyStorePath("src/test/resources/client_keystore.jks");
clientSSL.setKeyStorePath("src/test/resources/client_keystore.p12");
clientSSL.setKeyStorePassword("storepwd");
startClient(clientSSL);
@ -237,7 +237,7 @@ public class NeedWantClientAuthTest
});
SslContextFactory.Client clientSSL = new SslContextFactory.Client(true);
clientSSL.setKeyStorePath("src/test/resources/client_keystore.jks");
clientSSL.setKeyStorePath("src/test/resources/client_keystore.p12");
clientSSL.setKeyStorePassword("storepwd");
startClient(clientSSL);

View File

@ -77,7 +77,7 @@ public class SslBytesClientTest extends SslBytesTest
clientConnector.setSslContextFactory(sslContextFactory);
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
client.setMaxConnectionsPerDestination(1);
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks");
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.p12");
sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
sslContextFactory.setKeyStorePassword("storepwd");
client.start();

View File

@ -117,7 +117,7 @@ public class SslBytesServerTest extends SslBytesTest
httpParses.set(0);
serverEndPoint.set(null);
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks");
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.p12");
sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
sslContextFactory.setKeyStorePassword("storepwd");

View File

@ -42,7 +42,7 @@ public class SslConnectionTest
@Test
public void testSslConnectionClosedBeforeFill() throws Exception
{
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks");
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.p12");
SslContextFactory sslContextFactory = new SslContextFactory.Server();
sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
sslContextFactory.setKeyStorePassword("storepwd");

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,27 @@
Since OpenJDK 13.0.2/11.0.6 it is required that CA certificates have the extension CA=true.
The keystores are generated in the following way:
# Generates the server keystore. Note the BasicConstraint=CA:true extension.
$ keytool -v -genkeypair -validity 36500 -keyalg RSA -keysize 2048 -keystore keystore.p12 -storetype pkcs12 -dname "CN=server, OU=Jetty, O=Webtide, L=Omaha, S=NE, C=US" -ext BC=CA:true
# Export the server certificate.
$ keytool -v -export -keystore keystore.p12 -rfc -file server.crt
# Export the server private key.
$ openssl pkcs12 -in keystore.p12 -nodes -nocerts -out server.key
# Generate the client keystore.
$ keytool -v -genkeypair -validity 36500 -keyalg RSA -keysize 2048 -keystore client_keystore.p12 -storetype pkcs12 -dname "CN=client, OU=Jetty, O=Webtide, L=Omaha, S=NE, C=US"
# Generate the Certificate Signing Request.
$ keytool -certreq -file client.csr -keystore client_keystore.p12
# Sign the CSR.
$ openssl x509 -req -days 36500 -in client.csr -CA server.crt -CAkey server.key -CAcreateserial -sha256 -out signed.crt
# Import the server certificate into the client keystore.
$ keytool -v -import -alias ca -file server.crt -keystore client_keystore.p12
# Import the signed CSR.
$ keytool -import -file signed.crt -keystore client_keystore.p12

View File

@ -60,10 +60,10 @@ public class MultiPartFormInputStream
{
private static final Logger LOG = Log.getLogger(MultiPartFormInputStream.class);
private static final MultiMap<Part> EMPTY_MAP = new MultiMap<>(Collections.emptyMap());
private final MultiMap<Part> _parts;
private InputStream _in;
private MultipartConfigElement _config;
private String _contentType;
private MultiMap<Part> _parts;
private Throwable _err;
private File _tmpDir;
private File _contextTmpDir;
@ -341,16 +341,19 @@ public class MultiPartFormInputStream
if (_config == null)
_config = new MultipartConfigElement(_contextTmpDir.getAbsolutePath());
MultiMap parts = new MultiMap();
if (in instanceof ServletInputStream)
{
if (((ServletInputStream)in).isFinished())
{
_parts = EMPTY_MAP;
parts = EMPTY_MAP;
_parsed = true;
return;
}
}
_in = new BufferedInputStream(in);
if (!_parsed)
_in = new BufferedInputStream(in);
_parts = parts;
}
/**
@ -411,6 +414,9 @@ public class MultiPartFormInputStream
parse();
throwIfError();
if (_parts.isEmpty())
return Collections.emptyList();
Collection<List<Part>> values = _parts.values();
List<Part> parts = new ArrayList<>();
for (List<Part> o : values)
@ -471,9 +477,6 @@ public class MultiPartFormInputStream
Handler handler = new Handler();
try
{
// initialize
_parts = new MultiMap<>();
// if its not a multipart request, don't parse it
if (_contentType == null || !_contentType.startsWith("multipart/form-data"))
return;

View File

@ -509,6 +509,16 @@ public class MultiPartFormInputStreamTest
assertThat(stuff.exists(), is(false)); //tmp file was removed after cleanup
}
@Test
public void testDeleteNPE()
{
final InputStream input = new ByteArrayInputStream(createMultipartRequestString("myFile").getBytes());
MultipartConfigElement config = new MultipartConfigElement(_dirname, 1024, 1024, 50);
MultiPartFormInputStream mpis = new MultiPartFormInputStream(input, _contentType, config, _tmpDir);
mpis.deleteParts(); // this should not be an NPE
}
@Test
public void testLFOnlyRequest()
throws Exception

View File

@ -19,27 +19,53 @@
package org.eclipse.jetty.util;
import java.net.InetAddress;
import java.util.Iterator;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import org.eclipse.jetty.toolchain.test.Net;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class InetAddressSetTest
{
@Test
public void testInetAddress() throws Exception
public static Stream<String> loopbacks()
{
assertTrue(InetAddress.getByName("127.0.0.1").isLoopbackAddress());
assertTrue(InetAddress.getByName("::1").isLoopbackAddress());
assertTrue(InetAddress.getByName("::0.0.0.1").isLoopbackAddress());
assertTrue(InetAddress.getByName("[::1]").isLoopbackAddress());
assertTrue(InetAddress.getByName("[::0.0.0.1]").isLoopbackAddress());
assertTrue(InetAddress.getByName("[::ffff:127.0.0.1]").isLoopbackAddress());
List<String> loopbacks = new ArrayList<>();
loopbacks.add("127.0.0.1");
loopbacks.add("127.0.0.2");
if (Net.isIpv6InterfaceAvailable())
{
loopbacks.add("::1");
loopbacks.add("::0.0.0.1");
loopbacks.add("[::1]");
loopbacks.add("[::0.0.0.1]");
loopbacks.add("[::ffff:127.0.0.1]");
}
return loopbacks.stream();
}
@ParameterizedTest
@MethodSource("loopbacks")
public void testInetAddressLoopback(String addr) throws Exception
{
InetAddress inetAddress = InetAddress.getByName(addr);
assertNotNull(inetAddress);
assertTrue(inetAddress.isLoopbackAddress());
}
@Test
@ -71,32 +97,37 @@ public class InetAddressSetTest
assertFalse(set.test(InetAddress.getByName("1::abcd")));
}
@Test
public void testBadSingleton() throws Exception
public static Stream<String> badsingletons()
{
String[] tests = new String[]
{
"unknown",
"1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16",
"a.b.c.d",
"[::1",
"[xxx]",
"[:::1]",
};
List<String> bad = new ArrayList<>();
InetAddressSet set = new InetAddressSet();
bad.add("intentionally invalid hostname");
bad.add("nonexistentdomain.tld");
bad.add("1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16");
bad.add("a.b.c.d");
for (String t : tests)
bad.add("[::1"); // incomplete
bad.add("[xxx]"); // not valid octets
bad.add("[:::1]"); // too many colons
return bad.stream();
}
@ParameterizedTest
@MethodSource("badsingletons")
public void testBadSingleton(final String badAddr)
{
try
{
try
{
set.add(t);
fail(t);
}
catch (IllegalArgumentException e)
{
assertThat(e.getMessage(), containsString(t));
}
InetAddress inetAddress = InetAddress.getByName(badAddr);
Assumptions.assumeTrue(inetAddress == null);
}
catch (UnknownHostException expected)
{
//noinspection MismatchedQueryAndUpdateOfCollection
InetAddressSet inetAddressSet = new InetAddressSet();
IllegalArgumentException cause = assertThrows(IllegalArgumentException.class, () -> inetAddressSet.add(badAddr));
assertThat(cause.getMessage(), containsString(badAddr));
}
}
@ -147,34 +178,34 @@ public class InetAddressSetTest
assertTrue(set.test(InetAddress.getByName("5.22.192.1")));
}
@Test
public void testBadCIDR() throws Exception
public static Stream<String> badCidrs()
{
String[] tests = new String[]
{
"unknown/8",
"1.2.3.4/-1",
"1.2.3.4/xxx",
"1.2.3.4/33",
"255.255.8.0/16",
"255.255.8.1/17",
"[::1]/129",
};
List<String> bad = new ArrayList<>();
bad.add("intentionally invalid hostname/8");
bad.add("nonexistentdomain.tld/8");
bad.add("1.2.3.4/-1");
bad.add("1.2.3.4/xxx");
bad.add("1.2.3.4/33");
bad.add("255.255.8.0/16");
bad.add("255.255.8.1/17");
InetAddressSet set = new InetAddressSet();
for (String t : tests)
if (Net.isIpv6InterfaceAvailable())
{
try
{
set.add(t);
fail(t);
}
catch (IllegalArgumentException e)
{
assertThat(e.getMessage(), containsString(t));
}
bad.add("[::1]/129");
}
return bad.stream();
}
@ParameterizedTest
@MethodSource("badCidrs")
public void testBadCIDR(String cidr)
{
//noinspection MismatchedQueryAndUpdateOfCollection
InetAddressSet inetAddressSet = new InetAddressSet();
IllegalArgumentException cause = assertThrows(IllegalArgumentException.class, () -> inetAddressSet.add(cidr));
assertThat(cause.getMessage(), containsString(cidr));
}
@Test
@ -184,7 +215,11 @@ public class InetAddressSetTest
set.add("10.0.0.4-10.0.0.6");
set.add("10.1.0.254-10.1.1.1");
set.add("[abcd:ef::fffe]-[abcd:ef::1:1]");
if (Net.isIpv6InterfaceAvailable())
{
set.add("[abcd:ef::fffe]-[abcd:ef::1:1]");
}
assertFalse(set.test(InetAddress.getByName("10.0.0.3")));
assertTrue(set.test(InetAddress.getByName("10.0.0.4")));
@ -199,37 +234,28 @@ public class InetAddressSetTest
assertTrue(set.test(InetAddress.getByName("10.1.1.1")));
assertFalse(set.test(InetAddress.getByName("10.1.1.2")));
assertFalse(set.test(InetAddress.getByName("ABCD:EF::FFFD")));
assertTrue(set.test(InetAddress.getByName("ABCD:EF::FFFE")));
assertTrue(set.test(InetAddress.getByName("ABCD:EF::FFFF")));
assertTrue(set.test(InetAddress.getByName("ABCD:EF::1:0")));
assertTrue(set.test(InetAddress.getByName("ABCD:EF::1:1")));
assertFalse(set.test(InetAddress.getByName("ABCD:EF::1:2")));
if (Net.isIpv6InterfaceAvailable())
{
assertFalse(set.test(InetAddress.getByName("ABCD:EF::FFFD")));
assertTrue(set.test(InetAddress.getByName("ABCD:EF::FFFE")));
assertTrue(set.test(InetAddress.getByName("ABCD:EF::FFFF")));
assertTrue(set.test(InetAddress.getByName("ABCD:EF::1:0")));
assertTrue(set.test(InetAddress.getByName("ABCD:EF::1:1")));
assertFalse(set.test(InetAddress.getByName("ABCD:EF::1:2")));
}
}
@Test
public void testBadMinMax() throws Exception
@ParameterizedTest
@ValueSource(strings = {
"10.0.0.0-9.0.0.0",
"9.0.0.0-[::10.0.0.0]"
})
public void testBadMinMax(String bad)
{
String[] tests = new String[]
{
"10.0.0.0-9.0.0.0",
"9.0.0.0-[::10.0.0.0]",
};
InetAddressSet set = new InetAddressSet();
for (String t : tests)
{
try
{
set.add(t);
fail(t);
}
catch (IllegalArgumentException e)
{
assertThat(e.getMessage(), containsString(t));
}
}
//noinspection MismatchedQueryAndUpdateOfCollection
InetAddressSet inetAddressSet = new InetAddressSet();
IllegalArgumentException cause = assertThrows(IllegalArgumentException.class, () -> inetAddressSet.add(bad));
assertThat(cause.getMessage(), containsString(bad));
}
@Test
@ -258,30 +284,18 @@ public class InetAddressSetTest
assertFalse(set.test(InetAddress.getByName("10.0.244.3")));
}
@Test
public void testBadLegacy() throws Exception
@ParameterizedTest
@ValueSource(strings = {
"9.0-10.0",
"10.0.0--1.1",
"10.0.0-256.1"
})
public void testBadLegacy(String bad)
{
String[] tests = new String[]
{
"9.0-10.0",
"10.0.0--1.1",
"10.0.0-256.1",
};
InetAddressSet set = new InetAddressSet();
for (String t : tests)
{
try
{
set.add(t);
fail(t);
}
catch (IllegalArgumentException e)
{
assertThat(e.getMessage(), containsString(t));
}
}
//noinspection MismatchedQueryAndUpdateOfCollection
InetAddressSet inetAddressSet = new InetAddressSet();
IllegalArgumentException cause = assertThrows(IllegalArgumentException.class, () -> inetAddressSet.add(bad));
assertThat(cause.getMessage(), containsString(bad));
}
@Test
@ -299,10 +313,13 @@ public class InetAddressSetTest
assertTrue(set.test(InetAddress.getByName("1.2.3.4")));
assertTrue(set.test(InetAddress.getByAddress(new byte[]{(byte)1, (byte)2, (byte)3, (byte)4})));
assertTrue(set.test(InetAddress.getByAddress("hostname", new byte[]{(byte)1, (byte)2, (byte)3, (byte)4})));
assertTrue(set.test(InetAddress.getByName("::0:0:abcd")));
assertTrue(set.test(InetAddress.getByName("::abcd")));
assertTrue(set.test(InetAddress.getByName("[::abcd]")));
assertTrue(set.test(InetAddress.getByName("::ffff:1.2.3.4")));
if (Net.isIpv6InterfaceAvailable())
{
assertTrue(set.test(InetAddress.getByName("::0:0:abcd")));
assertTrue(set.test(InetAddress.getByName("::abcd")));
assertTrue(set.test(InetAddress.getByName("[::abcd]")));
assertTrue(set.test(InetAddress.getByName("::ffff:1.2.3.4")));
}
assertTrue(set.test(InetAddress.getByName("10.0.0.4")));
assertTrue(set.test(InetAddress.getByName("10.0.0.5")));
assertTrue(set.test(InetAddress.getByName("10.0.0.6")));
@ -313,28 +330,31 @@ public class InetAddressSetTest
assertFalse(set.test(InetAddress.getByName("1.2.3.4")));
assertFalse(set.test(InetAddress.getByAddress(new byte[]{(byte)1, (byte)2, (byte)3, (byte)4})));
assertFalse(set.test(InetAddress.getByAddress("hostname", new byte[]{(byte)1, (byte)2, (byte)3, (byte)4})));
assertTrue(set.test(InetAddress.getByName("::0:0:abcd")));
assertTrue(set.test(InetAddress.getByName("::abcd")));
assertTrue(set.test(InetAddress.getByName("[::abcd]")));
assertFalse(set.test(InetAddress.getByName("::ffff:1.2.3.4")));
if (Net.isIpv6InterfaceAvailable())
{
assertTrue(set.test(InetAddress.getByName("::0:0:abcd")));
assertTrue(set.test(InetAddress.getByName("::abcd")));
assertTrue(set.test(InetAddress.getByName("[::abcd]")));
assertFalse(set.test(InetAddress.getByName("::ffff:1.2.3.4")));
}
assertTrue(set.test(InetAddress.getByName("10.0.0.4")));
assertTrue(set.test(InetAddress.getByName("10.0.0.5")));
assertTrue(set.test(InetAddress.getByName("10.0.0.6")));
for (Iterator<String> i = set.iterator(); i.hasNext(); )
{
if ("::abcd".equals(i.next()))
i.remove();
}
set.removeIf("::abcd"::equals);
assertTrue(set.test(InetAddress.getByName("webtide.com")));
assertTrue(set.test(InetAddress.getByName(InetAddress.getByName("webtide.com").getHostAddress())));
assertFalse(set.test(InetAddress.getByName("1.2.3.4")));
assertFalse(set.test(InetAddress.getByAddress(new byte[]{(byte)1, (byte)2, (byte)3, (byte)4})));
assertFalse(set.test(InetAddress.getByAddress("hostname", new byte[]{(byte)1, (byte)2, (byte)3, (byte)4})));
assertFalse(set.test(InetAddress.getByName("::0:0:abcd")));
assertFalse(set.test(InetAddress.getByName("::abcd")));
assertFalse(set.test(InetAddress.getByName("[::abcd]")));
assertFalse(set.test(InetAddress.getByName("::ffff:1.2.3.4")));
if (Net.isIpv6InterfaceAvailable())
{
assertFalse(set.test(InetAddress.getByName("::0:0:abcd")));
assertFalse(set.test(InetAddress.getByName("::abcd")));
assertFalse(set.test(InetAddress.getByName("[::abcd]")));
assertFalse(set.test(InetAddress.getByName("::ffff:1.2.3.4")));
}
assertTrue(set.test(InetAddress.getByName("10.0.0.4")));
assertTrue(set.test(InetAddress.getByName("10.0.0.5")));
assertTrue(set.test(InetAddress.getByName("10.0.0.6")));