X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2Forg%2Fcacert%2Fgigi%2FLauncher.java;h=7c588d8e95a28b49183735478489b2f09e6309f0;hb=cd8500a5faf420aace24ee253a4f2407eb85588d;hp=56d0d4fba2f17551add4113bb0689f921b9af437;hpb=98024a6c871785aa7966f55c174715fec317fb94;p=gigi.git diff --git a/src/org/cacert/gigi/Launcher.java b/src/org/cacert/gigi/Launcher.java index 56d0d4fb..7c588d8e 100644 --- a/src/org/cacert/gigi/Launcher.java +++ b/src/org/cacert/gigi/Launcher.java @@ -1,6 +1,12 @@ package org.cacert.gigi; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; import java.security.GeneralSecurityException; import java.security.Key; import java.security.KeyStore; @@ -8,6 +14,9 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.util.List; import java.util.Locale; import java.util.Properties; @@ -25,13 +34,17 @@ import org.cacert.gigi.api.GigiAPI; import org.cacert.gigi.email.EmailProvider; import org.cacert.gigi.natives.SetUID; import org.cacert.gigi.util.CipherInfo; +import org.cacert.gigi.util.PEM; import org.cacert.gigi.util.ServerConstants; +import org.eclipse.jetty.http.HttpFields; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConfiguration.Customizer; import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; @@ -50,20 +63,65 @@ import org.eclipse.jetty.util.ssl.SslContextFactory; public class Launcher { + class ExtendedForwarded implements Customizer { + + @Override + public void customize(Connector connector, HttpConfiguration config, Request request) { + HttpFields httpFields = request.getHttpFields(); + + String ip = httpFields.getStringField("X-Real-IP"); + String proto = httpFields.getStringField("X-Real-Proto"); + String cert = httpFields.getStringField("X-Client-Cert"); + request.setSecure("https".equals(proto)); + request.setScheme(proto); + if ( !"https".equals(proto)) { + cert = null; + + } + if (cert != null) { + X509Certificate[] certs = new X509Certificate[1]; + try { + certs[0] = (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(new ByteArrayInputStream(PEM.decode("CERTIFICATE", cert))); + request.setAttribute("javax.servlet.request.X509Certificate", certs); + } catch (CertificateException e) { + e.printStackTrace(); + } + } + if (ip != null) { + String[] parts = ip.split(":"); + if (parts.length == 2) { + request.setRemoteAddr(InetSocketAddress.createUnresolved(parts[0], Integer.parseInt(parts[1]))); + } + } + + } + } + public static void main(String[] args) throws Exception { System.setProperty("jdk.tls.ephemeralDHKeySize", "4096"); - new Launcher().boot(); + InputStream in; + if (args.length >= 1) { + in = new FileInputStream(new File(args[0])); + } else { + in = System.in; + } + new Launcher().boot(in); } Server s; GigiConfig conf; - public synchronized void boot() throws Exception { + private boolean isSystemPort(int port) { + return 1 <= port && port <= 1024; + } + + public synchronized void boot(InputStream in) throws Exception { Locale.setDefault(Locale.ENGLISH); TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + HttpURLConnection.setFollowRedirects(false); - conf = GigiConfig.parse(System.in); + conf = GigiConfig.parse(in); ServerConstants.init(conf.getMainProps()); initEmails(conf); @@ -73,10 +131,24 @@ public class Launcher { initHandlers(); s.start(); - if ((ServerConstants.getSecurePort() <= 1024 || ServerConstants.getPort() <= 1024) && !System.getProperty("os.name").toLowerCase().contains("win")) { - SetUID uid = new SetUID(); - if ( !uid.setUid(65536 - 2, 65536 - 2).getSuccess()) { - Log.getLogger(Launcher.class).warn("Couldn't set uid!"); + if ((isSystemPort(ServerConstants.getSecurePort()) || isSystemPort(ServerConstants.getPort())) && !System.getProperty("os.name").toLowerCase().contains("win")) { + String uid_s = conf.getMainProps().getProperty("gigi.uid", Integer.toString(65536 - 2)); + String gid_s = conf.getMainProps().getProperty("gigi.gid", Integer.toString(65536 - 2)); + try { + int uid = Integer.parseInt(uid_s); + int gid = Integer.parseInt(gid_s); + if (uid == -1 && gid == -1) { + // skip setuid step + } else if (uid > 0 && gid > 0 && uid < 65536 && gid < 65536) { + SetUID.Status status = new SetUID().setUid(uid, gid); + if ( !status.getSuccess()) { + Log.getLogger(Launcher.class).warn(status.getMessage()); + } + } else { + Log.getLogger(Launcher.class).warn("Invalid uid or gid (must satisfy 0 < id < 65536)"); + } + } catch (NumberFormatException e) { + Log.getLogger(Launcher.class).warn("Invalid gigi.uid or gigi.gid", e); } } } @@ -90,19 +162,30 @@ public class Launcher { } 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) - }); + if (conf.getMainProps().getProperty("proxy", "false").equals("true")) { + httpConfig.addCustomizer(new ExtendedForwarded()); + s.setConnectors(new Connector[] { + ConnectorsLauncher.createConnector(conf, s, httpConfig, false) + }); + } else { + HttpConfiguration httpsConfig = createHttpConfiguration(); + // for client-cert auth + httpsConfig.addCustomizer(new SecureRequestCustomizer()); + 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()); + Certificate mail = null; + Key k = null; + if (privateStore != null && privateStore.containsAlias("mail")) { + mail = privateStore.getCertificate("mail"); + k = privateStore.getKey("mail", conf.getPrivateStorePw().toCharArray()); + } EmailProvider.initSystem(conf.getMainProps(), mail, k); } @@ -112,16 +195,19 @@ public class Launcher { protected static ServerConnector createConnector(GigiConfig conf, Server s, HttpConfiguration httpConfig, boolean doHttps) throws GeneralSecurityException, IOException { ServerConnector connector; + int port; if (doHttps) { connector = new ServerConnector(s, createConnectionFactory(conf), new HttpConnectionFactory(httpConfig)); + port = ServerConstants.getSecurePort(); } else { connector = new ServerConnector(s, new HttpConnectionFactory(httpConfig)); + port = ServerConstants.getPort(); } - connector.setHost(conf.getMainProps().getProperty("host")); - if (doHttps) { - connector.setPort(ServerConstants.getSecurePort()); + if (port == -1) { + connector.setInheritChannel(true); } else { - connector.setPort(ServerConstants.getPort()); + connector.setHost(conf.getMainProps().getProperty("host")); + connector.setPort(port); } connector.setAcceptQueueSize(100); return connector; @@ -131,7 +217,7 @@ public class Launcher { final SslContextFactory sslContextFactory = generateSSLContextFactory(conf, "www"); final SslContextFactory secureContextFactory = generateSSLContextFactory(conf, "secure"); secureContextFactory.setWantClientAuth(true); - secureContextFactory.setNeedClientAuth(false); + secureContextFactory.setNeedClientAuth(true); final SslContextFactory staticContextFactory = generateSSLContextFactory(conf, "static"); final SslContextFactory apiContextFactory = generateSSLContextFactory(conf, "api"); apiContextFactory.setWantClientAuth(true); @@ -232,11 +318,11 @@ public class Launcher { ContextHandler ch = generateGigiServletContext(webAppServlet); ch.setVirtualHosts(new String[] { - ServerConstants.getWwwHostName() + ServerConstants.getWwwHostName() }); ContextHandler chSecure = generateGigiServletContext(webAppServlet); chSecure.setVirtualHosts(new String[] { - ServerConstants.getSecureHostName() + ServerConstants.getSecureHostName() }); HandlerList hl = new HandlerList(); @@ -254,7 +340,7 @@ public class Launcher { hw.setHandler(rh); ServletContextHandler servlet = new ServletContextHandler(ServletContextHandler.SESSIONS); - servlet.setInitParameter(SessionManager.__SessionCookieProperty, "CACert-Session"); + servlet.setInitParameter(SessionManager.__SessionCookieProperty, "SomeCA-Session"); servlet.addServlet(webAppServlet, "/*"); ErrorPageErrorHandler epeh = new ErrorPageErrorHandler(); epeh.addErrorPage(404, "/error"); @@ -278,7 +364,7 @@ public class Launcher { ContextHandler ch = new ContextHandler(); ch.setHandler(rh); ch.setVirtualHosts(new String[] { - ServerConstants.getStaticHostName() + ServerConstants.getStaticHostName() }); return ch; @@ -301,7 +387,7 @@ public class Launcher { ServletContextHandler sch = new ServletContextHandler(); sch.addVirtualHosts(new String[] { - ServerConstants.getApiHostName() + ServerConstants.getApiHostName() }); sch.addServlet(new ServletHolder(new GigiAPI()), "/*"); return sch;