]> WPIA git - gigi.git/blobdiff - util/org/cacert/gigi/util/SimpleSigner.java
New Signer Job Table.
[gigi.git] / util / org / cacert / gigi / util / SimpleSigner.java
index eb7073325db3ea607045d88b53a4cd89be34e7a2..36e94bdccf7ab93e974a847dede588a11a6189e0 100644 (file)
@@ -1,11 +1,20 @@
 package org.cacert.gigi.util;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.Arrays;
 import java.util.Properties;
 
 import org.cacert.gigi.database.DatabaseConnection;
@@ -16,50 +25,91 @@ public class SimpleSigner {
        private static PreparedStatement readyMail;
        private static PreparedStatement revoke;
        private static PreparedStatement revokeCompleted;
+       private static PreparedStatement finishJob;
+       private static boolean running = true;
+       private static Thread runner;
 
-       public static void main(String[] args) throws IOException, SQLException,
-                       InterruptedException {
+       public static void main(String[] args) throws IOException, SQLException, InterruptedException {
                Properties p = new Properties();
                p.load(new FileReader("config/gigi.properties"));
                DatabaseConnection.init(p);
 
-               readyMail = DatabaseConnection.getInstance().prepare(
-                               "SELECT id, csr_name FROM emailcerts"
-                                               + " WHERE csr_name is not null"//
-                                               + " AND created=0"//
-                                               + " AND crt_name=''"//
-                                               + " AND warning<3");
+               runSigner();
+       }
+
+       public synchronized static void stopSigner() throws InterruptedException {
+               if (runner == null) {
+                       throw new IllegalStateException("already stopped");
+               }
+               running = false;
+               runner.interrupt();
+               runner.join();
+               runner = null;
+       }
+
+       public synchronized static void runSigner() throws SQLException, IOException, InterruptedException {
+               if (runner != null) {
+                       throw new IllegalStateException("already running");
+               }
+               running = true;
+               readyMail = DatabaseConnection
+                       .getInstance()
+                       .prepare(
+                               "SELECT emailcerts.id,emailcerts.csr_name,emailcerts.subject, jobs.id FROM jobs INNER JOIN emailcerts ON emailcerts.id=jobs.targetId"
+                                       + " WHERE jobs.state='open'"//
+                                       + " AND task='sign'");
 
                updateMail = DatabaseConnection.getInstance().prepare(
-                               "UPDATE emailcerts SET crt_name=?,"
-                                               + " created=NOW() WHERE id=?");
+                       "UPDATE emailcerts SET crt_name=?," + " created=NOW(), serial=? WHERE id=?");
                warnMail = DatabaseConnection.getInstance().prepare(
-                               "UPDATE emailcerts SET warning=warning+1 WHERE id=?");
+                       "UPDATE jobs SET warning=warning+1, state=IF(warning<3, 'open','error') WHERE id=?");
 
                revoke = DatabaseConnection.getInstance().prepare(
-                               "SELECT id, csr_name FROM emailcerts"
-                                               + " WHERE csr_name is not null"//
-                                               + " AND created != 0"//
-                                               + " AND revoked = '1970-01-01'");
-               revokeCompleted = DatabaseConnection.getInstance().prepare(
-                               "UPDATE emailcerts SET revoked=NOW() WHERE id=?");
-               gencrl();
-               while (true) {
-                       System.out.println("ping");
-                       executeOutstanders();
-                       revokeOutstanders();
-                       Thread.sleep(5000);
+                       "SELECT emailcerts.id, emailcerts.csr_name,jobs.id FROM jobs INNER JOIN emailcerts ON jobs.targetId=emailcerts.id"
+                               + " WHERE jobs.state='open' AND task='revoke'");
+               revokeCompleted = DatabaseConnection.getInstance().prepare("UPDATE emailcerts SET revoked=NOW() WHERE id=?");
+
+               finishJob = DatabaseConnection.getInstance().prepare("UPDATE jobs SET state='done' WHERE id=?");
+
+               runner = new Thread() {
+                       @Override
+                       public void run() {
+                               work();
+                       }
+
+               };
+               runner.start();
+       }
+
+       private static void work() {
+               try {
+                       gencrl();
+               } catch (IOException e2) {
+                       e2.printStackTrace();
+               } catch (InterruptedException e2) {
+                       e2.printStackTrace();
+               }
+               while (running) {
+                       try {
+                               signCertificates();
+                               revokeCertificates();
+                               Thread.sleep(5000);
+                       } catch (IOException e) {
+                               e.printStackTrace();
+                       } catch (SQLException e) {
+                               e.printStackTrace();
+                       } catch (InterruptedException e1) {
+                       }
                }
        }
 
