⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractvpnclient.java

📁 这是linux下ssl vpn的实现程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 *  SSL-Explorer
 *
 *  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2 of
 *  the License, or (at your option) any later version.
 *  This program 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 for more details.
 *
 *  You should have received a copy of the GNU General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
			
package com.sslexplorer.vpn.base;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

import com.maverick.crypto.security.SecureRandom;
import com.maverick.http.AuthenticationCancelledException;
import com.maverick.http.AuthenticationPrompt;
import com.maverick.http.ConnectMethod;
import com.maverick.http.GetMethod;
import com.maverick.http.HttpClient;
import com.maverick.http.HttpException;
import com.maverick.http.HttpMethod;
import com.maverick.http.HttpResponse;
import com.maverick.http.PasswordCredentials;
import com.maverick.http.URLDecoder;
import com.maverick.http.UnsupportedAuthenticationException;
import com.maverick.multiplex.Channel;
import com.maverick.multiplex.ChannelFactory;
import com.maverick.multiplex.ChannelListener;
import com.maverick.multiplex.MultiplexedConnection;
import com.maverick.multiplex.SocketChannel;
import com.maverick.ssl.SSLException;
import com.sslexplorer.vpn.util.IOStreamConnectorListener;
import com.sslexplorer.vpn.util.Tunnel;
import com.sslexplorer.vpn.util.URI;
import com.sslexplorer.vpn.util.XMLElement;

/**
 * An abstract class to provide the common features of the SSL-Explorer VPN
 * Client. When a user wants to tunnel through the gateway they must first
 * register a tunnel using
 * {@link registerApplicationTunnel(String, String, int)}. The client returns
 * an {@link ApplicationTunnel} which can be used to obtain a Socket with
 * {@link createTunnel(ApplicationTunnel)}.
 * 
 * @author Lee David Painter
 * @version $Revision: 1.52 $
 */
