From: Felix Dörre Date: Wed, 25 Jun 2014 12:16:19 +0000 (+0200) Subject: Refactor "Email checker" (for testing purposes) X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=093f4797bc1e84c4963a67093f2b21393656edab Refactor "Email checker" (for testing purposes) --- diff --git a/src/org/cacert/gigi/database/DatabaseConnection.java b/src/org/cacert/gigi/database/DatabaseConnection.java index 9f9193a7..9cbcaeb5 100644 --- a/src/org/cacert/gigi/database/DatabaseConnection.java +++ b/src/org/cacert/gigi/database/DatabaseConnection.java @@ -86,4 +86,21 @@ public class DatabaseConnection { } credentials = conf; } + public void beginTransaction() throws SQLException { + c.setAutoCommit(false); + } + public void commitTransaction() throws SQLException { + c.commit(); + c.setAutoCommit(true); + } + public void quitTransaction() { + try { + if (!c.getAutoCommit()) { + c.rollback(); + c.setAutoCommit(true); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } } diff --git a/src/org/cacert/gigi/email/EmailChecker.java b/src/org/cacert/gigi/email/EmailChecker.java deleted file mode 100644 index 7e18f68b..00000000 --- a/src/org/cacert/gigi/email/EmailChecker.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.cacert.gigi.email; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.Socket; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.LinkedList; -import java.util.regex.Pattern; - -import org.cacert.gigi.database.DatabaseConnection; - -public class EmailChecker { - public static final String OK = "OK"; - public static final String FAIL = "FAIL"; - private static final Pattern MAIL = Pattern - .compile("^([a-zA-Z0-9])+([a-zA-Z0-9\\+\\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\\._-]+)+$"); - private EmailChecker() { - } - public static String checkEmailServer(int forUid, String address) - throws IOException { - if (MAIL.matcher(address).matches()) { - String[] parts = address.split("@", 2); - String domain = parts[1]; - - LinkedList mxhosts = getMxHosts(domain); - - for (String host : mxhosts) { - try (Socket s = new Socket(host, 25); - BufferedReader br = new BufferedReader( - new InputStreamReader(s.getInputStream())); - PrintWriter pw = new PrintWriter(s.getOutputStream())) { - String line; - while ((line = br.readLine()) != null - && line.startsWith("220-")) { - } - if (line == null || !line.startsWith("220")) { - continue; - } - - pw.print("HELO www.cacert.org\r\n"); - pw.flush(); - - while ((line = br.readLine()) != null - && line.startsWith("220")) { - } - - if (line == null || !line.startsWith("250")) { - continue; - } - pw.print("MAIL FROM: \r\n"); - pw.flush(); - - line = br.readLine(); - - if (line == null || !line.startsWith("250")) { - continue; - } - pw.print("RCPT TO: <" + address + ">\r\n"); - pw.flush(); - - line = br.readLine(); - pw.print("QUIT\r\n"); - pw.flush(); - - try { - PreparedStatement statmt = DatabaseConnection - .getInstance() - .prepare( - "insert into `pinglog` set `when`=NOW(), `email`=?, `result`=?, `uid`=?"); - statmt.setString(1, address); - statmt.setString(2, line); - statmt.setInt(3, forUid); - statmt.execute(); - } catch (SQLException e) { - e.printStackTrace(); - } - - if (line == null || !line.startsWith("250")) { - return line; - } else { - return OK; - } - } - - } - } - try { - PreparedStatement statmt = DatabaseConnection - .getInstance() - .prepare( - "insert into `pinglog` set `when`=NOW(), `email`=?, `result`=?, `uid`=?"); - statmt.setString(1, address); - statmt.setString(2, - "Failed to make a connection to the mail server"); - statmt.setInt(3, forUid); - statmt.execute(); - } catch (SQLException e) { - e.printStackTrace(); - } - return FAIL; - } - private static LinkedList getMxHosts(String domain) - throws IOException { - LinkedList mxhosts = new LinkedList(); - Process dig = Runtime.getRuntime().exec( - new String[]{"dig", "+short", "MX", domain}); - try (BufferedReader br = new BufferedReader(new InputStreamReader( - dig.getInputStream()))) { - String line; - while ((line = br.readLine()) != null) { - String[] mxparts = line.split(" ", 2); - if (mxparts.length != 2) { - continue; - } - mxhosts.add(mxparts[1].substring(0, mxparts[1].length() - 1)); - } - } - return mxhosts; - } - -} diff --git a/src/org/cacert/gigi/email/EmailProvider.java b/src/org/cacert/gigi/email/EmailProvider.java index b5ac8d5c..644c4621 100644 --- a/src/org/cacert/gigi/email/EmailProvider.java +++ b/src/org/cacert/gigi/email/EmailProvider.java @@ -1,7 +1,17 @@ package org.cacert.gigi.email; +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; +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.database.DatabaseConnection; public abstract class EmailProvider { public abstract void sendmail(String to, String subject, String message, @@ -20,4 +30,111 @@ public abstract class EmailProvider { e.printStackTrace(); } } + + public static final String OK = "OK"; + public static final String FAIL = "FAIL"; + private static final Pattern MAIL = Pattern + .compile("^([a-zA-Z0-9])+([a-zA-Z0-9\\+\\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\\._-]+)+$"); + + public String checkEmailServer(int forUid, String address) + throws IOException { + if (MAIL.matcher(address).matches()) { + String[] parts = address.split("@", 2); + String domain = parts[1]; + + LinkedList mxhosts = getMxHosts(domain); + + for (String host : mxhosts) { + try (Socket s = new Socket(host, 25); + BufferedReader br = new BufferedReader( + new InputStreamReader(s.getInputStream())); + PrintWriter pw = new PrintWriter(s.getOutputStream())) { + String line; + while ((line = br.readLine()) != null + && line.startsWith("220-")) { + } + if (line == null || !line.startsWith("220")) { + continue; + } + + pw.print("HELO www.cacert.org\r\n"); + pw.flush(); + + while ((line = br.readLine()) != null + && line.startsWith("220")) { + } + + if (line == null || !line.startsWith("250")) { + continue; + } + pw.print("MAIL FROM: \r\n"); + pw.flush(); + + line = br.readLine(); + + if (line == null || !line.startsWith("250")) { + continue; + } + pw.print("RCPT TO: <" + address + ">\r\n"); + pw.flush(); + + line = br.readLine(); + pw.print("QUIT\r\n"); + pw.flush(); + + try { + PreparedStatement statmt = DatabaseConnection + .getInstance() + .prepare( + "insert into `pinglog` set `when`=NOW(), `email`=?, `result`=?, `uid`=?"); + statmt.setString(1, address); + statmt.setString(2, line); + statmt.setInt(3, forUid); + statmt.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + + if (line == null || !line.startsWith("250")) { + return line; + } else { + return OK; + } + } + + } + } + try { + PreparedStatement statmt = DatabaseConnection + .getInstance() + .prepare( + "insert into `pinglog` set `when`=NOW(), `email`=?, `result`=?, `uid`=?"); + statmt.setString(1, address); + statmt.setString(2, + "Failed to make a connection to the mail server"); + statmt.setInt(3, forUid); + statmt.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } + return FAIL; + } + private static LinkedList getMxHosts(String domain) + throws IOException { + LinkedList mxhosts = new LinkedList(); + Process dig = Runtime.getRuntime().exec( + new String[]{"dig", "+short", "MX", domain}); + try (BufferedReader br = new BufferedReader(new InputStreamReader( + dig.getInputStream()))) { + String line; + while ((line = br.readLine()) != null) { + String[] mxparts = line.split(" ", 2); + if (mxparts.length != 2) { + continue; + } + mxhosts.add(mxparts[1].substring(0, mxparts[1].length() - 1)); + } + } + return mxhosts; + } } diff --git a/src/org/cacert/gigi/email/TestEmailProvider.java b/src/org/cacert/gigi/email/TestEmailProvider.java index e37e802a..9f37be97 100644 --- a/src/org/cacert/gigi/email/TestEmailProvider.java +++ b/src/org/cacert/gigi/email/TestEmailProvider.java @@ -1,5 +1,6 @@ package org.cacert.gigi.email; +import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.InetAddress; @@ -11,6 +12,7 @@ class TestEmailProvider extends EmailProvider { ServerSocket servs; Socket client; DataOutputStream out; + DataInputStream in; protected TestEmailProvider(Properties props) { try { servs = new ServerSocket(Integer.parseInt(props @@ -29,8 +31,10 @@ class TestEmailProvider extends EmailProvider { if (client == null || client.isClosed()) { client = servs.accept(); out = new DataOutputStream(client.getOutputStream()); + in = new DataInputStream(client.getInputStream()); } try { + out.writeUTF("mail"); write(to); write(subject); write(message); @@ -43,6 +47,14 @@ class TestEmailProvider extends EmailProvider { } } } + @Override + public String checkEmailServer(int forUid, String address) + throws IOException { + out.writeUTF("challengeAddrBox"); + out.writeUTF(address); + return in.readUTF(); + } + private void write(String to) throws IOException { if (to == null) { out.writeUTF(""); diff --git a/src/org/cacert/gigi/pages/main/Signup.java b/src/org/cacert/gigi/pages/main/Signup.java index 58203edf..f2b24c80 100644 --- a/src/org/cacert/gigi/pages/main/Signup.java +++ b/src/org/cacert/gigi/pages/main/Signup.java @@ -16,7 +16,6 @@ import javax.servlet.http.HttpServletRequest; import org.cacert.gigi.Language; import org.cacert.gigi.User; import org.cacert.gigi.database.DatabaseConnection; -import org.cacert.gigi.email.EmailChecker; import org.cacert.gigi.email.EmailProvider; import org.cacert.gigi.output.DateSelector; import org.cacert.gigi.output.Template; @@ -172,12 +171,13 @@ public class Signup { e.printStackTrace(); failed = true; } - String mailResult = EmailChecker.FAIL; + String mailResult = EmailProvider.FAIL; try { - mailResult = EmailChecker.checkEmailServer(0, buildup.getEmail()); + mailResult = EmailProvider.getInstance().checkEmailServer(0, + buildup.getEmail()); } catch (IOException e) { } - if (!mailResult.equals(EmailChecker.OK)) { + if (!mailResult.equals(EmailProvider.OK)) { if (mailResult.startsWith("4")) { outputError( out, @@ -193,7 +193,7 @@ public class Signup { + " couldn't be made to your server, or the server" + " rejected the email address as invalid"); } - if (mailResult.equals(EmailChecker.FAIL)) { + if (mailResult.equals(EmailProvider.FAIL)) { outputError(out, req, "Failed to make a connection to the mail server"); } else { @@ -223,54 +223,61 @@ public class Signup { private void run(HttpServletRequest req, String password) throws SQLException { - String hash = RandomToken.generateToken(16); + try { + DatabaseConnection.getInstance().beginTransaction(); + String hash = RandomToken.generateToken(16); - buildup.insert(password); - int memid = buildup.getId(); - PreparedStatement ps = DatabaseConnection.getInstance().prepare( - "insert into `email` set `email`=?," - + " `hash`=?, `created`=NOW(),`memid`=?"); - ps.setString(1, buildup.getEmail()); - ps.setString(2, hash); - ps.setInt(3, memid); - ps.execute(); - int emailid = DatabaseConnection.lastInsertId(ps); - ps = DatabaseConnection - .getInstance() - .prepare( - "insert into `alerts` set `memid`=?," - + " `general`=?, `country`=?, `regional`=?, `radius`=?"); - ps.setInt(1, memid); - ps.setString(2, general ? "1" : "0"); - ps.setString(3, country ? "1" : "0"); - ps.setString(4, regional ? "1" : "0"); - ps.setString(5, radius ? "1" : "0"); - ps.execute(); - Notary.writeUserAgreement(memid, "CCA", "account creation", "", true, 0); + buildup.insert(password); + int memid = buildup.getId(); + PreparedStatement ps = DatabaseConnection.getInstance().prepare( + "insert into `email` set `email`=?," + + " `hash`=?, `created`=NOW(),`memid`=?"); + ps.setString(1, buildup.getEmail()); + ps.setString(2, hash); + ps.setInt(3, memid); + ps.execute(); + int emailid = DatabaseConnection.lastInsertId(ps); + ps = DatabaseConnection + .getInstance() + .prepare( + "insert into `alerts` set `memid`=?," + + " `general`=?, `country`=?, `regional`=?, `radius`=?"); + ps.setInt(1, memid); + ps.setString(2, general ? "1" : "0"); + ps.setString(3, country ? "1" : "0"); + ps.setString(4, regional ? "1" : "0"); + ps.setString(5, radius ? "1" : "0"); + ps.execute(); + Notary.writeUserAgreement(memid, "CCA", "account creation", "", + true, 0); - StringBuffer body = new StringBuffer(); - body.append(Page - .translate( - req, - "Thanks for signing up with CAcert.org, below is the link you need to open to verify your account. Once your account is verified you will be able to start issuing certificates till your hearts' content!")); - body.append("\n\n"); - body.append("http://"); - body.append(ServerConstants.NORMAL_HOST_NAME); - body.append("/verify.php?type=email&emailid="); - body.append(emailid); - body.append("&hash="); - body.append(hash); - body.append("\n\n"); - body.append(Page.translate(req, "Best regards")); - body.append("\n"); - body.append(Page.translate(req, "CAcert.org Support!")); - try { - EmailProvider.getInstance().sendmail(buildup.getEmail(), - "[CAcert.org] " + Page.translate(req, "Mail Probe"), - body.toString(), "support@cacert.org", null, null, null, - null, false); - } catch (IOException e) { - e.printStackTrace(); + StringBuffer body = new StringBuffer(); + body.append(Page + .translate( + req, + "Thanks for signing up with CAcert.org, below is the link you need to open to verify your account. Once your account is verified you will be able to start issuing certificates till your hearts' content!")); + body.append("\n\n"); + body.append("http://"); + body.append(ServerConstants.NORMAL_HOST_NAME); + body.append("/verify.php?type=email&emailid="); + body.append(emailid); + body.append("&hash="); + body.append(hash); + body.append("\n\n"); + body.append(Page.translate(req, "Best regards")); + body.append("\n"); + body.append(Page.translate(req, "CAcert.org Support!")); + try { + EmailProvider.getInstance().sendmail(buildup.getEmail(), + "[CAcert.org] " + Page.translate(req, "Mail Probe"), + body.toString(), "support@cacert.org", null, null, + null, null, false); + } catch (IOException e) { + e.printStackTrace(); + } + DatabaseConnection.getInstance().commitTransaction(); + } finally { + DatabaseConnection.getInstance().quitTransaction(); } } diff --git a/src/org/cacert/gigi/util/Notary.java b/src/org/cacert/gigi/util/Notary.java index 92609ff5..92b231da 100644 --- a/src/org/cacert/gigi/util/Notary.java +++ b/src/org/cacert/gigi/util/Notary.java @@ -7,22 +7,19 @@ import org.cacert.gigi.database.DatabaseConnection; public class Notary { public static void writeUserAgreement(int memid, String document, - String method, String comment, boolean active, int secmemid) { - try { - PreparedStatement q = DatabaseConnection - .getInstance() - .prepare( - "insert into `user_agreements` set `memid`=?, `secmemid`=?," - + " `document`=?,`date`=NOW(), `active`=?,`method`=?,`comment`=?"); - q.setInt(1, memid); - q.setInt(2, secmemid); - q.setString(3, document); - q.setInt(4, active ? 1 : 0); - q.setString(5, method); - q.setString(6, comment); - q.execute(); - } catch (SQLException e) { - e.printStackTrace(); - } + String method, String comment, boolean active, int secmemid) + throws SQLException { + PreparedStatement q = DatabaseConnection + .getInstance() + .prepare( + "insert into `user_agreements` set `memid`=?, `secmemid`=?," + + " `document`=?,`date`=NOW(), `active`=?,`method`=?,`comment`=?"); + q.setInt(1, memid); + q.setInt(2, secmemid); + q.setString(3, document); + q.setInt(4, active ? 1 : 0); + q.setString(5, method); + q.setString(6, comment); + q.execute(); } }