📄 vpnclient.java
字号:
/*
* 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.client;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import com.maverick.http.AuthenticationCancelledException;
import com.maverick.http.AuthenticationPrompt;
import com.maverick.http.GetMethod;
import com.maverick.http.HttpAuthenticator;
import com.maverick.http.HttpClient;
import com.maverick.http.HttpException;
import com.maverick.http.HttpResponse;
import com.maverick.http.PostMethod;
import com.maverick.http.URLDecoder;
import com.maverick.http.UnsupportedAuthenticationException;
import com.maverick.multiplex.Channel;
import com.maverick.multiplex.MultiplexedConnection;
import com.maverick.ssl.SSLIOException;
import com.maverick.ssl.https.HttpsURLStreamHandlerFactory;
import com.sshtools.ui.awt.options.OptionDialog;
import com.sslexplorer.vpn.base.AbstractVPNClient;
import com.sslexplorer.vpn.base.BrowserProxySettings;
import com.sslexplorer.vpn.base.DefaultTunnel;
import com.sslexplorer.vpn.base.ProxyInfo;
import com.sslexplorer.vpn.base.ProxyUtil;
import com.sslexplorer.vpn.base.VPNConnectionListener;
import com.sslexplorer.vpn.base.VPNTunnel;
import com.sslexplorer.vpn.util.ApplicationLauncher;
import com.sslexplorer.vpn.util.ApplicationLauncherEvents;
import com.sslexplorer.vpn.util.BrowserLauncher;
import com.sslexplorer.vpn.util.ClientCacheRemover;
import com.sslexplorer.vpn.util.IOStreamConnector;
import com.sslexplorer.vpn.util.IOStreamConnectorListener;
import com.sslexplorer.vpn.util.ProcessMonitor;
import com.sslexplorer.vpn.util.ProgressBar;
import com.sslexplorer.vpn.util.Tunnel;
import com.sslexplorer.vpn.util.URI;
import com.sslexplorer.vpn.util.XMLElement;
import com.sslexplorer.vpn.util.XMLParseException;
public class VPNClient extends AbstractVPNClient implements HTTPRequestListener, AuthenticationPrompt {
int HEARTBEAT_PERIOD = 60000;
int SHUTDOWN_PERIOD = 10000;
int WEBFORWARD_INACTIVITY = 300000; // 5 mins
int TUNNEL_INACTIVITY = 600000; // 10 mins
String BROWSER_COMMAND = null;
long lastTx;
long lastRx;
final int STATE_IDLE = 1;
final int STATE_ACTIVE_CONNECTIONS = 2;
final int STATE_DISCONNECTED = 3;
int currentState = STATE_IDLE;
HTTPServer httpd;
int randomPort;
TXRXMonitor txm = new TXRXMonitor();
Heartbeat heartbeat = new Heartbeat();
IOStreamConnectorListener txIo, rxIo;
static ConsoleOutputStream CONSOLE;
static PortMonitor PORTS;
VPNClientGUI gui;
Vector extensions = new Vector();
String extensionClasses;
/* DEBUG */static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(VPNClient.class);
public VPNClient() {
/* DEBUG */log.info("Allow untrusted hosts is set to "
/* DEBUG */+ System.getProperty("com.maverick.ssl.allowUntrustedCertificates", "false"));
}
public void init(String proxyHost, int proxyPort, String username, String ticket) {
try {
super.init(proxyHost, proxyPort, username, ticket);
/**
* Decide on the type of GUI required. Only use a systray icon if
* we're running an NT based version of Windows.
*/
if (ApplicationLauncher.checkVersion("1.2") && System.getProperty("os.name").startsWith("Windows")
&& !System.getProperty("os.name").startsWith("Windows 98")
&& !System.getProperty("os.name").startsWith("Windows 95")
&& !System.getProperty("os.name").startsWith("Windows ME")) {
gui = new SystemTrayGUI();
}
/*
*
* Experimental code bringing the tray icon to Gnome on Linux. This
* has been disabled until some issues with focus in the JDIC API
* have been resolved (http://jdic.dev.java.net/).
*/
// else if(ApplicationLauncher.checkVersion("1.4") &&
// System.getProperty("os.name").toLowerCase().startsWith("linux"))
// {
// gui = new TrayGUI();
// }
else {
gui = new BasicFrameGUI();
}
gui.init(new MyGUIListener());
gui.showTxRx();
startupHTTPD();
gui.showIdle();
/**
* BPS - We now use the Maverick HttpClient directly
*
* Note to BPS from LDP: this is still needed, although most uses of
* URLConnection have been removed we are still using it in the
* ApplicationLauncher. We cannot use HttpClient there because that
* would require including Maverick SSL/HTTP in the v.small launcher
* applet, removing this breaks application launching!
*/
installHTTPSSupport();
configureProxy();
gui.showTxRx();
// We should now inform the SSL Explorer of our chosen port
// for this session.
registerClient();
// Start the Tx/Rx monitor so we have some animated icons
txm.start();
// Get any tunnels to start
if (!retrievePersistantForwardingTunnels()) {
/* DEBUG */log.error("Failed to retrieve tunnels.");
} else {
startForwardingTunnels();
}
// Start the heartbear monitor so that we can notify if the server
// goes
// down
heartbeat.start();
gui.showIdle();
updateInformation();
startTunnelInactivityMonitor();
} catch (SSLIOException ex) {
/* DEBUG */log.info("An unexpected error has occurred", ex.getRealException());
/* DEBUG */log.info("SSL-Explorer Agent must now exit");
gui.showDisconnected();
OptionDialog.error(null, "Error", "The SSL-Explorer Agent failed connect.", ex);
System.exit(4);
} catch (IOException ex) {
/* DEBUG */log.info("An unexpected error has occurred", ex);
/* DEBUG */log.info("SSL-Explorer Agent must now exit");
OptionDialog.error(null, "Error", "The SSL-Explorer Agent failed connect.", ex);
gui.showDisconnected();
System.exit(4);
} catch (Throwable t) {
OptionDialog.error(null, "Error", "The SSL-Explorer Agent failed connect.", t);
/* DEBUG */log.info("Critical failure", t);
gui.showDisconnected();
System.exit(4);
}
}
private void startExtensions(String extensionClasses) {
StringTokenizer classes = new StringTokenizer(extensionClasses, ",");
while(classes.hasMoreTokens()) {
String cls = classes.nextToken();
try {
Class agent = getClass().forName(cls);
AgentExtension ext = (AgentExtension) agent.newInstance();
/* DEBUG */log.info("Starting " + ext.getName());
ext.init(this);
extensions.addElement(ext);
} catch (Exception e1) {
/* DEBUG */log.info("Unable to start extension " + cls, e1);
continue;
}
}
}
/**
* This is a hack because the MSJVM does not allow access to protected
* members from an anonymous class.
*
* @return Hashtable
*/
protected Hashtable getActiveListeners() {
return activeListeners;
}
protected Hashtable getActiveDirectTunnels() {
return activeDirectTunnels;
}
private void startTunnelInactivityMonitor() {
Thread t = new Thread() {
public void run() {
/* DEBUG */log.info("Starting tunnel inactivity monitor (tunnels " + TUNNEL_INACTIVITY + "ms, web forwards "
/* DEBUG */+ WEBFORWARD_INACTIVITY + ")");
while (true) {
try {
Thread.sleep(30000);
if (currentState == STATE_DISCONNECTED) {
break;
}
/* DEBUG */log.info("Checking for tunnel inactivity");
// Hack to allow MSJVM access to the protected member
Hashtable activeListeners = getActiveListeners();
synchronized (activeListeners) {
long now = System.currentTimeMillis();
for (Enumeration e = activeListeners.keys(); e.hasMoreElements();) {
String ticket = (String) e.nextElement();
VPNConnectionListener l = (VPNConnectionListener) activeListeners.get(ticket);
try {
if (l.isListening()) {
// Temporary single connect tunnels and
// permanent tunnels
if (TUNNEL_INACTIVITY != 0
&& (l.getTunnel().isPermanent() || (!l.getTunnel().isPermanent() && l
.getTunnel().isTemporarySingleConnect()))) {
if (now > (l.getDataLastTransferredTime() + TUNNEL_INACTIVITY)) {
/* DEBUG */log.info("Permanent / Temporary Single Connect tunnel " + ticket
/* DEBUG */+ " is out of date, closing");
stopListeningSocket(ticket);
}
}
// Temporary tunnels that allow multiple
// connections (i.e.
// web forwards)
else if (WEBFORWARD_INACTIVITY != 0
&& (!l.getTunnel().isPermanent() && !l.getTunnel()
.isTemporarySingleConnect())) {
if (now > (l.getDataLastTransferredTime() + WEBFORWARD_INACTIVITY)) {
/* DEBUG */log.info("Temporary Multiple Connection (Webforward) tunnel " + ticket
/* DEBUG */+ " is out of date, closing");
stopListeningSocket(ticket);
}
}
}
} catch (Throwable t) {
/* DEBUG */log.error("Failed to check the state of tunnel " + ticket, t);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -