KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > agent > client > Agent


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.agent.client;
21
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InterruptedIOException JavaDoc;
28 import java.io.PrintStream JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.text.MessageFormat JavaDoc;
31 import java.text.SimpleDateFormat JavaDoc;
32 import java.util.Date JavaDoc;
33 import java.util.Enumeration JavaDoc;
34 import java.util.Hashtable JavaDoc;
35 import java.util.Locale JavaDoc;
36 import java.util.Properties JavaDoc;
37 import java.util.StringTokenizer JavaDoc;
38 import java.util.Vector JavaDoc;
39
40 import com.maverick.http.AuthenticationCancelledException;
41 import com.maverick.http.AuthenticationPrompt;
42 import com.maverick.http.GetMethod;
43 import com.maverick.http.HttpAuthenticator;
44 import com.maverick.http.HttpAuthenticatorFactory;
45 import com.maverick.http.HttpClient;
46 import com.maverick.http.HttpConnection;
47 import com.maverick.http.HttpException;
48 import com.maverick.http.HttpResponse;
49 import com.maverick.http.PasswordCredentials;
50 import com.maverick.http.URLDecoder;
51 import com.maverick.http.UnsupportedAuthenticationException;
52 import com.maverick.multiplex.MultiplexedConnection;
53 import com.maverick.multiplex.MultiplexedConnectionListener;
54 import com.maverick.multiplex.Request;
55 import com.maverick.multiplex.RequestHandler;
56 import com.maverick.ssl.SSLIOException;
57 import com.maverick.ssl.https.HttpsURLStreamHandlerFactory;
58 import com.maverick.util.ByteArrayReader;
59 import com.maverick.util.ByteArrayWriter;
60 import com.sslexplorer.agent.client.applications.ApplicationManager;
61 import com.sslexplorer.agent.client.networkplaces.NetworkPlaceManager;
62 import com.sslexplorer.agent.client.tunneling.DefaultTunnel;
63 import com.sslexplorer.agent.client.tunneling.LocalTunnelServer;
64 import com.sslexplorer.agent.client.tunneling.TunnelInactivityMonitor;
65 import com.sslexplorer.agent.client.tunneling.TunnelManager;
66 import com.sslexplorer.agent.client.util.BrowserLauncher;
67 import com.sslexplorer.agent.client.util.IOStreamConnectorListener;
68 import com.sslexplorer.agent.client.util.TunnelConfiguration;
69 import com.sslexplorer.agent.client.util.URI;
70 import com.sslexplorer.agent.client.util.Utils;
71 import com.sslexplorer.agent.client.util.URI.MalformedURIException;
72 import com.sslexplorer.agent.client.webforwards.WebForwardManager;
73
74 /**
75  * Concrete implementation of an {@link AbstractVPNClient} that runs as
76  * standalone applicaiton launched from the SSL-Explorer web interface (via the
77  * <i>Laumcher</i> applet.
78  * <p>
79  * See package description for more information.
80  *
81  * @author Lee David Painter <a HREF="mailto: lee@3sp.com">&lt;lee@3sp.com&gt;</a>
82  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
83  * @version $Revision: 1.22.2.5 $
84  */