public abstract class AbstractVPNClient implements ChannelListener /*
                                                                     * THIS
                                                                     * BREAKS
                                                                     * THE
                                                                     * EMBEDDED
                                                                     * VPN
                                                                     * CLIENT
                                                                     * ,AuthenticationPrompt
                                                                     */{

    /** The lowest possible random port to select * */
    public final int LOWEST_RANDOM_PORT = 49152;

    /** The highest possible random port to select * */
    public final int HIGHEST_RANDOM_PORT = 65535;

    /** The collection of active socket listeners * */
    protected Hashtable activeListeners = new Hashtable();

    /** The hostname of the SSL-Explorer proxy * */
    protected String sslexplorerHostname;
    /** The port of the SSL-Explorer proxy * */
    protected int sslexplorerPort;
    /** The username for this session * */
    protected String username;
    /** The VPN client ticket for an authenticated session * */
    protected String ticket;

    /** The hostname of the local HTTPS proxy server * */
    protected URI localProxyURL;

    /** The active application tunnels * */
    protected Vector activeApplicationTunnels = new Vector();
    /** All local forwarding tunnels * */
    protected Vector forwardingTunnels = new Vector();
    /** The remote listeners * */
    protected Hashtable remoteListeners = new Hashtable();
    /** All registered tunnels by ticket * */
    protected Hashtable registeredListeningSockets = new Hashtable();
    /** All remote forwarding tunnels * */
    protected Vector remoteTunnels = new Vector();
    /** The active forwarding tunnels * */
    protected Vector activeForwardingTunnels = new Vector();
    /** The active direct tunnels (i.e. no listening sockets)* */
    protected Hashtable activeDirectTunnels = new Hashtable();
    /** We store all the available proxy information here * */
    protected static Hashtable proxiesIE = new Hashtable();
    /** We store all the local bypass addresses here * */
    protected static Vector proxyBypassIE = new Vector();

    protected static Hashtable proxiesFF = new Hashtable();

    protected static Vector proxyBypassFF = new Vector();
    /** HttpClient instances are cached * */
    protected HttpClient client;

    protected String defaultProxyHost;
    protected int defaultProxyPort = 80;
    protected PasswordCredentials defaultProxyCredentials;
    protected String defaultProxyPreferredAuthentication;
    protected boolean autoDetectProxies = true;
    protected AuthenticationPrompt defaultProxyAuthenticationPrompt;
    protected int defaultProxyType = HttpClient.PROXY_HTTP;

    // #ifdef DEBUG
    org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(AbstractVPNClient.class);

    // #endif
    
    static {
        HttpClient.setUserAgent("SSL-Explorer/Agent"); 
    }

    public AbstractVPNClient() {
    }

    /**
     * Initializes the abstract client with the SSL-Explorer servers host
     * details, the user's name and the authenticated ticket for this session.
     * 
     * @param sslexplorerHostname String
     * @param proxyPort int
     * @param username String
     * @param ticket String
     */
    public void init(String sslexplorerHostname, int sslexplorerPort, String username, String ticket) {

        this.sslexplorerHostname = sslexplorerHostname;
        this.sslexplorerPort = sslexplorerPort;
        this.username = username;
        this.ticket = ticket;
    }

    /**
     * Set the URL of the HTTPS proxy server to use for all outgoing connections
     * 
     * @param localProxyURL local proxy URL
     */
    public void setLocalProxyURL(String localProxyURL) throws URI.MalformedURIException {
        this.localProxyURL = new URI(localProxyURL);

        // FIXME What about HttpsURLConnection?
    }

    /**
     * Get the hostname of the SSL-Explorer proxy
     * 
     * @return
     */
    public String getSSLExplorerHost() {
        return sslexplorerHostname;
    }

    /**
     * Get the port of the SSL-Explorer proxy
     * 
     * @return
     */
    public int getSSLExplorerPort() {
        return sslexplorerPort;
    }

    /**
     * Get the username for this session
     * 
     * @return
     */
    public String getUsername() {
        return username;
    }

    /**
     * Get the authenticated VPN client ticket for this session
     * 
     * @return
     */
    public String getTicket() {
        return ticket;
    }

    public void configureProxy() {

        // Configure local proxy support
        if (localProxyURL != null && !localProxyURL.equals("")) {
            // #ifdef DEBUG
            log.info("Configuring HTTP proxy to " + obfuscateURL(localProxyURL.toString()));
            // #endif
            String userInfo = localProxyURL.getUserinfo();
            String user = "";
            String password = "";
            if (userInfo != null && !userInfo.equals("")) {
                int idx = userInfo.indexOf(':');
                user = URLDecoder.decode(userInfo);
                if (idx != -1) {
                    password = URLDecoder.decode(userInfo.substring(idx + 1));
                    user = URLDecoder.decode(userInfo.substring(0, idx));
                }
            }
            int port = localProxyURL.getPort();
            setDefaultProxyType(localProxyURL.getScheme().equals("https") ? HttpClient.PROXY_HTTPS : HttpClient.PROXY_HTTP);
            setDefaultProxyHost(localProxyURL.getHost());
            setDefaultProxyPort(port == -1 ? 80 : port);
            if (!user.equals("")) {
                setDefaultProxyCredentials(new PasswordCredentials(user, password));
            }
            if (localProxyURL.getQueryString() != null) {
                setDefaultProxyPreferredAuthentication(localProxyURL.getQueryString());
            }
        }
    }

    public synchronized HttpClient getHttpClient() {
        if (client == null) {
            // #ifdef DEBUG
            log.info("Creating HttpClient instance");
            // #endif
            client = new HttpClient(sslexplorerHostname, sslexplorerPort, true);
            if (defaultProxyHost != null && !defaultProxyHost.equals("")) {
                // #ifdef DEBUG
                log.info("Configuring proxies for HttpClient instance");
                // #endif
                client.setProxyAuthenticationPrompt(defaultProxyAuthenticationPrompt);
                client.setProxyHost(defaultProxyHost);
                client.setProxyPort(defaultProxyPort);
                client.setProxyType(defaultProxyType);
                if (defaultProxyCredentials != null && defaultProxyCredentials.getUsername() != null
                                && !defaultProxyCredentials.getUsername().equals("")) {
                    /**
                     * LDP - This used to set preemptive authentication but its causing problems with
                     * NTLM
                     */
                    client.setProxyCredentials(defaultProxyCredentials);
                }
                client.setProxyPreferedAuthentication("AUTO".equalsIgnoreCase(defaultProxyPreferredAuthentication) ? null
                                : defaultProxyPreferredAuthentication);
            }
        }

        return client;
    }

    /**
     * Register an application tunnel; this is typically used where an
     * application can utilize the Input/OutputStreams of a tunnel. This removes
     * the need for opening a seperate listening socket.
     * 
     * @param name
     * @param hostToConnect
     * @param portToConnect
     * @return
     * @throws IOException
     * @throws UnsupportedAuthenticationException
     * @throws HttpException
     */
    public Tunnel registerApplicationTunnel(String name, String hostToConnect, int portToConnect) throws IOException,
                    HttpException, UnsupportedAuthenticationException, AuthenticationCancelledException {
        // #ifdef DEBUG
        log.info("Registering application tunnel " + name + " host=" + hostToConnect + ":" + portToConnect);
        // #endif

        HttpClient client = getHttpClient();
        GetMethod get = new GetMethod("/registerListeningSocket.do");
        get.setParameter("sourcePort", String.valueOf(portToConnect));
        get.setParameter("destinationHost", hostToConnect);
        get.setParameter("destinationPort", String.valueOf(portToConnect));
        get.setParameter("allowExternalHosts", "false");
        get.setParameter("ticket", ticket);

        HttpResponse response = null;
        try {
            response = client.execute(get);

            XMLElement xml = new XMLElement();
            xml.parseFromReader(new InputStreamReader(response.getInputStream()));

            if (xml.getName().equalsIgnoreCase("success")) {
                // This is the ticket we will use for proxy authentication
                DefaultTunnel tunnel = new DefaultTunnel(-1, Tunnel.LOCAL_TUNNEL, false, Tunnel.TCP_TUNNEL, username,
                                portToConnect, portToConnect, hostToConnect, false, false, true, name, false);
                tunnel.setTicket(xml.getContent());
                // ApplicationTunnel tunnel = new ApplicationTunnel(-1, name,
                // hostToConnect, portToConnect);
                // tunnel.setTicket(xml.getContent());
                // #ifdef DEBUG
                log.info("Registered tunnel " + tunnel.getDestinationHost() + ":" + tunnel.getDestinationPort());
                // #endif
                activeDirectTunnels.put(tunnel.getDestinationHost() + ":" + tunnel.getDestinationPort(), tunnel);
                return tunnel;
            } else
                throw new IOException("The server failed to register the application tunnel named " + name + " " + xml.getContent());
        } finally {
            if (response != null)
                response.close();
        }

    }

    /**
     * Retrieve the list of persistant forwarding tunnels from the server
     * 
     * @return ok
     * @throws IOException
     */
    protected boolean startForwardingTunnels() throws IOException {
        for (Enumeration e = forwardingTunnels.elements(); e.hasMoreElements();) {
            Tunnel t = (Tunnel) e.nextElement();
            if (t.isAutoStart()) {
                switch (t.getType()) {
                    case Tunnel.REMOTE_TUNNEL:
                        startRemoteForwarding(t);
                        break;
                    default:
                        createPermanentListeningSocket(t);
                        break;
                }
            }
        }
        return true;
    }

    /**
     * Get a persistant forwarding tunnel given its id. <code>null</code> will
     * be returned if no such tunnel exists
     * 
     * @param id id
     * @return forwarding tunnel
     */
    protected Tunnel getPersistantForwardingTunnel(int id) {
        Tunnel t;
        for (Enumeration e = forwardingTunnels.elements(); e.hasMoreElements();) {
            t = (Tunnel) e.nextElement();
            if (t.getId() == id) {
                return t;
            }
        }
        for (Enumeration e = remoteTunnels.elements(); e.hasMoreElements();) {
            t = (Tunnel) e.nextElement();
            if (t.getId() == id) {
                return t;
            }
        }

        return null;
    }

    /**
     * Retrieve the list of persistant forwarding tunnels from the server

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -