]> WPIA git - gigi.git/blobdiff - tests/org/cacert/gigi/testUtils/ManagedTest.java
Factor out more test-things.
[gigi.git] / tests / org / cacert / gigi / testUtils / ManagedTest.java
index 9b77f87c1e0ba64445394ce0267e67dd7fdc4252..aa800251e5b7a9995fd3d7a25e9a89c7d9a1c2ad 100644 (file)
@@ -1,5 +1,6 @@
 package org.cacert.gigi.testUtils;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -12,19 +13,35 @@ import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.HttpURLConnection;
 import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.Socket;
 import java.net.URL;
+import java.net.URLConnection;
 import java.net.URLEncoder;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.X509KeyManager;
 
 import org.cacert.gigi.DevelLauncher;
 import org.cacert.gigi.database.DatabaseConnection;
 import org.cacert.gigi.testUtils.TestEmailReciever.TestMail;
 import org.cacert.gigi.util.DatabaseManager;
+import org.cacert.gigi.util.SimpleSigner;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -39,6 +56,7 @@ public class ManagedTest {
        public static String getServerName() {
                return url;
        }
+
        static Properties testProps = new Properties();
        static {
                InitTruststore.run();
@@ -53,60 +71,44 @@ public class ManagedTest {
                                DatabaseConnection.init(testProps);
                        }
                        System.out.println("... purging Database");
-                       DatabaseManager.run(new String[]{
-                                       testProps.getProperty("sql.driver"),
-                                       testProps.getProperty("sql.url"),
-                                       testProps.getProperty("sql.user"),
-                                       testProps.getProperty("sql.password")});
+                       DatabaseManager.run(new String[] { testProps.getProperty("sql.driver"), testProps.getProperty("sql.url"),
+                                       testProps.getProperty("sql.user"), testProps.getProperty("sql.password") });
 
                        String type = testProps.getProperty("type");
                        if (type.equals("local")) {
-                               url = testProps.getProperty("server");
+                               url = testProps.getProperty("name.www") + ":" + testProps.getProperty("serverPort");
                                String[] parts = testProps.getProperty("mail").split(":", 2);
-                               ter = new TestEmailReciever(new InetSocketAddress(parts[0],
-                                               Integer.parseInt(parts[1])));
+                               ter = new TestEmailReciever(new InetSocketAddress(parts[0], Integer.parseInt(parts[1])));
                                return;
                        }
-                       url = testProps.getProperty("name.www") + ":"
-                                       + testProps.getProperty("serverPort");
+                       url = testProps.getProperty("name.www") + ":" + testProps.getProperty("serverPort");
                        gigi = Runtime.getRuntime().exec(testProps.getProperty("java"));
-                       DataOutputStream toGigi = new DataOutputStream(
-                                       gigi.getOutputStream());
+                       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("name.secure", testProps.getProperty("name.secure"));
+                       mainProps.setProperty("name.www", testProps.getProperty("name.www"));
+                       mainProps.setProperty("name.static", testProps.getProperty("name.static"));
 
                        mainProps.setProperty("port", testProps.getProperty("serverPort"));
-                       mainProps.setProperty("emailProvider",
-                                       "org.cacert.gigi.email.TestEmailProvider");
+                       mainProps.setProperty("emailProvider", "org.cacert.gigi.email.TestEmailProvider");
                        mainProps.setProperty("emailProvider.port", "8473");
-                       mainProps.setProperty("sql.driver",
-                                       testProps.getProperty("sql.driver"));
+                       mainProps.setProperty("sql.driver", testProps.getProperty("sql.driver"));
                        mainProps.setProperty("sql.url", testProps.getProperty("sql.url"));
-                       mainProps
-                                       .setProperty("sql.user", testProps.getProperty("sql.user"));
-                       mainProps.setProperty("sql.password",
-                                       testProps.getProperty("sql.password"));
-
-                       byte[] cacerts = Files
-                                       .readAllBytes(Paths.get("config/cacerts.jks"));
-                       byte[] keystore = Files.readAllBytes(Paths
-                                       .get("config/keystore.pkcs12"));
-
-                       DevelLauncher.writeGigiConfig(toGigi, "changeit".getBytes(),
-                                       "changeit".getBytes(), mainProps, cacerts, keystore);
+                       mainProps.setProperty("sql.user", testProps.getProperty("sql.user"));
+                       mainProps.setProperty("sql.password", testProps.getProperty("sql.password"));
+
+                       byte[] cacerts = Files.readAllBytes(Paths.get("config/cacerts.jks"));
+                       byte[] keystore = Files.readAllBytes(Paths.get("config/keystore.pkcs12"));
+
+                       DevelLauncher.writeGigiConfig(toGigi, "changeit".getBytes(), "changeit".getBytes(), mainProps, cacerts,
+                               keystore);
                        toGigi.flush();
 
-                       final BufferedReader br = new BufferedReader(new InputStreamReader(
-                                       gigi.getErrorStream()));
+                       final BufferedReader br = new BufferedReader(new InputStreamReader(gigi.getErrorStream()));
                        String line;
-                       while ((line = br.readLine()) != null
-                                       && !line.contains("Server:main: Started")) {
-                               System.err.println(line);
+                       while ((line = br.readLine()) != null && !line.contains("Server:main: Started")) {
                        }
                        new Thread() {
                                @Override
@@ -121,28 +123,36 @@ public class ManagedTest {
                                        }
                                }
                        }.start();
-                       System.err.println(line);
                        if (line == null) {
                                throw new Error("Server startup failed");
                        }
-                       ter = new TestEmailReciever(
-                                       new InetSocketAddress("localhost", 8473));
+                       ter = new TestEmailReciever(new InetSocketAddress("localhost", 8473));
+                       SimpleSigner.runSigner();
                } catch (IOException e) {
                        throw new Error(e);
                } catch (ClassNotFoundException e1) {
                        e1.printStackTrace();
                } catch (SQLException e1) {
                        e1.printStackTrace();
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
                }
 
        }
