KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > server > Main


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.server;
21
22 import java.io.BufferedReader JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FilenameFilter JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.net.Authenticator JavaDoc;
30 import java.net.Inet4Address JavaDoc;
31 import java.net.InetAddress JavaDoc;
32 import java.net.NetworkInterface JavaDoc;
33 import java.net.Socket JavaDoc;
34 import java.net.SocketException JavaDoc;
35 import java.net.URL JavaDoc;
36 import java.net.URLClassLoader JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.Arrays JavaDoc;
39 import java.util.Collection JavaDoc;
40 import java.util.Enumeration JavaDoc;
41 import java.util.HashMap JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.List JavaDoc;
44 import java.util.Map JavaDoc;
45 import java.util.Properties JavaDoc;
46 import java.util.StringTokenizer JavaDoc;
47 import java.util.TreeMap JavaDoc;
48 import java.util.prefs.BackingStoreException JavaDoc;
49 import java.util.prefs.Preferences JavaDoc;
50
51 import javax.net.ssl.TrustManager;
52 import javax.servlet.http.HttpServletRequest JavaDoc;
53 import javax.servlet.http.HttpServletResponse JavaDoc;
54 import javax.swing.JOptionPane JavaDoc;
55 import javax.swing.SwingUtilities JavaDoc;
56 import javax.swing.UIManager JavaDoc;
57
58 import org.apache.commons.logging.Log;
59 import org.apache.commons.logging.LogFactory;
60 import org.jdom.Element;
61 import org.jdom.JDOMException;
62 import org.jdom.input.SAXBuilder;
63 import org.mortbay.http.HttpContext;
64 import org.mortbay.http.NCSARequestLog;
65 import org.mortbay.http.ResourceCache;
66 import org.mortbay.http.SocketListener;
67 import org.mortbay.http.handler.MsieSslHandler;
68 import org.mortbay.jetty.Server;
69 import org.mortbay.jetty.servlet.ServletHandler;
70 import org.mortbay.jetty.servlet.ServletHttpRequest;
71 import org.mortbay.jetty.servlet.ServletHttpResponse;
72 import org.mortbay.util.LifeCycleEvent;
73 import org.mortbay.util.LifeCycleListener;
74 import org.mortbay.util.Password;
75 import org.tanukisoftware.wrapper.WrapperListener;
76 import org.tanukisoftware.wrapper.WrapperManager;
77
78 import com.sslexplorer.boot.BootProgressMonitor;
79 import com.sslexplorer.boot.BrowserLauncher;
80 import com.sslexplorer.boot.Context;
81 import com.sslexplorer.boot.ContextConfig;
82 import com.sslexplorer.boot.ContextHolder;
83 import com.sslexplorer.boot.ContextKey;
84 import com.sslexplorer.boot.ContextListener;
85 import com.sslexplorer.boot.DefaultPropertyDefinition;
86 import com.sslexplorer.boot.KeyStoreManager;
87 import com.sslexplorer.boot.LogBootProgressMonitor;
88 import com.sslexplorer.boot.PropertyClass;
89 import com.sslexplorer.boot.PropertyClassManager;
90 import com.sslexplorer.boot.PropertyDefinition;
91 import com.sslexplorer.boot.PropertyList;
92 import com.sslexplorer.boot.PropertyPreferences;
93 import com.sslexplorer.boot.RequestHandler;
94 import com.sslexplorer.boot.RequestHandlerRequest;
95 import com.sslexplorer.boot.RequestHandlerResponse;
96 import com.sslexplorer.boot.StopContextListenerThread;
97 import com.sslexplorer.boot.Util;
98 import com.sslexplorer.boot.VersionInfo;
99 import com.sslexplorer.boot.XMLPropertyDefinition;
100 import com.sslexplorer.boot.VersionInfo.Version;
101 import com.sslexplorer.server.jetty.CustomHttpContext;
102 import com.sslexplorer.server.jetty.CustomJsseListener;
103 import com.sslexplorer.server.jetty.CustomWebApplicationContext;
104 import com.sslexplorer.server.jetty.HTTPRedirectHandler;
105 import com.sslexplorer.server.jetty.JspPrecompiler;
106
107 /**
108  * <p>
109  * Provides an entry point and a default environment for starting the
110  * SSL-Explorer service.
111  *
112  * <p>
113  * SSL-Explorer is primarily a standard Java web application. However, it
114  * requires a few additional services from the container that it is running in.
115  * This environment is called the {@link com.sslexplorer.boot.Context} (see this
116  * interfaces Javadoc for more information about this environment) and this
117  * class implements that interface.
118  *
119  * <p>
120  * This class currently provides an implementation that uses Jetty for the
121  * servlet / JSP container.
122  *
123  * <p>
124  * The <i>Context Properties</b> are stored using the Java Preferences API so
125  * will likely end up in the Windows register on Win32 platforms or XML files
126  * everywhere else.
127  *
128  * @see com.sslexplorer.boot.Context
129  * @author Brett Smith <brett@3sp.com>
130  */

131 public class Main implements WrapperListener, Context {
132     // Private statics
133

134     private static File JavaDoc DB_DIR = new File JavaDoc("db");
135     private static File JavaDoc CONF_DIR = new File JavaDoc("conf");
136     private static File JavaDoc TMP_DIR = new File JavaDoc("tmp");
137     private static File JavaDoc LOG_DIR = new File JavaDoc("logs");
138     private static File JavaDoc appDir = null;
139
140     static Log log;
141     static Preferences JavaDoc PREF;
142
143     // Private instance variables
144
private Server server;
145     private long startupStarted;
146     private HashMap JavaDoc<URL JavaDoc,ResourceCache> resourceCaches;
147     private String JavaDoc hostAddress;
148     private static boolean useWrapper = false;
149     private boolean install;
150     private boolean gui;
151     private Throwable JavaDoc startupException;
152     private List JavaDoc<SocketListener> listeners;
153     private CustomWebApplicationContext webappContext;
154     private CustomHttpContext httpContext;
155     private String JavaDoc jettyLog;
156     private int defaultPort;
157     private int actualPort;
158     private boolean useDevConfig;
159     private String JavaDoc hostname;
160     private ServerLock serverLock;
161     private Thread JavaDoc mainThread;
162     private Thread JavaDoc insecureThread;
163     private ThreadGroup JavaDoc threadGroup;
164     private TreeMap JavaDoc<String JavaDoc, PropertyDefinition> contextPropertyDefinitions;
165     private List JavaDoc<ContextListener> contextListeners;
166     private boolean shuttingDown;
167     private ContextConfig contextConfiguration;
168     private BootProgressMonitor bootProgressMonitor;
169     private boolean logToConsole;
170     private boolean restarting;
171     private Server insecureServer;
172     private ServletHandler servletHandler;
173
174     /**
175      * Entry point
176      *
177      * @param args
178      * @throws Throwable
179      */

180     public static void main(String JavaDoc[] args) throws Throwable JavaDoc {
181
182         // This is a hack to allow the Install4J installer to get the java
183
// runtime that will be used
184
if (args.length > 0 && args[0].equals("--jvmdir")) {
185             System.out.println(System.getProperty("java.home"));
186             System.exit(0);
187         }
188         useWrapper = System.getProperty("wrapper.key") != null;
189         final Main main = new Main();
190         ContextHolder.setContext(main);
191
192         if (useWrapper) {
193             WrapperManager.start(main, args);
194         } else {
195             Integer JavaDoc returnCode = main.start(args);
196             if (returnCode != null) {
197                 if (main.gui) {
198                     if (main.startupException == null) {
199                         main.startupException = new Exception JavaDoc("An exit code of " + returnCode + " was returned.");
200                     }
201                     try {
202                         if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
203                             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
204                         }
205                     } catch (Exception JavaDoc e) {
206                     }
207                     String JavaDoc mesg = main.startupException.getMessage() == null ? "No message supplied." : main.startupException
208                                     .getMessage();
209                     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
210                     int l = 0;
211                     char ch = ' ';
212                     for (int i = 0; i < mesg.length(); i++) {
213                         ch = mesg.charAt(i);
214                         if (l > 50 && ch == ' ') {
215                             buf.append("\n");
216                             l = 0;
217                         } else {
218                             if (ch == '\n') {
219                                 l = 0;
220                             } else {
221                                 l++;
222                             }
223                             buf.append(ch);
224                         }
225                     }
226                     mesg = buf.toString();
227                     final String JavaDoc fMesg = mesg;
228                     SwingUtilities.invokeAndWait(new Runnable JavaDoc() {
229                         public void run() {
230                             JOptionPane.showMessageDialog(null, fMesg, "SSL-Explorer Startup Error", JOptionPane.ERROR_MESSAGE);
231                         }
232                     });
233                 }
234                 System.exit(returnCode.intValue());
235             } else {
236                 Runtime.getRuntime().addShutdownHook(new Thread JavaDoc() {
237                     public void run() {
238                         if (!main.shuttingDown) {
239                             main.stop(0);
240                         }
241                     }
242                 });
243             }
244         }
245     }
246
247     /*
248      * (non-Javadoc)
249      *
250      * @see org.tanukisoftware.wrapper.WrapperListener#start(java.lang.String[])
251      */

