[UPDATE-CONFIG] Use 3 hosts www, secure and static.
authorFelix Dörre <felix@dogcraft.de>
Thu, 3 Jul 2014 09:39:33 +0000 (11:39 +0200)
committerFelix Dörre <felix@dogcraft.de>
Thu, 3 Jul 2014 15:22:21 +0000 (17:22 +0200)
(they need to be configured)
- add hosts,
- update both .properties
- regenerate keys and truststore.

28 files changed:
config/gigi.properties.template
config/test.properties.template
doc/beforeYouStart.txt
doc/scripts/generateKeys.sh
doc/scripts/generateTruststore.sh
src/org/cacert/gigi/DevelLauncher.java
src/org/cacert/gigi/Gigi.java
src/org/cacert/gigi/GigiConfig.java
src/org/cacert/gigi/Launcher.java
src/org/cacert/gigi/PolicyRedirector.java
src/org/cacert/gigi/pages/main/Signup.java
src/org/cacert/gigi/util/ServerConstants.java
static/static/default.css [moved from static/default.css with 100% similarity]
static/static/menu.js [moved from static/menu.js with 100% similarity]
static/www/policy/AssurancePolicy.html [moved from static/policy/AssurancePolicy.html with 100% similarity]
static/www/policy/CAcertCommunityAgreement.html [moved from static/policy/CAcertCommunityAgreement.html with 100% similarity]
static/www/policy/CertificationPracticeStatement.html [moved from static/policy/CertificationPracticeStatement.html with 100% similarity]
static/www/policy/DisputeResolutionPolicy.html [moved from static/policy/DisputeResolutionPolicy.html with 100% similarity]
static/www/policy/NRPDisclaimerAndLicence.html [moved from static/policy/NRPDisclaimerAndLicence.html with 100% similarity]
static/www/policy/OrganisationAssurancePolicy.html [moved from static/policy/OrganisationAssurancePolicy.html with 100% similarity]
static/www/policy/PolicyOnPolicy.html [moved from static/policy/PolicyOnPolicy.html with 100% similarity]
static/www/policy/PrivacyPolicy.html [moved from static/policy/PrivacyPolicy.html with 100% similarity]
static/www/policy/RootDistributionLicense.html [moved from static/policy/RootDistributionLicense.html with 100% similarity]
static/www/policy/cacert-draft.png [moved from static/policy/cacert-draft.png with 100% similarity]
templates/base.html
tests/org/cacert/gigi/pages/main/RegisterPageTest.java
tests/org/cacert/gigi/testUtils/ManagedTest.java
tests/org/cacert/gigi/testUtils/TestEmailReciever.java

index 474d677..b37825f 100644 (file)
@@ -1,4 +1,7 @@
 host=127.0.0.1
+name.static=static.cacert.local
+name.secure=secure.cacert.local
+name.www=www.cacert.local
 port=443
 #emailProvider=org.cacert.gigi.email.Sendmail
 emailProvider=org.cacert.gigi.email.CommandlineEmailProvider
index 1bd8a58..01a83df 100644 (file)
@@ -12,6 +12,9 @@ mailPort=8473
 
 
 # ==== ALL ===
+name.static=static.cacert.local
+name.secure=secure.cacert.local
+name.www=www.cacert.local
 sql.driver=com.mysql.jdbc.Driver
 sql.url=jdbc:mysql://localhost:3306/cacert
 sql.user=cacert
index bfa3f39..b51c5db 100644 (file)
@@ -5,6 +5,9 @@ Before you start using you might want to:
 
 - download locales (util/ org.cacert.gigi.util.FetchLocales)
 - write your sql connection properties: config/gigi.properties.template -> config/gigi.properties
+- install "hosts" entries for the hosts you entered in "gigi.properties"
+   (be aware if you change the default ones you need to change the CN given in the certificates)
+
 - add the corresponding jdbc connector to your path.
 
 - on unix-like systems: to securely run on privileged ports <= 1024 build the native setuid library (run the makefile in natives/).