+
        @AfterClass
        public static void tearDownServer() {
                String type = testProps.getProperty("type");
+               ter.destroy();
                if (type.equals("local")) {
                        return;
                }
                gigi.destroy();
+               try {
+                       SimpleSigner.stopSigner();
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
        }
 
        @After
@@ -157,35 +167,41 @@ public class ManagedTest {
                        throw new Error(e);
                }
        }
+
        public static TestEmailReciever getMailReciever() {
                return ter;
        }
+
        public String runRegister(String param) throws IOException {
-               HttpURLConnection uc = (HttpURLConnection) new URL("https://"
-                               + getServerName() + registerService).openConnection();
+               URL regist = new URL("https://" + getServerName() + registerService);
+               HttpURLConnection uc = (HttpURLConnection) regist.openConnection();
+               HttpURLConnection csrfConn = (HttpURLConnection) regist.openConnection();
+
+               String headerField = csrfConn.getHeaderField("Set-Cookie");
+               headerField = stripCookie(headerField);
+
+               String csrf = getCSRF(csrfConn);
+               uc.addRequestProperty("Cookie", headerField);
                uc.setDoOutput(true);
-               uc.getOutputStream().write(param.getBytes());
+               uc.getOutputStream().write((param + "&csrf=" + csrf).getBytes());
                String d = IOUtils.readURL(uc);
                return d;
        }
+
        public String fetchStartErrorMessage(String d) throws IOException {
                String formFail = "<div class='formError'>";
                int idx = d.indexOf(formFail);
                assertNotEquals(-1, idx);
-               String startError = d.substring(idx + formFail.length(), idx + 100)
-                               .trim();
+               String startError = d.substring(idx + formFail.length(), idx + 100).trim();
                return startError;
        }
 