-       private static void revokeOutstanders() throws SQLException, IOException,
-                       InterruptedException {
+       private static void revokeCertificates() throws SQLException, IOException, InterruptedException {
                ResultSet rs = revoke.executeQuery();
                boolean worked = false;
                while (rs.next()) {
                        int id = rs.getInt(1);
                        File crt = KeyStorage.locateCrt(id);
-                       String[] call = new String[]{"openssl", "ca",//
+                       String[] call = new String[] { "openssl", "ca",//
                                        "-cert", "testca.crt",//
                                        "-keyfile", "testca.key",//
                                        "-revoke", "../" + crt.getPath(),//
@@ -67,13 +117,14 @@ public class SimpleSigner {
                                        "-config", "selfsign.config"
 
                        };
-                       Process p1 = Runtime.getRuntime()
-                                       .exec(call, null, new File("keys"));
+                       Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
                        System.out.println("revoking: " + crt.getPath());
                        if (p1.waitFor() == 0) {
                                worked = true;
                                revokeCompleted.setInt(1, id);
                                revokeCompleted.execute();
+                               finishJob.setInt(1, rs.getInt(3));
+                               finishJob.execute();
                        } else {
                                System.out.println("Failed");
                        }
@@ -82,8 +133,9 @@ public class SimpleSigner {
                        gencrl();
                }
        }
+
        private static void gencrl() throws IOException, InterruptedException {
-               String[] call = new String[]{"openssl", "ca",//
+               String[] call = new String[] { "openssl", "ca",//
                                "-cert", "testca.crt",//
                                "-keyfile", "testca.key",//
                                "-gencrl",//
@@ -98,36 +150,57 @@ public class SimpleSigner {
                        System.out.println("Error while generating crl.");
                }
        }
-       private static void executeOutstanders() throws SQLException, IOException,
-                       InterruptedException {
+
+       private static void signCertificates() throws SQLException, IOException, InterruptedException {
                ResultSet rs = readyMail.executeQuery();
                while (rs.next()) {
                        String csrname = rs.getString(2);
                        System.out.println("sign: " + csrname);
                        int id = rs.getInt(1);
                        File crt = KeyStorage.locateCrt(id);
-                       String[] call = new String[]{"openssl", "ca",//
+                       String[] call = new String[] { "openssl", "ca",//
                                        "-cert", "testca.crt",//
                                        "-keyfile", "testca.key",//
                                        "-in", "../" + csrname,//
                                        "-out", "../" + crt.getPath(),//
                                        "-days", "356",//
                                        "-batch",//
+                                       "-subj", rs.getString(3),//
                                        "-config", "selfsign.config"
 
                        };
-                       Process p1 = Runtime.getRuntime()
-                                       .exec(call, null, new File("keys"));
+                       Process p1 = Runtime.getRuntime().exec(call, null, new File("keys"));
 
                        int waitFor = p1.waitFor();
                        if (waitFor == 0) {
-                               updateMail.setString(1, crt.getPath());
-                               updateMail.setInt(2, id);
-                               updateMail.execute();
-                               System.out.println("sign: " + id);
+                               try (InputStream is = new FileInputStream(crt)) {
+                                       CertificateFactory cf = CertificateFactory.getInstance("X.509");
+                                       X509Certificate crtp = (X509Certificate) cf.generateCertificate(is);
+                                       BigInteger serial = crtp.getSerialNumber();
+                                       updateMail.setString(1, crt.getPath());
+                                       updateMail.setString(2, serial.toString(16));
+                                       updateMail.setInt(3, id);
+                                       updateMail.execute();
+
+                                       finishJob.setInt(1, rs.getInt(4));
+                                       finishJob.execute();
+                                       System.out.println("signed: " + id);
+                                       continue;
+                               } catch (GeneralSecurityException e) {
+                                       e.printStackTrace();
+                               }
+                               System.out.println("ERROR Afterwards: " + id);
+                               warnMail.setInt(1, rs.getInt(4));
+                               warnMail.execute();
                        } else {
+                               BufferedReader br = new BufferedReader(new InputStreamReader(p1.getErrorStream()));
+                               String s;
+                               while ((s = br.readLine()) != null) {
+                                       System.out.println(s);
+                               }
+                               System.out.println(Arrays.toString(call));
                                System.out.println("ERROR: " + id);
-                               warnMail.setInt(1, id);
+                               warnMail.setInt(1, rs.getInt(4));
                                warnMail.execute();
                        }