index 545b12a..80bbf89 100755 (executable)
@@ -19,9 +19,9 @@ openssl genrsa -out $1.key 4096
 openssl req -new -key $1.key -out $1.csr -subj "/CN=$1.cacert.local" -config selfsign.config
 openssl ca -cert testca.crt -keyfile testca.key -in $1.csr -out $1.crt -days 356 -batch -config selfsign.config
 
-openssl pkcs12 -inkey $1.key -in $1.crt -name $1 -export -passout pass: -out $1.pkcs12
+openssl pkcs12 -inkey $1.key -in $1.crt -name $1 -export -passout pass:changeit -out $1.pkcs12
 
-keytool -importkeystore -noprompt -srckeystore $1.pkcs12 -destkeystore ../../config/keystore.pkcs12 -srcstoretype pkcs12 -deststoretype pkcs12 -srcstorepass "" -deststorepass ""
+keytool -importkeystore -noprompt -srckeystore $1.pkcs12 -destkeystore ../../config/keystore.pkcs12 -srcstoretype pkcs12 -deststoretype pkcs12 -srcstorepass "changeit" -deststorepass "changeit"
 
 }
 
@@ -30,4 +30,4 @@ genserver secure
 genserver static
 genserver api
 
-keytool -list -keystore ../../config/keystore.pkcs12 -storetype pkcs12 -storepass ""
+keytool -list -keystore ../../config/keystore.pkcs12 -storetype pkcs12 -storepass "changeit"
index 1295294..6b96902 100755 (executable)
@@ -6,6 +6,6 @@ wget -N http://www.cacert.org/certs/class3.crt
 
 keytool -importcert -keystore ../../config/cacerts.jks -file root.crt -alias root -storepass "changeit" $1
 keytool -importcert -keystore ../../config/cacerts.jks -file class3.crt -alias class3 -storepass "changeit" $1
-keytool -importcert -keystore ../../config/cacerts.jks -file jetty.crt -alias own -storepass "changeit" $1
+keytool -importcert -keystore ../../config/cacerts.jks -file testca.crt -alias own -storepass "changeit" $1
 
 keytool -list -keystore ../../config/cacerts.jks -storepass "changeit"
