Path: blob/master/test/jdk/javax/net/ssl/ServerName/BestEffortOnLazyConnected.java
41152 views
/*1* Copyright (c) 2016, 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//24// SunJSSE does not support dynamic system properties, no way to re-use25// system properties in samevm/agentvm mode.26//2728/**29* @test30* @bug 814456631* @summary Custom HostnameVerifier disables SNI extension32* @run main/othervm BestEffortOnLazyConnected33*/3435import java.io.*;36import java.net.*;37import javax.net.ssl.*;3839public class BestEffortOnLazyConnected {4041/*42* =============================================================43* Set the various variables needed for the tests, then44* specify what tests to run on each side.45*/4647/*48* Should we run the client or server in a separate thread?49* Both sides can throw exceptions, but do you have a preference50* as to which side should be the main thread.51*/52private static final boolean separateServerThread = true;5354/*55* Where do we find the keystores?56*/57private static final String pathToStores = "../etc";58private static final String keyStoreFile = "keystore";59private static final String trustStoreFile = "truststore";60private static final String passwd = "passphrase";6162/*63* Is the server ready to serve?64*/65private static volatile boolean serverReady = false;6667/*68* Turn on SSL debugging?69*/70private static final boolean debug = false;7172/*73* the fully qualified domain name of localhost74*/75private static String hostname = null;7677/*78* If the client or server is doing some kind of object creation79* that the other side depends on, and that thread prematurely80* exits, you may experience a hang. The test harness will81* terminate all hung threads after its timeout has expired,82* currently 3 minutes by default, but you might try to be83* smart about it....84*/8586/*87* Define the server side of the test.88*89* If the server prematurely exits, serverReady will be set to true90* to avoid infinite hangs.91*/92private void doServerSide() throws Exception {93SSLServerSocketFactory sslssf =94(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();95try (SSLServerSocket sslServerSocket =96(SSLServerSocket) sslssf.createServerSocket(serverPort)) {9798serverPort = sslServerSocket.getLocalPort();99100/*101* Signal Client, we're ready for his connect.102*/103serverReady = true;104105try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {106InputStream sslIS = sslSocket.getInputStream();107OutputStream sslOS = sslSocket.getOutputStream();108109sslIS.read();110sslOS.write(85);111sslOS.flush();112113ExtendedSSLSession session =114(ExtendedSSLSession)sslSocket.getSession();115if (session.getRequestedServerNames().isEmpty()) {116throw new Exception("No expected Server Name Indication");117}118}119}120}121122/*123* Define the client side of the test.124*125* If the server prematurely exits, serverReady will be set to true126* to avoid infinite hangs.127*/128private void doClientSide() throws Exception {129130/*131* Wait for server to get started.132*/133while (!serverReady) {134Thread.sleep(50);135}136137SSLSocketFactory sslsf =138(SSLSocketFactory) SSLSocketFactory.getDefault();139140try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) {141142sslSocket.connect(new InetSocketAddress(hostname, serverPort), 0);143144InputStream sslIS = sslSocket.getInputStream();145OutputStream sslOS = sslSocket.getOutputStream();146147sslOS.write(280);148sslOS.flush();149sslIS.read();150}151}152153154/*155* =============================================================156* The remainder is just support stuff157*/158159// use any free port by default160private volatile int serverPort = 0;161162private volatile Exception serverException = null;163private volatile Exception clientException = null;164165public static void main(String[] args) throws Exception {166String keyFilename =167System.getProperty("test.src", ".") + "/" + pathToStores +168"/" + keyStoreFile;169String trustFilename =170System.getProperty("test.src", ".") + "/" + pathToStores +171"/" + trustStoreFile;172173System.setProperty("javax.net.ssl.keyStore", keyFilename);174System.setProperty("javax.net.ssl.keyStorePassword", passwd);175System.setProperty("javax.net.ssl.trustStore", trustFilename);176System.setProperty("javax.net.ssl.trustStorePassword", passwd);177178if (debug) {179System.setProperty("javax.net.debug", "all");180}181182try {183hostname = InetAddress.getLocalHost().getCanonicalHostName();184} catch (UnknownHostException uhe) {185System.out.println(186"Ignore the test as the local hostname cannot be determined");187188return;189}190191System.out.println(192"The fully qualified domain name of the local host is " +193hostname);194// Ignore the test if the hostname does not sound like a domain name.195if ((hostname == null) || hostname.isEmpty() ||196!hostname.contains(".") || hostname.endsWith(".") ||197hostname.startsWith("localhost") ||198Character.isDigit(hostname.charAt(hostname.length() - 1))) {199200System.out.println("Ignore the test as the local hostname " +201"cannot be determined as fully qualified domain name");202203return;204}205206/*207* Start the tests.208*/209new BestEffortOnLazyConnected();210}211212private Thread clientThread = null;213private Thread serverThread = null;214215/*216* Primary constructor, used to drive remainder of the test.217*218* Fork off the other side, then do your work.219*/220BestEffortOnLazyConnected() throws Exception {221try {222if (separateServerThread) {223startServer(true);224startClient(false);225} else {226startClient(true);227startServer(false);228}229} catch (Exception e) {230// swallow for now. Show later231}232233/*234* Wait for other side to close down.235*/236if (separateServerThread) {237serverThread.join();238} else {239clientThread.join();240}241242/*243* When we get here, the test is pretty much over.244* Which side threw the error?245*/246Exception local;247Exception remote;248String whichRemote;249250if (separateServerThread) {251remote = serverException;252local = clientException;253whichRemote = "server";254} else {255remote = clientException;256local = serverException;257whichRemote = "client";258}259260/*261* If both failed, return the curthread's exception, but also262* print the remote side Exception263*/264if ((local != null) && (remote != null)) {265System.out.println(whichRemote + " also threw:");266remote.printStackTrace();267System.out.println();268throw local;269}270271if (remote != null) {272throw remote;273}274275if (local != null) {276throw local;277}278}279280private void startServer(boolean newThread) throws Exception {281if (newThread) {282serverThread = new Thread() {283public void run() {284try {285doServerSide();286} catch (Exception e) {287/*288* Our server thread just died.289*290* Release the client, if not active already...291*/292System.err.println("Server died...");293serverReady = true;294serverException = e;295}296}297};298serverThread.start();299} else {300try {301doServerSide();302} catch (Exception e) {303serverException = e;304} finally {305serverReady = true;306}307}308}309310private void startClient(boolean newThread) throws Exception {311if (newThread) {312clientThread = new Thread() {313public void run() {314try {315doClientSide();316} catch (Exception e) {317/*318* Our client thread just died.319*/320System.err.println("Client died...");321clientException = e;322}323}324};325clientThread.start();326} else {327try {328doClientSide();329} catch (Exception e) {330clientException = e;331}332}333}334}335336337