From 98024a6c871785aa7966f55c174715fec317fb94 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Sun, 1 Mar 2015 02:37:15 +0100 Subject: [PATCH] Fix: clean up launching process. --- src/org/cacert/gigi/Launcher.java | 361 +++++++++--------- .../cacert/gigi/output/template/Template.java | 23 +- .../cacert/gigi/testUtils/ManagedTest.java | 2 +- .../org/cacert/gigi/DevelLauncher.java | 14 +- .../org/cacert/gigi/TestLauncher.java | 12 + 5 files changed, 214 insertions(+), 198 deletions(-) rename {src => util-testing}/org/cacert/gigi/DevelLauncher.java (92%) create mode 100644 util-testing/org/cacert/gigi/TestLauncher.java diff --git a/src/org/cacert/gigi/Launcher.java b/src/org/cacert/gigi/Launcher.java index a399dcdd..56d0d4fb 100644 --- a/src/org/cacert/gigi/Launcher.java +++ b/src/org/cacert/gigi/Launcher.java @@ -52,34 +52,26 @@ public class Launcher { public static void main(String[] args) throws Exception { System.setProperty("jdk.tls.ephemeralDHKeySize", "4096"); - boot(); + new Launcher().boot(); } - public static void boot() throws Exception { + Server s; + + GigiConfig conf; + + public synchronized void boot() throws Exception { Locale.setDefault(Locale.ENGLISH); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - GigiConfig conf = GigiConfig.parse(System.in); + conf = GigiConfig.parse(System.in); ServerConstants.init(conf.getMainProps()); initEmails(conf); - Server s = new Server(); - HttpConfiguration httpsConfig = createHttpConfiguration(); + s = new Server(); - // for client-cert auth - httpsConfig.addCustomizer(new SecureRequestCustomizer()); + initConnectors(); + initHandlers(); - HttpConfiguration httpConfig = createHttpConfiguration(); - - s.setConnectors(new Connector[] { - createConnector(conf, s, httpsConfig, true), createConnector(conf, s, httpConfig, false) - }); - - HandlerList hl = new HandlerList(); - hl.setHandlers(new Handler[] { - generateStaticContext(), generateGigiContexts(conf.getMainProps(), conf.getTrustStore()), generateAPIContext() - }); - s.setHandler(hl); s.start(); if ((ServerConstants.getSecurePort() <= 1024 || ServerConstants.getPort() <= 1024) && !System.getProperty("os.name").toLowerCase().contains("win")) { SetUID uid = new SetUID(); @@ -87,29 +79,9 @@ public class Launcher { Log.getLogger(Launcher.class).warn("Couldn't set uid!"); } } - if (conf.getMainProps().containsKey("testrunner")) { - DevelLauncher.addDevelPage(); - } } - private static ServerConnector createConnector(GigiConfig conf, Server s, HttpConfiguration httpConfig, boolean doHttps) throws GeneralSecurityException, IOException { - ServerConnector connector; - if (doHttps) { - connector = new ServerConnector(s, createConnectionFactory(conf), new HttpConnectionFactory(httpConfig)); - } else { - connector = new ServerConnector(s, new HttpConnectionFactory(httpConfig)); - } - connector.setHost(conf.getMainProps().getProperty("host")); - if (doHttps) { - connector.setPort(ServerConstants.getSecurePort()); - } else { - connector.setPort(ServerConstants.getPort()); - } - connector.setAcceptQueueSize(100); - return connector; - } - - private static HttpConfiguration createHttpConfiguration() { + private HttpConfiguration createHttpConfiguration() { // SSL HTTP Configuration HttpConfiguration httpsConfig = new HttpConfiguration(); httpsConfig.setSendServerVersion(false); @@ -117,177 +89,224 @@ public class Launcher { return httpsConfig; } - private static void initEmails(GigiConfig conf) throws GeneralSecurityException, IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { + private void initConnectors() throws GeneralSecurityException, IOException { + HttpConfiguration httpsConfig = createHttpConfiguration(); + // for client-cert auth + httpsConfig.addCustomizer(new SecureRequestCustomizer()); + HttpConfiguration httpConfig = createHttpConfiguration(); + s.setConnectors(new Connector[] { + ConnectorsLauncher.createConnector(conf, s, httpsConfig, true), ConnectorsLauncher.createConnector(conf, s, httpConfig, false) + }); + } + + private void initEmails(GigiConfig conf) throws GeneralSecurityException, IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { KeyStore privateStore = conf.getPrivateStore(); Certificate mail = privateStore.getCertificate("mail"); Key k = privateStore.getKey("mail", conf.getPrivateStorePw().toCharArray()); EmailProvider.initSystem(conf.getMainProps(), mail, k); } - private static SslConnectionFactory createConnectionFactory(GigiConfig conf) throws GeneralSecurityException, IOException { - final SslContextFactory sslContextFactory = generateSSLContextFactory(conf, "www"); - final SslContextFactory secureContextFactory = generateSSLContextFactory(conf, "secure"); - secureContextFactory.setWantClientAuth(true); - secureContextFactory.setNeedClientAuth(false); - final SslContextFactory staticContextFactory = generateSSLContextFactory(conf, "static"); - final SslContextFactory apiContextFactory = generateSSLContextFactory(conf, "api"); - apiContextFactory.setWantClientAuth(true); - try { - secureContextFactory.start(); - staticContextFactory.start(); - apiContextFactory.start(); - } catch (Exception e) { - e.printStackTrace(); + private static class ConnectorsLauncher { + + private ConnectorsLauncher() {} + + protected static ServerConnector createConnector(GigiConfig conf, Server s, HttpConfiguration httpConfig, boolean doHttps) throws GeneralSecurityException, IOException { + ServerConnector connector; + if (doHttps) { + connector = new ServerConnector(s, createConnectionFactory(conf), new HttpConnectionFactory(httpConfig)); + } else { + connector = new ServerConnector(s, new HttpConnectionFactory(httpConfig)); + } + connector.setHost(conf.getMainProps().getProperty("host")); + if (doHttps) { + connector.setPort(ServerConstants.getSecurePort()); + } else { + connector.setPort(ServerConstants.getPort()); + } + connector.setAcceptQueueSize(100); + return connector; } - return new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()) { - @Override - public boolean shouldRestartSSL() { - return true; + private static SslConnectionFactory createConnectionFactory(GigiConfig conf) throws GeneralSecurityException, IOException { + final SslContextFactory sslContextFactory = generateSSLContextFactory(conf, "www"); + final SslContextFactory secureContextFactory = generateSSLContextFactory(conf, "secure"); + secureContextFactory.setWantClientAuth(true); + secureContextFactory.setNeedClientAuth(false); + final SslContextFactory staticContextFactory = generateSSLContextFactory(conf, "static"); + final SslContextFactory apiContextFactory = generateSSLContextFactory(conf, "api"); + apiContextFactory.setWantClientAuth(true); + try { + secureContextFactory.start(); + staticContextFactory.start(); + apiContextFactory.start(); + } catch (Exception e) { + e.printStackTrace(); } + return new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()) { + + @Override + public boolean shouldRestartSSL() { + return true; + } - @Override - public SSLEngine restartSSL(SSLSession sslSession) { - SSLEngine e2 = null; - if (sslSession instanceof ExtendedSSLSession) { - ExtendedSSLSession es = (ExtendedSSLSession) sslSession; - List names = es.getRequestedServerNames(); - for (SNIServerName sniServerName : names) { - if (sniServerName instanceof SNIHostName) { - SNIHostName host = (SNIHostName) sniServerName; - String hostname = host.getAsciiName(); - if (hostname.equals(ServerConstants.getWwwHostName())) { - e2 = sslContextFactory.newSSLEngine(); - } else if (hostname.equals(ServerConstants.getStaticHostName())) { - e2 = staticContextFactory.newSSLEngine(); - } else if (hostname.equals(ServerConstants.getSecureHostName())) { - e2 = secureContextFactory.newSSLEngine(); - } else if (hostname.equals(ServerConstants.getApiHostName())) { - e2 = apiContextFactory.newSSLEngine(); + @Override + public SSLEngine restartSSL(SSLSession sslSession) { + SSLEngine e2 = null; + if (sslSession instanceof ExtendedSSLSession) { + ExtendedSSLSession es = (ExtendedSSLSession) sslSession; + List names = es.getRequestedServerNames(); + for (SNIServerName sniServerName : names) { + if (sniServerName instanceof SNIHostName) { + SNIHostName host = (SNIHostName) sniServerName; + String hostname = host.getAsciiName(); + if (hostname.equals(ServerConstants.getWwwHostName())) { + e2 = sslContextFactory.newSSLEngine(); + } else if (hostname.equals(ServerConstants.getStaticHostName())) { + e2 = staticContextFactory.newSSLEngine(); + } else if (hostname.equals(ServerConstants.getSecureHostName())) { + e2 = secureContextFactory.newSSLEngine(); + } else if (hostname.equals(ServerConstants.getApiHostName())) { + e2 = apiContextFactory.newSSLEngine(); + } + break; } - break; } } + if (e2 == null) { + e2 = sslContextFactory.newSSLEngine(sslSession.getPeerHost(), sslSession.getPeerPort()); + } + e2.setUseClientMode(false); + return e2; } - if (e2 == null) { - e2 = sslContextFactory.newSSLEngine(sslSession.getPeerHost(), sslSession.getPeerPort()); - } - e2.setUseClientMode(false); - return e2; - } - }; - } + }; + } - private static Handler generateGigiContexts(Properties conf, KeyStore trust) { - ServletHolder webAppServlet = new ServletHolder(new Gigi(conf, trust)); + private static SslContextFactory generateSSLContextFactory(GigiConfig conf, String alias) throws GeneralSecurityException, IOException { + SslContextFactory scf = new SslContextFactory() { - ContextHandler ch = generateGigiServletContext(webAppServlet); - ch.setVirtualHosts(new String[] { - ServerConstants.getWwwHostName() - }); - ContextHandler chSecure = generateGigiServletContext(webAppServlet); - chSecure.setVirtualHosts(new String[] { - ServerConstants.getSecureHostName() - }); + String[] ciphers = null; - HandlerList hl = new HandlerList(); - hl.setHandlers(new Handler[] { - ch, chSecure - }); - return hl; - } + @Override + public void customize(SSLEngine sslEngine) { + super.customize(sslEngine); + + SSLParameters ssl = sslEngine.getSSLParameters(); + ssl.setUseCipherSuitesOrder(true); + if (ciphers == null) { + ciphers = CipherInfo.filter(sslEngine.getSupportedCipherSuites()); + } - private static ContextHandler generateGigiServletContext(ServletHolder webAppServlet) { - final ResourceHandler rh = generateResourceHandler(); - rh.setResourceBase("static/www"); + ssl.setCipherSuites(ciphers); + sslEngine.setSSLParameters(ssl); - HandlerWrapper hw = new PolicyRedirector(); - hw.setHandler(rh); + } - ServletContextHandler servlet = new ServletContextHandler(ServletContextHandler.SESSIONS); - servlet.setInitParameter(SessionManager.__SessionCookieProperty, "CACert-Session"); - servlet.addServlet(webAppServlet, "/*"); - ErrorPageErrorHandler epeh = new ErrorPageErrorHandler(); - epeh.addErrorPage(404, "/error"); - epeh.addErrorPage(403, "/denied"); - servlet.setErrorHandler(epeh); + }; + scf.setRenegotiationAllowed(false); + + scf.setProtocol("TLS"); + scf.setIncludeProtocols("TLSv1", "TLSv1.1", "TLSv1.2"); + scf.setTrustStore(conf.getTrustStore()); + KeyStore privateStore = conf.getPrivateStore(); + scf.setKeyStorePassword(conf.getPrivateStorePw()); + scf.setKeyStore(privateStore); + scf.setCertAlias(alias); + return scf; + } + } + private void initHandlers() throws GeneralSecurityException, IOException { HandlerList hl = new HandlerList(); hl.setHandlers(new Handler[] { - hw, servlet + ContextLauncher.generateStaticContext(), ContextLauncher.generateGigiContexts(conf.getMainProps(), conf.getTrustStore()), ContextLauncher.generateAPIContext() }); - - ContextHandler ch = new ContextHandler(); - ch.setHandler(hl); - return ch; + s.setHandler(hl); } - private static Handler generateStaticContext() { - final ResourceHandler rh = generateResourceHandler(); - rh.setResourceBase("static/static"); + private static class ContextLauncher { - ContextHandler ch = new ContextHandler(); - ch.setHandler(rh); - ch.setVirtualHosts(new String[] { - ServerConstants.getStaticHostName() - }); + private ContextLauncher() {} - return ch; - } + protected static Handler generateGigiContexts(Properties conf, KeyStore trust) { + ServletHolder webAppServlet = new ServletHolder(new Gigi(conf, trust)); - private static ResourceHandler generateResourceHandler() { - ResourceHandler rh = new ResourceHandler() { + ContextHandler ch = generateGigiServletContext(webAppServlet); + ch.setVirtualHosts(new String[] { + ServerConstants.getWwwHostName() + }); + ContextHandler chSecure = generateGigiServletContext(webAppServlet); + chSecure.setVirtualHosts(new String[] { + ServerConstants.getSecureHostName() + }); - @Override - protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType) { - super.doResponseHeaders(response, resource, mimeType); - response.setDateHeader(HttpHeader.EXPIRES.asString(), System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 7); - } - }; - rh.setEtags(true); - return rh; - } + HandlerList hl = new HandlerList(); + hl.setHandlers(new Handler[] { + ch, chSecure + }); + return hl; + } - private static Handler generateAPIContext() { - ServletContextHandler sch = new ServletContextHandler(); + private static ContextHandler generateGigiServletContext(ServletHolder webAppServlet) { + final ResourceHandler rh = generateResourceHandler(); + rh.setResourceBase("static/www"); + + HandlerWrapper hw = new PolicyRedirector(); + hw.setHandler(rh); + + ServletContextHandler servlet = new ServletContextHandler(ServletContextHandler.SESSIONS); + servlet.setInitParameter(SessionManager.__SessionCookieProperty, "CACert-Session"); + servlet.addServlet(webAppServlet, "/*"); + ErrorPageErrorHandler epeh = new ErrorPageErrorHandler(); + epeh.addErrorPage(404, "/error"); + epeh.addErrorPage(403, "/denied"); + servlet.setErrorHandler(epeh); + + HandlerList hl = new HandlerList(); + hl.setHandlers(new Handler[] { + hw, servlet + }); + + ContextHandler ch = new ContextHandler(); + ch.setHandler(hl); + return ch; + } - sch.addVirtualHosts(new String[] { - ServerConstants.getApiHostName() - }); - sch.addServlet(new ServletHolder(new GigiAPI()), "/*"); - return sch; - } + protected static Handler generateStaticContext() { + final ResourceHandler rh = generateResourceHandler(); + rh.setResourceBase("static/static"); - private static SslContextFactory generateSSLContextFactory(GigiConfig conf, String alias) throws GeneralSecurityException, IOException { - SslContextFactory scf = new SslContextFactory() { + ContextHandler ch = new ContextHandler(); + ch.setHandler(rh); + ch.setVirtualHosts(new String[] { + ServerConstants.getStaticHostName() + }); - String[] ciphers = null; + return ch; + } - @Override - public void customize(SSLEngine sslEngine) { - super.customize(sslEngine); + private static ResourceHandler generateResourceHandler() { + ResourceHandler rh = new ResourceHandler() { - SSLParameters ssl = sslEngine.getSSLParameters(); - ssl.setUseCipherSuitesOrder(true); - if (ciphers == null) { - ciphers = CipherInfo.filter(sslEngine.getSupportedCipherSuites()); + @Override + protected void doResponseHeaders(HttpServletResponse response, Resource resource, String mimeType) { + super.doResponseHeaders(response, resource, mimeType); + response.setDateHeader(HttpHeader.EXPIRES.asString(), System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 7); } + }; + rh.setEtags(true); + return rh; + } - ssl.setCipherSuites(ciphers); - sslEngine.setSSLParameters(ssl); - - } + protected static Handler generateAPIContext() { + ServletContextHandler sch = new ServletContextHandler(); - }; - scf.setRenegotiationAllowed(false); + sch.addVirtualHosts(new String[] { + ServerConstants.getApiHostName() + }); + sch.addServlet(new ServletHolder(new GigiAPI()), "/*"); + return sch; + } - scf.setProtocol("TLS"); - scf.setIncludeProtocols("TLSv1", "TLSv1.1", "TLSv1.2"); - scf.setTrustStore(conf.getTrustStore()); - KeyStore privateStore = conf.getPrivateStore(); - scf.setKeyStorePassword(conf.getPrivateStorePw()); - scf.setKeyStore(privateStore); - scf.setCertAlias(alias); - return scf; } + } diff --git a/src/org/cacert/gigi/output/template/Template.java b/src/org/cacert/gigi/output/template/Template.java index 4789a365..d49df9ae 100644 --- a/src/org/cacert/gigi/output/template/Template.java +++ b/src/org/cacert/gigi/output/template/Template.java @@ -14,7 +14,6 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.cacert.gigi.DevelLauncher; import org.cacert.gigi.localisation.Language; import org.cacert.gigi.util.HTMLEncoder; @@ -63,7 +62,7 @@ public class Template implements Outputable { try { Reader r = new InputStreamReader(u.openStream(), "UTF-8"); try { - if (u.getProtocol().equals("file") && DevelLauncher.DEVEL) { + if (u.getProtocol().equals("file")) { source = new File(u.toURI()); lastLoaded = source.lastModified() + 1000; } @@ -166,17 +165,15 @@ public class Template implements Outputable { @Override public void output(PrintWriter out, Language l, Map vars) { - if (source != null && DevelLauncher.DEVEL) { - if (lastLoaded < source.lastModified()) { - try { - System.out.println("Reloading template.... " + source); - InputStreamReader r = new InputStreamReader(new FileInputStream(source), "UTF-8"); - data = parse(r).getBlock(null); - r.close(); - lastLoaded = source.lastModified() + 1000; - } catch (IOException e) { - e.printStackTrace(); - } + if (source != null && lastLoaded < source.lastModified()) { + try { + System.out.println("Reloading template.... " + source); + InputStreamReader r = new InputStreamReader(new FileInputStream(source), "UTF-8"); + data = parse(r).getBlock(null); + r.close(); + lastLoaded = source.lastModified() + 1000; + } catch (IOException e) { + e.printStackTrace(); } } data.output(out, l, vars); diff --git a/tests/org/cacert/gigi/testUtils/ManagedTest.java b/tests/org/cacert/gigi/testUtils/ManagedTest.java index 65f1d4b3..584b10e4 100644 --- a/tests/org/cacert/gigi/testUtils/ManagedTest.java +++ b/tests/org/cacert/gigi/testUtils/ManagedTest.java @@ -120,7 +120,7 @@ public class ManagedTest extends ConfiguredTest { final BufferedReader br = new BufferedReader(new InputStreamReader(gigi.getErrorStream(), "UTF-8")); String line; - while ((line = br.readLine()) != null && !line.contains("Server:main: Started")) { + while ((line = br.readLine()) != null && !line.contains("System successfully started.")) { } new Thread() { diff --git a/src/org/cacert/gigi/DevelLauncher.java b/util-testing/org/cacert/gigi/DevelLauncher.java similarity index 92% rename from src/org/cacert/gigi/DevelLauncher.java rename to util-testing/org/cacert/gigi/DevelLauncher.java index 97b4b3d5..2f28757d 100644 --- a/src/org/cacert/gigi/DevelLauncher.java +++ b/util-testing/org/cacert/gigi/DevelLauncher.java @@ -4,7 +4,6 @@ import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; -import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -30,8 +29,6 @@ import org.kamranzafar.jtar.TarOutputStream; public class DevelLauncher { - public static final boolean DEVEL = true; - public static void main(String[] args) throws Exception { Properties mainProps = new Properties(); try (FileInputStream inStream = new FileInputStream("config/gigi.properties")) { @@ -54,7 +51,7 @@ public class DevelLauncher { dos.flush(); InputStream oldin = System.in; System.setIn(new ByteArrayInputStream(chunkConfig.toByteArray())); - Launcher.boot(); + new Launcher().boot(); addDevelPage(); System.setIn(oldin); BufferedReader br = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); @@ -153,13 +150,4 @@ public class DevelLauncher { tos.write(data); } - public static void writeChunk(DataOutputStream dos, byte[] chunk) throws IOException { - dos.writeInt(chunk.length); - dos.write(chunk); - } - - public static void launch(Properties props, File cacerts, File keystore) throws IOException { - ByteArrayOutputStream config = new ByteArrayOutputStream(); - props.store(config, ""); - } } diff --git a/util-testing/org/cacert/gigi/TestLauncher.java b/util-testing/org/cacert/gigi/TestLauncher.java new file mode 100644 index 00000000..0181de7a --- /dev/null +++ b/util-testing/org/cacert/gigi/TestLauncher.java @@ -0,0 +1,12 @@ +package org.cacert.gigi; + +public class TestLauncher { + + public static void main(String[] args) throws Exception { + // As clean as possible + Launcher.main(args); + DevelLauncher.addDevelPage(); + System.err.println("System successfully started."); + + } +} -- 2.39.2