Hi Oleg,
I am using Sun's default provider.
I have a sample code that does http tunnelling with basic auth, Can you please
help me where to make changes so that it does NTLM auth and https tunnelling. I
am learning NTLM a lot these days.
I am sending the sample code too.
many many thanks
Pavan
----- Original Message -----
From: "Oleg Kalnichevski" <[EMAIL PROTECTED]>
To: "HttpClient User Discussion" <[email protected]>
Subject: Re: https tunnelling with NTLM+Proxy
Date: Tue, 14 Jun 2005 10:51:11 +0200
>
> On Tue, Jun 14, 2005 at 03:35:54PM +0800, pavan kumar wrote:
> > Hi All,
> >
> >
> > Does Apache's HttpClient 3.0 support Https Tunnelling over Proxy
> > with NTLM. ( I am using MSProxy2.0 on win2k server).
> >
>
> Yes, it does
>
>
> > Can some one throw light on that?
> > Is jdk1.3 compatibale with Apache's HttpClient 3.0
> >
>
> What provider? IBM? Sun? HttpClient is compatible with Java 1.2 or
> above. However, Sun JSSE 1.0.3 is known to have problems, so it is
> highly recommended to upgrade to Java 1.4 when using SSL
>
> http://jakarta.apache.org/commons/httpclient/3.0/sslguide.html#Known%20limitations%20and%20problems
>
> Hope this helps
>
> Oleg
>
>
> > Thanks in advance Pavan
> >
> >
> > -- _______________________________________________
> > Get your free email from http://www.dellmail.com
> >
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
import java.net.*;
import java.io.*;
import java.security.*;
import sun.misc.BASE64Encoder;
import javax.net.*;
import javax.net.ssl.*;
/*
* This example is based on JavaWorld Tip 111. Thanks to Pua Yeow Cheong for
writing it.
* It tunnels through a proxy using the Https protocol.
* Thanks go to David Lord in the java forums for figuring out the main
problem with Tip 111
* PLEASE NOTE: You need to have the JSSE 1.0.2 jars installed for this to work
*/
/**
* Downloads contents of a URL, using Proxy Tunneling and Basic Authentication
*/
public class URLReader {
/**
* The main program for the URLReader class
*/
public static void main(String[] args) throws Exception {
//set up strings for use in app. Change these to your own settings
String proxyPassword ="chn_Kjagad";
String proxyUsername = "password123";
String proxyHost = "10.132.58.182";
String proxyPort = "80";
String connectionURL = "https://www.verisign.com";
//set up system properties to indicate we are using a proxy
System.setProperty("https.proxyHost", proxyHost);
System.setProperty("https.proxyPort", proxyPort);
System.setProperty("proxyHost", proxyHost);
System.setProperty("proxyPort", proxyPort);
System.setProperty("proxySet", "true");
System.setProperty("http.proxyHost", proxyHost);
System.setProperty("http.proxyPort", proxyPort);
System.setProperty("http.proxySet", "true");
//set up handler for jsse
System.setProperty("java.protocol.handler.pkgs",
"com.sun.net.ssl.internal.www.protocol");
java.security.Provider prov = new
com.sun.net.ssl.internal.ssl.Provider();
Security.addProvider(prov);
//create the connection
// URL myURL = new URL(connectionURL);
URL myURL = new URL(null,connectionURL,new
com.sun.net.ssl.internal.www.protocol.https.Handler());
URLConnection myConnection = myURL.openConnection();
if (myConnection instanceof com.sun.net.ssl.HttpsURLConnection) {
((com.sun.net.ssl.HttpsURLConnection)
myConnection).setSSLSocketFactory(new
SSLTunnelSocketFactory(System.getProperty("proxyHost"),
System.getProperty("proxyPort")));
}
myConnection.setDoInput(true);
myConnection.setDoOutput(true);
BufferedReader in;
try {
System.err.println("opening Input stream1");
in = new BufferedReader(
new InputStreamReader(
myConnection.getInputStream()));
String inputLine;
System.err.println("Input stream is Open1");
while ((inputLine = in.readLine()) != null) {
System.err.println(inputLine);
}
in.close();
System.err.println("Input stream is Closed1");
} catch (Exception e) {
e.printStackTrace(System.err);
String tmp = e.getMessage().toLowerCase().trim();
System.err.println("tmp *" + tmp + "*");
if (tmp.indexOf("http") > -1) {
//http error message to be parsed
tmp = tmp.substring(tmp.indexOf("http")).trim();
System.err.println("tmp *" + tmp + "*");
tmp = tmp.substring(8).trim();
System.err.println("tmp *" + tmp + "*");
if (tmp.startsWith("407")) {
//proxy authentication required
myURL = new URL(connectionURL);
myConnection = myURL.openConnection();
if (myConnection instanceof
com.sun.net.ssl.HttpsURLConnection) {
((com.sun.net.ssl.HttpsURLConnection)
myConnection).setSSLSocketFactory(new
SSLTunnelSocketFactory(System.getProperty("proxyHost"),
System.getProperty("proxyPort"), proxyUsername, proxyPassword));
}
myConnection.setDoInput(true);
myConnection.setDoOutput(true);
try {
System.err.println("opening Input stream 2");
in = new BufferedReader(
new InputStreamReader(
myConnection.getInputStream()));
String inputLine;
System.err.println("Input stream is Open 2");
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
in.close();
System.err.println("Input stream is closed 2");
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace(System.err);
}
}
}
}
}
}
/**
* SSLSocket used to tunnel through a proxy
*/
class SSLTunnelSocketFactory extends SSLSocketFactory {
private String tunnelHost;
private int tunnelPort;
private SSLSocketFactory dfactory;
private String tunnelPassword;
private String tunnelUserName;
private boolean socketConnected = false;
private int falsecount = 0;
/**
* Constructor for the SSLTunnelSocketFactory object
*
[EMAIL PROTECTED] proxyHost The url of the proxy host
[EMAIL PROTECTED] proxyPort the port of the proxy
*/
public SSLTunnelSocketFactory(String proxyHost, String proxyPort) {
System.err.println("creating Socket Factory");
tunnelHost = proxyHost;
tunnelPort = Integer.parseInt(proxyPort);
dfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
}
/**
* Constructor for the SSLTunnelSocketFactory object
*
[EMAIL PROTECTED] proxyHost The url of the proxy host
[EMAIL PROTECTED] proxyPort the port of the proxy
[EMAIL PROTECTED] proxyUserName username for authenticating with the
proxy
[EMAIL PROTECTED] proxyPassword password for authenticating with the
proxy
*/
public SSLTunnelSocketFactory(String proxyHost, String proxyPort, String
proxyUserName, String proxyPassword) {
System.err.println("creating Socket Factory with password/username");
tunnelHost = proxyHost;
tunnelPort = Integer.parseInt(proxyPort);
tunnelUserName = proxyUserName;
tunnelPassword = proxyPassword;
dfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
}
/**
* Sets the proxyUserName attribute of the SSLTunnelSocketFactory object
*
[EMAIL PROTECTED] proxyUserName The new proxyUserName value
*/
public void setProxyUserName(String proxyUserName) {
tunnelUserName = proxyUserName;
}
/**
* Sets the proxyPassword attribute of the SSLTunnelSocketFactory object
*
[EMAIL PROTECTED] proxyPassword The new proxyPassword value
*/
public void setProxyPassword(String proxyPassword) {
tunnelPassword = proxyPassword;
}
/**
* Gets the supportedCipherSuites attribute of the SSLTunnelSocketFactory
* object
*
[EMAIL PROTECTED] The supportedCipherSuites value
*/
public String[] getSupportedCipherSuites() {
return dfactory.getSupportedCipherSuites();
}
/**
* Gets the defaultCipherSuites attribute of the SSLTunnelSocketFactory
* object
*
[EMAIL PROTECTED] The defaultCipherSuites value
*/
public String[] getDefaultCipherSuites() {
return dfactory.getDefaultCipherSuites();
}
/**
* Gets the socketConnected attribute of the SSLTunnelSocketFactory object
*
[EMAIL PROTECTED] The socketConnected value
*/
public synchronized boolean getSocketConnected() {
return socketConnected;
}
/**
* Creates a new SSL Tunneled Socket
*
[EMAIL PROTECTED] s Ignored
[EMAIL PROTECTED] host destination host
[EMAIL PROTECTED] port destination port
[EMAIL PROTECTED] autoClose wether to close the socket
automaticly
[EMAIL PROTECTED] proxy tunneled socket
[EMAIL PROTECTED] IOException raised by an IO error
[EMAIL PROTECTED] UnknownHostException raised when the host is unknown
*/
public Socket createSocket(Socket s, String host, int port, boolean
autoClose)
throws IOException, UnknownHostException {
Socket tunnel = new Socket(tunnelHost, tunnelPort);
doTunnelHandshake(tunnel, host, port);
SSLSocket result = (SSLSocket) dfactory.createSocket(tunnel, host,
port, autoClose);
result.addHandshakeCompletedListener(
new HandshakeCompletedListener() {
public void handshakeCompleted(HandshakeCompletedEvent event) {
System.out.println("Handshake Finished!");
System.out.println("\t CipherSuite :" +
event.getCipherSuite());
System.out.println("\t SessionId: " + event.getSession());
System.out.println("\t PeerHost: " +
event.getSession().getPeerHost());
setSocketConnected(true);
}
});
// thanks to David Lord in the java forums for figuring out this line
is the problem
// result.startHandshake(); //this line is the bug which stops Tip111
from working correctly
return result;
}
/**
* Creates a new SSL Tunneled Socket
*
[EMAIL PROTECTED] host destination host
[EMAIL PROTECTED] port destination port
[EMAIL PROTECTED] tunneled SSL Socket
[EMAIL PROTECTED] IOException raised by IO error
[EMAIL PROTECTED] UnknownHostException raised when the host is unknown
*/
public Socket createSocket(String host, int port)
throws IOException, UnknownHostException {
return createSocket(null, host, port, true);
}
/**
* Creates a new SSL Tunneled Socket
*
[EMAIL PROTECTED] host Destination Host
[EMAIL PROTECTED] port Destination Port
[EMAIL PROTECTED] clientHost Ignored
[EMAIL PROTECTED] clientPort Ignored
[EMAIL PROTECTED] SSL Tunneled Socket
[EMAIL PROTECTED] IOException Raised when IO error occurs
[EMAIL PROTECTED] UnknownHostException Raised when the destination host
is
* unknown
*/
public Socket createSocket(String host, int port, InetAddress clientHost,
int clientPort)
throws IOException, UnknownHostException {
return createSocket(null, host, port, true);
}
/**
* Creates a new SSL Tunneled Socket
*
[EMAIL PROTECTED] host destination host
[EMAIL PROTECTED] port destination port
[EMAIL PROTECTED] tunneled SSL Socket
[EMAIL PROTECTED] IOException raised when IO error occurs
*/
public Socket createSocket(InetAddress host, int port)
throws IOException {
return createSocket(null, host.getHostName(), port, true);
}
/**
* Creates a new SSL Tunneled Socket
*
[EMAIL PROTECTED] address destination host
[EMAIL PROTECTED] port destination port
[EMAIL PROTECTED] clientAddress ignored
[EMAIL PROTECTED] clientPort ignored
[EMAIL PROTECTED] tunneled SSL Socket
[EMAIL PROTECTED] IOException raised when IO exception occurs
*/
public Socket createSocket(InetAddress address, int port,
InetAddress clientAddress, int clientPort)
throws IOException {
return createSocket(null, address.getHostName(), port, true);
}
/**
* Sets the socketConnected attribute of the SSLTunnelSocketFactory object
*
[EMAIL PROTECTED] b The new socketConnected value
*/
private synchronized void setSocketConnected(boolean b) {
socketConnected = b;
}
/**
* Description of the Method
*
[EMAIL PROTECTED] tunnel tunnel socket
[EMAIL PROTECTED] host destination host
[EMAIL PROTECTED] port destination port
[EMAIL PROTECTED] IOException raised when an IO error occurs
*/
private void doTunnelHandshake(Socket tunnel, String host, int port) throws
IOException {
OutputStream out = tunnel.getOutputStream();
//generate connection string
String msg = "CONNECT " + host + ":" + port + " HTTP/1.0\n"
+ "User-Agent: "
+ sun.net.www.protocol.http.HttpURLConnection.userAgent;
if (tunnelUserName != null && tunnelPassword != null) {
//add basic authentication header for the proxy
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
String encodedPassword = enc.encode((tunnelUserName + ":" +
tunnelPassword).getBytes());
msg = msg + "\nProxy-Authorization: Basic " + encodedPassword;
}
msg = msg + "\nContent-Length: 0";
msg = msg + "\nPragma: no-cache";
msg = msg + "\r\n\r\n";
System.err.println(msg);
byte b[];
try {
//we really do want ASCII7 as the http protocol doesnt change with
locale
b = msg.getBytes("ASCII7");
} catch (UnsupportedEncodingException ignored) {
//If ASCII7 isn't there, something is seriously wrong!
b = msg.getBytes();
}
out.write(b);
out.flush();
byte reply[] = new byte[200];
int replyLen = 0;
int newlinesSeen = 0;
boolean headerDone = false;
InputStream in = tunnel.getInputStream();
boolean error = false;
while (newlinesSeen < 2) {
int i = in.read();
System.out.print((char)i);
if (i < 0) {
throw new IOException("Unexpected EOF from Proxy");
}
if (i == '\n') {
headerDone = true;
++newlinesSeen;
} else
if (i != '\r') {
newlinesSeen = 0;
if (!headerDone && replyLen < reply.length) {
reply[replyLen++] = (byte) i;
}
}
}
//convert byte array to string
String replyStr;
try {
replyStr = new String(reply, 0, replyLen, "ASCII7");
} catch (UnsupportedEncodingException ignored) {
replyStr = new String(reply, 0, replyLen);
}
System.out.println("Reply String : " + replyStr);
//we check for connection established because our proxy returns
http/1.1 instead of 1.0
if (replyStr.toLowerCase().indexOf("200 connection established") == -1)
{
System.err.println(replyStr);
throw new IOException("Unable to tunnel through " + tunnelHost +
":" + tunnelPort + ". Proxy returns\"" + replyStr + "\"");
}
//tunneling hanshake was successful
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]