]> WPIA git - gigi.git/blobdiff - util-testing/org/cacert/gigi/util/SimpleSigner.java
Fix: SimpleSigner Thread safety
[gigi.git] / util-testing / org / cacert / gigi / util / SimpleSigner.java
index 1c635c2e73a55082ea17124d3a8468293c3cb4ad..eba8f8529d887b81d82505fd51a3c80daaa86884 100644 (file)
@@ -3,9 +3,11 @@ package org.cacert.gigi.util;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.Reader;
 import java.math.BigInteger;
@@ -45,7 +47,7 @@ public class SimpleSigner {
 
     private static GigiPreparedStatement finishJob;
 
-    private static boolean running = true;
+    private static volatile boolean running = true;
 
     private static Thread runner;
 
@@ -66,14 +68,17 @@ public class SimpleSigner {
         runSigner();
     }
 
-    public synchronized static void stopSigner() throws InterruptedException {
-        if (runner == null) {
-            throw new IllegalStateException("already stopped");
+    public static void stopSigner() throws InterruptedException {
+        Thread capturedRunner;
+        synchronized (SimpleSigner.class) {
+            if (runner == null) {
+                throw new IllegalStateException("already stopped");
+            }
+            capturedRunner = runner;
+            running = false;
+            SimpleSigner.class.notifyAll();
         }
-        running = false;
-        runner.interrupt();
-        runner.join();
-        runner = null;
+        capturedRunner.join();
     }
 
     public synchronized static void runSigner() throws SQLException, IOException, InterruptedException {
@@ -109,7 +114,7 @@ public class SimpleSigner {
         runner.start();
     }
 
-    private static void work() {
+    private synchronized static void work() {
         try {
             gencrl();
         } catch (IOException e2) {
@@ -117,11 +122,13 @@ public class SimpleSigner {
         } catch (InterruptedException e2) {
             e2.printStackTrace();
         }
+
         while (running) {
             try {
                 signCertificates();
                 revokeCertificates();
-                Thread.sleep(5000);
+
+                SimpleSigner.class.wait(5000);
             } catch (IOException e) {
                 e.printStackTrace();
             } catch (SQLException e) {
@@ -129,6 +136,7 @@ public class SimpleSigner {
             } catch (InterruptedException e1) {
             }
         }
+        runner = null;
     }
 
     private static void revokeCertificates() throws SQLException, IOException, InterruptedException {
@@ -236,7 +244,7 @@ public class SimpleSigner {
                 GigiResultSet san = getSANSs.executeQuery();
 
                 File f = new File("keys", "SANFile" + System.currentTimeMillis() + (counter++) + ".cfg");
-                PrintWriter cfg = new PrintWriter(f);
+                PrintWriter cfg = new PrintWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
                 boolean first = true;
                 while (san.next()) {
                     if ( !first) {
@@ -272,40 +280,46 @@ public class SimpleSigner {
                     subj.put("CN", "<empty>");
                     System.out.println("WARNING: DN was empty");
                 }
-                String[] call = new String[] {
-                        "openssl", "ca",//
-                        "-in",
-                        "../../" + csrname,//
-                        "-cert",
-                        "../" + ca + ".crt",//
-                        "-keyfile",
-                        "../" + ca + ".key",//
-                        "-out",
-                        "../../" + crt.getPath(),//
-                        "-utf8",
-                        "-startdate",
-                        sdf.format(fromDate),//
-                        "-enddate",
-                        sdf.format(toDate),//
-                        "-batch",//
-                        "-md",
-                        rs.getString("md"),//
-                        "-extfile",
-                        "../" + f.getName(),//
-
-                        "-subj",
-                        Certificate.stringifyDN(subj),//
-                        "-config",
-                        "../selfsign.config"//
-
-                };
+                String[] call;
+                synchronized (sdf) {
+                    call = new String[] {
+                            "openssl", "ca",//
+                            "-in",
+                            "../../" + csrname,//
+                            "-cert",
+                            "../" + ca + ".crt",//
+                            "-keyfile",
+                            "../" + ca + ".key",//
+                            "-out",
+                            "../../" + crt.getPath(),//
+                            "-utf8",
+                            "-startdate",
+                            sdf.format(fromDate),//
+                            "-enddate",
+                            sdf.format(toDate),//
+                            "-batch",//
+                            "-md",
+                            rs.getString("md"),//
+                            "-extfile",
+                            "../" + f.getName(),//
+
+                            "-subj",
+                            Certificate.stringifyDN(subj),//
+                            "-config",
+                            "../selfsign.config"//
+                    };
+                }
+
                 if (ct == CSRType.SPKAC) {
                     call[2] = "-spkac";
                 }
+
                 Process p1 = Runtime.getRuntime().exec(call, null, new File("keys/unassured.ca"));
 
                 int waitFor = p1.waitFor();
-                f.delete();
+                if ( !f.delete()) {
+                    System.err.println("Could not delete SAN-File " + f.getAbsolutePath());
+                }
                 if (waitFor == 0) {
                     try (InputStream is = new FileInputStream(crt)) {
                         CertificateFactory cf = CertificateFactory.getInstance("X.509");