From 234dae50395faa589810f0b1d8d6b7a0fba7393f Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Mon, 29 Aug 2016 14:10:09 +0200 Subject: [PATCH] Support socket activation There are now separate properties for the port that is "displayed" (e.g. when issuing redirects) and the port that is actually bound. The bind ports may also be set to "stdin", in which case System.inheritedChannel is used (expects a socket as file descriptor 0). This allows gigi to inherit a socket from the system manager ((x)inetd, systemd), which in turn allows one to run gigi as any user on root ports (e.g. port 80). Change-Id: I343e1e25daae94aae67db1dd6f25fcfb6241d0fc --- src/org/cacert/gigi/Launcher.java | 17 ++++++++++++----- src/org/cacert/gigi/util/ServerConstants.java | 18 +++++++++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/org/cacert/gigi/Launcher.java b/src/org/cacert/gigi/Launcher.java index cff94772..5f767a63 100644 --- a/src/org/cacert/gigi/Launcher.java +++ b/src/org/cacert/gigi/Launcher.java @@ -112,6 +112,10 @@ public class Launcher { GigiConfig conf; + 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")); @@ -127,7 +131,7 @@ public class Launcher { initHandlers(); s.start(); - if ((ServerConstants.getSecurePort() <= 1024 || ServerConstants.getPort() <= 1024) && !System.getProperty("os.name").toLowerCase().contains("win")) { + if ((isSystemPort(ServerConstants.getSecurePort()) || isSystemPort(ServerConstants.getPort())) && !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!"); @@ -177,16 +181,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; diff --git a/src/org/cacert/gigi/util/ServerConstants.java b/src/org/cacert/gigi/util/ServerConstants.java index 21bbce98..3bf32635 100644 --- a/src/org/cacert/gigi/util/ServerConstants.java +++ b/src/org/cacert/gigi/util/ServerConstants.java @@ -12,7 +12,7 @@ public class ServerConstants { private static String apiHostName = "api.cacert.local"; - private static String securePort, port; + private static String securePort, port, secureBindPort, bindPort; private static String suffix = "cacert.local"; @@ -24,6 +24,8 @@ public class ServerConstants { if ( !conf.getProperty("http.port").equals("80")) { port = ":" + conf.getProperty("http.port"); } + secureBindPort = conf.getProperty("https.bindPort", conf.getProperty("https.port")); + bindPort = conf.getProperty("http.bindPort", conf.getProperty("http.port")); wwwHostName = conf.getProperty("name.www"); secureHostName = conf.getProperty("name.secure"); staticHostName = conf.getProperty("name.static"); @@ -73,6 +75,13 @@ public class ServerConstants { } public static int getSecurePort() { + if (secureBindPort != null && !secureBindPort.isEmpty()) { + if (secureBindPort.equals("stdin")) { + return -1; + } else { + return Integer.parseInt(secureBindPort); + } + } if (securePort.isEmpty()) { return 443; } @@ -80,6 +89,13 @@ public class ServerConstants { } public static int getPort() { + if (bindPort != null && !bindPort.isEmpty()) { + if (bindPort.equals("stdin")) { + return -1; + } else { + return Integer.parseInt(bindPort); + } + } if (port.isEmpty()) { return 80; } -- 2.39.2