8229481: sun/net/www/protocol/https/ChunkedOutputStream.java failed with a SSLException

The test is updated to ignore plain text connections

Reviewed-by: chegar, michaelm
This commit is contained in:
Daniel Fuchs 2019-08-16 15:01:58 +01:00
parent ae5615c614
commit e81ee784d3
3 changed files with 66 additions and 1 deletions

View File

@ -37,6 +37,7 @@
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import java.util.concurrent.atomic.AtomicInteger;
public class ChunkedOutputStream implements HttpCallback {
/*
@ -47,6 +48,7 @@ public class ChunkedOutputStream implements HttpCallback {
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
static int count = 0;
static final AtomicInteger rogueCount = new AtomicInteger();
static final String str1 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+
"1234567890abcdefkjsdlkjflkjsldkfjlsdkjflkj"+
@ -132,12 +134,23 @@ public class ChunkedOutputStream implements HttpCallback {
req.sendResponse(200, "OK");
req.orderlyClose();
break;
default:
req.sendResponse(404, "Not Found");
req.orderlyClose();
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean dropPlainTextConnections() {
System.out.println("Unrecognized SSL message, plaintext connection?");
System.out.println("TestHttpsServer receveived rogue connection: ignoring it.");
rogueCount.incrementAndGet();
return true;
}
static void readAndCompare(InputStream is, String cmp) throws IOException {
int c;
byte buf[] = new byte[1024];
@ -153,6 +166,26 @@ public class ChunkedOutputStream implements HttpCallback {
}
}
/* basic smoke test: verify that server drops plain connections */
static void testPlainText(String authority) throws Exception {
URL url = new URL("http://" + authority + "/Donauschiffsgesellschaftskapitaenskajuete");
System.out.println("client opening connection to: " + url);
HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
int rogue = rogueCount.get();
try {
int code = urlc.getResponseCode();
System.out.println("Unexpected response: " + code);
throw new AssertionError("Unexpected response: " + code);
} catch (SocketException x) {
// we expect that the server will drop the connection and
// close the accepted socket, so we should get a SocketException
// on the client side, and confirm that this::dropPlainTextConnections
// has ben called.
if (rogueCount.get() == rogue) throw x;
System.out.println("Got expected exception: " + x);
}
}
/* basic chunked test (runs twice) */
static void test1(String u) throws Exception {
@ -303,6 +336,7 @@ public class ChunkedOutputStream implements HttpCallback {
server = new TestHttpsServer(
new ChunkedOutputStream(), 1, 10, loopback, 0);
System.out.println("Server started: listening on: " + server.getAuthority());
testPlainText(server.getAuthority());
// the test server doesn't support keep-alive yet
// test1("http://" + server.getAuthority() + "/d0");
test1("https://" + server.getAuthority() + "/d01");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2019, 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
@ -36,4 +36,15 @@ public interface HttpCallback {
* client and used to send the response
*/
void request (HttpTransaction msg);
/**
* Tells whether the server should simply close the
* connection and ignore the request when the first
* byte received by the server looks like a plain
* text connection.
* @return true if the request should be ignored.
**/
default boolean dropPlainTextConnections() {
return false;
}
}

View File

@ -316,6 +316,7 @@ public class TestHttpsServer {
HttpCallback cb;
HandshakeStatus currentHSStatus;
boolean initialHSComplete;
boolean handshakeStarted;
/*
* All inbound data goes through this buffer.
*
@ -364,6 +365,25 @@ public class TestHttpsServer {
case NEED_UNWRAP:
int bytes = schan.read(inNetBB);
if (!handshakeStarted && bytes > 0) {
handshakeStarted = true;
int byte0 = inNetBB.get(0);
if (byte0 != 0x16) {
// first byte of a TLS connection is supposed to be
// 0x16. If not it may be a plain text connection.
//
// Sometime a rogue client may try to open a plain
// connection with our server. Calling this method
// gives a chance to the test logic to ignore such
// rogue connections.
//
if (cb.dropPlainTextConnections()) {
try { schan.close(); } catch (IOException x) { };
return;
}
// else sslEng.unwrap will throw later on...
}
}
needIO:
while (currentHSStatus == HandshakeStatus.NEED_UNWRAP) {