From: Felix Dörre Date: Mon, 23 Jun 2014 20:46:50 +0000 (+0200) Subject: Add the "fast email check" X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=4819c620856c8feff2dbda6fbe229b778c440a5e;ds=sidebyside Add the "fast email check" --- diff --git a/src/org/cacert/gigi/pages/main/Signup.java b/src/org/cacert/gigi/pages/main/Signup.java index b13b374f..4c44c37f 100644 --- a/src/org/cacert/gigi/pages/main/Signup.java +++ b/src/org/cacert/gigi/pages/main/Signup.java @@ -1,5 +1,6 @@ package org.cacert.gigi.pages.main; +import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; @@ -18,6 +19,7 @@ import org.cacert.gigi.database.DatabaseConnection; import org.cacert.gigi.output.DateSelector; import org.cacert.gigi.output.Template; import org.cacert.gigi.pages.Page; +import org.cacert.gigi.util.EmailChecker; import org.cacert.gigi.util.HTMLEncoder; public class Signup { @@ -158,7 +160,37 @@ public class Signup { e.printStackTrace(); failed = true; } - // TODO fast-check mail + String mailResult = EmailChecker.FAIL; + try { + mailResult = EmailChecker.checkEmailServer(0, buildup.getEmail()); + } catch (IOException e) { + } + if (!mailResult.equals(EmailChecker.OK)) { + if (mailResult.startsWith("4")) { + outputError( + out, + req, + "The mail server responsible for your domain indicated" + + " a temporary failure. This may be due to anti-SPAM measures, such" + + " as greylisting. Please try again in a few minutes."); + } else { + outputError( + out, + req, + "Email Address given was invalid, or a test connection" + + " couldn't be made to your server, or the server" + + " rejected the email address as invalid"); + } + if (mailResult.equals(EmailChecker.FAIL)) { + outputError(out, req, + "Failed to make a connection to the mail server"); + } else { + out.print("
"); + out.print(mailResult); + out.println("
"); + } + failed = true; + } out.println(""); if (failed) { diff --git a/src/org/cacert/gigi/util/EmailChecker.java b/src/org/cacert/gigi/util/EmailChecker.java new file mode 100644 index 00000000..00c6738c --- /dev/null +++ b/src/org/cacert/gigi/util/EmailChecker.java @@ -0,0 +1,123 @@ +package org.cacert.gigi.util; + +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()).startsWith("220-")) { + } + + if (!line.startsWith("220")) { + continue; + } + + pw.print("HELO www.cacert.org\r\n"); + pw.flush(); + + while ((line = br.readLine()).startsWith("220")) { + } + + if (!line.startsWith("250")) { + continue; + } + pw.print("MAIL FROM: \r\n"); + pw.flush(); + + line = br.readLine(); + + if (!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.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; + } + +}