Custom ProtocolSocketFactory not being used

View: New views
5 Messages — Rating Filter:   Alert me  

Custom ProtocolSocketFactory not being used

by Ian Pilcher :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I am following the instructions at
http://hc.apache.org/httpclient-3.x/sslguide.html to connect to a server
whose certificate is signed by an internal certificate authority (CA).
I've created my own implementation of SecureProtocolSocketFactory, and
I've verified that the SSLSockets it creates can successfully handshake
with the server.

I cannot figure out, however, how to get HttpClient to actually use my
factory.  I've tried all of the methods suggested in the HttpClient SSL
Guide:

  - registering my factory as the factory for https

  - registering my factory as the factory for a different protocol and
    using that protocol in my URL

  - httpclient.getHostConfiguration().setHost(...)

None of these techniques has any effect.  I've added a println at the
beginning of all of the createSocket methods in my factory, and I can
see that none of them is being called.

What am I missing?

Thanks!

--
========================================================================
Ian Pilcher                                         arequipeno@...
========================================================================

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@...
For additional commands, e-mail: httpclient-users-help@...


Re: Custom ProtocolSocketFactory not being used

by Olindo Pindaro-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi, ian, i had your same problem and i used succssfuly a "fake" (as yours)
class that works well.

Do you want it?

Bye
Olindo

2009/6/23 Ian Pilcher <arequipeno@...>

> I am following the instructions at
> http://hc.apache.org/httpclient-3.x/sslguide.html to connect to a server
> whose certificate is signed by an internal certificate authority (CA).
> I've created my own implementation of SecureProtocolSocketFactory, and
> I've verified that the SSLSockets it creates can successfully handshake
> with the server.
>
> I cannot figure out, however, how to get HttpClient to actually use my
> factory.  I've tried all of the methods suggested in the HttpClient SSL
> Guide:
>
>  - registering my factory as the factory for https
>
>  - registering my factory as the factory for a different protocol and
>    using that protocol in my URL
>
>  - httpclient.getHostConfiguration().setHost(...)
>
> None of these techniques has any effect.  I've added a println at the
> beginning of all of the createSocket methods in my factory, and I can
> see that none of them is being called.
>
> What am I missing?
>
> Thanks!
>
> --
> ========================================================================
> Ian Pilcher                                         arequipeno@...
> ========================================================================
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@...
> For additional commands, e-mail: httpclient-users-help@...
>
>


--
Olindo Pindaro
http://www.linkedin.com/in/olindopindaro
+39 3939455830

Re: Custom ProtocolSocketFactory not being used

by Ian Pilcher :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Olindo Pindaro wrote:
> Hi, ian, i had your same problem and i used succssfuly a "fake" (as yours)
> class that works well.

After I posted my question, I found this
http://marc.info/?l=jakarta-commons-user&m=111996432020654&w=2.  I have
found that I can get my ProtocolSocketFactory to be used if I use my own
protocol name in *both* the Protocol constructor and registerProtocol:

    Protocol.registerProtocol("foo", new Protocol("foo",
            MyProtocolSocketFactory.getInstance(), port));

I still haven't found a way to use my own ProtocolSocketFactory for
"https" URLs.

Anyone?

Thanks!

--
========================================================================
Ian Pilcher                                         arequipeno@...
========================================================================

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@...
For additional commands, e-mail: httpclient-users-help@...


Re: Custom ProtocolSocketFactory not being used

by Olindo Pindaro-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This is the "fake" class.


