import org.ibex.io.*;
import org.ibex.mail.protocol.*;
import org.ibex.util.*;
+import org.ibex.net.*;
import java.sql.*;
import java.net.*;
import java.io.*;
import java.sql.Timestamp;
import java.sql.Connection;
-// now all I need is the click-through page
+public class Whitelist extends SqliteTable {
-// FIXME: periodic cleanup
-public class Whitelist {
-
- private Connection conn;
-
- // FIXME very ugly
- static {
- new Thread() { public void run() { startWebServer(); } }.start();
+ public Whitelist(String filename) {
+ super(filename,
+ new String[] {
+ "create table if not exists 'whitelist' (email)",
+ "create table if not exists 'pending' (spamid,email,message,date)"
+ },
+ "pending",
+ "date");
}
- public static void startWebServer() {
+
+ public synchronized boolean handleRequest(org.ibex.io.Connection c) {
try {
- ServerSocket ss = new ServerSocket(8025);
- while(true) {
- final Socket sock = ss.accept();
- new Thread() {
- public void run() {
- try {
- BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
- String s = br.readLine();
- String url = s.substring(s.indexOf(' ')+1);
- url = url.substring(0, url.indexOf(' '));
- while(s!=null && !s.equals(""))
- s = br.readLine();
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
- if (!url.startsWith("/whitelist/")) {
- pw.print("HTTP/1.0 404 Not FoundK\r\n");
- pw.print("Content-Type: text/plain\r\n");
- pw.print("\r\n");
- pw.println("you are lost.");
- } else {
- url = url.substring("/whitelist/".length());
- url = URLDecoder.decode(url);
- pw.print("HTTP/1.0 200 OK\r\n");
- pw.print("Content-Type: text/plain\r\n");
- pw.print("\r\n");
- try {
- SMTP.whitelist.response(url);
- pw.println("Thanks! You've been added to my list of non-spammers and your message");
- pw.println("has been moved to my inbox.");
- pw.println("email id " + url);
- pw.println("");
- } catch (Exception e) {
- e.printStackTrace(pw);
- }
- }
- pw.flush();
- sock.close();
- } catch (Exception e) { throw new RuntimeException(e); }
- }
- }.start();
+ Socket sock = c.getSocket();
+ BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+ String s = br.readLine();
+ String url = s.substring(s.indexOf(' ')+1);
+ url = url.substring(0, url.indexOf(' '));
+ while(s!=null && !s.equals(""))
+ s = br.readLine();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
+ if (!url.startsWith("/whitelist/")) {
+ pw.print("HTTP/1.0 404 Not FoundK\r\n");
+ pw.print("Content-Type: text/plain\r\n");
+ pw.print("\r\n");
+ pw.println("you are lost.");
+ } else {
+ url = url.substring("/whitelist/".length());
+ url = URLDecoder.decode(url);
+ pw.print("HTTP/1.0 200 OK\r\n");
+ pw.print("Content-Type: text/plain\r\n");
+ pw.print("\r\n");
+ try {
+ SMTP.whitelist.response(url);
+ pw.println("Thanks! You've been added to my list of non-spammers and your message");
+ pw.println("has been moved to my inbox.");
+ pw.println("email id " + url);
+ pw.println("");
+ } catch (Exception e) {
+ e.printStackTrace(pw);
+ }
}
+ pw.flush();
+ sock.close();
} catch (Exception e) { throw new RuntimeException(e); }
- }
-
-
- public Whitelist(String filename) {
- try {
- Class.forName("org.sqlite.JDBC");
- conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
- conn.prepareStatement("create table if not exists "+
- "'whitelist' (email)").executeUpdate();
- conn.prepareStatement("create table if not exists "+
- "'pending' (spamid,email,message,date)").executeUpdate();
- }
- catch (SQLException e) { throw new RuntimeException(e); }
- catch (ClassNotFoundException e) { throw new RuntimeException(e); }
+ return true;
}
public synchronized boolean isWhitelisted(Address a) {
try {
+ if (a==null) return false;
PreparedStatement check = conn.prepareStatement("select * from 'whitelist' where email=?");
check.setString(1, a.toString(false).toLowerCase());
ResultSet rs = check.executeQuery();
public synchronized void challenge(Message m) {
try {
Log.warn(Whitelist.class, "challenging message: " + m.summary());
+
Address to = m.headers.get("reply-to")==null ? null : Address.parse(m.headers.get("reply-to"));
if (to==null) to = m.from;
if (to==null) to = m.envelopeFrom;
- // FIXME
- //if (to==null) return ibex.mail.drop("message is missing a to/replyto/envelopeto header; cannot accept");
+ if (m.envelopeTo==null || m.envelopeTo.equals("null") || m.envelopeTo.equals("")) {
+ Log.warn(this, "message is missing a to/replyto/envelopeto header; cannot accept");
+ return;
+ }
+ if (m.headers.get("Auto-Submitted") != null &&
+ m.headers.get("Auto-Submitted").toLowerCase().indexOf("auto-replied")!=-1) {
+ Log.warn(this, "refusing to send a challenge to a message "+
+ "with Auto-Submitted=\""+m.headers.get("Auto-Submitted")+"\"");
+ return;
+ }
Address from = Address.parse("adam@megacz.com");
" http://www.templetons.com/brad/spam/crgood.html\n";
Message challenge = Message.newMessage(new Fountain.StringFountain(message));
- if (!SMTP.Outgoing.attempt(challenge))
- throw new RuntimeException("attempted to send challenge but could not: " + m.summary());
+
+ PreparedStatement query = conn.prepareStatement("select email from pending where email=?");
+ query.setString(1, to.toString(false));
+ ResultSet rs = query.executeQuery();
+ if (rs.next()) {
+ Log.warn(this, "already challenged " + to.toString(false) + "; not challenging again.");
+ } else {
+ if (!SMTP.Outgoing.attempt(challenge))
+ throw new RuntimeException("attempted to send challenge but could not: " + m.summary());
+ }
PreparedStatement add = conn.prepareStatement("insert into pending values(?,?,?,?)");
add.setString(1, messageid);