252     public Integer JavaDoc start(String JavaDoc[] args) {
253         startupStarted = System.currentTimeMillis();
254
255         // Inform the wrapper the startup process may take a while
256
if (useWrapper) {
257             WrapperManager.signalStarting(60000);
258         }
259         
260         // Parse the command line
261
Integer JavaDoc returnCode = parseCommandLine(args);
262         if (returnCode != null) {
263             if (returnCode.intValue() == 999) {
264                 return null;
265             }
266             return returnCode;
267         }
268         
269         // Create the boot progress monitor
270
if(gui) {
271             try {
272                 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
273             } catch (Exception JavaDoc e) {
274             }
275             bootProgressMonitor = new SwingBootProgressMonitor();
276         }
277         else {
278             bootProgressMonitor = new LogBootProgressMonitor();
279         }
280
281         //
282
resourceCaches = new HashMap JavaDoc<URL JavaDoc,ResourceCache>();
283         contextListeners = new ArrayList JavaDoc<ContextListener>();
284
285         loadSystemProperties();
286         initialiseLogging();
287
288         /*
289          * Migrate preferences.
290          */

291         File JavaDoc newPrefDir = new File JavaDoc(ContextHolder.getContext().getConfDirectory(), "prefs");
292         PREF = PropertyPreferences.SYSTEM_ROOT;
293         try {
294             if (!newPrefDir.exists() && Preferences.systemRoot().node("/com").nodeExists("sslexplorer")) {
295                 Preferences JavaDoc from = Preferences.systemRoot().node("/com/sslexplorer");
296                 log.warn("Migrating preferences");
297                 try {
298                     copyNode(from.node("core") , PREF.node("core"));
299                     from.node("core").removeNode();
300                     copyNode(from.node("plugin") , PREF.node("plugin"));
301                     from.node("plugin").removeNode();
302                     copyNode(from.node("extensions") , PREF.node("extensions"));
303                     from.node("extensions").removeNode();
304                     copyNode(from.node("dbupgrader") , PREF.node("dbupgrader"));
305                     from.node("dbupgrader").removeNode();
306                 } catch (Exception JavaDoc e) {
307                     log.error("Failed to migrate preferences.", e);
308                 }
309                 try {
310                     from.flush();
311                 } catch (BackingStoreException JavaDoc bse) {
312                     log.error("Failed to flush old preferences");
313                 }
314                 try {
315                     PREF.flush();
316                 } catch (BackingStoreException JavaDoc bse) {
317                     log.error("Failed to flush new preferences");
318                 }
319                 if (log.isInfoEnabled()) {
320                     log.info("Flushing preferences");
321                 }
322
323             }
324         } catch (BackingStoreException JavaDoc bse) {
325             log.error("Failed to migrate preferences.", bse);
326         }
327         
328         // Inform the wrapper the startup process is going ok
329
if (useWrapper) {
330             WrapperManager.signalStarting(60000);
331         }
332
333         try {
334             clearTemp();
335             try {
336                 hostname = Inet4Address.getLocalHost().getCanonicalHostName();
337                 hostAddress = Inet4Address.getLocalHost().getHostAddress();
338             } catch (Exception JavaDoc ex) {
339                 // This should be fatal, we now rely on the hostname being
340
// available
341
throw new Exception JavaDoc("The host name or address on which this service is running could not "
342                                 + "be determined. Check you network configuration. One possible cause is "
343                                 + "a misconfigured 'hosts' file (e.g. on UNIX-like systems this would be "
344                                 + "/etc/hosts, on Windows XP it would be " + "C:\\Windows\\System32\\Drivers\\Etc\\Hosts).");
345             }
346             
347             PropertyClassManager.getInstance().registerPropertyClass(contextConfiguration = new ContextConfig());
348
349             // Display some information about the system we are running on
350
displaySystemInfo();
351
352             // Load the context property definitions
353
loadContextProperties();
354             
355             // Inform the wrapper the startup process is going ok
356
if (useWrapper) {
357                 WrapperManager.signalStarting(60000);
358             }
359
360             // Configure any HTTP / HTTPS / SOCKS proxy servers
361
configureProxyServers();
362  
363             PropertyList l = contextConfiguration.retrievePropertyList(new ContextKey("webServer.bindAddress"));
364             getBootProgressMonitor().updateMessage("Creating server lock");
365             getBootProgressMonitor().updateProgress(6);
366             serverLock = new ServerLock((String JavaDoc) l.get(0));
367             if (serverLock.isLocked()) {
368                 if (!isSetupMode()) {
369                     if (serverLock.isSetup()) {
370                         throw new Exception JavaDoc("The SSL-Explorer installation wizard is currently running. "
371                                         + "Please shut this down by pointing your browser " + "to http://" + getHostname() + ":"
372                                         + serverLock.getPort() + "/showShutdown.do before attempting to start the server again.");
373                     } else {
374                         throw new Exception JavaDoc("SSL-Explorer is already running.");
375                     }
376                 } else {
377                     if (!serverLock.isSetup()) {
378                         throw new Exception JavaDoc("SSL-Explorer is currently already running. "
379                                         + "Please shut this down by pointing your browser " + "to https://" + getHostname() + ":"
380                                         + serverLock.getPort() + "/showShutdown.do before attempting to start the server again.");
381                     } else {
382                         throw new Exception JavaDoc("The SSL-Explorer installation wizard is running..");
383                     }
384
385                 }
386
387             }
388             
389             // Inform the wrapper the startup process is going ok
390
if (useWrapper) {
391                 WrapperManager.signalStarting(60000);
392             }
393
394             Runtime.getRuntime().addShutdownHook(new Thread JavaDoc() {
395                 public void run() {
396                     serverLock.stop();
397                 }
398             });
399
400             //
401
registerKeyStores();
402
403             //
404
threadGroup = new ThreadGroup JavaDoc("MainThreadGroup");
405
406             if (install) {
407                 setupMode();
408
409             } else {
410                 normalMode();
411                 startHttpServer();
412             }
413         } catch (Throwable JavaDoc t) {
414             startupException = t;
415             log.error("Failed to start SSL Explorer. " + t.getMessage(), t);
416             return new Integer JavaDoc(1);
417         }
418
419         return null;
420     }
421
422     /* (non-Javadoc)
423      * @see com.sslexplorer.boot.Context#getConfig()
424      */

425     public PropertyClass getConfig() {
426         return contextConfiguration;
427     }
428
429     /*
430      * (non-Javadoc)
431      *
432      * @see org.tanukisoftware.wrapper.WrapperListener#controlEvent(int)
433      */

434     public void controlEvent(int evt) {
435         if (evt == WrapperManager.WRAPPER_CTRL_C_EVENT) {
436             if (log.isInfoEnabled())
437                 log.info("Got CTRL+C event");
438             WrapperManager.stop(0);
439         } else if (evt == WrapperManager.WRAPPER_CTRL_CLOSE_EVENT) {
440             if (log.isInfoEnabled())
441                 log.info("Got windows close event, ignoring.");
442         } else if (evt == WrapperManager.WRAPPER_CTRL_LOGOFF_EVENT) {
443             if (log.isInfoEnabled())
444                 log.info("Got windows logoff event, ignoring.");
445         } else if (evt == WrapperManager.WRAPPER_CTRL_SHUTDOWN_EVENT) {
446             if (log.isInfoEnabled())
447                 log.info("Got shutdown event");
448             WrapperManager.stop(0);
449         } else {
450             if (log.isInfoEnabled())
451                 log.info("Got unknown control event " + evt + ", ignoring.");
452         }
453
454     }
455
456     /*
457      * (non-Javadoc)
458      *
459      * @see org.tanukisoftware.wrapper.WrapperListener#stop(int)
460      */