/*
 * $HeadURL$
 * $Revision: 1.1 $
 * $Date: 2009/03/27 16:26:22 $
 *
 * ====================================================================
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.commons.httpclient.contrib.ssl;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>
 * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s
 * that accept self-signed certificates.
 * </p>
 * <p>
 * This socket factory SHOULD NOT be used for productive systems
 * due to security reasons, unless it is a concious decision and
 * you are perfectly aware of security implications of accepting
 * self-signed certificates
 * </p>
 *
 * <p>
 * Example of using custom protocol socket factory for a specific host:
 *     <pre>
 *     Protocol easyhttps = new Protocol("https", new
EasySSLProtocolSocketFactory(), 443);
 *
 *     URI uri = new URI("https://localhost/", true);
 *     // use relative url only
 *     GetMethod httpget = new GetMethod(uri.getPathQuery());
 *     HostConfiguration hc = new HostConfiguration();
 *     hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
 *     HttpClient client = new HttpClient();
 *     client.executeMethod(hc, httpget);
 *     </pre>
 * </p>
 * <p>
 * Example of using custom protocol socket factory per default instead
of the standard one:
 *     <pre>
 *     Protocol easyhttps = new Protocol("https", new
EasySSLProtocolSocketFactory(), 443);
 *     Protocol.registerProtocol("https", easyhttps);
 *
 *     HttpClient client = new HttpClient();
 *     GetMethod httpget = new GetMethod("https://localhost/");
 *     client.executeMethod(httpget);
 *     </pre>
 * </p>
 *
 * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
 *
 * <p>
 * DISCLAIMER: HttpClient developers DO NOT actively support this component.
 * The component is provided as a reference material, which may be inappropriate
 * for use without additional customization.
 * </p>
 */

public class EasySSLProtocolSocketFactory implements
SecureProtocolSocketFactory {

    /** Log object for this class. */
    private static final Log LOG =
LogFactory.getLog(EasySSLProtocolSocketFactory.class);

    private SSLContext sslcontext = null;

    /**
     * Constructor for EasySSLProtocolSocketFactory.
     */
    public EasySSLProtocolSocketFactory() {
        super();
    }

    private static SSLContext createEasySSLContext() {
        try {
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(
              null,
              new TrustManager[] {new EasyX509TrustManager(null)},
              null);
            return context;
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            throw new HttpClientError(e.toString());
        }
    }

    private SSLContext getSSLContext() {
        if (this.sslcontext == null) {
            this.sslcontext = createEasySSLContext();
        }
        return this.sslcontext;
    }

    /**
     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
     */
    public Socket createSocket(
        String host,
        int port,
        InetAddress clientHost,
        int clientPort)
        throws IOException, UnknownHostException {

        return getSSLContext().getSocketFactory().createSocket(
            host,
            port,
            clientHost,
            clientPort
        );
    }

    /**
     * Attempts to get a new socket connection to the given host
within the given time limit.
     * <p>
     * To circumvent the limitations of older JREs that do not support
connect timeout a
     * controller thread is executed. The controller thread attempts
to create a new socket
     * within the given limit of time. If socket constructor does not
return until the
     * timeout expires, the controller terminates and throws an {@link
ConnectTimeoutException}
     * </p>
     *
     * @param host the host name/IP
     * @param port the port on the host
     * @param clientHost the local host name/IP to bind the socket to
     * @param clientPort the port on the local machine
     * @param params {@link HttpConnectionParams Http connection parameters}
     *
     * @return Socket a new socket
     *
     * @throws IOException if an I/O error occurs while creating the socket
     * @throws UnknownHostException if the IP address of the host cannot be
     * determined
     */
    public Socket createSocket(
        final String host,
        final int port,
        final InetAddress localAddress,
        final int localPort,
        final HttpConnectionParams params
    ) throws IOException, UnknownHostException, ConnectTimeoutException {
        if (params == null) {
            throw new IllegalArgumentException("Parameters may not be null");
        }
        int timeout = params.getConnectionTimeout();
        SocketFactory socketfactory = getSSLContext().getSocketFactory();
        if (timeout == 0) {
            return socketfactory.createSocket(host, port,
localAddress, localPort);
        } else {
            Socket socket = socketfactory.createSocket();
            SocketAddress localaddr = new
InetSocketAddress(localAddress, localPort);
            SocketAddress remoteaddr = new InetSocketAddress(host, port);
            socket.bind(localaddr);
            socket.connect(remoteaddr, timeout);
            return socket;
        }
    }

    /**
     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
     */
    public Socket createSocket(String host, int port)
        throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(
            host,
            port
        );
    }

    /**
     * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
     */
    public Socket createSocket(
        Socket socket,
        String host,
        int port,
        boolean autoClose)
        throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(
            socket,
            host,
            port,
            autoClose
        );
    }

    public boolean equals(Object obj) {
        return ((obj != null) &&
obj.getClass().equals(EasySSLProtocolSocketFactory.class));
    }

    public int hashCode() {
        return EasySSLProtocolSocketFactory.class.hashCode();
    }

}