-       public void registerUser(String firstName, String lastName, String email,
-                       String password) {
+       public void registerUser(String firstName, String lastName, String email, String password) {
                try {
-                       String query = "fname=" + URLEncoder.encode(firstName, "UTF-8")
-                                       + "&lname=" + URLEncoder.encode(lastName, "UTF-8")
-                                       + "&email=" + URLEncoder.encode(email, "UTF-8")
-                                       + "&pword1=" + URLEncoder.encode(password, "UTF-8")
-                                       + "&pword2=" + URLEncoder.encode(password, "UTF-8")
-                                       + "&day=1&month=1&year=1910&cca_agree=1";
+                       String query = "fname=" + URLEncoder.encode(firstName, "UTF-8") + "&lname="
+                               + URLEncoder.encode(lastName, "UTF-8") + "&email=" + URLEncoder.encode(email, "UTF-8") + "&pword1="
+                               + URLEncoder.encode(password, "UTF-8") + "&pword2=" + URLEncoder.encode(password, "UTF-8")
+                               + "&day=1&month=1&year=1910&cca_agree=1";
                        String data = fetchStartErrorMessage(runRegister(query));
                        assertTrue(data, data.startsWith("</div>"));
                } catch (UnsupportedEncodingException e) {
@@ -194,18 +210,17 @@ public class ManagedTest {
                        throw new Error(e);
                }
        }
-       public int createVerifiedUser(String firstName, String lastName,
-                       String email, String password) {
+
+       public int createVerifiedUser(String firstName, String lastName, String email, String password) {
                registerUser(firstName, lastName, email, password);
                try {
                        TestMail tm = ter.recieve();
                        String verifyLink = tm.extractLink();
                        String[] parts = verifyLink.split("\\?");
-                       URL u = new URL("https://" + getServerName() + "/verify?"
-                                       + parts[1]);
-                       u.openStream().close();;
-                       PreparedStatement ps = DatabaseConnection.getInstance().prepare(
-                                       "SELECT id FROM users where email=?");
+                       URL u = new URL("https://" + getServerName() + "/verify?" + parts[1]);
+                       u.openStream().close();
+                       ;
+                       PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id FROM users where email=?");
                        ps.setString(1, email);
                        ResultSet rs = ps.executeQuery();
                        if (rs.next()) {
@@ -220,6 +235,7 @@ public class ManagedTest {
                        throw new Error(e);
                }
        }
+
        /**
         * Creates a new user with 100 Assurance points given by an (invalid)
         * assurance.
@@ -234,19 +250,15 @@ public class ManagedTest {
         *            the password
         * @return a new userid.
         */
-       public int createAssuranceUser(String firstName, String lastName,
-                       String email, String password) {
+       public int createAssuranceUser(String firstName, String lastName, String email, String password) {
                int uid = createVerifiedUser(firstName, lastName, email, password);
                try {
-                       PreparedStatement ps = DatabaseConnection
-                                       .getInstance()
-                                       .prepare(
-                                                       "INSERT INTO `cats_passed` SET `user_id`=?, `variant_id`=?");
+                       PreparedStatement ps = DatabaseConnection.getInstance().prepare(
+                               "INSERT INTO `cats_passed` SET `user_id`=?, `variant_id`=?");
                        ps.setInt(1, uid);
                        ps.setInt(2, 0);
                        ps.execute();
-                       ps = DatabaseConnection.getInstance().prepare(
-                                       "INSERT INTO `notary` SET `from`=?, `to`=?, points='100'");
+                       ps = DatabaseConnection.getInstance().prepare("INSERT INTO `notary` SET `from`=?, `to`=?, points='100'");
                        ps.setInt(1, uid);
                        ps.setInt(2, uid);
                        ps.execute();
@@ -256,21 +268,119 @@ public class ManagedTest {
                }
                return uid;
        }
+
        static int count = 0;
+
        public String createUniqueName() {
                return "test" + System.currentTimeMillis() + "a" + (count++);
        }
+
+       private String stripCookie(String headerField) {
+               return headerField.substring(0, headerField.indexOf(';'));
+       }
+
+       public static final String SECURE_REFERENCE = "/account/certs/email";
+
+       public boolean isLoggedin(String cookie) throws IOException {
+               URL u = new URL("https://" + getServerName() + SECURE_REFERENCE);
+               HttpURLConnection huc = (HttpURLConnection) u.openConnection();
+               huc.addRequestProperty("Cookie", cookie);
+               return huc.getResponseCode() == 200;
+       }
+
        public String login(String email, String pw) throws IOException {
                URL u = new URL("https://" + getServerName() + "/login");
                HttpURLConnection huc = (HttpURLConnection) u.openConnection();
                huc.setDoOutput(true);
                OutputStream os = huc.getOutputStream();
-               String data = "username=" + URLEncoder.encode(email, "UTF-8")
-                               + "&password=" + URLEncoder.encode(pw, "UTF-8");
+               String data = "username=" + URLEncoder.encode(email, "UTF-8") + "&password=" + URLEncoder.encode(pw, "UTF-8");
                os.write(data.getBytes());
                os.flush();
                String headerField = huc.getHeaderField("Set-Cookie");
-               headerField = headerField.substring(0, headerField.indexOf(';'));
-               return headerField;
+               return stripCookie(headerField);
+       }
+
+       public String login(final PrivateKey pk, final X509Certificate ce) throws NoSuchAlgorithmException,
+               KeyManagementException, IOException, MalformedURLException {
+
+               HttpURLConnection connection = (HttpURLConnection) new URL("https://"
+                       + getServerName().replaceFirst("^www.", "secure.") + "/login").openConnection();
+               authenticateClientCert(pk, ce, connection);
+               if (connection.getResponseCode() == 302) {
+                       assertEquals("https://" + getServerName().replaceFirst("^www.", "secure.").replaceFirst(":443$", "") + "/",
+                               connection.getHeaderField("Location").replaceFirst(":443$", ""));
+                       return stripCookie(connection.getHeaderField("Set-Cookie"));
+               } else {
+                       return null;
+               }
+       }
+
+       public void authenticateClientCert(final PrivateKey pk, final X509Certificate ce, HttpURLConnection connection)
+               throws NoSuchAlgorithmException, KeyManagementException {
+               KeyManager km = new X509KeyManager() {
+
+                       @Override
+                       public String chooseClientAlias(String[] arg0, Principal[] arg1, Socket arg2) {
+                               return "client";
+                       }
+
+                       @Override
+                       public String chooseServerAlias(String arg0, Principal[] arg1, Socket arg2) {
+                               return null;
+                       }
+
+                       @Override
+                       public X509Certificate[] getCertificateChain(String arg0) {
+                               return new X509Certificate[] { ce };
+                       }
+
+                       @Override
+                       public String[] getClientAliases(String arg0, Principal[] arg1) {
+                               return new String[] { "client" };
+                       }
+
+                       @Override
+                       public PrivateKey getPrivateKey(String arg0) {
+                               if (arg0.equals("client")) {
+                                       return pk;
+                               }
+                               return null;
+                       }
+
+                       @Override
+                       public String[] getServerAliases(String arg0, Principal[] arg1) {
+                               return new String[] { "client" };
+                       }
+               };
+               SSLContext sc = SSLContext.getInstance("TLS");
+               sc.init(new KeyManager[] { km }, null, null);
+               if (connection instanceof HttpsURLConnection) {
+                       ((HttpsURLConnection) connection).setSSLSocketFactory(sc.getSocketFactory());
+               }
+       }
+
+       public String getCSRF(URLConnection u) throws IOException {
+               String content = IOUtils.readURL(u);
+               Pattern p = Pattern.compile("<input type='hidden' name='csrf' value='([^']+)'>");
+               Matcher m = p.matcher(content);
+               if (!m.find()) {
+                       throw new Error("No CSRF Token");
+               }
+               return m.group(1);
        }
+
+       public static String[] generateCSR(String dn) throws IOException {
+               Process p = Runtime.getRuntime().exec(
+                       new String[] { "openssl", "req", "-newkey", "rsa:1024", "-nodes", "-subj", dn, "-config",
+                                       "keys/selfsign.config" });
+               String csr = IOUtils.readURL(new InputStreamReader(p.getInputStream()));
+
+               String[] parts = csr.split("(?<=-----)\n(?=-----)");
+               if (parts.length != 2) {
+                       System.err.println(IOUtils.readURL(new InputStreamReader(p.getErrorStream())));
+                       throw new Error();
+               }
+               return parts;
+       }
+
 }