JDK-4323990 : HttpsURLConnection doesn't send Proxy-Authorization on CONNECT
  • Type: Enhancement
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 1.0,1.0.1,1.0.2
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    generic,linux,solaris_2.6,windows_nt generic,linux,solaris_2.6,windows_nt
  • CPU: generic,x86,sparc
  • Submitted: 2000-03-22
  • Updated: 2001-07-09
  • Resolved: 2001-07-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.0 beta2Fixed
Related Reports
Duplicate :  
Description

Name: stC104175			Date: 03/22/2000


Classic VM (build JDK-1.2.1, green threads, mipsjit)


I am trying to make a secure https connection through my company's proxy.  The
proxy requires a name:password authorization.   I have modified your sample
URLReaderWith Options.java from the JSSE to set a "Proxy-Authorization:" header.

The exception that comes back when attempting to connect through the proxy is
from the proxy "402 Authorization Required".

I believe that when HttpsURLConnection.connect() issues the CONNECT GET <URL> to
the proxy initially it must also send a header to read "Proxy-Authorization:
<encoded name:password>".  This doesn't seem to be sent, and I can't see any
option to set the authorization string.

I added these lines to the sample code URLReaderWithOptions:

  
     BASE64Encoder b64Encoder = new BASE64Encoder();

     StringBuffer authStringb = new StringBuffer( "Basic " );
     authStringb.append( b64Encoder.encodeBuffer( "500922:sugartree".getBytes()
) );
     String authString = authStringb.toString();

     // Somehow authString acquires an extra '\n' so chop it off
     authString = authString.substring( 0, authString.length() - 1 );

     conn.setRequestProperty( "Proxy-Authorization", authString );

When I run the program I get:

USAGE: java URLReaderWithOptions [-h proxyhost -p proxyport] [-k
protocolhandlerpkgs] [-c ciphersarray]
d: -h
h: www-proxy.sabre.com
d: -p
p: 80
d: -k
k: com.sun.net.ssl.internal.www.protocol

Exception in thread "main" java.io.IOException: Unable to tunnel through
www-proxy.sabre.com:80.  Proxy return
s "HTTP/1.0 407 Proxy authorization required"
        at
com.sun.net.ssl.internal.www.https.HttpsClient.a([DashoPro-V1.2-120198])
        at
com.sun.net.ssl.internal.www.https.HttpsClient.doConnect([DashoPro-V1.2-120198])
        at
com.sun.net.ssl.internal.www.NetworkClient.openServer([DashoPro-V1.2-120198])
        at
com.sun.net.ssl.internal.www.https.HttpClient.d([DashoPro-V1.2-120198])
        at
com.sun.net.ssl.internal.www.https.HttpClient.<init>([DashoPro-V1.2-120198])
        at
com.sun.net.ssl.internal.www.https.HttpsClient.<init>([DashoPro-V1.2-120198])
        at
com.sun.net.ssl.internal.www.https.HttpsClient.New([DashoPro-V1.2-120198])
        at
com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection.connect([DashoPro
-V1.2-120198])
        at
com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection.getInputStream([D
ashoPro-V1.2-120198
])
        at URLReaderWithOptions.main(URLReaderWithOptions.java:96)

Testing shows that the following is sent to the Proxy:

CONNECT www.verisign.com:443 HTTP/1.0
  User-Agent: Java1.2.1

I believe this should also contain:
Proxy-Authorization:  <authString>
(Review ID: 102231) 
======================================================================

Name: krC82822			Date: 02/06/2001


java version "1.3.0rc3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0rc3-Z)
Java HotSpot(TM) Client VM (build 1.3.0rc3-Z, mixed mode)


1. Set up a proxy server that requires authentication and try running the demo
program SSLSocketClientWithTunneling provided in samples/sockets/client

You will get
java.io.IOException: Unable to tunnel through <proxyIP:port>.  Proxy return
s "HTTP/1.0 407 Proxy Authentication Required"
        at SSLSocketClientWithTunneling.doTunnelHandshake(SSLSocketClientWithTun
neling.java:148)
        at SSLSocketClientWithTunneling.doIt(SSLSocketClientWithTunneling.java:4
7)
        at SSLSocketClientWithTunneling.main(SSLSocketClientWithTunneling.java:3
4)

2. Bug in the source code in
com/sun/net/ssl/internal/www/protocol/https/HttpsClient.java
line 128 (in the decompiled version)

        String s1 = "CONNECT " + s + ":" + j + " HTTP/1.0\n" + "User-Agent: " +
HttpURLConnection.userAgent + "\r\n\r\n";


line: 172
        if(!s2.startsWith("HTTP/1.0 200"))
            throw new IOException("Unable to tunnel through " + g + ":" + h
+ ".  Proxy returns \"" + s2 + "\"");

3.
java.io.IOException: Unable to tunnel through <Proxyhost:proxyport>.  Proxy
return
s "HTTP/1.0 407 Proxy Authentication Required"
        at SSLSocketClientWithTunneling.doTunnelHandshake(SSLSocketClientWithTun
neling.java:148)
        at SSLSocketClientWithTunneling.doIt(SSLSocketClientWithTunneling.java:4
7)
        at SSLSocketClientWithTunneling.main(SSLSocketClientWithTunneling.java:3
(Review ID: 109110)
======================================================================

Name: krC82822			Date: 03/23/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)


I have made changes to the sample URLReaderWithOptions.java code
to get through our firewall/proxy server.  It requires a userid:password.
I have set this up using BASE64encode, and have gotten it to work
with http://www.sun.com.  The problem is that it does not work
when connecting to https://www.sun.com.  Whenever I try to connect
to any secure site, it doesn't work.  The response from my firewall
is an error 407 Proxy Authentication Required.  The following is a
snippet from the sample code as I have changed it.


HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty("Proxy-Authorization", "Basic " + auth);


I put an IP sniffer on my machine, and I can see that the
Proxy-Authorization token/parameter is NOT being sent when
attempting connection to an https site.  In this vein, I tried
adding another setRequestProperty(), and did not see this
token being passed, either.

I don't think its a fundamental problem with JSSE, as I was
able to change the SSLSocketClientWithTunneling.java sample
and make it work.  All I had to do was add the appropriate
"Proxy-Authorization:" token to the "CONNECT" statement in the
doTunnelHandshake method.
(Review ID: 119406)
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: ventura FIXED IN: merlin-beta2 INTEGRATED IN: merlin-beta2
02-09-2004

WORK AROUND The work around involves some work for the API user. One can add support for proxy auth by writing a tunneling code, as illustrated in the JSSE sample program SSLSocketClientWithTunneling.java. This sample program does not handle proxy auth, but can be extended to support proxy auth. jayalaxmi.hangal@Eng 2001-03-19 Name: krC82822 Date: 03/23/2001 None that I can think of, except use SSL Sockets and not HttpsURLConnections. (Review ID: 119406) ======================================================================
02-09-2004

EVALUATION We should do similar things in Https.doTunnelHandshake() for proxy auth as we did in HttpURLConnection. yingxian.wang@eng 2001-03-01 This involves handling proxy authorization in HttpsClient.doTunnelHandshake method. CONNECT method's request and response processing will have to be modified to include support for proxy auth. This is enhancement of the feature for CONNECT handling rather than a bug fix. jayalaxmi.hangal@Eng 2001-03-19
19-03-2001