From: Felix Dörre Date: Tue, 5 Aug 2014 17:16:56 +0000 (+0200) Subject: Include smime signed messages from "sendmail" provider X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=fd17f68ac74d7b0f3e7a1ede403ec773fc452509 Include smime signed messages from "sendmail" provider (currently fully base64 encoded) --- diff --git a/src/org/cacert/gigi/Gigi.java b/src/org/cacert/gigi/Gigi.java index af0e222b..8900cfc8 100644 --- a/src/org/cacert/gigi/Gigi.java +++ b/src/org/cacert/gigi/Gigi.java @@ -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); } diff --git a/src/org/cacert/gigi/Launcher.java b/src/org/cacert/gigi/Launcher.java index c2e11286..f056be96 100644 --- a/src/org/cacert/gigi/Launcher.java +++ b/src/org/cacert/gigi/Launcher.java @@ -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"); diff --git a/src/org/cacert/gigi/email/EmailProvider.java b/src/org/cacert/gigi/email/EmailProvider.java index 3ccac586..e82a44d7 100644 --- a/src/org/cacert/gigi/email/EmailProvider.java +++ b/src/org/cacert/gigi/email/EmailProvider.java @@ -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(); } diff --git a/src/org/cacert/gigi/email/Sendmail.java b/src/org/cacert/gigi/email/Sendmail.java index 67c0fb5b..812de6bd 100644 --- a/src/org/cacert/gigi/email/Sendmail.java +++ b/src/org/cacert/gigi/email/Sendmail.java @@ -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();