import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.util.List;
+import java.util.Locale;
import java.util.Properties;
+import java.util.TimeZone;
import javax.net.ssl.ExtendedSSLSession;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
+import javax.servlet.http.HttpServletResponse;
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.ServerConstants;
+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.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
public class Launcher {
public static void main(String[] args) throws Exception {
+ System.setProperty("jdk.tls.ephemeralDHKeySize", "4096");
+ boot();
+ }
+
+ public static void boot() throws Exception {
+ Locale.setDefault(Locale.ENGLISH);
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+
GigiConfig conf = GigiConfig.parse(System.in);
ServerConstants.init(conf.getMainProps());
initEmails(conf);
Server s = new Server();
- // === SSL HTTP Configuration ===
- HttpConfiguration https_config = new HttpConfiguration();
- https_config.setSendServerVersion(false);
- https_config.setSendXPoweredBy(false);
+ HttpConfiguration httpsConfig = createHttpConfiguration();
// for client-cert auth
- https_config.addCustomizer(new SecureRequestCustomizer());
+ httpsConfig.addCustomizer(new SecureRequestCustomizer());
+
+ HttpConfiguration httpConfig = createHttpConfiguration();
- ServerConnector connector = new ServerConnector(s, createConnectionFactory(conf), new HttpConnectionFactory(https_config));
- connector.setHost(conf.getMainProps().getProperty("host"));
- connector.setPort(Integer.parseInt(conf.getMainProps().getProperty("port")));
- connector.setAcceptQueueSize(100);
s.setConnectors(new Connector[] {
- connector
+ createConnector(conf, s, httpsConfig, true), createConnector(conf, s, httpConfig, false)
});
HandlerList hl = new HandlerList();
hl.setHandlers(new Handler[] {
- generateStaticContext(), generateGigiContexts(conf.getMainProps()), generateAPIContext()
+ generateStaticContext(), generateGigiContexts(conf.getMainProps(), conf.getTrustStore()), generateAPIContext()
});
s.setHandler(hl);
s.start();
- if (connector.getPort() <= 1024 && !System.getProperty("os.name").toLowerCase().contains("win")) {
+ 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 (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() {
+ // SSL HTTP Configuration
+ HttpConfiguration httpsConfig = new HttpConfiguration();
+ httpsConfig.setSendServerVersion(false);
+ httpsConfig.setSendXPoweredBy(false);
+ return httpsConfig;
}
private static void initEmails(GigiConfig conf) throws GeneralSecurityException, IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
secureContextFactory.setNeedClientAuth(false);
final SslContextFactory staticContextFactory = generateSSLContextFactory(conf, "static");
final SslContextFactory apiContextFactory = generateSSLContextFactory(conf, "api");
+ apiContextFactory.setWantClientAuth(true);
try {
secureContextFactory.start();
staticContextFactory.start();
};
}
- private static Handler generateGigiContexts(Properties conf) {
- ServletHolder webAppServlet = new ServletHolder(new Gigi(conf));
+ private static Handler generateGigiContexts(Properties conf, KeyStore trust) {
+ ServletHolder webAppServlet = new ServletHolder(new Gigi(conf, trust));
ContextHandler ch = generateGigiServletContext(webAppServlet);
ch.setVirtualHosts(new String[] {
}
private static ContextHandler generateGigiServletContext(ServletHolder webAppServlet) {
- final ResourceHandler rh = new ResourceHandler();
+ final ResourceHandler rh = generateResourceHandler();
rh.setResourceBase("static/www");
HandlerWrapper hw = new PolicyRedirector();
servlet.addServlet(webAppServlet, "/*");
ErrorPageErrorHandler epeh = new ErrorPageErrorHandler();
epeh.addErrorPage(404, "/error");
+ epeh.addErrorPage(403, "/denied");
servlet.setErrorHandler(epeh);
HandlerList hl = new HandlerList();
}
private static Handler generateStaticContext() {
- final ResourceHandler rh = new ResourceHandler();
+ final ResourceHandler rh = generateResourceHandler();
rh.setResourceBase("static/static");
ContextHandler ch = new ContextHandler();
return ch;
}
+ private static ResourceHandler generateResourceHandler() {
+ ResourceHandler rh = new ResourceHandler() {
+
+ @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;
+ }
+
private static Handler generateAPIContext() {
ServletContextHandler sch = new ServletContextHandler();
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());