]> WPIA git - gigi.git/blob - src/org/cacert/gigi/email/EmailProvider.java
Merge branch 'libs/jetty/upstream' into libs/jetty/local
[gigi.git] / src / org / cacert / gigi / email / EmailProvider.java
1 package org.cacert.gigi.email;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.io.PrintWriter;
7 import java.net.Socket;
8 import java.sql.PreparedStatement;
9 import java.sql.SQLException;
10 import java.util.LinkedList;
11 import java.util.Properties;
12 import java.util.regex.Pattern;
13
14 import org.cacert.gigi.database.DatabaseConnection;
15
16 public abstract class EmailProvider {
17         public abstract void sendmail(String to, String subject, String message,
18                         String from, String replyto, String toname, String fromname,
19                         String errorsto, boolean extra) throws IOException;
20         private static EmailProvider instance;
21         public static EmailProvider getInstance() {
22                 return instance;
23         }
24         public static void init(Properties conf) {
25                 try {
26                         Class<?> c = Class.forName(conf.getProperty("emailProvider"));
27                         instance = (EmailProvider) c.getDeclaredConstructor(
28                                         Properties.class).newInstance(conf);
29                 } catch (ReflectiveOperationException e) {
30                         e.printStackTrace();
31                 }
32         }
33
34         public static final String OK = "OK";
35         public static final String FAIL = "FAIL";
36         private static final Pattern MAIL = Pattern
37                         .compile("^([a-zA-Z0-9])+([a-zA-Z0-9\\+\\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\\._-]+)+$");
38
39         public String checkEmailServer(int forUid, String address)
40                         throws IOException {
41                 if (MAIL.matcher(address).matches()) {
42                         String[] parts = address.split("@", 2);
43                         String domain = parts[1];
44
45                         LinkedList<String> mxhosts = getMxHosts(domain);
46
47                         for (String host : mxhosts) {
48                                 try (Socket s = new Socket(host, 25);
49                                                 BufferedReader br = new BufferedReader(
50                                                                 new InputStreamReader(s.getInputStream()));
51                                                 PrintWriter pw = new PrintWriter(s.getOutputStream())) {
52                                         String line;
53                                         while ((line = br.readLine()) != null
54                                                         && line.startsWith("220-")) {
55                                         }
56                                         if (line == null || !line.startsWith("220")) {
57                                                 continue;
58                                         }
59
60                                         pw.print("HELO www.cacert.org\r\n");
61                                         pw.flush();
62
63                                         while ((line = br.readLine()) != null
64                                                         && line.startsWith("220")) {
65                                         }
66
67                                         if (line == null || !line.startsWith("250")) {
68                                                 continue;
69                                         }
70                                         pw.print("MAIL FROM: <returns@cacert.org>\r\n");
71                                         pw.flush();
72
73                                         line = br.readLine();
74
75                                         if (line == null || !line.startsWith("250")) {
76                                                 continue;
77                                         }
78                                         pw.print("RCPT TO: <" + address + ">\r\n");
79                                         pw.flush();
80
81                                         line = br.readLine();
82                                         pw.print("QUIT\r\n");
83                                         pw.flush();
84
85                                         try {
86                                                 PreparedStatement statmt = DatabaseConnection
87                                                                 .getInstance()
88                                                                 .prepare(
89                                                                                 "insert into `pinglog` set `when`=NOW(), `email`=?, `result`=?, `uid`=?");
90                                                 statmt.setString(1, address);
91                                                 statmt.setString(2, line);
92                                                 statmt.setInt(3, forUid);
93                                                 statmt.execute();
94                                         } catch (SQLException e) {
95                                                 e.printStackTrace();
96                                         }
97
98                                         if (line == null || !line.startsWith("250")) {
99                                                 return line;
100                                         } else {
101                                                 return OK;
102                                         }
103                                 }
104
105                         }
106                 }
107                 try {
108                         PreparedStatement statmt = DatabaseConnection
109                                         .getInstance()
110                                         .prepare(
111                                                         "insert into `pinglog` set `when`=NOW(), `email`=?, `result`=?, `uid`=?");
112                         statmt.setString(1, address);
113                         statmt.setString(2,
114                                         "Failed to make a connection to the mail server");
115                         statmt.setInt(3, forUid);
116                         statmt.execute();
117                 } catch (SQLException e) {
118                         e.printStackTrace();
119                 }
120                 return FAIL;
121         }
122         private static LinkedList<String> getMxHosts(String domain)
123                         throws IOException {
124                 LinkedList<String> mxhosts = new LinkedList<String>();
125                 Process dig = Runtime.getRuntime().exec(
126                                 new String[]{"dig", "+short", "MX", domain});
127                 try (BufferedReader br = new BufferedReader(new InputStreamReader(
128                                 dig.getInputStream()))) {
129                         String line;
130                         while ((line = br.readLine()) != null) {
131                                 String[] mxparts = line.split(" ", 2);
132                                 if (mxparts.length != 2) {
133                                         continue;
134                                 }
135                                 mxhosts.add(mxparts[1].substring(0, mxparts[1].length() - 1));
136                         }
137                 }
138                 return mxhosts;
139         }
140 }