index 74a4ae6..e8df9f5 100644 (file)
@@ -33,8 +33,8 @@ public class DevelLauncher {
                byte[] keystore = Files.readAllBytes(Paths
                                .get("config/keystore.pkcs12"));
 
-               DevelLauncher.writeGigiConfig(dos, new byte[]{}, "changeit".getBytes(),
-                               mainProps, cacerts, keystore);
+               DevelLauncher.writeGigiConfig(dos, "changeit".getBytes(),
+                               "changeit".getBytes(), mainProps, cacerts, keystore);
                dos.flush();
                InputStream oldin = System.in;
                System.setIn(new ByteArrayInputStream(chunkConfig.toByteArray()));
index cef1834..fa259c9 100644 (file)
@@ -28,6 +28,7 @@ import org.cacert.gigi.pages.account.MailOverview;
 import org.cacert.gigi.pages.account.MyDetails;
 import org.cacert.gigi.pages.main.RegisterPage;
 import org.cacert.gigi.pages.wot.AssurePage;
+import org.cacert.gigi.util.ServerConstants;
 import org.eclipse.jetty.util.log.Log;
 
 public class Gigi extends HttpServlet {
@@ -149,8 +150,9 @@ public class Gigi extends HttpServlet {
                hsr.addHeader("Access-Control-Allow-Origin",
                                "http://cacert.org https://localhost");
                hsr.addHeader("Access-Control-Max-Age", "60");
-               hsr.addHeader("Content-Security-Policy",
-                               "default-src 'self' https://www.cacert.org/*;frame-ancestors 'none'");
+               hsr.addHeader("Content-Security-Policy", "default-src 'self' https://"
+                               + ServerConstants.getStaticHostNamePort()
+                               + " https://www.cacert.org/*;frame-ancestors 'none'");
                // ;report-uri https://felix.dogcraft.de/report.php
 
        }
index 69c95bb..f8cf763 100644 (file)
@@ -84,4 +84,7 @@ public class GigiConfig {
                ks1.load(new ByteArrayInputStream(cacerts), truststorepw);
                return ks1;
        }
+       public String getPrivateStorePw() {
+               return new String(keystorpw);
+       }
 }
index 6c23490..41b09ff 100644 (file)
@@ -2,13 +2,20 @@ package org.cacert.gigi;
 import java.io.IOException;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
+import java.util.List;
 import java.util.Properties;
 
+import javax.net.ssl.ExtendedSSLSession;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
-import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.SSLSession;
+
 import org.cacert.gigi.natives.SetUID;
 import org.cacert.gigi.util.CipherInfo;
+import org.cacert.gigi.util.ServerConstants;
+import org.eclipse.jetty.http.HttpVersion;
 import org.eclipse.jetty.server.Connector;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.HttpConfiguration;
@@ -30,6 +37,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
 public class Launcher {
        public static void main(String[] args) throws Exception {
                GigiConfig conf = GigiConfig.parse(System.in);
+               ServerConstants.init(conf.getMainProps());
 
                Server s = new Server();
                // === SSL HTTP Configuration ===
@@ -41,8 +49,8 @@ public class Launcher {
                https_config.addCustomizer(new SecureRequestCustomizer());
 
                ServerConnector connector = new ServerConnector(s,
-                               new SslConnectionFactory(generateSSLContextFactory(conf),
-                                               "http/1.1"), new HttpConnectionFactory(https_config));
+                               createConnectionFactory(conf), new HttpConnectionFactory(
+                                               https_config));
                connector.setHost(conf.getMainProps().getProperty("host"));
                connector.setPort(Integer.parseInt(conf.getMainProps().getProperty(
                                "port")));
@@ -62,33 +70,95 @@ public class Launcher {
                }
        }
 
-       private static ServletContextHandler generateGigiContext(Properties conf) {
+       private static SslConnectionFactory createConnectionFactory(GigiConfig conf)
+                       throws GeneralSecurityException, IOException {
+               final SslContextFactory sslContextFactory = generateSSLContextFactory(
+                               conf, "www");
+               final SslContextFactory secureContextFactory = generateSSLContextFactory(
+                               conf, "secure");
+               secureContextFactory.setNeedClientAuth(true);
+               final SslContextFactory staticContextFactory = generateSSLContextFactory(
+                               conf, "static");
+               try {
+                       secureContextFactory.start();
+                       staticContextFactory.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<SNIServerName> names = es.getRequestedServerNames();
+                                       for (SNIServerName sniServerName : names) {
+                                               if (sniServerName instanceof SNIHostName) {
+                                                       SNIHostName host = (SNIHostName) sniServerName;
+                                                       String hostname = host.getAsciiName();
+                                                       if (hostname.equals("www.cacert.local")) {
+                                                               e2 = sslContextFactory.newSSLEngine();
+                                                       } else if (hostname.equals("static.cacert.local")) {
+                                                               e2 = staticContextFactory.newSSLEngine();
+                                                       } else if (hostname.equals("secure.cacert.local")) {
+                                                               e2 = secureContextFactory.newSSLEngine();
+                                                       }
+                                                       break;
+                                               }
+                                       }
+                               }
+                               if (e2 == null) {
+                                       e2 = sslContextFactory.newSSLEngine(
+                                                       sslSession.getPeerHost(), sslSession.getPeerPort());
+                               }
+                               e2.setUseClientMode(false);
+                               return e2;
+                       }
+               };
+       }
+
+       private static ContextHandler generateGigiContext(Properties conf) {
+               final ResourceHandler rh = new ResourceHandler();
+               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(new ServletHolder(new Gigi(conf)), "/*");
-               return servlet;
+
+               HandlerList hl = new HandlerList();
+               hl.setHandlers(new Handler[]{servlet, hw});
+
+               ContextHandler ch = new ContextHandler();
+               ch.setVirtualHosts(new String[]{ServerConstants.getWwwHostName(),
+                               ServerConstants.getSecureHostName()});
+               ch.setHandler(hl);
+
+               return ch;
        }
 
        private static Handler generateStaticContext() {
                final ResourceHandler rh = new ResourceHandler();
-               rh.setResourceBase("static");
-               HandlerWrapper hw = new PolicyRedirector();
-               hw.setHandler(rh);
+               rh.setResourceBase("static/static");
 
                ContextHandler ch = new ContextHandler();
-               ch.setContextPath("/static");
-               ch.setHandler(hw);
+               ch.setHandler(rh);
+               ch.setVirtualHosts(new String[]{ServerConstants.getStaticHostName()});
 
                return ch;
        }
 
-       private static SslContextFactory generateSSLContextFactory(GigiConfig conf)
-                       throws GeneralSecurityException, IOException {
-               TrustManagerFactory tmFactory = TrustManagerFactory.getInstance("PKIX");
-               tmFactory.init((KeyStore) null);
-
+       private static SslContextFactory generateSSLContextFactory(GigiConfig conf,
+                       String alias) throws GeneralSecurityException, IOException {
                SslContextFactory scf = new SslContextFactory() {
 
                        String[] ciphers = null;
@@ -111,11 +181,13 @@ public class Launcher {
 
                };
                scf.setRenegotiationAllowed(false);
-               scf.setWantClientAuth(true);
 
                scf.setProtocol("TLS");
                scf.setTrustStore(conf.getTrustStore());
-               scf.setKeyStore(conf.getPrivateStore());
+               KeyStore privateStore = conf.getPrivateStore();
+               scf.setKeyStorePassword(conf.getPrivateStorePw());
+               scf.setKeyStore(privateStore);
+               scf.setCertAlias(alias);
                return scf;
        }
 }
index 8714d95..300f880 100644 (file)
@@ -14,9 +14,10 @@ public class PolicyRedirector extends HandlerWrapper {
        public void handle(String target, Request baseRequest,
                        HttpServletRequest request, HttpServletResponse response)
                        throws IOException, ServletException {
+               System.out.println("h1"+target);
                if (target.startsWith("/policy/") && target.endsWith(".php")) {
                        target = target.replace(".php", ".html");
-                       response.sendRedirect("/static" + target);
+                       response.sendRedirect(target);
                        baseRequest.setHandled(true);
                        return;
                }
index 3d07444..428b068 100644 (file)
@@ -255,8 +255,8 @@ public class Signup extends Form {
                                        .translate(
                                                        req,
                                                        "Thanks for signing up with CAcert.org, below is the link you need to open to verify your account. Once your account is verified you will be able to start issuing certificates till your hearts' content!"));
-                       body.append("\n\n");
-                       body.append(ServerConstants.NORMAL_HOST_NAME);
+                       body.append("\n\nhttps://");
+                       body.append(ServerConstants.getWwwHostNamePort());
                        body.append("/verify?type=email&id=");
                        body.append(emailid);
                        body.append("&hash=");
index 82b124c..28a52eb 100644 (file)
@@ -1,5 +1,38 @@
 package org.cacert.gigi.util;
 
+import java.util.Properties;
+
 public class ServerConstants {
-       public static final String NORMAL_HOST_NAME = "http://www.cacert.org";
+       private static String wwwHostName = "www.cacert.local";
+       private static String secureHostName = "secure.cacert.local";
+       private static String staticHostName = "static.cacert.local";
+       private static String port;
+       public static void init(Properties conf) {
+               port = "";
+               if (!conf.getProperty("port").equals("443")) {
+                       port = ":" + conf.getProperty("port");
+               }
+               wwwHostName = conf.getProperty("name.www");
+               secureHostName = conf.getProperty("name.secure");
+               staticHostName = conf.getProperty("name.static");
+       }
+       public static String getSecureHostName() {
+               return secureHostName;
+       }
+       public static String getStaticHostName() {
+               return staticHostName;
+       }
+       public static String getWwwHostName() {
+               return wwwHostName;
+       }
+       public static String getSecureHostNamePort() {
+               return secureHostName + port;
+       }
+       public static String getStaticHostNamePort() {
+               return staticHostName + port;
+       }
+       public static String getWwwHostNamePort() {
+               return wwwHostName + port;
+       }
+
 }
similarity index 100%
rename from static/default.css
rename to static/static/default.css
similarity index 100%
rename from static/menu.js
rename to static/static/menu.js
index 7b0eafa..65ca476 100644 (file)
@@ -2,8 +2,8 @@
 <html>
 <head>
 <title>$title$</title>
-<link rel="stylesheet" href="/static/default.css" type="text/css">
-<script src="/static/menu.js"></script>
+<link rel="stylesheet" href="https://static.cacert.local/default.css" type="text/css">
+<script src="https://static.cacert.local/menu.js"></script>
 </head>
 <body>
        <div id="pagecell1">
index 0678724..af56fdf 100644 (file)
@@ -27,7 +27,7 @@ public class RegisterPageTest extends ManagedTest {
                registerUser("ab", "b", "correct" + uniq + "@email.de", "ap12UI.'");
                TestMail tm = waitForMail();
                String link = tm.extractLink();
-               assertTrue(link, link.startsWith("http://"));
+               assertTrue(link, link.startsWith("https://"));
        }
        @Test
        public void testNoFname() throws IOException {
index ce60a29..869d417 100644 (file)
@@ -67,13 +67,19 @@ public class ManagedTest {
                                                Integer.parseInt(parts[1])));
                                return;
                        }
-                       url = "localhost:" + testProps.getProperty("serverPort");
+                       url = testProps.getProperty("name.www") + ":"
+                                       + testProps.getProperty("serverPort");
                        gigi = Runtime.getRuntime().exec(testProps.getProperty("java"));
                        DataOutputStream toGigi = new DataOutputStream(
                                        gigi.getOutputStream());
                        System.out.println("... starting server");
                        Properties mainProps = new Properties();
                        mainProps.setProperty("host", "127.0.0.1");
+                       mainProps.setProperty("name.secure", "sec");
+                       mainProps
+                                       .setProperty("name.www", testProps.getProperty("name.www"));
+                       mainProps.setProperty("name.static", "stat");
+
                        mainProps.setProperty("port", testProps.getProperty("serverPort"));
                        mainProps.setProperty("emailProvider",
                                        "org.cacert.gigi.email.TestEmailProvider");
@@ -91,15 +97,10 @@ public class ManagedTest {
                        byte[] keystore = Files.readAllBytes(Paths
                                        .get("config/keystore.pkcs12"));
 
-                       DevelLauncher.writeGigiConfig(toGigi, new byte[]{},
+                       DevelLauncher.writeGigiConfig(toGigi, "changeit".getBytes(),
                                        "changeit".getBytes(), mainProps, cacerts, keystore);
                        toGigi.flush();
-                       // TODO wait for ready
-                       try {
-                               Thread.sleep(3000);
-                       } catch (InterruptedException e) {
-                               e.printStackTrace();
-                       }
+
                        final BufferedReader br = new BufferedReader(new InputStreamReader(
                                        gigi.getErrorStream()));
                        String line;
index e0131a3..fca0a09 100644 (file)
@@ -41,7 +41,7 @@ public class TestEmailReciever implements Runnable {
                        return replyto;
                }
                public String extractLink() {
-                       Pattern link = Pattern.compile("http://[^\\s]+(?=\\s)");
+                       Pattern link = Pattern.compile("https?://[^\\s]+(?=\\s)");
                        Matcher m = link.matcher(getMessage());
                        m.find();
                        return m.group(0);