Path: blob/master/test/jdk/sun/net/www/protocol/https/NewImpl/JavaxHostnameVerifier.java
41161 views
/*1* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223// SunJSSE does not support dynamic system properties, no way to re-use24// system properties in samevm/agentvm mode.2526/*27* @test28* @bug 4474255 448424629* @summary When an application enables anonymous SSL cipher suite,30* Hostname verification is not required31* @run main/othervm JavaxHostnameVerifier32*/3334import java.io.*;35import java.net.*;36import java.security.Security;37import java.security.cert.*;38import javax.net.ssl.*;3940/**41* Use javax.net.ssl.HostnameVerifier42*/43public class JavaxHostnameVerifier {4445/*46* =============================================================47* Set the various variables needed for the tests, then48* specify what tests to run on each side.49*/5051/*52* Should we run the client or server in a separate thread?53* Both sides can throw exceptions, but do you have a preference54* as to which side should be the main thread.55*/56static boolean separateServerThread = true;5758/*59* Is the server ready to serve?60*/61volatile static boolean serverReady = false;6263/*64* Turn on SSL debugging?65*/66static boolean debug = false;6768/*69* If the client or server is doing some kind of object creation70* that the other side depends on, and that thread prematurely71* exits, you may experience a hang. The test harness will72* terminate all hung threads after its timeout has expired,73* currently 3 minutes by default, but you might try to be74* smart about it....75*/7677/**78* Returns the path to the file obtained from79* parsing the HTML header.80*/81private static String getPath(DataInputStream in)82throws IOException83{84String line = in.readLine();85String path = "";86// extract class from GET line87if (line == null)88return null;8990if (line.startsWith("GET /")) {91line = line.substring(5, line.length()-1).trim();92int index = line.indexOf(' ');93if (index != -1) {94path = line.substring(0, index);95}96}9798// eat the rest of header99do {100line = in.readLine();101} while ((line.length() != 0) &&102(line.charAt(0) != '\r') && (line.charAt(0) != '\n'));103104if (path.length() != 0) {105return path;106} else {107throw new IOException("Malformed Header");108}109}110111/**112* Returns an array of bytes containing the bytes for113* the file represented by the argument <b>path</b>.114*115* In our case, we just pretend to send something back.116*117* @return the bytes for the file118* @exception FileNotFoundException if the file corresponding119* to <b>path</b> could not be loaded.120*/121private byte[] getBytes(String path)122throws IOException123{124return "Hello world, I am here".getBytes();125}126127/*128* Define the server side of the test.129*130* If the server prematurely exits, serverReady will be set to true131* to avoid infinite hangs.132*/133void doServerSide() throws Exception {134135SSLServerSocketFactory sslssf =136(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();137138// doClientSide() connects to "localhost"139InetAddress localHost = InetAddress.getByName("localhost");140InetSocketAddress address = new InetSocketAddress(localHost, serverPort);141142SSLServerSocket sslServerSocket =143(SSLServerSocket) sslssf.createServerSocket();144sslServerSocket.bind(address);145serverPort = sslServerSocket.getLocalPort();146147String ciphers[]= { "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA" };148sslServerSocket.setEnabledCipherSuites(ciphers);149150/*151* Signal Client, we're ready for his connect.152*/153serverReady = true;154155SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();156DataOutputStream out =157new DataOutputStream(sslSocket.getOutputStream());158159try {160// get path to class file from header161DataInputStream in =162new DataInputStream(sslSocket.getInputStream());163String path = getPath(in);164// retrieve bytecodes165byte[] bytecodes = getBytes(path);166// send bytecodes in response (assumes HTTP/1.0 or later)167try {168out.writeBytes("HTTP/1.0 200 OK\r\n");169out.writeBytes("Content-Length: " + bytecodes.length + "\r\n");170out.writeBytes("Content-Type: text/html\r\n\r\n");171out.write(bytecodes);172out.flush();173} catch (IOException ie) {174ie.printStackTrace();175return;176}177178} catch (Exception e) {179e.printStackTrace();180// write out error response181out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");182out.writeBytes("Content-Type: text/html\r\n\r\n");183out.flush();184} finally {185// close the socket186System.out.println("Server closing socket");187sslSocket.close();188serverReady = false;189}190}191192/*193* Define the client side of the test.194*195* If the server prematurely exits, serverReady will be set to true196* to avoid infinite hangs.197*/198void doClientSide() throws Exception {199/*200* Wait for server to get started.201*/202while (!serverReady) {203Thread.sleep(50);204}205206System.setProperty("https.cipherSuites",207"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA");208209// use the default hostname verifier210211URL url = new URL("https://" + "localhost:" + serverPort +212"/etc/hosts");213URLConnection urlc = url.openConnection(Proxy.NO_PROXY);214215if (!(urlc instanceof javax.net.ssl.HttpsURLConnection)) {216throw new Exception(217"URLConnection ! instanceof javax.net.ssl.HttpsURLConnection");218}219220BufferedReader in = null;221try {222in = new BufferedReader(new InputStreamReader(223urlc.getInputStream()));224String inputLine;225System.out.print("Client reading... ");226while ((inputLine = in.readLine()) != null)227System.out.println(inputLine);228System.out.println("Cipher Suite: " +229((HttpsURLConnection)urlc).getCipherSuite());230in.close();231} catch (SSLException e) {232if (in != null)233in.close();234throw e;235}236System.out.println("Client reports: SUCCESS");237}238239/*240* =============================================================241* The remainder is just support stuff242*/243244// use any free port by default245volatile int serverPort = 0;246247volatile Exception serverException = null;248volatile Exception clientException = null;249250public static void main(String[] args) throws Exception {251// re-enable 3DES252Security.setProperty("jdk.tls.disabledAlgorithms", "");253254if (debug)255System.setProperty("javax.net.debug", "all");256257/*258* Start the tests.259*/260new JavaxHostnameVerifier();261}262263Thread clientThread = null;264Thread serverThread = null;265266/*267* Primary constructor, used to drive remainder of the test.268*269* Fork off the other side, then do your work.270*/271JavaxHostnameVerifier() throws Exception {272if (separateServerThread) {273startServer(true);274startClient(false);275} else {276startClient(true);277startServer(false);278}279280/*281* Wait for other side to close down.282*/283if (separateServerThread) {284serverThread.join();285} else {286clientThread.join();287}288289/*290* When we get here, the test is pretty much over.291*292* If the main thread excepted, that propagates back293* immediately. If the other thread threw an exception, we294* should report back.295*/296if (serverException != null) {297System.out.print("Server Exception:");298throw serverException;299}300if (clientException != null) {301System.out.print("Client Exception:");302throw clientException;303}304}305306void startServer(boolean newThread) throws Exception {307if (newThread) {308serverThread = new Thread() {309public void run() {310try {311doServerSide();312} catch (Exception e) {313/*314* Our server thread just died.315*316* Release the client, if not active already...317*/318System.err.println("Server died...");319serverReady = true;320serverException = e;321}322}323};324serverThread.start();325} else {326doServerSide();327}328}329330void startClient(boolean newThread) throws Exception {331if (newThread) {332clientThread = new Thread() {333public void run() {334try {335doClientSide();336} catch (Exception e) {337/*338* Our client thread just died.339*/340System.err.println("Client died...");341clientException = e;342}343}344};345clientThread.start();346} else {347doClientSide();348}349}350}351352353