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

📄 abstractvpnclient.java

📁 这是linux下ssl vpn的实现程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * 
     * @return ok
     * @throws IOException
     * @throws UnsupportedAuthenticationException
     * @throws HttpException
     */
    protected boolean retrievePersistantForwardingTunnels() throws IOException, HttpException, UnsupportedAuthenticationException,
                    AuthenticationCancelledException {

        HttpClient client = getHttpClient();
        GetMethod get = new GetMethod("/getTunnels.do");
        get.setParameter("ticket", ticket);
        HttpResponse response = client.execute(get);
        try {

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

            if (xml.getName().equals("tunnels")) {
                forwardingTunnels.removeAllElements();

                // Create any tunnels that should be started upon registration

                // #ifdef DEBUG
                log.info("Looking for tunnels to open");
                // #endif
                for (Enumeration e2 = xml.enumerateChildren(); e2.hasMoreElements();) {
                    XMLElement el2 = (XMLElement) e2.nextElement();
                    if (el2.getName().equals("tunnel")) {
                        int id = el2.getIntAttribute("id");
                        int type = el2.getIntAttribute("type");
                        boolean autoStart = el2.getBooleanAttribute("autoStart", "true", "false", false);
                        String transport = (String) el2.getAttribute("transport");
                        String username = (String) el2.getAttribute("username");
                        int sourcePort = el2.getIntAttribute("sourcePort");
                        int destinationPort = el2.getIntAttribute("destinationPort");
                        String destinationHost = el2.getStringAttribute("destinationHost");
                        boolean allowExternalHosts = el2.getBooleanAttribute("allowExternalHosts", "true", "false", false);
                        // #ifdef DEBUG
                        log.info("Tunnel " + transport + " from " + sourcePort + " to " + destinationHost + ":" + destinationPort);
                        // #endif
                        forwardingTunnels.addElement(new DefaultTunnel(id, type, autoStart, transport, username, sourcePort,
                                        destinationPort, destinationHost, allowExternalHosts, true, false, destinationHost + ":"
                                                        + destinationPort, false));
                    } else {
                        // #ifdef DEBUG
                        log.error("Invalid child element in success.tunnels");
                        // #endif
                    }
                }
                return true;
            } else {
                // #ifdef DEBUG
                log.error("Did not get a list of tunnels to start, got '" + xml.toString() + " instead.");
                // #endif
                return false;
            }
        } finally {
            response.close();
        }
    }

    /**
     * Unregisters an application tunnel.
     * 
     * @param tunnel
     * @return
     * @throws IOException
     * @throws UnsupportedAuthenticationException
     * @throws HttpException
     */
    public boolean unregisterApplicationTunnel(Tunnel tunnel) throws IOException, HttpException,
                    UnsupportedAuthenticationException, AuthenticationCancelledException {

        HttpClient client = getHttpClient();
        GetMethod get = new GetMethod("/unregisterListeningSocket.do");
        get.setParameter("ticket", ticket);
        get.setParameter("tunnel", tunnel.getTicket());
        HttpResponse response = client.execute(get);
        try {
            XMLElement xml = new XMLElement();
            xml.parseFromReader(new InputStreamReader(response.getInputStream()));
            return xml.getName().equalsIgnoreCase("success");
        } finally {
            response.close();
        }

    }

    /**
     * Called by a {@link VPNConnectionListener}to register a new forwarding
     * tunnel.
     * 
     * @param tunnel
     */
    protected void registerForwardingTunnel(VPNTunnel tunnel) {
        activeForwardingTunnels.addElement(tunnel);
    }

    /**
     * Called by a {@link VPNConnectionListener}to unregister a new forwarding
     * tunnel.
     * 
     * @param tunnel
     */
    protected void unregisterForwardingTunnel(VPNTunnel tunnel) {
        activeForwardingTunnels.removeElement(tunnel);
    }

    /**
     * Select a random port. NOTE: this method does not gaurentee that the port
     * is available.
     * 
     * @return
     */
    protected int selectRandomPort() {
        SecureRandom rnd = SecureRandom.getInstance();
        int n = HIGHEST_RANDOM_PORT - LOWEST_RANDOM_PORT + 1;
        int i = rnd.nextInt() % n;
        if (i < 0)
            i = -i;
        return LOWEST_RANDOM_PORT + i;
    }

    /**
     * Create a permanent listening socket.
     * 
     * @param portToBind
     * @param hostToConnect
     * @param portToConnect
     * @param allowExternalHosts
     * @return
     */
    public VPNConnectionListener createPermanentListeningSocket(Tunnel tunnel) {
        try {
            // #ifdef DEBUG
            log.info("Attempting to create a listening socket for " + tunnel.getDestinationHost() + ":"
                            + tunnel.getDestinationPort() + " on the port " + tunnel.getSourcePort());
            // #endif

            return startListeningSocket(tunnel);
        } catch (IOException ex) {
            // #ifdef DEBUG
            log.info("Failed to start listening socket", ex);
            // #endif
            return null;
        }
    }

    /**
     * Attempt to create a tunnel that listens on the callers preferred port. If
     * the port is already being used then generate a random port and return the
     * listening port to the caller.
     * 
     * @param hostToConnect host to connect
     * @param portToConnect port to connect
     * @param allowExternalHosts allow hosts other than the one the client is
     *        running on to connect
     * @param preferredListeningPort the port on which to try and create a
     *        listener first. Upon failure a random port will be used
     * @param maxAttempts the maximum number of times to try and create a
     *        listener
     * @param temporarySingleConnect true if this tunnel can be used only once
     * @return the listener
     */
    public VPNConnectionListener createTemporaryListeningSocket(String hostToConnect, int portToConnect,
                                                                boolean allowExternalHosts, int preferredListeningPort,
                                                                int maxAttempts, boolean temporarySingleConnect) {

        try {
            if (preferredListeningPort == -1) {
                throw new IOException();
            }

            // #ifdef DEBUG
            log.info("Attempting to create a " + (temporarySingleConnect ? "temporary single connect" : "temporary")
                            + " listening socket for " + hostToConnect + ":" + portToConnect + " on the preferred port "
                            + preferredListeningPort);
            // #endif

            Tunnel tunnel = new DefaultTunnel(-1, Tunnel.LOCAL_TUNNEL, false, Tunnel.TCP_TUNNEL, username, preferredListeningPort,
                            portToConnect, hostToConnect, allowExternalHosts, false, temporarySingleConnect, hostToConnect + ":"
                                            + portToConnect, false);

            return startListeningSocket(tunnel);
        } catch (IOException ex) {

            // #ifdef DEBUG
            if (preferredListeningPort == -1) {
                log.info("Preferred port disabled, choosing a random one.");
            } else {
                log.info("Preferred port failed as its probably in use by another application");
            }
            // #endif

            /**
             * The preferred port failed so lets try up to the maximum on a
             * random port
             */
            int port = -1;

            for (int i = 0; i < maxAttempts; i++) {
                try {

                    port = selectRandomPort();

                    // #ifdef DEBUG
                    log.info("Attempting to create a listening socket for " + hostToConnect + ":" + portToConnect
                                    + " on the random port " + port);
                    // #endif

                    Tunnel tunnel = new DefaultTunnel(-1, Tunnel.LOCAL_TUNNEL, false, Tunnel.TCP_TUNNEL, username, port,
                                    portToConnect, hostToConnect, allowExternalHosts, false, temporarySingleConnect, hostToConnect
                                                    + ":" + portToConnect, false);

                    return startListeningSocket(tunnel);

                } catch (IOException ex2) {
                    // Ignore and try again up to maxAttempts

                    // #ifdef DEBUG
                    log.info("Random port " + port + " failed! " + (maxAttempts - i) + " attempts left", ex2);
                    // #endif
                }
            }
        }

        // #ifdef DEBUG
        log.info("All attempts to create a listening socket failed");
        // #endif
        // If we reacahed here we failed so return a failure value
        return null;

    }

    /**
     * Start a listening socket, wait for connections and tunnel all connected
     * sockets to a remote host.
     * 
     * @param tunnel Tunnel
     * @return VPNConnectionListener
     * @throws IOException
     */
    public VPNConnectionListener startListeningSocket(Tunnel tunnel) throws IOException {

        VPNConnectionListener listener = new VPNConnectionListener(this, getTXIOListener(), getRXIOListener(), tunnel);
        listener.start();

        // Save the listener to our table
        activeListeners.put(listener.getTicket(), listener);

        return listener;

    }

    public MultiplexedConnection startRemoteForwarding(Tunnel tunnel) throws IOException {

        if (tunnel.getType() != Tunnel.REMOTE_TUNNEL)
            throw new IOException("Invalid tunnel type " + tunnel.getType()
                            + ": only remote forwards can request a remote listening socket");

        try {

            XMLElement xml = registerListeningSocket(true, tunnel);

            if (xml == null)
                throw new IOException("Unexpected error in fowarding registration!");

            String ticket = xml.getContent();
            tunnel.setTicket(ticket);

            HttpClient client = getHttpClient();
            client.setCredentials(new PasswordCredentials(getTicket(), tunnel.getTicket()));
            client.setPreemtiveAuthentication(true);

            GetMethod listen = new GetMethod("CONNECT", (tunnel.isAllowExternalHosts() ? "0.0.0.0" : "127.0.0.1") + ":"
                            + tunnel.getSourcePort() + "#" + tunnel.getDestinationHost() + ":" + tunnel.getDestinationPort());

            HttpResponse response = client.execute(listen);

            MultiplexedConnection con = new MultiplexedConnection(0, 0, 0, response.getConnection().getInputStream(), response
                            .getConnection().getOutputStream(), new ChannelFactory() {
                public Channel createChannel(String type) {
                    Channel channel = new SocketChannel();
                    channel.addListener(AbstractVPNClient.this);
                    return channel;
                }
            });

            remoteListeners.put(tunnel.getTicket(), con);

            return con;

        } catch (AuthenticationCancelledException ex) {
            throw new IOException("Unexpected authentication error in HTTP request: " + ex.getMessage());
        } catch (UnsupportedAuthenticationException ex) {
            throw new IOException("Unexpected authentication error in HTTP request: " + ex.getMessage());
        } catch (HttpException ex) {
            throw new IOException("Unexpected HTTP error: " + ex.getMessage());
        } catch (UnknownHostException ex) {
            throw new IOException("Unexpected host not found error in HTTP request: " + ex.getMessage());
        } catch (Exception ex) {
            throw new IOException(ex.getMessage());
        }
    }

    public boolean unregisterListeningSocket(Tunnel tunnel) {

        try {
            HttpClient client = getHttpClient();
            GetMethod get = new GetMethod("/unregisterListeningSocket.do");
            get.setParameter("ticket", getTicket());
            get.setParameter("tunnel", tunnel.getTicket());
            HttpResponse response = client.execute(get);
            try {

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

                return xml.getName().equalsIgnoreCase("success");
            } finally {
                registeredListeningSockets.remove(tunnel.getTicket());
                response.close();
            }

        } catch (MalformedURLException ex) {
            // #ifdef DEBUG
            log.info("Failed to construct url", ex);
            // #endif
        } catch (Throwable ex) {
            // #ifdef DEBUG
            log.info("Failed to connect url", ex);
            // #endif
        }

        return false;

    }

    /**
     * Register a tunnel with the server. An XML element will be return with id
     * and ticket attributes. The id attribute is the tunnel ID. A new tunnel
     * will be created and the new id returned if the supplied
     * <code>Tunnel</code> object has an ID of -1.
     * 
     * @param start automatically start the tunnel
     * @param tunnel the tunnel
     * @return tunnel details
     */
    public XMLElement registerListeningSocket(boolean start, Tunnel tunnel) throws Exception {

        HttpClient client = getHttpClient();
        GetMethod get = new GetMethod("/registerListeningSocket.do");
        get.setParameter("ticket", getTicket());
        get.setParameter("start", String.valueOf(start));
        if (tunnel.getId() == -1) {
            get.setParameter("sourcePort", String.valueOf(tunnel.getSourcePort()));
            get.setParameter("destinationHost", tunnel.getDestinationHost());
            get.setParameter("destinationPort", String.valueOf(tunnel.getDestinationPort()));
            get.setParameter("allowExternalHosts", String.valueOf(tunnel.isAllowExternalHosts()));
            get.setParameter("permanent", String.valueOf(tunnel.isPermanent()));
            get.setParameter("autoStart", String.valueOf(tunnel.isAutoStart()));
            get.setParameter("transport", tunnel.getTransport());
            get.setParameter("type", String.valueOf(tunnel.getType()));
        } else {
            get.setParameter("id", String.valueOf(tunnel.getId()));
        }
        HttpResponse response = client.execute(get);
        try {
            // #ifdef DEBUG
            log.info("Registering tunnel");
            // #endif

⌨️ 快捷键说明

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