85 public class Agent implements RequestHandler, MultiplexedConnectionListener {
86     
87     /*
88      * Replaced by build
89      */

90     public final static String JavaDoc AGENT_VERSION = "999.999.999";
91
92     /** The hostname of the SSL-Explorer proxy * */
93     protected String JavaDoc sslexplorerHostname;
94
95     /** The port of the SSL-Explorer proxy * */
96     protected int sslexplorerPort;
97
98     /** The username for this session * */
99     protected String JavaDoc username;
100
101     /** The VPN client ticket for an authenticated session * */
102     protected String JavaDoc ticket;
103
104     /** The hostname of the local HTTPS proxy server * */
105     protected URI localProxyURL;
106
107     /** We store all the available proxy information here * */
108     protected static Hashtable JavaDoc proxiesIE = new Hashtable JavaDoc();
109
110     /** We store all the local bypass addresses here * */
111     protected static Vector JavaDoc proxyBypassIE = new Vector JavaDoc();
112
113     protected static Hashtable JavaDoc proxiesFF = new Hashtable JavaDoc();
114
115     protected static Vector JavaDoc proxyBypassFF = new Vector JavaDoc();
116
117     /** HttpClient instances are cached * */
118
119     protected AgentConfiguration agentConfiguration;
120
121     protected String JavaDoc serverVersion;
122
123     protected HttpClient client;
124
125     protected String JavaDoc defaultProxyHost;
126
127     protected int defaultProxyPort = 80;
128
129     protected PasswordCredentials defaultProxyCredentials;
130
131     protected String JavaDoc defaultProxyPreferredAuthentication;
132
133     protected boolean autoDetectProxies = true;
134
135     protected AuthenticationPrompt defaultProxyAuthenticationPrompt;
136
137     protected int defaultProxyType = HttpClient.PROXY_HTTP;
138
139     protected ApplicationManager applicationManager;
140
141     protected TunnelManager tunnelManager;
142
143     protected WebForwardManager webForwardManager;
144
145     protected NetworkPlaceManager networkPlaceManager;
146
147     boolean ticketIsPassword;
148
149     // Public statics
150

151     /**
152      * Client is connected
153      */

154     public final static int STATE_CONNECTED = 1;
155
156     /**
157      * Client is disconnected
158      */

159     public final static int STATE_DISCONNECTED = 2;
160
161     // Private instance variables
162

163     private int currentState = STATE_DISCONNECTED;
164
165     private TXRXMonitor txm;
166
167     private AgentClientGUI gui;
168
169     private Vector JavaDoc extensions = new Vector JavaDoc();
170
171     private TunnelInactivityMonitor inactivityMonitor;
172
173     private KeepAliveThread keepAlive;
174
175     // Statics
176

177     MultiplexedConnection con = null;
178
179     HttpConnection httpConnection = null;
180
181     public static final String JavaDoc SHUTDOWN_REQUEST = "shutdown@3sp.com";
182
183     public static final String JavaDoc OPEN_URL_REQUEST = "openURL@3sp.com";
184
185     public static final String JavaDoc MESSAGE_REQUEST = "agentMessage@3sp.com";
186
187     public static final String JavaDoc UPDATE_RESOURCES_REQUEST = "updateResources@3sp.com";
188
189     public static final String JavaDoc SYNCHRONIZED_REQUEST = "synchronized@3sp.com";
190
191     // #ifdef DEBUG
192
static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
193             .getLog(Agent.class);
194     // #endif
195

196     static {
197         HttpClient.setUserAgent("SSL-Explorer/Agent"); //$NON-NLS-1$
198
}
199
200     /**
201      * Set the URL of the HTTPS proxy server to use for all outgoing connections
202      *
203      * @param localProxyURL
204      * local proxy URL
205      * @throws URI.MalformedURIException
206      */

207     public void setLocalProxyURL(String JavaDoc localProxyURL)
208             throws URI.MalformedURIException {
209         this.localProxyURL = new URI(localProxyURL);
210
211         // FIXME What about HttpsURLConnection?
212
}
213
214     /**
215      * Get the application manager for this agent.
216      *
217      * @return application manager
218      */

219     public ApplicationManager getApplicationManager() {
220         return applicationManager;
221     }
222
223     /**
224      * Get the tunnel manager for this agent
225      *
226      * @return tunnel mananger
227      */

228     public TunnelManager getTunnelManager() {
229         return tunnelManager;
230     }
231
232     /**
233      * Get the network place manager for this agent
234      *
235      * @return network place manager
236      */

237     public NetworkPlaceManager getNetworkPlaceManager() {
238         return networkPlaceManager;
239     }
240
241     /**
242      * Get the version of the server this agent is connected to. Will be
243      * <code>null</code> until connected.
244      *
245      * @return server version
246      */

247     public String JavaDoc getServerVersion() {
248         return serverVersion;
249     }
250
251     /**
252      * Get the client version. This will be 999.999.999 when running
253      * directly from classes or the agent extension version when
254      * running from deployed version.
255      *
256      * @return client version
257      */

258     public String JavaDoc getClientVersion() {
259         return AGENT_VERSION;
260     }
261
262     public MultiplexedConnection getConnection() {
263         return con;
264     }
265
266     /**
267      * Get the hostname of the SSL-Explorer proxy
268      *
269      * @return hostname
270      */

271     public String JavaDoc getSSLExplorerHost() {
272         return sslexplorerHostname;
273     }
274
275     public String JavaDoc getTicket() {
276         return ticket;
277     }
278
279     /**
280      * Get the port of the SSL-Explorer proxy
281      *
282      * @return port
283      */

284     public int getSSLExplorerPort() {
285         return sslexplorerPort;
286     }
287
288     /**
289      * Get the username for this session
290      *
291      * @return username
292      */

293     public String JavaDoc getUsername() {
294         return username;
295     }
296
297     public void onConnectionClose() {
298         currentState = STATE_DISCONNECTED;
299         if (getConfiguration().isSystemExitOnDisconnect()) {
300             startShutdownProcedure();
301         } else {
302             getGUI().showDisconnected();
303         }
304     }
305
306     public void onConnectionOpen() {
307         currentState = STATE_CONNECTED;
308     }
309
310     /**
311      * Configure the proxy server using the currently set <i>Local Proxy URL</i>
312      * (set by {@link #setLocalProxyURL(String)}.
313      */

314     public void configureProxy() {
315
316         // Configure local proxy support
317
if (localProxyURL != null && !localProxyURL.equals("")) { //$NON-NLS-1$
318
// #ifdef DEBUG
319
log.info("Configuring HTTP proxy to "
320                     + obfuscateURL(localProxyURL.toString()));
321             // #endif
322
String JavaDoc userInfo = localProxyURL.getUserinfo();
323             String JavaDoc user = ""; //$NON-NLS-1$
324
String JavaDoc password = ""; //$NON-NLS-1$
325
if (userInfo != null && !userInfo.equals("")) { //$NON-NLS-1$
326
int idx = userInfo.indexOf(':');
327                 user = URLDecoder.decode(userInfo);
328                 if (idx != -1) {
329                     password = URLDecoder.decode(userInfo.substring(idx + 1));
330                     user = URLDecoder.decode(userInfo.substring(0, idx));
331                 }
332             }
333             int port = localProxyURL.getPort();
334             setDefaultProxyType(localProxyURL.getScheme().equals("https") ? HttpClient.PROXY_HTTPS : HttpClient.PROXY_HTTP); //$NON-NLS-1$
335
setDefaultProxyHost(localProxyURL.getHost());
336             setDefaultProxyPort(port == -1 ? 80 : port);
337             if (!user.equals("")) { //$NON-NLS-1$
338
setDefaultProxyCredentials(new PasswordCredentials(user,
339                         password));
340             }
341             if (localProxyURL.getQueryString() != null) {
342                 setDefaultProxyPreferredAuthentication(localProxyURL
343                         .getQueryString());
344             }
345         }
346         if (localProxyURL != null && !localProxyURL.equals("")) { //$NON-NLS-1$
347
setDefaultProxyAuthenticationPrompt(gui);
348         }
349
350     }
351
352     /**
353      * Get the {@link HttpClient} that is being used by this VPN client for
354      * communication with SSL-Explorer.
355      *
356      * @return http client
357      */

358     private synchronized HttpClient getHttpClient() {
359         if (client == null) {
360             // #ifdef DEBUG
361
log.info("Creating HttpClient instance"); //$NON-NLS-1$
362
// #endif
363
client = new HttpClient(sslexplorerHostname, sslexplorerPort, true);
364             client.setAuthenticationPrompt(getGUI());
365             if (defaultProxyHost != null && !defaultProxyHost.equals("")) { //$NON-NLS-1$
366
// #ifdef DEBUG
367
log.info("Configuring proxies for HttpClient instance"); //$NON-NLS-1$
368
// #endif
369
client
370                         .setProxyAuthenticationPrompt(defaultProxyAuthenticationPrompt);
371                 client.setProxyHost(defaultProxyHost);
372                 client.setProxyPort(defaultProxyPort);
373                 client.setProxyType(defaultProxyType);
374
375                 if (defaultProxyCredentials != null
376                         && defaultProxyCredentials.getUsername() != null
377                         && !defaultProxyCredentials.getUsername().equals("")) { //$NON-NLS-1$
378
/**
379                      * LDP - This used to set preemptive authentication but its
380                      * causing problems with NTLM
381                      */

382                     client.setProxyCredentials(defaultProxyCredentials);
383
384                     /**
385                      * LDP - It seems preemptive might be needed for Basic
386                      * authentication. There are lots of users seeing
387                      * EOFExceptions after 407 proxy authentication required.
388                      */

389                     if ("BASIC"
390                             .equalsIgnoreCase(defaultProxyPreferredAuthentication)) {
391                         client.setProxyPreemptiveAuthentication(true);
392                     }
393                 }
394                 client
395                         .setProxyPreferedAuthentication("AUTO".equalsIgnoreCase(defaultProxyPreferredAuthentication) ? null //$NON-NLS-1$
396
: defaultProxyPreferredAuthentication);
397             }
398         }
399
400         return client;
401     }
402
403     /**
404      * Constructor preventing direct instantiation.
405      */

406     public Agent(AgentConfiguration agentConfiguration) {
407         this.agentConfiguration = agentConfiguration;
408
409         // Forced
410
if (getConfiguration().getGUIClass() != null) {
411             try {
412                 gui = (AgentClientGUI) Class.forName(
413                         getConfiguration().getGUIClass()).newInstance();
414             } catch (Exception JavaDoc e) {
415                 //#ifdef DEBUG
416
log.error("Failed to create GUI", e);
417                 //#endif
418
}
419
420         }
421
422         //
423
if (gui == null) {
424
425             // SWT
426
try {
427                 Class.forName("org.eclipse.swt.widgets.Display");
428                 gui = (AgentClientGUI) Class
429                         .forName(
430                                 "com.sslexplorer.agent.client.gui.swt.SWTSystemTrayGUI")
431                         .newInstance();
432             } catch (Exception JavaDoc e) {
433                 //#ifdef DEBUG
434
log.debug("Failed to create SWT GUI", e);
435                 //#endif
436
}
437
438             //
439
if (gui == null) {
440
441                 // JDK6
442
if (Utils.checkVersion("1.6")) { //$NON-NLS-1$
443
try {
444                         // yay, finally agent tray icon for linux
445
gui = (AgentClientGUI) Class
446                                 .forName(
447                                         "com.sslexplorer.agent.client.gui.awt.JDK6SystemTrayGUI")
448                                 .newInstance();
449                     } catch (Exception JavaDoc e) {
450                         //#ifdef DEBUG
451
log.debug("Failed to create JDK6 GUI", e);
452                         //#endif
453
}
454                 }
455
456                 // Systray4j
457
if (gui == null
458                         && Utils.checkVersion("1.2") && System.getProperty("os.name").startsWith("Windows") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
459
&& !System
460                                 .getProperty("os.name").startsWith("Windows 98") //$NON-NLS-1$ //$NON-NLS-2$
461
&& !System
462                                 .getProperty("os.name").startsWith("Windows 95") //$NON-NLS-1$ //$NON-NLS-2$
463
&& !System
464                                 .getProperty("os.name").startsWith("Windows ME")) { //$NON-NLS-1$ //$NON-NLS-2$
465
try {
466                         gui = (AgentClientGUI) Class
467                                 .forName(
468                                         "com.sslexplorer.agent.client.gui.awt.SystemTrayGUI")
469                                 .newInstance();
470                     } catch (Exception JavaDoc e) {
471                         //#ifdef DEBUG
472
log.debug("Failed to create JDIC GUI", e);
473                         //#endif
474
}
475                 }
476
477                 // Fallback to basic frame GUI
478
if (gui == null) {
479                     try {
480                         gui = (AgentClientGUI) Class
481                                 .forName(
482                                         "com.sslexplorer.agent.client.gui.awt.BasicFrameGUI")
483                                 .newInstance();
484                     } catch (Exception JavaDoc e) {
485                         //#ifdef DEBUG
486
log.debug("Failed to create basic GUI", e);
487                         //#endif
488
}
489
490                     // No GUI? Probably embedded so use a dummy GUI
491
if (gui == null) {
492                         gui = new DummyGUI();
493                     }
494                 }
495             }
496         }
497     }
498
499     // /**
500
// * Get the static instance of the {@link Agent}.
501
// *
502
// * @return instance
503
// */
504
// public static Agent getVPN() {
505
// if (vpn == null) {
506
// vpn = new Agent();
507
// }
508
// return vpn;
509
// }
510

511     /**
512      * Get the current state. Will be one of {@link #STATE_DISCONNECTED} or
513      * {@link #STATE_CONNECTED}.
514      *
515      * @return state
516      */

517     public int getState() {
518         return currentState;
519     }
520
521     /**
522      * Get the object the stores various configuration options
523      *
524      * @return configuration
525      */

526     public AgentConfiguration getConfiguration() {
527         return agentConfiguration;
528     }
529
530     /*
531      * (non-Javadoc)
532      *
533      * @see com.sslexplorer.vpn.base.AbstractVPNClient#init(java.lang.String,
534      * int, java.lang.String, java.lang.String)
535      */

536     public void init() throws SecurityException JavaDoc, IOException JavaDoc {
537
538         // #ifdef DEBUG
539
log.info("Allow untrusted hosts is set to " + System.getProperty("com.maverick.ssl.allowUntrustedCertificates", "false")); //$NON-NLS-1$ //$NON-NLS-2$
540
log.info("Cache directory is " + getConfiguration().getCacheDir());
541         // #endif
542

543         // #ifdef DEBUG
544
log.info("Initialising GUI"); //$NON-NLS-1$
545
// #endif
546
gui.init(this);
547         disconnected();
548
549         // Install and configure HTTP / HTTPS support
550
// #ifdef DEBUG
551
log.info("Installing Maverick SSL support for HTTPSURLStreamHandler"); //$NON-NLS-1$
552
// #endif
553

554         try {
555             HttpsURLStreamHandlerFactory.addHTTPSSupport();
556             configureProxy();
557         } catch (SecurityException JavaDoc se) {
558             disconnected();
559             throw se;
560         } catch (IOException JavaDoc ioe) {
561             disconnected();
562             throw ioe;
563         }
564     }
565
566     public void connect(String JavaDoc sslexplorerHostname, int sslexplorerPort,
567             String JavaDoc username, String JavaDoc ticket, boolean ticketIsPassword)
568             throws IOException JavaDoc, HttpException,
569             UnsupportedAuthenticationException,
570             AuthenticationCancelledException {
571
572         this.sslexplorerHostname = sslexplorerHostname;
573         this.sslexplorerPort = sslexplorerPort;
574         this.username = username;
575         this.ticket = ticket;
576         this.ticketIsPassword = ticketIsPassword;
577
578         inactivityMonitor = new TunnelInactivityMonitor(this);
579         keepAlive = new KeepAliveThread();
580
581         gui.showTxRx();
582
583         connectAgent();
584
585         // Start the Tx/Rx monitor so we have some animated icons
586
txm = new TXRXMonitor(this);
587         txm.start();
588
589         gui.showIdle();
590         updateInformation();
591
592         inactivityMonitor.start();
593
594         if (getConfiguration().getKeepAlivePeriod() > 0)
595             keepAlive.start();
596
597         if (getConfiguration().isDisplayInformationPopups()) {
598             getGUI().popup(null, Messages.getString("VPNClient.nowRunning"), //$NON-NLS-1$
599
Messages.getString("VPNClient.title"), "popup-agent", -1); //$NON-NLS-1$
600
}
601
602     }
603
604     public boolean processRequest(Request request, MultiplexedConnection con) {
605
606         if (request.getRequestName().equals(SHUTDOWN_REQUEST)) {
607             disconnectAgent();
608             return true;
609         } else if (request.getRequestName().equals(MESSAGE_REQUEST)) {
610             displayMessage(request);
611             return true;
612         } else if (request.getRequestName().equals(UPDATE_RESOURCES_REQUEST)) {
613             final ByteArrayReader bar = new ByteArrayReader(request.getRequestData());
614             Thread JavaDoc t = new Thread JavaDoc() {
615                 public void run() {
616                     try {
617                         updateResources((int)bar.readInt());
618                     }
619                     catch(IOException JavaDoc e) {
620                     }
621                 }
622             };
623             t.start();
624             return true;
625         } else if (request.getRequestName().equals(OPEN_URL_REQUEST)
626                 && request.getRequestData() != null) {
627             try {
628                 ByteArrayReader msg = new ByteArrayReader(request
629                         .getRequestData());
630                 openURL(msg.readString(), msg.readString(), request);
631                 return true;
632             } catch (IOException JavaDoc e) {
633                 // #ifdef DEBUG
634
log.error("Failed to process openURL request", e);
635                 // #endif
636
return false;
637             }
638         } else
639             return false;
640     }
641
642     public void postReply(MultiplexedConnection connection) {
643     }
644
645     private void displayMessage(Request request) {
646
647         try {
648             if (request.getRequestData() != null) {
649                 ByteArrayReader msg = new ByteArrayReader(request
650                         .getRequestData());
651                 String JavaDoc title = msg.readString();
652                 msg.readInt(); // type
653
String JavaDoc message = msg.readString();
654
655                 getGUI().popup(
656                         null,
657                         MessageFormat.format(Messages
658                                 .getString("Agent.received"), new Object JavaDoc[] {
659                                 SimpleDateFormat.getDateTimeInstance().format(
660                                         new Date JavaDoc()), message }),
661                         title.equals("") ? Messages
662                                 .getString("Agent.promptTitle") : title,
663                         "popup-mail", 0);
664             }
665         } catch (IOException JavaDoc e) {
666             // #ifdef DEBUG
667
log.error("Failed to read message data from popup message request",
668                     e);
669             // #endif
670
}
671
672     }
673
674     private boolean openURL(String JavaDoc link, String JavaDoc launchId, Request request) {
675
676         // #ifdef DEBUG
677
log.info("Request to open " + link + " via a temporary tunnel"); //$NON-NLS-1$ //$NON-NLS-2$
678
// #endif
679

680         // Parse the link address and create a new address for the browser
681
// to use
682
try {
683             URI url = new URI(link);
684             String JavaDoc linkHost = url.getHost();
685             int linkPort = url.getPort() == -1 ? (url.getScheme()
686                     .equalsIgnoreCase("https") ? 443 : 80) : url.getPort(); //$NON-NLS-1$
687

688             // Start a tunnel
689

690             DefaultTunnel t = new DefaultTunnel(-1,
691                     TunnelConfiguration.LOCAL_TUNNEL,
692                     TunnelConfiguration.TCP_TUNNEL, null, 0, linkPort,
693                     linkHost, false, false, linkHost + ":" + linkPort, launchId);
694
695             LocalTunnelServer listener = getTunnelManager().startLocalTunnel(t);
696
697             // #ifdef DEBUG
698
log.info("Tunneled web forward listener started on port "
699                     + listener.getLocalPort());
700             // #endif
701

702             ByteArrayWriter w = new ByteArrayWriter();
703             w.writeInt(listener.getLocalPort());
704             request.setRequestData(w.toByteArray());
705             return true;
706         } catch (Exception JavaDoc e) {
707             // #ifdef DEBUG
708
log.error("Failed to process openURL request", e);
709             // #endif
710
}
711         return false;
712     }
713
714     /**
715      * Get the current GUI.
716      *
717      * @return gui
718      */

719     public AgentClientGUI getGUI() {
720         return gui;
721     }
722
723     public void updateInformation() {
724
725         // String msg = ""; //$NON-NLS-1$
726
// int count = getActiveDirectTunnels().size()
727
// + activeForwardingTunnels.size();
728
//
729
// for (Enumeration e = remoteListeners.elements();
730
// e.hasMoreElements();) {
731
// MultiplexedConnection con = (MultiplexedConnection) e.nextElement();
732
// count += con.getActiveChannels().length;
733
// }
734
// int ports = activeListeners.size() + remoteListeners.size();
735
// if (ports > 0) {
736
// if (count > 0) {
737
// msg = MessageFormat
738
// .format(
739
// Messages
740
// .getString("VPNClient.information.active"), new Object[] { new
741
// Integer(ports), new Integer(count) }); //$NON-NLS-1$
742
// } else {
743
// msg = MessageFormat
744
// .format(
745
// Messages
746
// .getString("VPNClient.information.notActive"), new Object[] { new
747
// Integer(ports) }); //$NON-NLS-1$
748
// }
749
// } else if (count > 0) {
750
// msg = MessageFormat
751
// .format(
752
// Messages
753
// .getString("VPNClient.information.remainingConnections"), new
754
// Object[] { new Integer(count) }); //$NON-NLS-1$
755
//
756
// }
757
//
758
// if (msg.equals("")) { //$NON-NLS-1$
759
// msg = Messages.getString("VPNClient.information.idle"); //$NON-NLS-1$
760
// }
761
//
762
// gui.setInfo(msg);
763
}
764
765     /*
766      * (non-Javadoc)
767      *
768      * @see com.sslexplorer.vpn.base.AbstractVPNClient#getTXIOListener()
769      */

770     public IOStreamConnectorListener getTXIOListener() {
771         return txm != null ? txm.getTxListener() : null;
772     }
773
774     public IOStreamConnectorListener getRXIOListener() {
775         return txm != null ? txm.getRxListener() : null;
776     }
777
778     /**
779      * Get the full URL to use for a redirect given the path. The appropriate
780      * hostname and port will automatically be added.
781      *
782      * @param path
783      * path
784      * @return full URL including appropriate host and port
785      */

786     protected String JavaDoc getRedirectUrl(String JavaDoc path) {
787         try {
788             new URL JavaDoc(path);
789             return path;
790         } catch (Exception JavaDoc e) {
791             return "https://" + getSSLExplorerHost() + ":" + getSSLExplorerPort() + path; //$NON-NLS-1$ //$NON-NLS-2$
792
}
793     }
794
795     private void startExtensions(String JavaDoc extensionClasses) {
796         StringTokenizer JavaDoc classes = new StringTokenizer JavaDoc(extensionClasses, ","); //$NON-NLS-1$
797
while (classes.hasMoreTokens()) {
798             String JavaDoc cls = classes.nextToken();
799             try {
800                 Class JavaDoc agent = Class.forName(cls);
801                 AgentExtension ext = (AgentExtension) agent.newInstance();
802                 // #ifdef DEBUG
803
log.info("Starting " + ext.getName());
804                 // #endif
805
ext.init(this);
806                 extensions.addElement(ext);
807             } catch (Exception JavaDoc e1) {
808                 // #ifdef DEBUG
809
log.info("Unable to start extension " + cls, e1);
810                 // #endif
811
continue;
812             }
813         }
814     }
815
816     private void connectAgent() throws IOException JavaDoc, HttpException,
817             UnsupportedAuthenticationException,
818             AuthenticationCancelledException {
819
820         HttpResponse response = null;
821
822         try {
823             for (int i = 0; i < 3; i++) {
824
825                 // #ifdef DEBUG
826
log.info("Registering with the SSL-Explorer server"); //$NON-NLS-1$
827
log.info("Server is " + getSSLExplorerHost() //$NON-NLS-1$
828
+ ":" + getSSLExplorerPort()); //$NON-NLS-1$
829
// #endif
830

831                 HttpClient client = getHttpClient();
832                 GetMethod post = new GetMethod("/agent"); //$NON-NLS-1$
833

834                 if (ticketIsPassword) {
835                     client.setCredentials(new PasswordCredentials(username,
836                             ticket));
837                     client.setPreferredAuthentication("Basic");
838                     client.setPreemtiveAuthentication(true);
839                 } else {
840                     if (ticket != null) {
841                         post.setParameter("ticket", ticket); //$NON-NLS-1$
842
}
843                 }
844
845                 post.setParameter(
846                         "agentType", getConfiguration().getAgentType()); //$NON-NLS-1$ //$NON-NLS-2$
847
post.setParameter("locale", Locale.getDefault().toString()); //$NON-NLS-1$
848

849                 response = client.execute(post);
850
851                 if (response.getStatus() == 302) {
852                     // Reset the client
853
this.client = null;
854
855                     URL JavaDoc url = new URL JavaDoc(response.getHeaderField("Location")); //$NON-NLS-1$
856
sslexplorerHostname = url.getHost();
857                     if (url.getPort() > 0)
858                         sslexplorerPort = url.getPort();
859                     continue;
860                 } else if (response.getStatus() == 200) {
861                     con = new MultiplexedConnection(new AgentChannelFactory(
862                             this));
863                     con.addListener(this);
864                     httpConnection = response.getConnection(); // Preserve the
865
// connection
866
con.registerRequestHandler(MESSAGE_REQUEST, this);
867                     con.registerRequestHandler(SHUTDOWN_REQUEST, this);
868                     con.registerRequestHandler(OPEN_URL_REQUEST, this);
869                     con.registerRequestHandler(UPDATE_RESOURCES_REQUEST, this);
870
871                     // Start the protocol
872

873                     con.startProtocol(
874                             response.getConnection().getInputStream(), response
875                                     .getConnection().getOutputStream(), true);
876
877                     // Synchronize and read back server information
878
Request syncRequest = new Request(SYNCHRONIZED_REQUEST);
879                     con.sendRequest(syncRequest, true);
880                     if (syncRequest.getRequestData() == null)
881                         throw new IOException JavaDoc(
882                                 "Server failed to return version data");
883
884                     ByteArrayReader reader = new ByteArrayReader(syncRequest
885                             .getRequestData());
886                     serverVersion = reader.readString();
887
888                     /**
889                      * Initialize the managers. Tunnels are no longer recorded
890                      * here unless they are active. This simplifies the agent by
891                      * making it respond to start and stop requests from the new
892                      * persistent connection with SSL-Explorer.
893                      */

894                     tunnelManager = new TunnelManager(this);
895                     applicationManager = new ApplicationManager(this);
896                     webForwardManager = new WebForwardManager(this);
897                     networkPlaceManager = new NetworkPlaceManager(this);
898                     updateResources(-1);
899                     return;
900                 } else if (response.getStatus() == 401) {
901                     HttpAuthenticator authenticator = HttpAuthenticatorFactory
902                             .createAuthenticator(
903                                     response.getConnection(),
904                                     response
905                                             .getHeaderFields("WWW-Authenticate"),
906                                     "WWW-Authenticate", "Authorization",
907                                     HttpAuthenticatorFactory.BASIC, post
908                                             .getURI());
909                     if (authenticator.wantsPrompt()) {
910                         if (!getGUI()
911                                 .promptForCredentials(false, authenticator)) {
912                             throw new AuthenticationCancelledException();
913                         }
914                     }
915                 } else {
916
917                     // TODO: Popup error message
918

919                     throw new IOException JavaDoc(MessageFormat.format(Messages
920                             .getString("VPNClient.register.failed"),
921                             new Object JavaDoc[] {
922                                     String.valueOf(response.getStatus()),
923                                     response.getReason() }));
924                 }
925             }
926
927             throw new IOException JavaDoc(Messages
928                     .getString("VPNClient.register.tooManyRedirects")); //$NON-NLS-1$
929
} catch (IOException JavaDoc ioe) {
930             disconnected();
931             throw ioe;
932         } catch (HttpException httpe) {
933             disconnected();
934             throw httpe;
935         } catch (UnsupportedAuthenticationException uae) {
936             disconnected();
937             throw uae;
938         } catch (AuthenticationCancelledException ace) {
939             disconnected();
940             throw ace;
941         }
942
943     }
944     
945     public boolean isConnected() {
946         return con != null && con.isRunning();
947     }
948
949     public void disconnect() {
950         if (isConnected()) {
951             disconnectAgent();
952         }
953     }
954
955     /**
956      * Shutdown the Agent.
957      *
958      * @param deregister
959      * deregister the agent
960      * @param threadDeRegister
961      * deregister in a thread
962      */

963     public void startShutdownProcedure() {
964         // #ifdef DEBUG
965
log.info("Starting agent shutdown procedure."); //$NON-NLS-1$
966
// #endif
967

968         if (getConfiguration().isDisplayInformationPopups()) {
969             getGUI()
970                     .popup(
971                             null,
972                             Messages.getString("VPNClient.shutdown.popupText"), Messages.getString("VPNClient.title"), "popup-agent", -1); //$NON-NLS-1$ //$NON-NLS-2$
973
}
974
975         AgentExtension ext;
976         for (Enumeration JavaDoc e = extensions.elements(); e.hasMoreElements();) {
977             ext = (AgentExtension) e.nextElement();
978
979             // #ifdef DEBUG
980
log.info("Stopping extension " + ext.getName()); //$NON-NLS-1$
981
// #endif
982
ext.exit();
983         }
984
985         getGUI().showDisconnected();
986
987         if (getConfiguration().isCleanOnExit()) {
988             if (Utils.isSupportedPlatform("Windows")) {
989                 cleanupWindowsAgent();
990             } else if (Utils.isSupportedPlatform("Linux")) {
991                 cleanupLinuxAgent();
992             } else {
993                 // #ifdef DEBUG
994
log
995                         .info("Agent cleanOnExit is not supported on this platform."); //$NON-NLS-1$
996
// #endif
997

998             }
999         }
1000
1001        if (getConfiguration().isSystemExitOnDisconnect()) {
1002            scheduleExit();
1003        } else {
1004            gui.dispose();
1005        }
1006    }
1007
1008    /**
1009     * Get the default credentials used for proxy server authentication. By
1010     * default this will be <code>null</code>
1011     *
1012     * @return default credentials used for proxy server authentication.
1013     */

1014    public PasswordCredentials getDefaultProxyCredentials() {
1015        return defaultProxyCredentials;
1016    }
1017
1018    /**
1019     * Set the default credentials used for proxy server authentication.
1020     *
1021     * @param defaultProxyCredentials
1022     * default credentials used for proxy server authentication.
1023     */

1024    public void setDefaultProxyCredentials(
1025            PasswordCredentials defaultProxyCredentials) {
1026        this.defaultProxyCredentials = defaultProxyCredentials;
1027    }
1028
1029    /**
1030     * Get the default hostname for the proxy server to use. Use
1031     * <code>null</code> for no proxy server (the default).
1032     *
1033     * @return proxy hostname or <code>null</code> for no proxy
1034     */

1035    public String JavaDoc getDefaultProxyHost() {
1036        return defaultProxyHost;
1037    }
1038
1039    /**
1040     * Set the default hostname for the proxy server to use. Use
1041     * <code>null</code> for no proxy server (the default).
1042     *
1043     * @param defaultProxyHost
1044     * proxy hostname or <code>null</code> for no proxy
1045     */

1046    public void setDefaultProxyHost(String JavaDoc defaultProxyHost) {
1047        this.defaultProxyHost = defaultProxyHost;
1048    }
1049
1050    /**
1051     * Set the default proxy port. By default this is <i>80</i>.
1052     *
1053     * CHECK Why 80? IIS?
1054     *
1055     * @return default proxy port number
1056     */

1057    public int getDefaultProxyPort() {
1058        return defaultProxyPort;
1059    }
1060
1061    /**
1062     * Set the default proxy port. By default this is <i>80</i>.
1063     *
1064     * CHECK Why 80? IIS?
1065     *
1066     * @param defaultProxyPort
1067     * default proxy port number
1068     */

1069    public void setDefaultProxyPort(int defaultProxyPort) {
1070        this.defaultProxyPort = defaultProxyPort;
1071    }
1072
1073    /**
1074     * Get the default proxy type. This may be one of
1075     * {@link HttpClient#PROXY_HTTP}, {@link HttpClient#PROXY_HTTPS} or
1076     * {@link HttpClient#PROXY_NONE}. By default this is
1077     * {@link HttpClient#PROXY_HTTP}.
1078     *
1079     * @return default proxy type
1080     */

1081    public int getDefaultProxyType() {
1082        return defaultProxyType;
1083    }
1084
1085    /**
1086     * Set the default proxy type. This may be one of
1087     * {@link HttpClient#PROXY_HTTP}, {@link HttpClient#PROXY_HTTPS} or
1088     * {@link HttpClient#PROXY_NONE}. By default this is
1089     * {@link HttpClient#PROXY_HTTP}.
1090     *
1091     * @param defaultProxyType
1092     * default proxy type
1093     */

1094    public void setDefaultProxyType(int defaultProxyType) {
1095        this.defaultProxyType = defaultProxyType;
1096    }
1097
1098    /**
1099     * Get the default preferred authentication type to use for proxy servers.
1100     * This may be one of {@link HttpAuthenticatorFactory#BASIC},
1101     * {@link HttpAuthenticatorFactory#NTLM},
1102     * {@link HttpAuthenticatorFactory#DIGEST},
1103     * {@link HttpAuthenticatorFactory#NONE} or <code>null</code> (Automatic).
1104     * The string value <i>"AUTO"</i> may be used instead of <code>null</code>.
1105     *
1106     * @return default proxy authentication type
1107     */

1108    public String JavaDoc getDefaultProxyPreferredAuthentication() {
1109        return defaultProxyPreferredAuthentication;
1110    }
1111
1112    /**
1113     * Set the default preferred authentication type to use for proxy servers.
1114     * This may be one of {@link HttpAuthenticatorFactory#BASIC},
1115     * {@link HttpAuthenticatorFactory#NTLM},
1116     * {@link HttpAuthenticatorFactory#DIGEST},
1117     * {@link HttpAuthenticatorFactory#NONE} or <code>null</code> (Automatic).
1118     * The string value <i>"AUTO"</i> may be used instead of <code>null</code>.
1119     *
1120     * @param defaultProxyPreferredAuthentication
1121     * default proxy authentication type
1122     */

1123    public void setDefaultProxyPreferredAuthentication(
1124            String JavaDoc defaultProxyPreferredAuthentication) {
1125        this.defaultProxyPreferredAuthentication = defaultProxyPreferredAuthentication;
1126    }
1127
1128    /**
1129     * Get the {@link AuthenticationPrompt} that will be used if the proxy
1130     * server requires authentication. This may happen if the default
1131     * authentication details have not been set using the methods in the class
1132     * or if those details are incorrect and the proxy server is requesting
1133     * again.
1134     * <p>
1135     * The prompt may for example display a GUI dialog box that will ask the
1136     * user for details or it may retrieve them from somewhere else such as a
1137     * password database.
1138     * <p>
1139     * If <code>null</code> is returned then no authenitcation prompt is set.
1140     *
1141     * @return authentication prompt
1142     */

1143    public AuthenticationPrompt getDefaultProxyAuthenticationPrompt() {
1144        return defaultProxyAuthenticationPrompt;
1145    }
1146
1147    /**
1148     * Set the {@link AuthenticationPrompt} that will be used if the proxy
1149     * server requires authentication. This may happen if the default
1150     * authentication details have not been set using the methods in the class
1151     * or if those details are incorrect and the proxy server is requesting
1152     * again.
1153     * <p>
1154     * The prompt may for example display a GUI dialog box that will ask the
1155     * user for details or it may retrieve them from somewhere else such as a
1156     * password database.
1157     * <p>
1158     * If <code>null</code> is returned then no authenitcation prompt is set.
1159     *
1160     * @param defaultProxyAuthenticationPrompt
1161     * authentication prompt
1162     */

1163    public void setDefaultProxyAuthenticationPrompt(
1164            AuthenticationPrompt defaultProxyAuthenticationPrompt) {
1165        this.defaultProxyAuthenticationPrompt = defaultProxyAuthenticationPrompt;
1166    }
1167
1168    /**
1169     * Utility method to hide any passwords that may be present in the userinfo
1170     * portion of a URL.
1171     *
1172     * @param originalUrl
1173     * original url
1174     * @return obfuscated url
1175     */

1176    public static String JavaDoc obfuscateURL(String JavaDoc originalUrl) {
1177        try {
1178            URI url = new URI(originalUrl);
1179            String JavaDoc userInfo = url.getUserinfo();
1180            String JavaDoc user = ""; //$NON-NLS-1$
1181
if (userInfo != null && !userInfo.equals("")) { //$NON-NLS-1$
1182
int idx = userInfo.indexOf(':');
1183                user = userInfo;
1184                if (idx != -1) {
1185                    user = userInfo.substring(0, idx);
1186                }
1187                return url.getScheme()
1188                        + "://" + user + ":***@" + url.getHost() + ":" + url.getPort() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1189
+ (url.getQueryString() != null ? ("?" + url.getQueryString()) : ""); //$NON-NLS-1$ //$NON-NLS-2$
1190
} else {
1191                return originalUrl;
1192            }
1193
1194        } catch (URI.MalformedURIException e) {
1195            return originalUrl;
1196        }
1197    }
1198
1199    /**
1200     * Get a <code>Properties</code> that may be sent back to the server so it
1201     * can check if the client is in a supported environment. For example, the
1202     * sun.os.patch.level property may be used to deny clients that are running
1203     * Windows SP1.
1204     *
1205     * @return system properties
1206     */

1207    public static Properties JavaDoc getSystemPropertiesToSend() {
1208        Properties JavaDoc p = new Properties JavaDoc();
1209        setIfNotEmpty("java.version", p); //$NON-NLS-1$
1210
setIfNotEmpty("java.vendor", p); //$NON-NLS-1$
1211
setIfNotEmpty("sun.os.patch.level", p); //$NON-NLS-1$
1212
setIfNotEmpty("os.name", p); //$NON-NLS-1$
1213
setIfNotEmpty("os.version", p); //$NON-NLS-1$
1214
setIfNotEmpty("os.arch", p); //$NON-NLS-1$
1215
return p;
1216    }
1217
1218    protected static void setIfNotEmpty(String JavaDoc name, Properties JavaDoc p) {
1219        String JavaDoc v = System.getProperty(name);
1220        if (v != null && !v.equals("")) { //$NON-NLS-1$
1221
p.put(name, v);
1222        }
1223    }
1224
1225    private static String JavaDoc getCommandLineValue(String JavaDoc arg) {
1226        int idx = arg.indexOf('=');
1227        if (idx > -1)
1228            return arg.substring(idx + 1);
1229        else
1230            return arg;
1231    }
1232
1233    /**
1234     * Entry point.
1235     *
1236     * @param args
1237     * arguments
1238     */

1239    public static void main(String JavaDoc[] args) throws Throwable JavaDoc {
1240
1241        try {
1242            // #ifdef DEBUG
1243
org.apache.log4j.BasicConfigurator.configure();
1244            // #endif
1245

1246            String JavaDoc hostname = null;
1247            int port = 443;
1248            String JavaDoc username = null;
1249            String JavaDoc password = null;
1250            String JavaDoc ticket = null;
1251            String JavaDoc logProperties = null;
1252            int shutdown = -1;
1253            int webforwardInactivity = 300000;
1254            int tunnelInactivity = 600000;
1255            String JavaDoc browserCommand = null;
1256            String JavaDoc localProxyURL = null;
1257            String JavaDoc pluginProxyURL = null;
1258            String JavaDoc userAgent = null;
1259            String JavaDoc extensionClasses = null;
1260            String JavaDoc localeName = Locale.getDefault().toString();
1261
1262            AgentConfiguration configuration = new AgentConfiguration();
1263
1264            for (int i = 0; i < args.length; i++) {
1265                if (args[i].startsWith("hostname")) { //$NON-NLS-1$
1266
hostname = getCommandLineValue(args[i]);
1267                } else if (args[i].startsWith("port")) { //$NON-NLS-1$
1268
try {
1269                        port = Integer.parseInt(getCommandLineValue(args[i]));
1270                    } catch (NumberFormatException JavaDoc ex) {
1271                    }
1272                } else if (args[i].startsWith("username")) { //$NON-NLS-1$
1273
username = getCommandLineValue(args[i]);
1274                } else if (args[i].startsWith("password")) { //$NON-NLS-1$
1275
password = getCommandLineValue(args[i]);
1276                } else if (args[i].startsWith("localProxyURL")) { //$NON-NLS-1$
1277
localProxyURL = getCommandLineValue(args[i]);
1278                } else if (args[i].startsWith("pluginProxyURL")) { //$NON-NLS-1$
1279
pluginProxyURL = getCommandLineValue(args[i]);
1280                } else if (args[i].startsWith("ticket")) { //$NON-NLS-1$
1281
ticket = getCommandLineValue(args[i]);
1282                } else if (args[i].startsWith("browserCommand")) { //$NON-NLS-1$
1283
browserCommand = getCommandLineValue(args[i]);
1284                } else if (args[i].startsWith("userAgent")) { //$NON-NLS-1$
1285
userAgent = getCommandLineValue(args[i]);
1286                    HttpClient.setUserAgent(userAgent);
1287                } else if (args[i].startsWith("locale")) { //$NON-NLS-1$
1288
localeName = getCommandLineValue(args[i]);
1289                } else if (args[i].startsWith("webforward.inactivity")) { //$NON-NLS-1$
1290
try {
1291                        webforwardInactivity = Integer
1292                                .parseInt(getCommandLineValue(args[i]));
1293                    } catch (NumberFormatException JavaDoc ex) {
1294                    }
1295                } else if (args[i].startsWith("tunnel.inactivity")) { //$NON-NLS-1$
1296
try {
1297                        tunnelInactivity = Integer
1298                                .parseInt(getCommandLineValue(args[i]));
1299                    } catch (NumberFormatException JavaDoc ex) {
1300                    }
1301                } else if (args[i].startsWith("shutdown")) { //$NON-NLS-1$
1302
try {
1303                        shutdown = Integer
1304                                .parseInt(getCommandLineValue(args[i]));
1305                    } catch (NumberFormatException JavaDoc ex) {
1306                    }
1307                } else if (args[i].startsWith("log4j")) { //$NON-NLS-1$
1308
logProperties = getCommandLineValue(args[i]);
1309                } else if (args[i].startsWith("extensionClasses")) { //$NON-NLS-1$
1310
extensionClasses = getCommandLineValue(args[i]);
1311                } else if (args[i].startsWith("ignoreCertWarnings")) {
1312                    System.getProperties().put(
1313                            "com.maverick.ssl.allowUntrustedCertificates",
1314                            "true");
1315                    System.getProperties()
1316                            .put("com.maverick.ssl.allowInvalidCertificates",
1317                                    "true");
1318                } else if (args[i].startsWith("forceBasicUI")) {
1319                    configuration
1320                            .setGUIClass("com.sslexplorer.agent.client.gui.BasicFrameGUI");
1321                } else if (args[i].startsWith("displayInformationPopups")) {
1322                    configuration
1323                            .setDisplayInformationPopups(getCommandLineValue(
1324                                    args[i]).equalsIgnoreCase("true"));
1325                } else if (args[i]
1326                        .startsWith("remoteTunnelsRequireConfirmation")) {
1327                    configuration
1328                            .setRemoteTunnelsRequireConfirmation(getCommandLineValue(
1329                                    args[i]).equalsIgnoreCase("true"));
1330                } else if (args[i].startsWith("cleanOnExit")) {
1331                    configuration.setCleanOnExit(getCommandLineValue(args[i])
1332                            .equalsIgnoreCase("true"));
1333                } else if (args[i].startsWith("localhostAddress")) {
1334                    configuration.setLocalhostAddress(getCommandLineValue(args[i]));
1335                } else if (args[i].startsWith("dir")) {
1336                    configuration.setCacheDir(new File JavaDoc(
1337                            Utils.getHomeDirectory(),
1338                            getCommandLineValue(args[i])));
1339                } else if (args[i].startsWith("removeFiles")) {
1340                    StringTokenizer JavaDoc files = new StringTokenizer JavaDoc(
1341                            getCommandLineValue(args[i]), File.pathSeparator);
1342                    while (files.hasMoreTokens()) {
1343                        configuration.removeFileOnExit(new File JavaDoc(files
1344                                .nextToken()));
1345                    }
1346                } else if (args[i].startsWith("keepAlivePeriod")) {
1347                    configuration.setKeepAlivePeriod(Integer
1348                            .parseInt(getCommandLineValue(args[i])));
1349                }
1350            }
1351
1352            if(isWindows64()) {
1353                configuration.setGUIClass("com.sslexplorer.agent.client.gui.BasicFrameGUI");
1354            }
1355            
1356            /*
1357             * Load the message resources.
1358             */

1359            Locale.setDefault(Utils.createLocale(localeName));
1360
1361            if (logProperties == null) {
1362                System.out.println(Messages
1363                        .getString("VPNClient.main.debugModeWarning")); //$NON-NLS-1$
1364
}
1365
1366            if (port == -1 || hostname == null || username == null
1367                    || (ticket == null && password == null))
1368                throw new IOException JavaDoc(
1369                        Messages
1370                                .getString("VPNClient.main.missingCommandLineArguments")); //$NON-NLS-1$
1371

1372            if (shutdown > -1)
1373                configuration.setShutdownPeriod(shutdown);
1374            configuration.setSystemExitOnDisconnect(true);
1375            configuration.setWebForwardInactivity(webforwardInactivity);
1376            configuration.setTunnelInactivity(tunnelInactivity);
1377
1378            Agent agent = new Agent(configuration);
1379
1380            // Setup the output stream
1381
PrintStream JavaDoc consolePrintStream = new PrintStream JavaDoc(agent.getGUI()
1382                    .getConsole());
1383            System.setErr(consolePrintStream);
1384            System.setOut(consolePrintStream);
1385
1386            System.out.println("Java version "
1387                    + System.getProperty("java.version"));
1388            System.out.println("OS version " + System.getProperty("os.name"));
1389
1390            // #ifdef DEBUG
1391
if (logProperties != null) {
1392                File JavaDoc f = new File JavaDoc(logProperties);
1393                InputStream JavaDoc in = new FileInputStream JavaDoc(f);
1394                try {
1395                    Properties JavaDoc props = new Properties JavaDoc();
1396                    props.load(in);
1397                    File JavaDoc logfile = new File JavaDoc(f.getParent(), "agent.log"); //$NON-NLS-1$
1398
props
1399                            .put(
1400                                    "log4j.appender.logfile.File", logfile.getAbsolutePath()); //$NON-NLS-1$
1401
org.apache.log4j.PropertyConfigurator.configure(props);
1402                    log = org.apache.commons.logging.LogFactory
1403                            .getLog(Agent.class);
1404                    log.info("Configured logging"); //$NON-NLS-1$
1405
} finally {
1406                    in.close();
1407                }
1408            }
1409            
1410            Properties JavaDoc systemProperties = System.getProperties();
1411            String JavaDoc key;
1412            log.info("System properties:");
1413            for(Enumeration JavaDoc e = systemProperties.keys(); e.hasMoreElements();) {
1414                key = (String JavaDoc)e.nextElement();
1415                log.info(" " + key + ": " + systemProperties.getProperty(key));
1416            }
1417            
1418            // #endif
1419

1420            agent.setupProxy(localProxyURL, userAgent, pluginProxyURL);
1421
1422            if (browserCommand != null && !browserCommand.equals("")) { //$NON-NLS-1$
1423

1424                // #ifdef DEBUG
1425
log.info("Setting browser to " + browserCommand); //$NON-NLS-1$
1426
// #endif
1427
BrowserLauncher.setBrowserCommand(browserCommand);
1428            }
1429
1430            agent.initMain(hostname, port, username, password, ticket);
1431
1432            if (extensionClasses != null)
1433                agent.startExtensions(extensionClasses);
1434        } catch (Throwable JavaDoc t) {
1435            // Catch any nasties to make sure we exit
1436
// #ifdef DEBUG
1437
if (log != null) {
1438                log.error("Critical error, shutting down.", t); //$NON-NLS-1$
1439
} else {
1440                System.err.println("Critical error, shutting down.");
1441                t.printStackTrace();
1442            }
1443            // #endif
1444
throw t;
1445        }
1446
1447    }
1448    
1449    private static boolean isWindows64() {
1450
1451        String JavaDoc prop = System.getProperty("os.name");
1452        if (prop == null || prop.startsWith("Windows") == false)
1453          return false;
1454
1455        prop = System.getProperty("os.arch");
1456        if (prop != null && prop.equalsIgnoreCase("amd64"))
1457          return true;
1458
1459        prop = System.getProperty("java.vm.name");
1460        if (prop != null && prop.indexOf("64-Bit") != -1)
1461          return true;
1462
1463        prop = System.getProperty("sun.arch.data.model");
1464        if (prop != null && prop.equals("64"))
1465          return true;
1466
1467        return false;
1468    }
1469    
1470    private static boolean isWindowsVista() {
1471        return System.getProperty("os.name").startsWith("Windows Vista");
1472    }
1473
1474    void initMain(String JavaDoc hostname, int port, String JavaDoc username, String JavaDoc password,
1475            String JavaDoc ticket) {
1476        try {
1477            init();
1478            connect(hostname, port, username, ticket == null ? password
1479                    : ticket, ticket == null);
1480        } catch (SSLIOException ex) {
1481            // #ifdef DEBUG
1482
log.info("An unexpected error has occured.", ex.getRealException()); //$NON-NLS-1$
1483
log.info("SSL-Explorer Agent must now exit"); //$NON-NLS-1$
1484
// #endif
1485
gui.showDisconnected();
1486            gui.error(Messages.getString("VPNClient.close"), null, //$NON-NLS-1$
1487
Messages.getString("VPNClient.error"), //$NON-NLS-1$
1488
Messages.getString("VPNClient.failedToConnect"), ex); //$NON-NLS-1$
1489
System.exit(4);
1490        } catch (IOException JavaDoc ex) {
1491            // #ifdef DEBUG
1492
log.info("An unexpected error has occured.", ex); //$NON-NLS-1$
1493
log.info("SSL-Explorer Agent must now exit"); //$NON-NLS-1$
1494
// #endif
1495
gui.error(Messages.getString("VPNClient.close"), null, //$NON-NLS-1$
1496
Messages.getString("VPNClient.error"), //$NON-NLS-1$
1497
Messages.getString("VPNClient.failedToConnect"), ex); //$NON-NLS-1$
1498
gui.showDisconnected();
1499            System.exit(4);
1500        } catch (Throwable JavaDoc t) {
1501            gui.error(Messages.getString("VPNClient.close"), null, //$NON-NLS-1$
1502
Messages.getString("VPNClient.error"), //$NON-NLS-1$
1503
Messages.getString("VPNClient.failedToConnect"), t); //$NON-NLS-1$
1504
// #ifdef DEBUG
1505
log.info("Critical failure", t); //$NON-NLS-1$
1506
// #endif
1507
gui.showDisconnected();
1508            System.exit(4);
1509        }
1510    }
1511
1512    public void setupProxy(String JavaDoc localProxyURL, String JavaDoc userAgent,
1513            String JavaDoc pluginProxyURL) throws MalformedURIException {
1514        if (localProxyURL != null
1515                && !localProxyURL.equals("") && !localProxyURL.startsWith("browser://")) { //$NON-NLS-1$ //$NON-NLS-2$
1516
// Use the user supplied proxy settings
1517

1518            // #ifdef DEBUG
1519
log.info("Setting user specified local proxy URL to " + obfuscateURL(localProxyURL)); //$NON-NLS-1$
1520
// #endif
1521
setLocalProxyURL(localProxyURL);
1522        } else {
1523            // #ifdef DEBUG
1524
log.info("Attempting to detect proxy settings using platform specific methods"); //$NON-NLS-1$
1525
// #endif
1526

1527            if (localProxyURL != null && localProxyURL.startsWith("browser://")) { //$NON-NLS-1$
1528

1529                URI uri = new URI(localProxyURL);
1530
1531                /*
1532                 * Try to determine the proxy settings by first usng platform /
1533                 * browser specific method, then the proxy supplied by the Java
1534                 * plugin.
1535                 *
1536                 * TODO be more intelligent about which browse to try first -
1537                 * use the userAgent parameter passed from the JSP
1538                 */

1539                String JavaDoc proxyURL = null;
1540                if (userAgent != null) {
1541
1542                    // TODO support more browsers
1543

1544                    BrowserProxySettings proxySettings = null;
1545                    if (userAgent.indexOf("MSIE") != -1) { //$NON-NLS-1$
1546
try {
1547                            // #ifdef DEBUG
1548
log.info("Looking for IE"); //$NON-NLS-1$
1549
// #endif
1550
proxySettings = ProxyUtil.lookupIEProxySettings();
1551                        } catch (Throwable JavaDoc t) {
1552                            // #ifdef DEBUG
1553
log
1554                                    .error(
1555                                            "Failed to get IE proxy settings, trying Firefox.", t); //$NON-NLS-1$
1556
// #endif
1557
}
1558                    }
1559
1560                    if (proxySettings == null
1561                            && userAgent.indexOf("Firefox") != -1) { //$NON-NLS-1$
1562
try {
1563                            // #ifdef DEBUG
1564
log.info("Looking for Firefox"); //$NON-NLS-1$
1565
// #endif
1566
proxySettings = ProxyUtil
1567                                    .lookupFirefoxProxySettings();
1568                        } catch (Throwable JavaDoc t) {
1569                            // #ifdef DEBUG
1570
log.error(
1571                                    "Failed to get Firefox proxy settings.", t); //$NON-NLS-1$
1572
// #endif
1573
}
1574                    }
1575                    if (proxySettings != null) {
1576                        // #ifdef DEBUG
1577
log.info("Found some proxy settings."); //$NON-NLS-1$
1578
// #endif
1579
ProxyInfo[] proxyInfo = proxySettings.getProxies();
1580                        for (int i = 0; proxyInfo != null
1581                                && i < proxyInfo.length; i++) {
1582                            // #ifdef DEBUG
1583
log
1584                                    .info("Checking if " + obfuscateURL(proxyInfo[i].toUri()) + " is suitable."); //$NON-NLS-1$
1585
// #endif
1586
if (proxyInfo[i].getProtocol().equals("ssl") || proxyInfo[i].getProtocol().equals("https") //$NON-NLS-1$ //$NON-NLS-2$
1587
|| proxyInfo[i].getProtocol().equals("all")) { //$NON-NLS-1$
1588
StringBuffer JavaDoc buf = new StringBuffer JavaDoc("http://"); //$NON-NLS-1$
1589
if (proxyInfo[i].getUsername() != null
1590                                        && !proxyInfo[i].getUsername().equals(
1591                                                "")) { //$NON-NLS-1$
1592
buf.append(proxyInfo[i].getUsername());
1593                                    if (proxyInfo[i].getPassword() != null
1594                                            && !proxyInfo[i].getPassword()
1595                                                    .equals("")) { //$NON-NLS-1$
1596
buf.append(":"); //$NON-NLS-1$
1597
buf.append(proxyInfo[i].getPassword());
1598                                    }
1599                                    buf.append("@"); //$NON-NLS-1$
1600
}
1601                                buf.append(proxyInfo[i].getHostname());
1602                                if (proxyInfo[i].getPort() != 0) {
1603                                    buf.append(":"); //$NON-NLS-1$
1604
buf.append(proxyInfo[i].getPort());
1605                                }
1606                                if (uri.getHost() != null) {
1607                                    buf.append("?"); //$NON-NLS-1$
1608
buf.append(uri.getHost());
1609                                }
1610                                proxyURL = buf.toString();
1611                                break;
1612                            }
1613                        }
1614                    } else {
1615                        // #ifdef DEBUG
1616
log
1617                                .warn("No useragent supplied, automatic proxy could not check for browse type."); //$NON-NLS-1$
1618
// #endif
1619
}
1620
1621                    // Use the proxy supplied by the plugin if it is
1622
// available
1623
if (proxyURL == null && pluginProxyURL != null
1624                            && !pluginProxyURL.equals("")) { //$NON-NLS-1$
1625
// #ifdef DEBUG
1626
log.info("Using plugin supplied proxy settings."); //$NON-NLS-1$
1627
// #endif
1628
proxyURL = pluginProxyURL;
1629                    }
1630                }
1631
1632                if (proxyURL != null) {
1633                    // #ifdef DEBUG
1634
log
1635                            .info("Setting local proxy URL to " + obfuscateURL(proxyURL) + "."); //$NON-NLS-1$
1636
// #endif
1637
setLocalProxyURL(proxyURL);
1638                }
1639            }
1640        }
1641    }
1642
1643    private void cleanupWindowsAgent() {
1644
1645        // #ifdef DEBUG
1646
log.info("Clearing Windows agent cache"); //$NON-NLS-1$
1647
// #endif
1648

1649        try {
1650            String JavaDoc[] cmds = null;
1651
1652            String JavaDoc homeDir = Utils.getHomeDirectory();
1653
1654            File JavaDoc cwd = getConfiguration().getCacheDir();
1655            // #ifdef DEBUG
1656
log.info("Will remove " + cwd.getAbsolutePath()); //$NON-NLS-1$
1657
// #endif
1658
File JavaDoc scriptFile = new File JavaDoc(homeDir, "sslexplorer-agent-cleanup.bat");
1659            File JavaDoc launchFile = new File JavaDoc(homeDir,
1660                    "sslexplorer-agent-cleanup-launch.bat");
1661            String JavaDoc scriptContents = "@echo off\r\n"
1662                    + "echo SSL-Explorer Agent is removing all downloaded files\r\n"
1663                    + ":Repeat\r\n" + "rd /S /Q \"" + cwd.getAbsolutePath()
1664                    + "\" > NUL 2>&1\r\n" + "if exist \""
1665                    + cwd.getAbsolutePath() + "\" > NUL 2>&1 goto Repeat\r\n";
1666
1667            File JavaDoc toRemove;
1668            for (Enumeration JavaDoc e = getConfiguration().getFilesToRemove(); e
1669                    .hasMoreElements();) {
1670                toRemove = (File JavaDoc) e.nextElement();
1671                if (toRemove.exists()) {
1672                    if (toRemove.isDirectory()) {
1673                        scriptContents += "rd /S /Q \""
1674                                + toRemove.getAbsolutePath()
1675                                + "\" > NUL 2>&1\r\n";
1676                    } else {
1677                        scriptContents += "del \"" + toRemove.getAbsolutePath()
1678                                + "\" > NUL 2>&1\r\n";
1679                    }
1680                }
1681            }
1682            scriptContents += "del \"" + scriptFile.getAbsolutePath()
1683                    + "\" > NUL 2>&1 && exit\r\n";
1684
1685            String JavaDoc launchScript = "start \"SSL-Explorer Agent Cleanup\" /MIN \""
1686                    + scriptFile.getAbsolutePath()
1687                    + "\"\r\n"
1688                    + "del \""
1689                    + launchFile.getAbsolutePath() + "\" > NUL 2>&1\r\n";
1690
1691            cmds = new String JavaDoc[3];
1692            cmds[0] = "cmd.exe";
1693            cmds[1] = "/C";
1694            cmds[2] = "\"" + launchFile.getAbsolutePath() + "\"";
1695
1696            FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(scriptFile);
1697            out.write(scriptContents.getBytes());
1698            out.close();
1699
1700            out = new FileOutputStream JavaDoc(launchFile);
1701            out.write(launchScript.getBytes());
1702            out.close();
1703
1704            final Process JavaDoc proc = Runtime.getRuntime().exec(cmds);
1705
1706            Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
1707                public void run() {
1708                    try {
1709                        InputStream JavaDoc in = proc.getInputStream();
1710                        while (in.read() > -1)
1711                            ;
1712                    } catch (IOException JavaDoc e) {
1713                    }
1714                }
1715            }, "CleanupAgentInput");
1716            Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
1717                public void run() {
1718                    try {
1719                        InputStream JavaDoc in = proc.getErrorStream();
1720                        while (in.read() > -1)
1721                            ;
1722                    } catch (IOException JavaDoc e) {
1723                    }
1724                }
1725            }, "CleanupAgentOutput");
1726
1727            t1.start();
1728            t2.start();
1729
1730        } catch (Exception JavaDoc e) {
1731
1732        }
1733    }
1734
1735    /**
1736     * Schedule a System.exit() in a thread. After the configured shutdown
1737     * period has elapsed the JVM will terminate.
1738     */

