Mercurial > hg > openjdk > jdk8u > jdk
changeset 4438:a80562f7ea50
6670868: StackOverFlow with bad authenticated Proxy tunnels
Reviewed-by: michaelm
author | chegar |
---|---|
date | Wed, 27 Jul 2011 18:10:10 +0100 |
parents | c563e8060adf |
children | 7525866a4046 |
files | src/share/classes/sun/net/www/http/HttpClient.java src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsProxyStackOverflow.java |
diffstat | 3 files changed, 130 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/net/www/http/HttpClient.java Mon Jul 25 16:20:39 2011 -0700 +++ b/src/share/classes/sun/net/www/http/HttpClient.java Wed Jul 27 18:10:10 2011 +0100 @@ -599,7 +599,9 @@ cachedHttpClient = false; if (!failedOnce && requests != null) { failedOnce = true; - if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) { + if (getRequestMethod().equals("CONNECT") || + (httpuc.getRequestMethod().equals("POST") && + (!retryPostProp || streaming))) { // do not retry the request } else { // try once more @@ -706,7 +708,9 @@ } else if (nread != 8) { if (!failedOnce && requests != null) { failedOnce = true; - if (httpuc.getRequestMethod().equals("POST") && (!retryPostProp || streaming)) { + if (getRequestMethod().equals("CONNECT") || + (httpuc.getRequestMethod().equals("POST") && + (!retryPostProp || streaming))) { // do not retry the request } else { closeServer(); @@ -891,6 +895,16 @@ return cacheRequest; } + String getRequestMethod() { + if (requests != null) { + String requestLine = requests.getKey(0); + if (requestLine != null) { + return requestLine.split("\\s+")[0]; + } + } + return ""; + } + @Override protected void finalize() throws Throwable { // This should do nothing. The stream finalizer will
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Mon Jul 25 16:20:39 2011 -0700 +++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jul 27 18:10:10 2011 +0100 @@ -1880,14 +1880,7 @@ private void sendCONNECTRequest() throws IOException { int port = url.getPort(); - // setRequests == true indicates the std. request headers - // have been set in (previous) requests. - // so the first one must be the http method (GET, etc.). - // we need to set it to CONNECT soon, remove this one first. - // otherwise, there may have 2 http methods in headers - if (setRequests) requests.set(0, null, null); - - requests.prepend(HTTP_CONNECT + " " + connectRequestURI(url) + requests.set(0, HTTP_CONNECT + " " + connectRequestURI(url) + " " + httpVersion, null); requests.setIfNotSet("User-Agent", userAgent); @@ -1912,8 +1905,6 @@ } http.writeRequests(requests, null); - // remove CONNECT header - requests.set(0, null, null); } /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsProxyStackOverflow.java Wed Jul 27 18:10:10 2011 +0100 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6670868 + * @summary StackOverFlow with bad authenticated Proxy tunnels + */ + +import java.io.IOException; +import java.io.InputStream; +import java.net.Authenticator; +import java.net.Proxy; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.URL; +import javax.net.ssl.HttpsURLConnection; + +public class HttpsProxyStackOverflow { + + public static void main(String[] args) throws IOException { + BadAuthProxyServer server = startServer(); + doClient(server); + } + + static void doClient(BadAuthProxyServer server) throws IOException { + // url doesn't matter since we will never make the connection + URL url = new URL("https://anythingwilldo/"); + HttpsURLConnection conn = (HttpsURLConnection) url.openConnection( + new Proxy(Proxy.Type.HTTP, + new InetSocketAddress("localhost", server.getPort()))); + try (InputStream is = conn.getInputStream()) { + } catch(IOException unused) { + // no real server, IOException is expected. + // failure if StackOverflowError + } finally { + server.done(); + } + } + + static BadAuthProxyServer startServer() throws IOException { + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication("xyz", "xyz".toCharArray()); + } + }); + + BadAuthProxyServer server = new BadAuthProxyServer(new ServerSocket(0)); + Thread serverThread = new Thread(server); + serverThread.start(); + return server; + } + + static class BadAuthProxyServer implements Runnable { + private ServerSocket ss; + private boolean done; + + BadAuthProxyServer(ServerSocket ss) { this.ss = ss; } + + public void run() { + try { + while (!done) { + Socket s = ss.accept(); + s.getOutputStream().write( + ("HTTP/1.1 407\nProxy-Authenticate:Basic " + + "realm=\"WallyWorld\"\n\n").getBytes("US-ASCII")); + + s.close(); + + s = ss.accept(); + s.close(); + } + } catch (IOException e) { + // Ignore IOException when the main thread calls done + } finally { + try { ss.close(); } catch (IOException e) {} + } + } + + int getPort() { + return ss.getLocalPort(); + } + + void done() { + try { ss.close(); } catch (IOException e) {} + done = true; + } + } +} +