undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Authenticator;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8169415
|
||||
* @library /test/lib
|
||||
* @modules java.logging
|
||||
* java.base/sun.net.www
|
||||
* java.base/sun.net.www.protocol.http
|
||||
* jdk.httpserver/sun.net.httpserver
|
||||
* @build jdk.test.lib.net.SimpleSSLContext HTTPTest HTTPTestServer HTTPTestClient HTTPSetAuthenticatorTest
|
||||
* @summary A simple HTTP test that starts an echo server supporting the given
|
||||
* authentication scheme, then starts a regular HTTP client to invoke it.
|
||||
* The client first does a GET request on "/", then follows on
|
||||
* with a POST request that sends "Hello World!" to the server.
|
||||
* The client expects to receive "Hello World!" in return.
|
||||
* The test supports several execution modes:
|
||||
* SERVER: The server performs Server authentication;
|
||||
* PROXY: The server pretends to be a proxy and performs
|
||||
* Proxy authentication;
|
||||
* SERVER307: The server redirects the client (307) to another
|
||||
* server that perform Server authentication;
|
||||
* PROXY305: The server attempts to redirect
|
||||
* the client to a proxy using 305 code;
|
||||
* This test runs the client several times, providing different
|
||||
* authenticators to the HttpURLConnection and verifies that
|
||||
* the authenticator is invoked as expected - validating that
|
||||
* connections with different authenticators do not share each
|
||||
* other's socket channel and authentication info.
|
||||
* Note: BASICSERVER means that the server will let the underlying
|
||||
* com.sun.net.httpserver.HttpServer perform BASIC
|
||||
* authentication when in Server mode. There should be
|
||||
* no real difference between BASICSERVER and BASIC - it should
|
||||
* be transparent on the client side.
|
||||
* @run main/othervm HTTPSetAuthenticatorTest NONE SERVER PROXY SERVER307 PROXY305
|
||||
* @run main/othervm -Dhttp.auth.digest.reEnabledAlgorithms=MD5 HTTPSetAuthenticatorTest DIGEST SERVER
|
||||
* @run main/othervm -Dhttp.auth.digest.reEnabledAlgorithms=MD5 HTTPSetAuthenticatorTest DIGEST PROXY
|
||||
* @run main/othervm -Dhttp.auth.digest.reEnabledAlgorithms=MD5 HTTPSetAuthenticatorTest DIGEST PROXY305
|
||||
* @run main/othervm -Dhttp.auth.digest.reEnabledAlgorithms=MD5 HTTPSetAuthenticatorTest DIGEST SERVER307
|
||||
* @run main/othervm HTTPSetAuthenticatorTest BASIC SERVER
|
||||
* @run main/othervm HTTPSetAuthenticatorTest BASIC PROXY
|
||||
* @run main/othervm HTTPSetAuthenticatorTest BASIC PROXY305
|
||||
* @run main/othervm HTTPSetAuthenticatorTest BASIC SERVER307
|
||||
* @run main/othervm HTTPSetAuthenticatorTest BASICSERVER SERVER
|
||||
* @run main/othervm HTTPSetAuthenticatorTest BASICSERVER SERVER307
|
||||
*
|
||||
* @author danielfuchs
|
||||
*/
|
||||
public class HTTPSetAuthenticatorTest extends HTTPTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String[] schemes;
|
||||
String[] params;
|
||||
if (args == null || args.length == 0) {
|
||||
schemes = Stream.of(HttpSchemeType.values())
|
||||
.map(HttpSchemeType::name)
|
||||
.collect(Collectors.toList())
|
||||
.toArray(new String[0]);
|
||||
params = new String[0];
|
||||
} else {
|
||||
schemes = new String[] { args[0] };
|
||||
params = Arrays.copyOfRange(args, 1, args.length);
|
||||
}
|
||||
for (String scheme : schemes) {
|
||||
System.out.println("==== Testing with scheme=" + scheme + " ====\n");
|
||||
new HTTPSetAuthenticatorTest(HttpSchemeType.valueOf(scheme))
|
||||
.execute(params);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
final HttpSchemeType scheme;
|
||||
public HTTPSetAuthenticatorTest(HttpSchemeType scheme) {
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSchemeType getHttpSchemeType() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int run(HTTPTestServer server,
|
||||
HttpProtocolType protocol,
|
||||
HttpAuthType mode)
|
||||
throws IOException
|
||||
{
|
||||
HttpTestAuthenticator authOne = new HttpTestAuthenticator("authOne", "dublin", "foox");
|
||||
HttpTestAuthenticator authTwo = new HttpTestAuthenticator("authTwo", "dublin", "foox");
|
||||
int expectedIncrement = scheme == HttpSchemeType.NONE
|
||||
? 0 : EXPECTED_AUTH_CALLS_PER_TEST;
|
||||
int count;
|
||||
int defaultCount = AUTHENTICATOR.count.get();
|
||||
// Connect to the server with a GET request, then with a
|
||||
// POST that contains "Hello World!"
|
||||
// Uses authenticator #1
|
||||
System.out.println("\nClient: Using authenticator #1: "
|
||||
+ toString(authOne));
|
||||
HTTPTestClient.connect(protocol, server, mode, authOne);
|
||||
count = authOne.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #1 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
|
||||
// Connect to the server with a GET request, then with a
|
||||
// POST that contains "Hello World!"
|
||||
// Uses authenticator #2
|
||||
System.out.println("\nClient: Using authenticator #2: "
|
||||
+ toString(authTwo));
|
||||
HTTPTestClient.connect(protocol, server, mode, authTwo);
|
||||
count = authTwo.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #2 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
|
||||
// Connect to the server with a GET request, then with a
|
||||
// POST that contains "Hello World!"
|
||||
// Uses authenticator #1
|
||||
System.out.println("\nClient: Using authenticator #1 again: "
|
||||
+ toString(authOne));
|
||||
HTTPTestClient.connect(protocol, server, mode, authOne);
|
||||
count = authOne.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #1 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
count = authTwo.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #2 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
count = AUTHENTICATOR.count.get();
|
||||
if (count != defaultCount) {
|
||||
throw new AssertionError("Default Authenticator called " + count(count)
|
||||
+ " expected it to be called " + expected(defaultCount));
|
||||
}
|
||||
|
||||
// Now tries with the default authenticator: it should be invoked.
|
||||
System.out.println("\nClient: Using the default authenticator: "
|
||||
+ toString(null));
|
||||
HTTPTestClient.connect(protocol, server, mode, null);
|
||||
count = authOne.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #1 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
count = authTwo.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #2 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
count = AUTHENTICATOR.count.get();
|
||||
if (count != defaultCount + expectedIncrement) {
|
||||
throw new AssertionError("Default Authenticator called " + count(count)
|
||||
+ " expected it to be called " + expected(defaultCount + expectedIncrement));
|
||||
}
|
||||
|
||||
// Now tries with explicitly setting the default authenticator: it should
|
||||
// be invoked again.
|
||||
// Uncomment the code below when 8169068 is available.
|
||||
System.out.println("\nClient: Explicitly setting the default authenticator: "
|
||||
+ toString(Authenticator.getDefault()));
|
||||
HTTPTestClient.connect(protocol, server, mode, Authenticator.getDefault());
|
||||
count = authOne.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #1 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
count = authTwo.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #2 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
count = AUTHENTICATOR.count.get();
|
||||
if (count != defaultCount + 2 * expectedIncrement) {
|
||||
throw new AssertionError("Default Authenticator called " + count(count)
|
||||
+ " expected it to be called "
|
||||
+ expected(defaultCount + 2 * expectedIncrement));
|
||||
}
|
||||
|
||||
// Now tries to set an authenticator on a connected connection.
|
||||
URL url = url(protocol, server.getAddress(), "/");
|
||||
Proxy proxy = proxy(server, mode);
|
||||
HttpURLConnection conn = openConnection(url, mode, proxy);
|
||||
try {
|
||||
conn.setAuthenticator(null);
|
||||
throw new RuntimeException("Expected NullPointerException"
|
||||
+ " trying to set a null authenticator"
|
||||
+ " not raised.");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("Client: caught expected NPE"
|
||||
+ " trying to set a null authenticator: "
|
||||
+ npe);
|
||||
}
|
||||
conn.connect();
|
||||
try {
|
||||
try {
|
||||
conn.setAuthenticator(authOne);
|
||||
throw new RuntimeException("Expected IllegalStateException"
|
||||
+ " trying to set an authenticator after connect"
|
||||
+ " not raised.");
|
||||
} catch (IllegalStateException ise) {
|
||||
System.out.println("Client: caught expected ISE"
|
||||
+ " trying to set an authenticator after connect: "
|
||||
+ ise);
|
||||
}
|
||||
// Uncomment the code below when 8169068 is available.
|
||||
try {
|
||||
conn.setAuthenticator(Authenticator.getDefault());
|
||||
throw new RuntimeException("Expected IllegalStateException"
|
||||
+ " trying to set an authenticator after connect"
|
||||
+ " not raised.");
|
||||
} catch (IllegalStateException ise) {
|
||||
System.out.println("Client: caught expected ISE"
|
||||
+ " trying to set an authenticator after connect: "
|
||||
+ ise);
|
||||
}
|
||||
try {
|
||||
conn.setAuthenticator(null);
|
||||
throw new RuntimeException("Expected"
|
||||
+ " IllegalStateException or NullPointerException"
|
||||
+ " trying to set a null authenticator after connect"
|
||||
+ " not raised.");
|
||||
} catch (IllegalStateException | NullPointerException xxe) {
|
||||
System.out.println("Client: caught expected "
|
||||
+ xxe.getClass().getSimpleName()
|
||||
+ " trying to set a null authenticator after connect: "
|
||||
+ xxe);
|
||||
}
|
||||
} finally {
|
||||
conn.disconnect();
|
||||
}
|
||||
|
||||
// double check that authOne and authTwo haven't been invoked.
|
||||
count = authOne.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #1 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
count = authTwo.count.get();
|
||||
if (count != expectedIncrement) {
|
||||
throw new AssertionError("Authenticator #2 called " + count(count)
|
||||
+ " expected it to be called " + expected(expectedIncrement));
|
||||
}
|
||||
|
||||
// All good!
|
||||
// return the number of times the default authenticator is supposed
|
||||
// to have been called.
|
||||
return scheme == HttpSchemeType.NONE ? 0 : 2 * EXPECTED_AUTH_CALLS_PER_TEST;
|
||||
}
|
||||
|
||||
static String toString(Authenticator a) {
|
||||
return a == null ? "null" : a.toString();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue