]> WPIA git - gigi.git/commitdiff
Include smime signed messages from "sendmail" provider
authorFelix Dörre <felix@dogcraft.de>
Tue, 5 Aug 2014 17:16:56 +0000 (19:16 +0200)
committerFelix Dörre <felix@dogcraft.de>
Tue, 5 Aug 2014 21:30:50 +0000 (23:30 +0200)
(currently fully base64 encoded)

src/org/cacert/gigi/Gigi.java
src/org/cacert/gigi/Launcher.java
src/org/cacert/gigi/email/EmailProvider.java
src/org/cacert/gigi/email/Sendmail.java

index af0e222b031c42a6005abb99adc9b203f63a386c..8900cfc8df5328aef6154bc3dd6d43c4586899b7 100644 (file)
@@ -14,7 +14,6 @@ import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
 import org.cacert.gigi.database.DatabaseConnection;
-import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.localisation.Language;
 import org.cacert.gigi.output.Form.CSRFException;
 import org.cacert.gigi.output.Menu;
@@ -52,7 +51,6 @@ public class Gigi extends HttpServlet {
     Menu m;
 
     public Gigi(Properties conf) {
-        EmailProvider.init(conf);
         DatabaseConnection.init(conf);
     }
 
index c2e11286a07414d6894e0d91b505c1184a2d84af..f056be96f8a61ead04617cf8eee78afacd701e7b 100644 (file)
@@ -2,7 +2,12 @@ package org.cacert.gigi;
 
 import java.io.IOException;
 import java.security.GeneralSecurityException;
+import java.security.Key;
 import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
 import java.util.List;
 import java.util.Properties;
 
@@ -14,6 +19,7 @@ import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLSession;
 
 import org.cacert.gigi.api.GigiAPI;
+import org.cacert.gigi.email.EmailProvider;
 import org.cacert.gigi.natives.SetUID;
 import org.cacert.gigi.util.CipherInfo;
 import org.cacert.gigi.util.ServerConstants;
@@ -42,6 +48,7 @@ public class Launcher {
     public static void main(String[] args) throws Exception {
         GigiConfig conf = GigiConfig.parse(System.in);
         ServerConstants.init(conf.getMainProps());
+        initEmails(conf);
 
         Server s = new Server();
         // === SSL HTTP Configuration ===
@@ -73,6 +80,13 @@ public class Launcher {
         }
     }
 
+    private static void initEmails(GigiConfig conf) throws GeneralSecurityException, IOException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
+        KeyStore privateStore = conf.getPrivateStore();
+        Certificate mail = privateStore.getCertificate("mail");
+        Key k = privateStore.getKey("mail", conf.getPrivateStorePw().toCharArray());
+        EmailProvider.initSystem(conf.getMainProps(), mail, k);
+    }
+
     private static SslConnectionFactory createConnectionFactory(GigiConfig conf) throws GeneralSecurityException, IOException {
         final SslContextFactory sslContextFactory = generateSSLContextFactory(conf, "www");
         final SslContextFactory secureContextFactory = generateSSLContextFactory(conf, "secure");
index 3ccac586e24a47ce7794e3d87169a261d781a964..e82a44d72f0571f09ad3423864711a4120b1386e 100644 (file)
@@ -5,12 +5,18 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.net.Socket;
+import java.security.GeneralSecurityException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.util.LinkedList;
 import java.util.Properties;
 import java.util.regex.Pattern;
 
+import org.cacert.gigi.crypto.SMIME;
 import org.cacert.gigi.database.DatabaseConnection;
 
 public abstract class EmailProvider {
@@ -19,6 +25,19 @@ public abstract class EmailProvider {
 
     private static EmailProvider instance;
 
+    private X509Certificate c;
+
+    private PrivateKey k;
+
+    protected final void init(Certificate c, Key k) {
+        this.c = (X509Certificate) c;
+        this.k = (PrivateKey) k;
+    }
+
+    protected final void sendSigned(String contents, PrintWriter output) throws IOException, GeneralSecurityException {
+        SMIME.smime(contents, k, c, output);
+    }
+
     public static EmailProvider getInstance() {
         return instance;
     }
@@ -27,10 +46,12 @@ public abstract class EmailProvider {
         EmailProvider.instance = instance;
     }
 
-    public static void init(Properties conf) {
+    public static void initSystem(Properties conf, Certificate cert, Key pk) {
         try {
             Class<?> c = Class.forName(conf.getProperty("emailProvider"));
-            instance = (EmailProvider) c.getDeclaredConstructor(Properties.class).newInstance(conf);
+            EmailProvider ep = (EmailProvider) c.getDeclaredConstructor(Properties.class).newInstance(conf);
+            ep.init(cert, pk);
+            instance = ep;
         } catch (ReflectiveOperationException e) {
             e.printStackTrace();
         }
index 67c0fb5b2eb00a6d802afe25989b2044ee2f0db2..812de6bd5b4cecd92758f9f19356b31ac478e3cd 100644 (file)
@@ -5,6 +5,7 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.net.Socket;
+import java.security.GeneralSecurityException;
 import java.text.SimpleDateFormat;
 import java.util.Base64;
 import java.util.Date;
@@ -12,6 +13,8 @@ import java.util.Locale;
 import java.util.Properties;
 import java.util.regex.Pattern;
 
+import org.cacert.gigi.util.ServerConstants;
+
 public class Sendmail extends EmailProvider {
 
     protected Sendmail(Properties props) {}
@@ -23,7 +26,7 @@ public class Sendmail extends EmailProvider {
 
         String[] bits = from.split(",");
 
-        Socket smtp = new Socket("dogcraft.de", 25);
+        Socket smtp = new Socket("localhost", 25);
         PrintWriter out = new PrintWriter(smtp.getOutputStream());
         BufferedReader in = new BufferedReader(new InputStreamReader(smtp.getInputStream()));
         readResponse(in);
@@ -56,7 +59,7 @@ public class Sendmail extends EmailProvider {
         } else {
             out.print("Reply-To: " + from + "\r\n");
         }
-        out.print("From: " + from + "\r\n");
+        out.print("From: support@" + ServerConstants.getWwwHostName().replaceAll("^www.", "") + "\r\n");
         out.print("To: " + to + "\r\n");
         if (NON_ASCII.matcher(subject).matches()) {
 
@@ -64,24 +67,24 @@ public class Sendmail extends EmailProvider {
         } else {
             out.print("Subject: " + subject + "\r\n");
         }
-        out.print("Mime-Version: 1.0\r\n");
-        if ( !extra) {
-            out.print("Content-Type: text/plain; charset=\"utf-8\"\r\n");
-            out.print("Content-Transfer-Encoding: 8bit\r\n");
-        } else {
-            out.print("Content-Type: text/plain; charset=\"iso-8859-1\"\r\n");
-            out.print("Content-Transfer-Encoding: quoted-printable\r\n");
-            out.print("Content-Disposition: inline\r\n");
-        }
-        // out.print("Content-Transfer-Encoding: BASE64\r\n");
-        out.print("\r\n");
+        StringBuffer headers = new StringBuffer();
+        headers.append("Content-Type: text/plain; charset=\"utf-8\"\r\n");
+        headers.append("Content-Transfer-Encoding: base64\r\n");
         // out.print(chunk_split(base64_encode(recode("html..utf-8",
         // $message)))."\r\n.\r\n");
-        message = message + "\r\n";
+        headers.append("\r\n");
+        headers.append(Base64.getEncoder().encodeToString(message.getBytes("UTF-8")).replaceAll("(.{64})(?=.)", "$1\r\n"));
+        headers.append("\r\n");
 
-        String sendM = message.replace("\r", "").replace("\n.\n", "\n").replace("\n.\n", "\n").replace("\n", "\r\n") + ".\r\n";
-        out.print(sendM);
-        out.flush();
+        try {
+            sendSigned(headers.toString(), out);
+            out.print("\r\n.\r\n");
+            out.flush();
+        } catch (GeneralSecurityException e) {
+            e.printStackTrace();
+            smtp.close();
+            return;
+        }
         readResponse(in);
         out.print("QUIT\n");
         out.flush();