1 /* 2 * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.*; 25 import java.net.*; 26 import java.security.KeyStore; 27 import javax.net.*; 28 import javax.net.ssl.*; 29 30 import jdk.test.lib.process.OutputAnalyzer; 31 import jdk.test.lib.process.ProcessTools; 32 33 /* 34 * @test 35 * @bug 4423074 36 * @modules java.base/sun.net.www 37 * @summary This test case is written to test the https POST through a proxy 38 * with proxy authentication. It includes a simple server that serves 39 * http POST method requests in secure channel, and a client that 40 * makes https POST request through a proxy. 41 * @library /test/lib 42 * @build jdk.test.lib.Utils 43 * jdk.test.lib.Asserts 44 * jdk.test.lib.JDKToolFinder 45 * jdk.test.lib.JDKToolLauncher 46 * jdk.test.lib.Platform 47 * jdk.test.lib.process.* 48 * @compile OriginServer.java ProxyTunnelServer.java 49 * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= PostThruProxyWithAuth 50 */ 51 public class PostThruProxyWithAuth { 52 53 private static final String TEST_SRC = System.getProperty("test.src", "."); 54 private static final int TIMEOUT = 30000; 55 56 /* 57 * Where do we find the keystores? 58 */ 59 static String pathToStores = "../../../../../../javax/net/ssl/etc"; 60 static String keyStoreFile = "keystore"; 61 static String trustStoreFile = "truststore"; 62 static String passwd = "passphrase"; 63 64 volatile private static int serverPort = 0; 65 66 /* 67 * The TestServer implements a OriginServer that 68 * processes HTTP requests and responses. 69 */ 70 static class TestServer extends OriginServer { 71 public TestServer(ServerSocket ss) throws Exception { 72 super(ss); 73 } 74 75 /* 76 * Returns an array of bytes containing the bytes for 77 * the data sent in the response. 78 * 79 * @return bytes for the data in the response 80 */ 81 public byte[] getBytes() { 82 return 83 "Https POST thru proxy is successful with proxy authentication". 84 getBytes(); 85 } 86 } 87 88 /* 89 * Main method to create the server and client 90 */ 91 public static void main(String args[]) throws Exception { 92 String keyFilename = TEST_SRC + "/" + pathToStores + "/" + keyStoreFile; 93 String trustFilename = TEST_SRC + "/" + pathToStores + "/" 94 + trustStoreFile; 95 96 System.setProperty("javax.net.ssl.keyStore", keyFilename); 97 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 98 System.setProperty("javax.net.ssl.trustStore", trustFilename); 99 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 100 101 boolean useSSL = true; 102 /* 103 * setup the server 104 */ 105 try { 106 ServerSocketFactory ssf = getServerSocketFactory(useSSL); 107 ServerSocket ss = ssf.createServerSocket(serverPort); 108 ss.setSoTimeout(TIMEOUT); // 30 seconds 109 serverPort = ss.getLocalPort(); 110 new TestServer(ss); 111 } catch (Exception e) { 112 System.out.println("Server side failed:" + 113 e.getMessage()); 114 throw e; 115 } 116 // trigger the client 117 try { 118 doClientSide(); 119 } catch (Exception e) { 120 System.out.println("Client side failed: " + 121 e.getMessage()); 122 throw e; 123 } 124 } 125 126 private static ServerSocketFactory getServerSocketFactory 127 (boolean useSSL) throws Exception { 128 if (useSSL) { 129 // set up key manager to do server authentication 130 SSLContext ctx = SSLContext.getInstance("TLS"); 131 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 132 KeyStore ks = KeyStore.getInstance("JKS"); 133 char[] passphrase = passwd.toCharArray(); 134 135 ks.load(new FileInputStream(System.getProperty( 136 "javax.net.ssl.keyStore")), passphrase); 137 kmf.init(ks, passphrase); 138 ctx.init(kmf.getKeyManagers(), null, null); 139 140 return ctx.getServerSocketFactory(); 141 } else { 142 return ServerSocketFactory.getDefault(); 143 } 144 } 145 146 /* 147 * Message to be posted 148 */ 149 static String postMsg = "Testing HTTP post on a https server"; 150 151 static void doClientSide() throws Exception { 152 /* 153 * setup up a proxy 154 */ 155 SocketAddress pAddr = setupProxy(); 156 157 /* 158 * we want to avoid URLspoofCheck failures in cases where the cert 159 * DN name does not match the hostname in the URL. 160 */ 161 HttpsURLConnection.setDefaultHostnameVerifier( 162 new NameVerifier()); 163 URL url = new URL("https://" + getHostname() + ":" + serverPort); 164 165 Proxy p = new Proxy(Proxy.Type.HTTP, pAddr); 166 HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p); 167 https.setConnectTimeout(TIMEOUT); 168 https.setReadTimeout(TIMEOUT); 169 https.setDoOutput(true); 170 https.setRequestMethod("POST"); 171 PrintStream ps = null; 172 try { 173 ps = new PrintStream(https.getOutputStream()); 174 ps.println(postMsg); 175 ps.flush(); 176 if (https.getResponseCode() != 200) { 177 throw new RuntimeException("test Failed"); 178 } 179 ps.close(); 180 // clear the pipe 181 BufferedReader in = new BufferedReader( 182 new InputStreamReader( 183 https.getInputStream())); 184 String inputLine; 185 while ((inputLine = in.readLine()) != null) 186 System.out.println("Client received: " + inputLine); 187 in.close(); 188 } catch (SSLException e) { 189 if (ps != null) 190 ps.close(); 191 throw e; 192 } catch (SocketTimeoutException e) { 193 System.out.println("Client can not get response in time: " 194 + e.getMessage()); 195 } 196 } 197 198 static class NameVerifier implements HostnameVerifier { 199 public boolean verify(String hostname, SSLSession session) { 200 return true; 201 } 202 } 203 204 static SocketAddress setupProxy() throws IOException { 205 ProxyTunnelServer pserver = new ProxyTunnelServer(); 206 207 /* 208 * register a system wide authenticator and setup the proxy for 209 * authentication 210 */ 211 Authenticator.setDefault(new TestAuthenticator()); 212 213 // register with the username and password 214 pserver.needUserAuth(true); 215 pserver.setUserAuth("Test", "test123"); 216 217 pserver.start(); 218 219 return new InetSocketAddress("localhost", pserver.getPort()); 220 } 221 222 public static class TestAuthenticator extends Authenticator { 223 public PasswordAuthentication getPasswordAuthentication() { 224 return new PasswordAuthentication("Test", 225 "test123".toCharArray()); 226 } 227 } 228 229 private static String getHostname() { 230 try { 231 OutputAnalyzer oa = ProcessTools.executeCommand("hostname"); 232 return oa.getOutput().trim(); 233 } catch (Throwable e) { 234 throw new RuntimeException("Get hostname failed.", e); 235 } 236 } 237 }