1739    public void scheduleExit() {
1740        Thread JavaDoc t = new Thread JavaDoc("ScheduledExit") {
1741            public void run() {
1742                try {
1743                    Thread.sleep(getConfiguration().getShutdownPeriod());
1744                } catch (InterruptedException JavaDoc ex) {
1745                }
1746                gui.dispose();
1747                // #ifdef DEBUG
1748
log.info("Exiting JVM."); //$NON-NLS-1$
1749
// #endif
1750
System.exit(0);
1751            }
1752        };
1753        t.start();
1754    }
1755
1756    private void disconnected() {
1757        currentState = STATE_DISCONNECTED;
1758        getGUI().showDisconnected();
1759    }
1760
1761    private void disconnectAgent() {
1762
1763        // #ifdef DEBUG
1764
log.info("Disconnecting Agent"); //$NON-NLS-1$
1765
// #endif
1766
// Disconnect the multiplexed protocol
1767
keepAlive.stopThread();
1768        con.disconnect("The agent is shutting down");
1769        // This is a backup to ensure that the socket is released.
1770
httpConnection.close();
1771    }
1772
1773    private void cleanupLinuxAgent() {
1774
1775        // #ifdef DEBUG
1776
log.info("Clearing Linux agent cache"); //$NON-NLS-1$
1777
// #endif
1778

1779        try {
1780            String JavaDoc[] cmds = null;
1781            String JavaDoc homeDir = Utils.getHomeDirectory();
1782            File JavaDoc cacheDir = getConfiguration().getCacheDir();
1783            // #ifdef DEBUG
1784
log.info("Will remove " + cacheDir.getAbsolutePath()); //$NON-NLS-1$
1785
// #endif
1786
File JavaDoc scriptFile = new File JavaDoc(homeDir, "sslexplorer-agent-cleanup.sh");
1787            File JavaDoc launchFile = new File JavaDoc(homeDir,
1788                    "sslexplorer-agent-cleanup-launch.sh");
1789
1790            // clean up script
1791
StringBuffer JavaDoc scriptContents = new StringBuffer JavaDoc();
1792            scriptContents.append("#!/bin/sh\n");
1793            scriptContents.append("sleep 3\n");
1794            scriptContents.append("rm -fr \"");
1795            scriptContents.append(cacheDir.getAbsolutePath());
1796            scriptContents.append("\" \"");
1797
1798            File JavaDoc toRemove;
1799            for (Enumeration JavaDoc e = getConfiguration().getFilesToRemove(); e
1800                    .hasMoreElements();) {
1801                toRemove = (File JavaDoc) e.nextElement();
1802                scriptContents.append(toRemove.getAbsolutePath());
1803                scriptContents.append("\" \"");
1804            }
1805
1806            scriptContents.append(scriptFile.getAbsolutePath());
1807            scriptContents.append("\" \"");
1808            scriptContents.append(launchFile.getAbsolutePath());
1809            scriptContents.append("\"\n");
1810
1811            // launch script
1812
StringBuffer JavaDoc launchScript = new StringBuffer JavaDoc();
1813            launchScript.append("#!/bin/sh\n");
1814            launchScript.append("nohup sh \"");
1815            launchScript.append(scriptFile.getAbsolutePath());
1816            launchScript.append("\" &\n");
1817
1818            cmds = new String JavaDoc[2];
1819            cmds[0] = "sh";
1820            cmds[1] = launchFile.getAbsolutePath();
1821
1822            FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(scriptFile);
1823            out.write(scriptContents.toString().getBytes());
1824            out.close();
1825
1826            out = new FileOutputStream JavaDoc(launchFile);
1827            out.write(launchScript.toString().getBytes());
1828            out.close();
1829
1830            final Process JavaDoc proc = Runtime.getRuntime().exec(cmds);
1831
1832            Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
1833                public void run() {
1834                    try {
1835                        InputStream JavaDoc in = proc.getInputStream();
1836                        while (in.read() > -1)
1837                            ;
1838                    } catch (IOException JavaDoc e) {
1839                    }
1840                }
1841            });
1842            Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
1843                public void run() {
1844                    try {
1845                        InputStream JavaDoc in = proc.getErrorStream();
1846                        while (in.read() > -1)
1847                            ;
1848                    } catch (IOException JavaDoc e) {
1849                    }
1850                }
1851            });
1852
1853            t1.start();
1854            t2.start();
1855
1856        } catch (Exception JavaDoc e) {
1857
1858        }
1859    }
1860    
1861    protected void updateResources(int resourceTypeId) {
1862        if (getConfiguration().isGetResources()) {
1863            /* TODO we should consider moving the services into the appropriate extension instead
1864             * of all in the agent module. It should now be possible to rewrite them as agent
1865             * extensions
1866             */

1867            
1868            // Applications
1869
if(resourceTypeId == -1 || resourceTypeId == ApplicationManager.APPLICATION_SHORTCUT_RESOURCE_TYPE_ID)
1870                applicationManager.getApplicationResources();
1871            
1872            // Tunnels
1873
if(resourceTypeId == -1 || resourceTypeId == TunnelManager.TUNNEL_RESOURCE_TYPE_ID)
1874                tunnelManager.getTunnelResources();
1875            
1876            // Web forwards
1877
if(resourceTypeId == -1 || resourceTypeId == WebForwardManager.WEBFORWARD_RESOURCE_TYPE_ID)
1878                webForwardManager.getWebForwardResources();
1879            
1880            // Network places
1881
if(resourceTypeId == -1 || resourceTypeId == NetworkPlaceManager.NETWORK_PLACE_RESOURCE_TYPE_ID)
1882                networkPlaceManager.getNetworkPlaceResources();
1883        }
1884    }
1885
1886    class KeepAliveThread extends Thread JavaDoc {
1887
1888        boolean running = true;
1889
1890        Request keepAlive = new Request("keepalive@3sp.com");
1891
1892        public void run() {
1893
1894            long period = getConfiguration().getKeepAlivePeriod();
1895
1896            while (running && con.isRunning()) {
1897                try {
1898                    Thread.sleep(period);
1899                } catch (InterruptedException JavaDoc e) {
1900                }
1901
1902                if (!running || !con.isRunning()) {
1903                    break;
1904                }
1905
1906                try {
1907                    con.sendRequest(keepAlive, true, getConfiguration()
1908                            .getKeepAliveTimeout());
1909                } catch (InterruptedIOException JavaDoc ex) {
1910                    //#ifdef DEBUG
1911
log.error("Keepalive packet timed out!! Agent connection is no longer operational", ex);
1912                    //#endif
1913
if (getConfiguration().isDisplayInformationPopups()) {
1914                        getGUI().popup(
1915                            null,
1916                            Messages.getString("VPNClient.keepalive.timeout"), Messages.getString("VPNClient.title"), "popup-error", -1); //$NON-NLS-1$ //$NON-NLS-2$
1917
}
1918                    try {
1919                        Thread.sleep(10000);
1920                    } catch (InterruptedException JavaDoc e) {
1921                    }
1922                    Agent.this.startShutdownProcedure();
1923                } catch (IOException JavaDoc e) {
1924                    //#ifdef DEBUG
1925
log.error("Keepalive IO error!! Agent connection is no longer operational", e);
1926                    //#endif
1927
if (getConfiguration().isDisplayInformationPopups()) {
1928                        getGUI().popup(
1929                            null,
1930                            Messages.getString("VPNClient.keepalive.error"), Messages.getString("VPNClient.title"), "popup-error", -1); //$NON-NLS-1$ //$NON-NLS-2$
1931
}
1932                    try {
1933                        Thread.sleep(10000);
1934                    } catch (InterruptedException JavaDoc e2) {
1935                    }
1936                    Agent.this.startShutdownProcedure();
1937                }
1938            }
1939
1940        }
1941
1942        public void stopThread() {
1943            running = false;
1944            interrupt();
1945        }
1946    }
1947}
1948
Popular Tags