[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 474d6771e48551ee92608cc1dadc5631773d997a..b37825f3e27f820dd6f25efa07d42f8a5ab6919b 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 1bd8a5845f01f229d14613b7e1448d4296a0606b..01a83dfc51ecedf96dbe1aae89a1cbbd3d565608 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 bfa3f39e591dc4b464f84593977c9a166c19ade2..b51c5db6812fdf176bb09c8527371f48cec262d7 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 545b12a42adbf3a375be2c986063951897a50920..80bbf8954b2014af47719bae1888648f99a3cd88 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 12952944dc2c4596ae93bd89d285efc27f6deaea..6b969026407fe967eb1b1dd87a33313a412c1bc2 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 74a4ae6a515ff95385e41a147c1c120a7fd27d1b..e8df9f5bdf2d048ff54569471f12bf4ccb425167 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 cef183495315a748cff19d96c8433d99679cb6ef..fa259c96c77cbf99835c8df72e374c863935bd3e 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 69c95bbdea18f54e817f7a2ec2062aa46187f4d2..f8cf76378aa1f6539e6e18403b95fa77191c08bc 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 6c234909f5714b3fe55df18cf6bac43afcf44c21..41b09ffb6a4a04736bf6316fe4ad1c89dd6ba666 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 8714d959f6c0f91173857ec3e6ca5529dfdee757..300f8800ad57d7f4d7c5420865531a20fbe59d1e 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 3d074441edbd3d587894d1ca865a0d3b62daaa02..428b068cc7aeeb5ba26ef3f6c25c88ecb42bd8e4 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 82b124c42f5391a6f8a23273581ed515d0d2cfaf..28a52eb4e924332fc9726ed35473209fac42ac31 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 7b0eafa16f6d777c058ca994442c57a9c5b8d25b..65ca4765f8deb833c66758ebc0556bb9b066669d 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 06787248d311a6f3639691a4e7c2726dda397bd7..af56fdf3479a1311a3218fcb941b59ae0bdea982 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 ce60a295832584c5c6b282af91bee8ae1de52838..869d417a47b7b932795e3bb6d32e20f075345cb0 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 e0131a3b3265ad3adb1857448882d74759f9118d..fca0a095a2c2c3d9b81109f03bdcf06bcd3d4045 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);