461     public int stop(int exitCode) {
462         if (log != null) {
463             if (log.isInfoEnabled()) {
464                 if(restarting)
465                     log.info("Restarting SSL Explorer.");
466                 else
467                     log.info("Shutting down SSL Explorer.");
468             }
469         }
470         if (useWrapper) {
471             WrapperManager.signalStopping(20000);
472         }
473
474         // TODO This really screws up wrapper on windows - no idea why
475
if (server != null && server.isStarted()) {
476             try {
477                 server.stop(false);
478             } catch (InterruptedException JavaDoc e) {
479                 if (log != null) {
480                     if (log.isInfoEnabled())
481                         log.info("Failed to stop server.", e);
482                 }
483             }
484         }
485
486         // Inform all context listeners of what is happening
487
for (ContextListener l : contextListeners) {
488             new StopContextListenerThread(l).waitForStop();
489         }
490
491         //
492
if (log.isInfoEnabled()) {
493             log.info("Flushing preferences");
494         }
495         try {
496             ContextHolder.getContext().getPreferences().flush();
497         } catch (BackingStoreException JavaDoc bse) {
498             log.error("Failed to flush context preferences.", bse);
499         }
500         try {
501             Preferences.systemRoot().flush();
502         } catch (BackingStoreException JavaDoc bse) {
503             log.error("Failed to flush system preferences");
504         }
505
506         return exitCode;
507     }
508     
509     void loadContextProperties() throws IOException JavaDoc, JDOMException {
510         getBootProgressMonitor().updateMessage("Loading context properties");
511         getBootProgressMonitor().updateProgress(4);
512         contextPropertyDefinitions = new TreeMap JavaDoc<String JavaDoc, PropertyDefinition>();
513         for(Enumeration JavaDoc<URL JavaDoc> e = getClass().getClassLoader().getResources(
514             "META-INF/systemConfig-definitions.xml"); e.hasMoreElements(); ) {
515             URL JavaDoc u = e.nextElement();
516             log.info("Loading context property definitions from " + u);
517             SAXBuilder build = new SAXBuilder();
518             Element root = build.build(u).getRootElement();
519             if(!root.getName().equals("definitions")) {
520                 throw new JDOMException("Root element in " + u + " should be <definitions>");
521             }
522             for(Iterator JavaDoc i = root.getChildren().iterator(); i.hasNext(); ) {
523                 Element c = (Element)i.next();
524                 if(c.getName().equals("definition")) {
525                     DefaultPropertyDefinition def = new XMLPropertyDefinition(c);
526                     contextPropertyDefinitions.put(def.getName(), def);
527                 }
528                 else {
529                     throw new JDOMException("Expect root element of <definitions> with child elements of <definition>. Got <" + c.getName() + ">.");
530                 }
531             }
532         }
533         
534     }
535
536     void copyNode(Preferences JavaDoc from, Preferences JavaDoc to) throws BackingStoreException JavaDoc {
537         String JavaDoc[] keys = from.keys();
538         for (int i = 0; i < keys.length; i++) {
539             to.put(keys[i], from.get(keys[i], ""));
540         }
541         String JavaDoc childNodes[] = from.childrenNames();
542         for (int i = 0; i < childNodes.length; i++) {
543             Preferences JavaDoc cn = from.node(childNodes[i]);
544             Preferences JavaDoc tn = to.node(childNodes[i]);
545             copyNode(cn, tn);
546         }
547     }
548
549     /*
550      * (non-Javadoc)
551      *
552      * @see com.sslexplorer.boot.Context#isSetupMode()
553      */

554     public boolean isSetupMode() {
555         return install;
556     }
557
558     /*
559      * (non-Javadoc)
560      *
561      * @see com.sslexplorer.boot.Context#isRestartAvailableMode()
562      */

563     public boolean isRestartAvailableMode() {
564         return ( useDevConfig || useWrapper ) && !isSetupMode();
565     }
566
567     /*
568      * (non-Javadoc)
569      *
570      * @see com.sslexplorer.boot.Context#shutdown(boolean)
571      */

572     public void shutdown(boolean restart) {
573         shuttingDown = true;
574         restarting = restart;
575         if (useWrapper) {
576             if (restart) {
577                 WrapperManager.restart();
578             } else {
579                 WrapperManager.stop(0);
580             }
581         } else {
582             stop(0);
583             System.exit(0);
584         }
585
586     }
587
588     /*
589      * (non-Javadoc)
590      *
591      * @see com.sslexplorer.boot.Context#getVersion()
592      */

593     public Version getVersion() {
594         return VersionInfo.getVersion();
595     }
596
597     /*
598      * (non-Javadoc)
599      *
600      * @see com.sslexplorer.boot.Context#getConfDirectory()
601      */

602     public File JavaDoc getConfDirectory() {
603         return CONF_DIR;
604     }
605
606     /*
607      * (non-Javadoc)
608      *
609      * @see com.sslexplorer.boot.Context#getTempDirectory()
610      */

611     public File JavaDoc getTempDirectory() {
612         return TMP_DIR;
613     }
614
615     /*
616      * (non-Javadoc)
617      *
618      * @see com.sslexplorer.boot.Context#getLogDirectory()
619      */

620     public File JavaDoc getLogDirectory() {
621         return LOG_DIR;
622     }
623
624     /*
625      * (non-Javadoc)
626      *
627      * @see com.sslexplorer.boot.Context#getApplicationDirectory()
628      */

629     public File JavaDoc getApplicationDirectory() {
630         return appDir == null ? new File JavaDoc(getTempDirectory(), "extensions") : appDir;
631     }
632
633     /*
634      * (non-Javadoc)
635      *
636      * @see com.sslexplorer.boot.Context#getDBDirectory()
637      */

638     public File JavaDoc getDBDirectory() {
639         return DB_DIR;
640     }
641
642     /*
643      * (non-Javadoc)
644      *
645      * @see com.sslexplorer.boot.Context#getMainThread()
646      */

647     public Thread JavaDoc getMainThread() {
648         return mainThread;
649     }
650
651     /* (non-Javadoc)
652      * @see com.sslexplorer.boot.Context#setResourceAlias(java.lang.String, java.lang.String)
653      */

654     public void setResourceAlias(String JavaDoc uri, String JavaDoc location) {
655         webappContext.setResourceAlias(uri, location);
656     }
657
658     /*
659      * (non-Javadoc)
660      *
661      * @see com.sslexplorer.boot.Context#addResourceBase(java.net.URL)
662      */

663     public void addResourceBase(URL JavaDoc base) {
664         if (log.isInfoEnabled())
665             log.info("Adding new resource base " + base.toExternalForm());
666         ResourceCache cache = new ResourceCache();
667         cache.setMimeMap(webappContext.getMimeMap());
668         cache.setEncodingMap(webappContext.getEncodingMap());
669         cache.setResourceBase(base.toExternalForm());
670         try {
671             cache.start();
672             webappContext.addResourceCache(cache);
673             if (httpContext != null) {
674                 httpContext.addResourceCache(cache);
675             }
676             resourceCaches.put(base, cache);
677         } catch (Exception JavaDoc e) {
678             log.error("Failed to add new resource base " + base.toExternalForm() + ".", e);
679         }
680
681     }
682
683     /*
684      * (non-Javadoc)
685      *
686      * @see com.sslexplorer.boot.Context#addResourceBase(java.net.URL)
687      */

688     public void removeResourceBase(URL JavaDoc base) {
689         if (log.isInfoEnabled())
690             log.info("Removing resource base " + base.toExternalForm());
691         ResourceCache cache = (ResourceCache) resourceCaches.get(base);
692         webappContext.removeResourceCache(cache);
693         if (httpContext != null) {
694             httpContext.removeResourceCache(cache);
695         }
696     }
697
698     /*
699      * (non-Javadoc)
700      *
701      * @see com.sslexplorer.boot.Context#getHostname()
702      */

703     public String JavaDoc getHostname() {
704         return hostname;
705     }
706
707     /*
708      * (non-Javadoc)
709      *
710      * @see com.sslexplorer.boot.Context#getPort()
711      */