And this is how use it:


package jpuzzle2.webdav.exchange;

import jpuzzle2.webdav.mail.ServerParameters;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;

public class ExchangeServerParameters extends ServerParameters {
       
        Protocol myhttps;
        Credentials creds;
       
        public ExchangeServerParameters(boolean isSecure, int port, String
username, String pass, String domain) {
                this.myhttps=new Protocol(
                                "https",
                                new EasySSLProtocolSocketFactory(), port);
                this.creds=new org.apache.commons.httpclient.NTCredentials(
                                username, pass,"localhost",domain);
               
                //this.creds=new
org.apache.commons.httpclient.UsernamePasswordCredentials(username,
pass);
        }
       
        public HttpClient HttpClientFactory() {
                Protocol.registerProtocol("https", myhttps);
                HttpClient httpclient = new HttpClient();
                httpclient.getState().setCredentials(AuthScope.ANY, creds);
                httpclient.getHostConfiguration().setHost("zuexc0035v.zerouno.loc",
443, myhttps);
                return httpclient;
        }

}

bye
Olindo

2009/6/23 Ian Pilcher <arequipeno@...>:

> Olindo Pindaro wrote:
>> Hi, ian, i had your same problem and i used succssfuly a "fake" (as yours)
>> class that works well.
>
> After I posted my question, I found this
> http://marc.info/?l=jakarta-commons-user&m=111996432020654&w=2.  I have
> found that I can get my ProtocolSocketFactory to be used if I use my own
> protocol name in *both* the Protocol constructor and registerProtocol:
>
>    Protocol.registerProtocol("foo", new Protocol("foo",
>            MyProtocolSocketFactory.getInstance(), port));
>
> I still haven't found a way to use my own ProtocolSocketFactory for
> "https" URLs.
>
> Anyone?
>
> Thanks!
>
> --
> ========================================================================
> Ian Pilcher                                         arequipeno@...
> ========================================================================
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@...
> For additional commands, e-mail: httpclient-users-help@...
>
>



--
Olindo Pindaro
http://www.linkedin.com/in/olindopindaro
+39 3939455830

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@...
For additional commands, e-mail: httpclient-users-help@...


Re: Custom ProtocolSocketFactory not being used

by olegk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Jun 22, 2009 at 07:42:15PM -0500, Ian Pilcher wrote:

> I am following the instructions at
> http://hc.apache.org/httpclient-3.x/sslguide.html to connect to a server
> whose certificate is signed by an internal certificate authority (CA).
> I've created my own implementation of SecureProtocolSocketFactory, and
> I've verified that the SSLSockets it creates can successfully handshake
> with the server.
>
> I cannot figure out, however, how to get HttpClient to actually use my
> factory.  I've tried all of the methods suggested in the HttpClient SSL
> Guide:
>
>   - registering my factory as the factory for https
>a

This should work.
 
>   - registering my factory as the factory for a different protocol and
>     using that protocol in my URL
>

This should work as well.


>   - httpclient.getHostConfiguration().setHost(...)
>

Make sure to use relative URIs for HTTP requests when using this approach.

Oleg


> None of these techniques has any effect.  I've added a println at the
> beginning of all of the createSocket methods in my factory, and I can
> see that none of them is being called.
>
> What am I missing?
>
> Thanks!
>
> --
> ========================================================================
> Ian Pilcher                                         arequipeno@...
> ========================================================================
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@...
> For additional commands, e-mail: httpclient-users-help@...
>

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@...
For additional commands, e-mail: httpclient-users-help@...