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]

Reply via email to