712     public int getPort() {
713         return actualPort;
714     }
715
716     /*
717      * (non-Javadoc)
718      *
719      * @see com.sslexplorer.boot.Context#addContextLoaderURL(java.net.URL)
720      */

721     public void addContextLoaderURL(URL JavaDoc url) {
722         webappContext.addContextLoaderURL(url);
723     }
724
725     /*
726      * (non-Javadoc)
727      *
728      * @see com.sslexplorer.boot.Context#registerRequestHandler(com.sslexplorer.boot.RequestHandler)
729      */

730     public void registerRequestHandler(RequestHandler requestHandler) {
731         registerRequestHandler(requestHandler, HandlerProtocol.HTTPS_PROTOCOL);
732     }
733
734     /*
735      * (non-Javadoc)
736      *
737      * @see com.sslexplorer.boot.Context#deregisterRequestHandler(com.sslexplorer.boot.RequestHandler)
738      */

739     public void deregisterRequestHandler(RequestHandler requestHandler) {
740         if (httpContext != null) {
741             httpContext.deregisterRequestHandler(requestHandler);
742         }
743         HTTPRedirectHandler.registerHandler(requestHandler);
744     }
745
746     private void registerKeyStores() throws Exception JavaDoc {
747         getBootProgressMonitor().updateMessage("Registering key stores");
748         getBootProgressMonitor().updateProgress(7);
749         String JavaDoc defaultKeyStorePassword = contextConfiguration.retrieveProperty(new ContextKey("webServer.keystore.sslCertificate.password"));
750         KeyStoreManager.registerKeyStore(KeyStoreManager.DEFAULT_KEY_STORE, "keystore", true, defaultKeyStorePassword,
751             KeyStoreManager.getKeyStoreType(contextConfiguration.retrieveProperty(new ContextKey("webServer.keyStoreType"))));
752
753         KeyStoreManager.registerKeyStore(KeyStoreManager.SERVER_AUTHENTICATION_CERTIFICATES_KEY_STORE, "keystore", true,
754             "sslexplorer", KeyStoreManager.TYPE_JKS);
755         KeyStoreManager.registerKeyStore(KeyStoreManager.TRUSTED_SERVER_CERTIFICATES_KEY_STORE, "keystore", true, "sslexplorer",
756             KeyStoreManager.TYPE_JKS);
757
758     }
759
760     private void clearTemp() {
761         String JavaDoc currVer = PREF.get("lastTempClear", "");
762         if ( currVer.equals("") || !currVer.equals(getVersion().toString()) || "true".equalsIgnoreCase(System.getProperty("sslexplorer.clearTemp"))) {
763             getBootProgressMonitor().updateMessage("Clearing temporary files");
764             getBootProgressMonitor().updateProgress(3);
765             if (log.isInfoEnabled())
766                 log.info("Clearing temporary directory");
767             Util.delTree(getTempDirectory());
768             if (!getTempDirectory().mkdirs()) {
769                 log.error("CRITICAL. Failed to recreate the temporary directory " + getTempDirectory() + ".");
770             }
771         }
772         PREF.put("lastTempClear", getVersion().toString());
773     }
774
775     private void initialiseLogging() {
776         getBootProgressMonitor().updateMessage("Intialising logging");
777         getBootProgressMonitor().updateProgress(2);
778         LOG_DIR.mkdirs();
779         if(logToConsole) {
780             InputStream JavaDoc in = null;
781             URL JavaDoc url = getClass().getResource("/log4j.properties");
782             try {
783                 if(url == null) {
784                     throw new IOException JavaDoc("Could not locate log4j.properties");
785                 }
786                 in = url.openStream();
787                 Properties JavaDoc p = new Properties JavaDoc();
788                 p.load(in);
789                 p.setProperty("log4j.rootCategory", p.getProperty("log4j.rootCategory", "WARN,logfile") + ",stdout");
790                 Class.forName("org.apache.log4j.PropertyConfigurator").getMethod("configure", new Class JavaDoc[] { Properties JavaDoc.class } ).invoke(null, new Object JavaDoc[] { p });
791             }
792             catch(Exception JavaDoc e) {
793             }
794             finally {
795                 Util.closeStream(in);
796             }
797         }
798         log = LogFactory.getLog(Main.class);
799     }
800
801     private void startHttpServer() throws Exception JavaDoc {
802
803         int port = contextConfiguration.retrievePropertyInt(new ContextKey("webServer.httpRedirectPort"));
804         if (port <= 0) {
805             if (log.isInfoEnabled())
806                 log.info("HTTP redirect port " + port + " is invalid");
807             return;
808         }
809         insecureServer = new Server();
810         SocketListener listener = new SocketListener();
811         listener.setPort(port);
812         listener.setMinThreads(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.minThreads")));
813         listener.setMaxThreads(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.maxThreads")));
814         listener.setMaxIdleTimeMs(0);
815         listener.setLowResourcePersistTimeMs(2000);
816         listener.setAcceptQueueSize(0);
817         listener.setPoolName("P2");
818         insecureServer.addListener(listener);
819
820         // Create the webapp
821
HttpContext context = new HttpContext();
822         context.setContextPath("/");
823         context.setResourceBase("./dummy/");
824         context.addHandler(new HTTPRedirectHandler());
825         insecureServer.addContext(context);
826
827         // Configure the server
828
insecureServer.setRequestsPerGC(2000);
829
830         insecureThread = new Thread JavaDoc(threadGroup, "InsecureWebServer") {
831             public void run() {
832                 // Start the server
833
try {
834                     insecureServer.start();
835                 } catch (Exception JavaDoc e) {
836                     log.warn("Failed to start HTTP Jetty. " + e.getMessage(), e);
837                 }
838             }
839         };
840
841         if (log.isInfoEnabled())
842             log.info("Starting HTTP redirect server");
843         insecureThread.start();
844
845     }
846
847     private void normalMode() throws Exception JavaDoc {
848
849         getBootProgressMonitor().updateMessage("Creating server");
850         getBootProgressMonitor().updateProgress(8);
851
852         if (log.isInfoEnabled())
853             log.info("Starting Jetty Web Server");
854
855         server = createServer();
856
857         // SunJsseListener listener = new SunJsseListener();
858
String JavaDoc keystorePassword = contextConfiguration.retrieveProperty(new ContextKey("webServer.keystore.sslCertificate.password"));
859         if (keystorePassword.equals("")) {
860             throw new Exception JavaDoc(
861                             "Private key / certificate password has not been set. Please run the SSL Explorer Installation Wizard.");
862         }
863
864         actualPort = defaultPort == -1 ? contextConfiguration.retrievePropertyInt(new ContextKey("webServer.port")) : defaultPort;
865         String JavaDoc bind = contextConfiguration.retrieveProperty(new ContextKey("webServer.bindAddress"));
866         listeners = new ArrayList JavaDoc();
867         PropertyList l = new PropertyList(bind.equals("") ? "0.0.0.0" : bind);
868         for (Iterator JavaDoc i = l.iterator(); i.hasNext();) {
869             String JavaDoc address = (String JavaDoc) i.next();
870             if (log.isInfoEnabled())
871                 log.info("Adding listener on " + address + ":" + actualPort);
872             if (!serverLock.isStarted()) {
873                 serverLock.start(actualPort);
874             }
875             SocketListener listener = null;
876             if (contextConfiguration.retrieveProperty(new ContextKey("webServer.protocol")).equals("http")) {
877                 listener = new SocketListener();
878                 log.warn("SSL-Explorer is configured to listen for plain HTTP connections.");
879             } else {
880                 listener = new CustomJsseListener(keystorePassword);
881                 MsieSslHandler sslHandler = new MsieSslHandler();
882                 sslHandler.setUserAgentSubString("MSIE 5");
883                 listener.setHttpHandler(sslHandler);
884             }
885             listener.setPort(actualPort);
886             listener.setMinThreads(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.minThreads")));
887             listener.setMaxThreads(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.maxThreads")));
888             listener.setMaxIdleTimeMs(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.maxIdleTimeMs")));
889             listener.setHost(address);
890             listener.setBufferSize(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.bufferSize")));
891             listener.setBufferReserve(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.bufferReserve")));
892             listener.setTcpNoDelay(contextConfiguration.retrievePropertyBoolean(new ContextKey("webServer.tcpNoDelay")));
893             listener.setThreadsPriority(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.threadPriority")));
894             listeners.add(listener);
895
896             listener.setLowResourcePersistTimeMs(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.lowResourcePersistTimeMs")));
897             listener.setPoolName("main");
898             server.addListener(listener);
899         }
900
901         /*
902          * <Call name="addListener"> <Arg> <New
903          * class="org.enhydra.servlet.connectionMethods.EnhydraDirector.EnhydraListener">
904          * <Set name="Port">9003</Set> <Set name="MinThreads">10</Set> <Set
905          * name="MaxThreads">100</Set> <Set name="SessionAffinity">true</Set>
906          * <Set name="BindAddress">(All Interfaces)</Set> <Set
907          * name="AuthKey">(Unauthenticated)</Set> <Set name="ClientTimeout">300</Set>
908          * </New> </Arg> </Call>
909          */

910         // EnhydraListener enhydraListener = new EnhydraListener();
911
// enhydraListener.setPort(9003);
912
// enhydraListener.setMinThreads(10);
913
// enhydraListener.setMaxThreads(100);
914
// enhydraListener.setSessionAffinity("true");
915
// enhydraListener.setBindAddress("(All Interfaces)");
916
// enhydraListener.setAuthKey("(Unauthenticated)");
917
// enhydraListener.setClientTimeout(300);
918
// server.addListener(enhydraListener);
919
// Add the context
920

921         getBootProgressMonitor().updateMessage("Creating web application");
922         getBootProgressMonitor().updateProgress(9);
923         
924         httpContext = new CustomHttpContext(server, "/", useDevConfig);
925         httpContext.setRedirectNullPath(false);
926         server.addContext(httpContext);
927         
928         // Dunny servlet handler for faking HttpServletRequest, HttpServletResponse
929
servletHandler = new ServletHandler();
930         servletHandler.initialize(httpContext);
931         servletHandler.start();
932         
933
934         // Add the webapp
935
webappContext = new CustomWebApplicationContext(useDevConfig);
936         addLifecycleListener(webappContext);
937
938         // Load any extension classes before adding the context to the server
939
File JavaDoc exts = new File JavaDoc("webapp/WEB-INF/exts");
940
941         // If the exts folder does not exist create it.
942
if (!exts.exists())
943             exts.mkdirs();
944
945         File JavaDoc[] jars = exts.listFiles(new FilenameFilter JavaDoc() {
946             public boolean accept(File JavaDoc f, String JavaDoc filename) {
947                 return filename.endsWith(".jar");
948             }
949         });
950
951         for (int i = 0; i < jars.length; i++) {
952             addContextLoaderURL(jars[i].toURL());
953         }
954
955         server.addContext(webappContext);
956         webappContext.setRedirectNullPath(false);
957
958         // Configure the server
959
server.setRequestsPerGC(contextConfiguration.retrievePropertyInt(new ContextKey("webServer.requestsPerGC")));
960         server.setTrace(false);
961         
962         // Set the request log
963
if (contextConfiguration.retrievePropertyBoolean(new ContextKey("webServer.requestLog"))) {
964             NCSARequestLog requestLog = new NCSARequestLog(jettyLog);
965             requestLog.setRetainDays(90);
966             requestLog.setAppend(true);
967             requestLog.setExtended(false);
968             requestLog.setBuffered(false);
969             requestLog.setLogTimeZone("GMT");
970             server.setRequestLog(requestLog);
971         }
972         
973         // Inform the wrapper the startup process is going ok
974
if (useWrapper) {
975             WrapperManager.signalStarting(60000);
976         }
977
978         mainThread = new Thread JavaDoc(threadGroup, "WebServer") {
979             public void run() {
980                 // Start the server
981
try {
982                     server.start();
983                     if (useDevConfig) {
984                         log.warn("Server startup took " + ((System.currentTimeMillis() - startupStarted) / 1000) + " seconds");
985                     }
986                     getBootProgressMonitor().updateMessage("SSL-Explorer is now running");
987                     getBootProgressMonitor().updateProgress(100);
988                     Thread.sleep(2000);
989                 } catch (Exception JavaDoc e) {
990                     log.error("Failed to start Jetty. " + e.getMessage(), e);
991                     if (useWrapper) {
992                         WrapperManager.stop(1);
993                     } else {
994                         System.exit(1);
995                     }
996                 }
997                 finally {
998                     getBootProgressMonitor().dispose();
999                 }
1000            }
1001        };
1002        mainThread.start();
1003    }
1004    
1005    void doPrecompile(CustomWebApplicationContext context) {
1006        if("true".equals(System.getProperty("sslexplorer.precompile", "false"))) {
1007
1008            
1009            // Inform the wrapper the startup process is going ok
1010
if (useWrapper) {
1011                WrapperManager.signalStarting(180000);
1012            }
1013            
1014            getBootProgressMonitor().updateMessage("Pre-compiling JSP pages. Please wait ...");
1015            getBootProgressMonitor().updateProgress(90);
1016            
1017            try {
1018                JspPrecompiler pc =new JspPrecompiler();
1019                pc.compile(context);
1020            }
1021            catch(Exception JavaDoc e) {
1022                log.error("Failed to pre-compile Jsp pages. SSL-Explorer may be slowing when first loading pages.", e);
1023            }
1024        }
1025    }
1026
1027    /*
1028     * (non-Javadoc)
1029     *
1030     * @see com.sslexplorer.boot.Context#addWebApp(java.lang.String,
1031     * java.lang.String)
1032     */

1033    public void addWebApp(String JavaDoc path, String JavaDoc warFile) throws Exception JavaDoc {
1034        log.info("Adding webapp '" + path + "' using path / war '" + warFile + "'");
1035        HttpContext context = server.addWebApplication(path, warFile);
1036        context.start();
1037    }
1038
1039    private void setupMode() throws Exception JavaDoc {
1040
1041        getBootProgressMonitor().updateMessage("Creating server");
1042        getBootProgressMonitor().updateProgress(8);
1043        
1044        actualPort = defaultPort == -1 ? 28080 : defaultPort;
1045        serverLock.start(actualPort);
1046
1047        server = createServer();
1048        
1049        SocketListener socketListener = new SocketListener();
1050        socketListener.setPort(actualPort);
1051        socketListener.setMinThreads(10);
1052        socketListener.setMaxThreads(200);
1053        socketListener.setMaxIdleTimeMs(0);
1054        socketListener.setLowResourcePersistTimeMs(2000);
1055        socketListener.setAcceptQueueSize(0);
1056        socketListener.setPoolName("P1");
1057        server.addListener(socketListener);
1058
1059        // // Add the context
1060
// HttpContext context = new CustomHttpContext(server, "/",
1061
// useDevConfig);
1062
// server.addContext(context);
1063

1064        // Create the webapp
1065

1066        getBootProgressMonitor().updateMessage("Creating web application");
1067        getBootProgressMonitor().updateProgress(9);
1068
1069        webappContext = new CustomWebApplicationContext(useDevConfig);
1070        addLifecycleListener(webappContext);
1071        server.addContext(webappContext);
1072
1073        // Configure the server
1074
server.setRequestsPerGC(2000);
1075
1076        String JavaDoc realHostname = hostname == null ? InetAddress.getLocalHost().getHostName() : hostname;
1077
1078        /*
1079         * If the 'Active DNS' feature is enabled, the DNS server may return the
1080         * wild-card name. This will probably fail. As a work-around, if the
1081         * hostname looks like a wildcard, then it is simply changed to
1082         * 'localhost'.
1083         */

1084        if (realHostname.startsWith("*.")) {
1085            realHostname = "localhost";
1086        }
1087
1088        //
1089
final String JavaDoc fRealHostname = realHostname;
1090        final int realPort = defaultPort == -1 ? 28080 : defaultPort;
1091
1092        
1093        // Inform the wrapper the startup process is going ok
1094
if (useWrapper) {
1095            WrapperManager.signalStarting(60000);
1096        }
1097        
1098        mainThread = new Thread JavaDoc(threadGroup, "WebServer") {
1099            public void run() {
1100                // Start the server
1101
try {
1102                    server.start();
1103
1104                    if (!useWrapper && !"true".equals(System.getProperty("sslexplorer.noBrowserLaunch"))) {
1105                        try {
1106                            BrowserLauncher.openURL("http://" + fRealHostname + ":" + realPort);
1107                            System.out.println("A browser has been opened and pointed to http://" + fRealHostname + ":" + realPort
1108                                            + ". ");
1109                        } catch (Exception JavaDoc ex) {
1110                            System.out.println("Point your browser to http://" + fRealHostname + ":" + realPort + ". ");
1111                        }
1112                    } else {
1113                        System.out.println("Point your browser to http://" + fRealHostname + ":" + realPort + ". ");
1114                    }
1115                    System.out
1116                                    .println("\nPress CTRL+C or use the 'Shutdown' option from the web interface to leave the installation wizard.");
1117                    getBootProgressMonitor().updateMessage("SSL-Explorer is now running");
1118                    getBootProgressMonitor().updateProgress(100);
1119                    Thread.sleep(2000);
1120                } catch (Exception JavaDoc e) {
1121                    log.error("Failed to start Jetty. " + e.getMessage(), e);
1122                    if (useWrapper) {
1123                        WrapperManager.stop(1);
1124                    } else {
1125                        System.exit(1);
1126                    }
1127                }
1128                finally {
1129                    getBootProgressMonitor().dispose();
1130                }
1131            }
1132        };
1133
1134        System.out.print("Starting SSL Explorer installation wizard");
1135        mainThread.start();
1136
1137        /* Wait for up to 5 minutes for the server to become available
1138         * we need to wait this long because precompilation can take a while!
1139         */

1140        
1141        int waitFor = 60 * 5;
1142        
1143        boolean running = false;
1144
1145        if (!"true".equals(System.getProperty("sslexplorer.disableStartupCheck", "false"))) {
1146            int i = 0;
1147            for (; i < waitFor && !running; i++) {
1148                try {
1149                    System.out.print(".");
1150                    Socket JavaDoc s = new Socket JavaDoc(realHostname, realPort);
1151                    s.close();
1152                    running = true;
1153                } catch (Exception JavaDoc ex) {
1154                    try {
1155                        Thread.sleep(1000);
1156                    } catch (Exception JavaDoc ex2) {
1157                    }
1158                }
1159            }
1160            System.out.println();
1161        } else {
1162            running = true;
1163        }
1164        if (!running) {
1165            System.out.println("Failed to start installation wizard. Check the logs for more detail.");
1166            if (useWrapper) {
1167                WrapperManager.stop(1);
1168            } else {
1169                System.exit(1);
1170            }
1171        }
1172    }
1173
1174    private void configureProxyServers() throws Exception JavaDoc {
1175        getBootProgressMonitor().updateMessage("Configuring proxy servers");
1176        getBootProgressMonitor().updateProgress(5);
1177
1178        String JavaDoc httpProxyHost = contextConfiguration.retrieveProperty(new ContextKey("proxies.http.proxyHost"));
1179        if (!httpProxyHost.equals("")) {
1180            if (log.isInfoEnabled())
1181                log.info("Configuring outgoing HTTP connections to use a proxy server.");
1182            System.setProperty("http.proxyHost", httpProxyHost);
1183            System.setProperty("com.maverick.ssl.https.HTTPProxyHostname", httpProxyHost);
1184            String JavaDoc httpProxyPort = contextConfiguration.retrieveProperty(new ContextKey("proxies.http.proxyPort"));
1185            
1186            
1187            String JavaDoc httpProxyUsername = contextConfiguration.retrieveProperty(new ContextKey("proxies.http.proxyUser"));
1188            String JavaDoc httpProxyPassword = contextConfiguration.retrieveProperty(new ContextKey("proxies.http.proxyPassword"));
1189            
1190            System.setProperty("http.proxyPort", httpProxyPort);
1191            System.setProperty("com.maverick.ssl.https.HTTPProxyPort", httpProxyPort);
1192            
1193            if(!httpProxyUsername.trim().equals(""))
1194                System.setProperty("com.maverick.ssl.https.HTTPProxyUsername", httpProxyUsername.trim());
1195            
1196            if(!httpProxyPassword.trim().equals(""))
1197                System.setProperty("com.maverick.ssl.https.HTTPProxyPassword", httpProxyPassword.trim());
1198            
1199            System.setProperty("com.maverick.ssl.https.HTTPProxySecure", "false");
1200
1201            PropertyList list = contextConfiguration.retrievePropertyList(new ContextKey("proxies.http.nonProxyHosts"));
1202            StringBuffer JavaDoc hosts = new StringBuffer JavaDoc();
1203            for (Iterator JavaDoc i = list.iterator(); i.hasNext();) {
1204                if (hosts.length() != 0) {
1205                    hosts.append("|");
1206                }
1207                hosts.append(i.next());
1208            }
1209            System.setProperty("http.nonProxyHosts", hosts.toString());
1210            System.setProperty("com.maverick.ssl.https.HTTPProxyNonProxyHosts", hosts.toString());
1211        }
1212        String JavaDoc socksProxyHost = contextConfiguration.retrieveProperty(new ContextKey("proxies.socksProxyHost"));
1213        if (!socksProxyHost.equals("")) {
1214            if (log.isInfoEnabled())
1215                log.info("Configuring outgoing TCP/IP connections to use a SOCKS proxy server.");
1216            System.setProperty("socksProxyHost", httpProxyHost);
1217            System.setProperty("socksProxyPort", contextConfiguration.retrieveProperty(new ContextKey("proxies.socksProxyPort")));
1218        }
1219        if (!socksProxyHost.equals("") || !httpProxyHost.equals("")) {
1220            Authenticator.setDefault(new ProxyAuthenticator());
1221        }
1222    }
1223    
1224    private Server createServer() {
1225        Server server = new Server();
1226        if (contextConfiguration.retrievePropertyBoolean(new ContextKey("webServer.stats"))) {
1227            new StatsLogger(server, contextConfiguration.retrievePropertyInt(new ContextKey("webServer.statsUpdate")));
1228        }
1229        return server;
1230    }
1231    
1232    private void addLifecycleListener(final CustomWebApplicationContext context) {
1233        context.addEventListener(new LifeCycleListener() {
1234            public void lifeCycleFailure(LifeCycleEvent arg0) {
1235            }
1236
1237            public void lifeCycleStarted(LifeCycleEvent arg0) {
1238                doPrecompile(context);
1239                getBootProgressMonitor().updateMessage("SSL-Explorer is now running");
1240                getBootProgressMonitor().updateProgress(100);
1241                try {
1242                    Thread.sleep(500);
1243                } catch (InterruptedException JavaDoc e) {
1244                }
1245            }
1246
1247            public void lifeCycleStarting(LifeCycleEvent arg0) {
1248            }
1249
1250            public void lifeCycleStopped(LifeCycleEvent arg0) {
1251            }
1252
1253            public void lifeCycleStopping(LifeCycleEvent arg0) {
1254            }
1255        });
1256    }
1257
1258    private void displaySystemInfo() throws SocketException JavaDoc {
1259
1260        //
1261

1262        if (useDevConfig) {
1263            log.warn("Development environment enabled. Do not use this on a production server.");
1264        }
1265
1266        if (log.isInfoEnabled()) {
1267            log.info("SSL-Explorer version is " + ContextHolder.getContext().getVersion());
1268            log.info("Java version is " + System.getProperty("java.version"));
1269            log.info("SSL Explorer is installed on " + hostname + "/" + hostAddress);
1270            log.info("Configuration: " + CONF_DIR.getAbsolutePath());
1271        }
1272
1273        Enumeration JavaDoc e = NetworkInterface.getNetworkInterfaces();
1274
1275        while (e.hasMoreElements()) {
1276            NetworkInterface JavaDoc netface = (NetworkInterface JavaDoc) e.nextElement();
1277            if (log.isInfoEnabled())
1278                log.info("Net interface: " + netface.getName());
1279
1280            Enumeration JavaDoc e2 = netface.getInetAddresses();
1281
1282            while (e2.hasMoreElements()) {
1283                InetAddress JavaDoc ip = (InetAddress JavaDoc) e2.nextElement();
1284                if (log.isInfoEnabled())
1285                    log.info("IP address: " + ip.toString());
1286            }
1287        }
1288
1289        if (log.isInfoEnabled())
1290            log.info("System properties follow:");
1291        Properties JavaDoc sysProps = System.getProperties();
1292        for (Iterator JavaDoc i = sysProps.entrySet().iterator(); i.hasNext();) {
1293            Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
1294            int idx = 0;
1295            String JavaDoc val = (String JavaDoc) entry.getValue();
1296            while (true) {
1297                if (entry.getKey().equals("java.class.path")) {
1298                    StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(entry.getValue().toString(), System.getProperty("path.separator", ","));
1299                    while (t.hasMoreTokens()) {
1300                        String JavaDoc s = t.nextToken();
1301                        if (log.isInfoEnabled())
1302                            log.info("java.class.path=" + s);
1303                    }
1304                    break;
1305                } else {
1306                    if ((val.length() - idx) > 256) {
1307                        if (log.isInfoEnabled())
1308                            log.info(" " + entry.getKey() + "=" + val.substring(idx, idx + 256));
1309                        idx += 256;
1310                    } else {
1311                        if (log.isInfoEnabled())
1312                            log.info(" " + entry.getKey() + "=" + val.substring(idx));
1313                        break;
1314                    }
1315                }
1316            }
1317        }
1318    }
1319
1320    private void loadSystemProperties() {
1321        getBootProgressMonitor().updateMessage("Loading system properties");
1322        getBootProgressMonitor().updateProgress(1);
1323
1324        /*
1325         * Read in system properties from a resource, more a debugging aid than
1326         * anything else
1327         */

1328        InputStream JavaDoc in = null;
1329        try {
1330            File JavaDoc f = new File JavaDoc(CONF_DIR, "system.properties");
1331            in = new FileInputStream JavaDoc(f);
1332            Properties JavaDoc p = new Properties JavaDoc();
1333            p.load(in);
1334            for (Enumeration JavaDoc e = p.keys(); e.hasMoreElements();) {
1335                String JavaDoc k = (String JavaDoc) e.nextElement();
1336                System.getProperties().setProperty(k, p.getProperty(k).trim());
1337            }
1338        } catch (IOException JavaDoc e) {
1339            // Dont care
1340
} finally {
1341            if (in != null) {
1342                try {
1343                    in.close();
1344                } catch (IOException JavaDoc ioe) {
1345
1346                }
1347            }
1348        }
1349
1350        /**
1351         * Are we in development mode?
1352         */

1353        useDevConfig = "true".equalsIgnoreCase(System.getProperty("sslexplorer.useDevConfig"));
1354
1355        if (!"".equals(System.getProperty("sslexplorer.extensions", ""))) {
1356            appDir = new File JavaDoc(System.getProperty("sslexplorer.extensions"));
1357        }
1358
1359        //
1360
System.setProperty("org.mortbay.jetty.servlet.SessionCookie", System.getProperty("sslexplorer.cookie", "JSESSIONID"));
1361    }
1362
1363    private Integer JavaDoc parseCommandLine(String JavaDoc[] args) {
1364        defaultPort = -1;
1365        logToConsole = false;
1366        jettyLog = "logs/yyyy_mm_dd.request.log";
1367        boolean fullReset = false;
1368        String JavaDoc os = System.getProperty("os.name").toLowerCase();
1369        gui = "true".equals(System.getProperty("sslexplorer.useDevConfig")) && os.startsWith("windows");
1370        try {
1371            for (int i = 0; i < args.length; i++) {
1372                if (args[i].equals("--manager")) {
1373                    System.err
1374                                    .println("The database manager can no longer be via the SSL-Explorer server command line. Run it directly from hsqldb.jar ensuring you have the SSL-Explorer webapp classes included in your class path.");
1375                    return new Integer JavaDoc(1);
1376                } else if (args[i].equals("--setup")) {
1377                    System.err.println("WARNING: --setup is deprecated, please use --install");
1378                    install = true;
1379                } else if (args[i].equals("--install")) {
1380                    install = true;
1381                } else if (args[i].equals("--logToConsole")) {
1382                    logToConsole = true;
1383                } else if (args[i].equals("--gui")) {
1384                    if (os.startsWith("windows")) {
1385                        gui = true;
1386                    } else if (os.equals("linux") || os.equals("solaris") || os.endsWith("aix")) {
1387                        String JavaDoc displaySysProp = System.getProperty("sslexplorer.display", "");
1388                        String JavaDoc display = null;
1389                        try {
1390                            display = displaySysProp.equals("") ? System.getenv("DISPLAY") : displaySysProp;
1391                        } catch (Throwable JavaDoc t) {
1392                        }
1393                        gui = display != null && display.length() > 0;
1394                    }
1395                } else if (args[i].startsWith("--db")) {
1396                    DB_DIR = new File JavaDoc(args[i].substring(5));
1397                    if (DB_DIR.exists() && !DB_DIR.isDirectory()) {
1398                        throw new Exception JavaDoc("--db option specifies an existing file, must either not exist or be a directory");
1399                    }
1400                } else if (args[i].startsWith("--applications")) {
1401                    appDir = new File JavaDoc(args[i].substring(15));
1402                    if (appDir.exists() && !appDir.isDirectory()) {
1403                        throw new Exception JavaDoc("--db option specifies an existing file, must either not exist or be a directory");
1404                    }
1405                } else if (args[i].startsWith("--temp")) {
1406                    TMP_DIR = new File JavaDoc(args[i].substring(7));
1407                    if (TMP_DIR.exists() && !TMP_DIR.isDirectory()) {
1408                        throw new Exception JavaDoc("--temp option specifies an existing file, must either not exist or be a directory");
1409                    }
1410                } else if (args[i].startsWith("--conf")) {
1411                    CONF_DIR = new File JavaDoc(args[i].substring(7));
1412                    if (!CONF_DIR.exists() || !CONF_DIR.isDirectory()) {
1413                        throw new Exception JavaDoc("--conf option does not specify a valid directory");
1414                    }
1415                } else if (args[i].startsWith("--port")) {
1416                    defaultPort = Integer.parseInt(args[i].substring(7));
1417                } else if (args[i].startsWith("--jettyLog")) {
1418                    jettyLog = args[i].substring(11);
1419                } else if (args[i].equals("--full-reset")) {
1420                    fullReset = true;
1421                } else if (args[i].startsWith("start")) {
1422                    // For compatibility with the install4j launcher
1423
} else {
1424                    System.err.println("Starts / configures the SSL Explorer server.\n");
1425                    System.err.println("Usage: sslexplorer [OPTION]...");
1426                    System.err.println("\nThe server may be started in setup or normal mode. When setup.\n");
1427                    System.err.println("mode is enabled a plain http server will be started on port 28080\n");
1428                    System.err.println("allowing you configure using a browser.\n\n");
1429                    System.out.println("Options:\n");
1430                    System.out.println(" --install Start the server in installation mode.");
1431                    System.out.println(" --full-reset Deletes *all* configuration data and resets");
1432                    System.out.println(" SSL-Explorer to its initial state. Use with");
1433                    System.out.println(" greate caution.");
1434                    System.out.println(" --db=DIR Set the directory where the configuration");
1435                    System.out.println(" database is stored.");
1436                    System.out.println(" --conf=DIR Set the directory where the configuration");
1437                    System.out.println(" files are stored.");
1438                    System.out.println(" --temp=DIR Set the directory where the temporary");
1439                    System.out.println(" files are stored.");
1440                    System.out.println(" --port=NUMBER The port on which the server will start.");
1441                    System.out.println(" Note that this applies to both setup and");
1442                    System.out.println(" normal mode and will overide whatever port");
1443                    System.out.println(" been configured within SSL Explorer.");
1444                    System.out.println(" --jettyLog=LOG The location of the Jetty NCSA request log.");
1445                    System.out.println("\nInvalid option: " + args[i] + ".\n");
1446                    return new Integer JavaDoc(2);
1447                }
1448            }
1449
1450            // Create the temporary directory
1451
if (!TMP_DIR.exists()) {
1452                if (!TMP_DIR.mkdirs()) {
1453                    throw new Exception JavaDoc("Could not create temporary directory " + TMP_DIR.getAbsolutePath() + ".");
1454                }
1455            }
1456        } catch (Exception JavaDoc e) {
1457            System.err.println(e.getMessage());
1458            return new Integer JavaDoc(2);
1459        }
1460
1461        // Perform a full reset
1462
if (fullReset) {
1463            if (fullReset()) {
1464                System.err.println("SSL-Explorer configuration has been fully reset");
1465                return new Integer JavaDoc(0);
1466            } else {
1467                System.err.println("Aborted full reset.");
1468                return new Integer JavaDoc(1);
1469            }
1470        }
1471
1472        // Another way for external processes to force starting installation
1473
// wizard
1474
if (new File JavaDoc(TMP_DIR, "setup.run").exists()) {
1475            install = true;
1476        }
1477
1478        return null;
1479
1480    }
1481
1482    /*
1483     * Perform a full reset
1484     */

1485    private boolean fullReset() {
1486        if (gui) {
1487            if (JOptionPane.showConfirmDialog(null, "The embedded configuration database will be\n"
1488                            + "completely deleted and re-created the next\ntime you run the server. Are you absolutely\n"
1489                            + "sure you wish to do this?", "Full Reset", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION) != JOptionPane.OK_OPTION) {
1490                return false;
1491            }
1492        } else {
1493            System.out.println("The embedded configuration database will be");
1494            System.out.println("completely deleted and re-created the next");
1495            System.out.println("time you run the server. Are you absolutely");
1496            System.out.println("sure you wish to do this?");
1497            System.out.println();
1498            BufferedReader JavaDoc br = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(System.in));
1499            while (true) {
1500                System.out.print("(Y)es or (N)o: ");
1501                String JavaDoc s;
1502                try {
1503                    s = br.readLine();
1504                    if (s == null) {
1505                        return false;
1506                    }
1507                    if (s.toLowerCase().equals("y") || s.toLowerCase().equals("yes")) {
1508                        break;
1509                    }
1510                    if (s.toLowerCase().equals("n") || s.toLowerCase().equals("no")) {
1511                        return false;
1512                    }
1513                    System.out.println("\nPlease answer 'y' or 'yes' to perform the reset, or 'n' or 'no' to abort the reset.");
1514                } catch (IOException JavaDoc e) {
1515                    return false;
1516                }
1517            }
1518        }
1519
1520        // Start the reset
1521
System.out.println("Resetting all configuration");
1522        File JavaDoc[] f = getDBDirectory().listFiles();
1523        if (f != null) {
1524            for (int i = 0; i < f.length; i++) {
1525                if (!f[i].getName().equals("CVS") && !f[i].equals(".cvsignore")) {
1526                    System.out.println(" Deleting " + f[i].getPath());
1527                    if (!f[i].delete()) {
1528                        System.out.println(" Failed to remove");
1529                    }
1530                }
1531            }
1532        }
1533
1534        return true;
1535    }
1536
1537    /*
1538     * (non-Javadoc)
1539     *
1540     * @see com.sslexplorer.boot.Context#deobfuscatePassword(java.lang.String)
1541     */

1542    public String JavaDoc deobfuscatePassword(String JavaDoc val) {
1543        try {
1544            return Password.deobfuscate(val);
1545        } catch (Exception JavaDoc e) {
1546            return "";
1547        }
1548    }
1549
1550    /*
1551     * (non-Javadoc)
1552     *
1553     * @see com.sslexplorer.boot.Context#obfuscatePassword(java.lang.String)
1554     */

1555    public String JavaDoc obfuscatePassword(String JavaDoc val) {
1556        return Password.obfuscate(val);
1557    }
1558
1559    /*
1560     * (non-Javadoc)
1561     *
1562     * @see com.sslexplorer.boot.Context#setTrustMananger(javax.net.ssl.TrustManager)
1563     */

1564    public void setTrustMananger(TrustManager trustManager, boolean require) {
1565        if (listeners == null || listeners.size() == 0) {
1566            log.warn("Not setting trust managers there are no SSL listeners configured.");
1567        } else {
1568            if (log.isInfoEnabled())
1569                log.info("Set trust managers");
1570            for (Iterator JavaDoc i = listeners.iterator(); i.hasNext();) {
1571                SocketListener l = (SocketListener) i.next();
1572                if (l instanceof CustomJsseListener) {
1573                    ((CustomJsseListener) l).setNeedClientAuth(trustManager != null);
1574                    ((CustomJsseListener) l).setTrustManager(trustManager, require);
1575                }
1576            }
1577        }
1578    }
1579
1580    /* (non-Javadoc)
1581     * @see com.sslexplorer.boot.Context#addContextListener(com.sslexplorer.boot.ContextListener)
1582     */

1583    public void addContextListener(ContextListener contextListener) {
1584        contextListeners.add(contextListener);
1585    }
1586
1587    /* (non-Javadoc)
1588     * @see com.sslexplorer.boot.Context#removeContextListener(com.sslexplorer.boot.ContextListener)
1589     */

1590    public void removeContextListener(ContextListener contextListener) {
1591        contextListeners.remove(contextListener);
1592    }
1593
1594    /* (non-Javadoc)
1595     * @see com.sslexplorer.boot.Context#getPreferences()
1596     */

1597    public Preferences JavaDoc getPreferences() {
1598        return PREF;
1599    }
1600
1601    /* (non-Javadoc)
1602     * @see com.sslexplorer.boot.Context#getContextLoaderClassPath()
1603     */

1604    public URL JavaDoc[] getContextLoaderClassPath() {
1605        List JavaDoc<URL JavaDoc> urlList = new ArrayList JavaDoc<URL JavaDoc>();
1606        ClassLoader JavaDoc webappContextClassLoader = webappContext.getClassLoader();
1607        while(webappContextClassLoader != null) {
1608            if(webappContextClassLoader != null && webappContextClassLoader instanceof URLClassLoader JavaDoc) {
1609                urlList.addAll(Arrays.asList(((URLClassLoader JavaDoc)webappContextClassLoader).getURLs()));
1610            }
1611            webappContextClassLoader = webappContextClassLoader.getParent();
1612        }
1613        URL JavaDoc[] urls = (URL JavaDoc[])urlList.toArray(new URL JavaDoc[urlList.size()]);
1614        return urls;
1615    }
1616
1617    /* (non-Javadoc)
1618     * @see com.sslexplorer.boot.Context#getContextLoader()
1619     */

1620    public ClassLoader JavaDoc getContextLoader() {
1621        return webappContext.getClassLoader();
1622    }
1623    
1624    public void removeResourceAlias(String JavaDoc uri) {
1625        webappContext.removeResourceAlias(uri);
1626    }
1627
1628    /* (non-Javadoc)
1629     * @see com.sslexplorer.boot.Context#getResourceBases()
1630     */

1631    public Collection JavaDoc<URL JavaDoc> getResourceBases() {
1632        return resourceCaches.keySet();
1633    }
1634
1635    /* (non-Javadoc)
1636     * @see com.sslexplorer.boot.Context#getBootProgressMonitor()
1637     */

1638    public BootProgressMonitor getBootProgressMonitor() {
1639        return bootProgressMonitor;
1640    }
1641
1642    public void registerRequestHandler(RequestHandler requestHandler, HandlerProtocol protocol) {
1643        if (httpContext != null) {
1644            if(protocol == HandlerProtocol.HTTPS_PROTOCOL
1645                    || protocol == HandlerProtocol.BOTH_PROTOCOLS)
1646                        httpContext.registerRequestHandler(requestHandler);
1647        }
1648        
1649        if(protocol == HandlerProtocol.HTTP_PROTOCOL || protocol == HandlerProtocol.BOTH_PROTOCOLS) {
1650            HTTPRedirectHandler.registerHandler(requestHandler);
1651        }
1652        
1653        
1654        
1655    }
1656
1657    public HttpServletRequest JavaDoc createServletRequest(RequestHandlerRequest request) {
1658        
1659        if(request instanceof com.sslexplorer.server.jetty.RequestAdapter) {
1660            ServletHttpRequest req = new ServletHttpRequest(servletHandler,request.getPath(), ((com.sslexplorer.server.jetty.RequestAdapter)request).getHttpRequest());
1661            return req;
1662        } else
1663            throw new IllegalArgumentException JavaDoc("Request must be RequestAdapter");
1664        
1665    }
1666    
1667    public HttpServletResponse JavaDoc createServletResponse(RequestHandlerResponse response, HttpServletRequest JavaDoc request) {
1668        if(response instanceof com.sslexplorer.server.jetty.ResponseAdapter) {
1669            ServletHttpResponse res = new ServletHttpResponse((ServletHttpRequest)request, ((com.sslexplorer.server.jetty.ResponseAdapter)response).getHttpResponse());
1670            ((ServletHttpRequest)request).getSession(true);
1671            return res;
1672        } else
1673            throw new IllegalArgumentException JavaDoc("Response must be ResponseAdapter");
1674    }
1675
1676}
1677
Popular Tags