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 * @compile OriginServer.java ProxyTunnelServer.java 43 * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= PostThruProxyWithAuth 44 */ 45 public class PostThruProxyWithAuth { 46 47 private static final String TEST_SRC = System.getProperty("test.src", "."); 48 private static final int TIMEOUT = 30000; 49 50 /* 51 * Where do we find the keystores? 52 */ 53 static String pathToStores = "../../../../../../javax/net/ssl/etc"; 54 static String keyStoreFile = "keystore"; 55 static String trustStoreFile = "truststore"; 56 static String passwd = "passphrase"; 57 58 volatile private static int serverPort = 0; 59 60 /* 61 * The TestServer implements a OriginServer that 62 * processes HTTP requests and responses. 63 */ 64 static class TestServer extends OriginServer { 65 public TestServer(ServerSocket ss) throws Exception { 66 super(ss); 67 } 68 69 /* 70 * Returns an array of bytes containing the bytes for 71 * the data sent in the response. 72 * 73 * @return bytes for the data in the response 74 */ 75 public byte[] getBytes() { 76 return 77 "Https POST thru proxy is successful with proxy authentication". 78 getBytes(); 79 } 80 } 81 82 /* 83 * Main method to create the server and client 84 */ 85 public static void main(String args[]) throws Exception { 86 String keyFilename = TEST_SRC + "/" + pathToStores + "/" + keyStoreFile; 87 String trustFilename = TEST_SRC + "/" + pathToStores + "/" 88 + trustStoreFile; 89 90 System.setProperty("javax.net.ssl.keyStore", keyFilename); 91 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 92 System.setProperty("javax.net.ssl.trustStore", trustFilename); 93 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 94 95 boolean useSSL = true; 96 /* 97 * setup the server 98 */ 99 try { 100 ServerSocketFactory ssf = getServerSocketFactory(useSSL); 101 ServerSocket ss = ssf.createServerSocket(serverPort); 102 ss.setSoTimeout(TIMEOUT); // 30 seconds 103 serverPort = ss.getLocalPort(); 104 new TestServer(ss); 105 } catch (Exception e) { 106 System.out.println("Server side failed:" + 107 e.getMessage()); 108 throw e; 109 } 110 // trigger the client 111 try { 112 doClientSide(); 113 } catch (Exception e) { 114 System.out.println("Client side failed: " + 115 e.getMessage()); 116 throw e; 117 } 118 } 119 120 private static ServerSocketFactory getServerSocketFactory 121 (boolean useSSL) throws Exception { 122 if (useSSL) { 123 // set up key manager to do server authentication 124 SSLContext ctx = SSLContext.getInstance("TLS"); 125 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 126 KeyStore ks = KeyStore.getInstance("JKS"); 127 char[] passphrase = passwd.toCharArray(); 128 129 ks.load(new FileInputStream(System.getProperty( 130 "javax.net.ssl.keyStore")), passphrase); 131 kmf.init(ks, passphrase); 132 ctx.init(kmf.getKeyManagers(), null, null); 133 134 return ctx.getServerSocketFactory(); 135 } else { 136 return ServerSocketFactory.getDefault(); 137 } 138 } 139 140 /* 141 * Message to be posted 142 */ 143 static String postMsg = "Testing HTTP post on a https server"; 144 145 static void doClientSide() throws Exception { 146 /* 147 * setup up a proxy 148 */ 149 SocketAddress pAddr = setupProxy(); 150 151 /* 152 * we want to avoid URLspoofCheck failures in cases where the cert 153 * DN name does not match the hostname in the URL. 154 */ 155 HttpsURLConnection.setDefaultHostnameVerifier( 156 new NameVerifier()); 157 URL url = new URL("https://" + getHostname() + ":" + serverPort); 158 159 Proxy p = new Proxy(Proxy.Type.HTTP, pAddr); 160 HttpsURLConnection https = (HttpsURLConnection)url.openConnection(p); 161 https.setConnectTimeout(TIMEOUT); 162 https.setReadTimeout(TIMEOUT); 163 https.setDoOutput(true); 164 https.setRequestMethod("POST"); 165 PrintStream ps = null; 166 try { 167 ps = new PrintStream(https.getOutputStream()); 168 ps.println(postMsg); 169 ps.flush(); 170 if (https.getResponseCode() != 200) { 171 throw new RuntimeException("test Failed"); 172 } 173 ps.close(); 174 // clear the pipe 175 BufferedReader in = new BufferedReader( 176 new InputStreamReader( 177 https.getInputStream())); 178 String inputLine; 179 while ((inputLine = in.readLine()) != null) 180 System.out.println("Client received: " + inputLine); 181 in.close(); 182 } catch (SSLException e) { 183 if (ps != null) 184 ps.close(); 185 throw e; 186 } catch (SocketTimeoutException e) { 187 System.out.println("Client can not get response in time: " 188 + e.getMessage()); 189 } 190 } 191 192 static class NameVerifier implements HostnameVerifier { 193 public boolean verify(String hostname, SSLSession session) { 194 return true; 195 } 196 } 197 198 static SocketAddress setupProxy() throws IOException { 199 ProxyTunnelServer pserver = new ProxyTunnelServer(); 200 201 /* 202 * register a system wide authenticator and setup the proxy for 203 * authentication 204 */ 205 Authenticator.setDefault(new TestAuthenticator()); 206 207 // register with the username and password 208 pserver.needUserAuth(true); 209 pserver.setUserAuth("Test", "test123"); 210 211 pserver.start(); 212 213 return new InetSocketAddress("localhost", pserver.getPort()); 214 } 215 216 public static class TestAuthenticator extends Authenticator { 217 public PasswordAuthentication getPasswordAuthentication() { 218 return new PasswordAuthentication("Test", 219 "test123".toCharArray()); 220 } 221 } 222 223 private static String getHostname() { 224 try { 225 OutputAnalyzer oa = ProcessTools.executeCommand("hostname"); 226 return oa.getOutput().trim(); 227 } catch (Throwable e) { 228 throw new RuntimeException("Get hostname failed.", e); 229 } 230 } 231 }