import java.util.*;
import java.sql.Timestamp;
-public class Graylist {
-
- private Connection conn;
+public class Graylist extends SqliteTable {
public Graylist(String filename) {
- try {
- Class.forName("org.sqlite.JDBC");
- conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
- conn.prepareStatement("create table if not exists "+
- "'whitelist' (ip unique)").executeUpdate();
- conn.prepareStatement("create table if not exists "+
- "'graylist' (ip,fromaddr,toaddr,date, primary key(ip,fromaddr,toaddr))").executeUpdate();
- }
- catch (SQLException e) { throw new RuntimeException(e); }
- catch (ClassNotFoundException e) { throw new RuntimeException(e); }
+ super(filename,
+ new String[] {
+ "create table if not exists 'whitelist' (ip unique)",
+ "create table if not exists 'graylist' (ip,fromaddr,toaddr,date, primary key(ip,fromaddr,toaddr))"
+ },
+ "graylist",
+ "date");
}
public synchronized void addWhitelist(InetAddress ip) {
--- /dev/null
+package org.ibex.mail;
+
+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.util.*;
+import java.sql.Timestamp;
+import java.sql.Connection;
+
+public class SqliteTable {
+
+ protected Connection conn;
+ private String filename;
+ private String reapTable;
+ private String reapColumn;
+
+ public SqliteTable(String filename, String[] tables, String reapTable, String reapColumn) {
+ this.filename = filename;
+ try {
+ Class.forName("org.sqlite.JDBC");
+ conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
+ for(String s : tables)
+ conn.prepareStatement(s).executeUpdate();
+ }
+ catch (SQLException e) { throw new RuntimeException(e); }
+ catch (ClassNotFoundException e) { throw new RuntimeException(e); }
+ this.reapTable = reapTable;
+ this.reapColumn = reapColumn;
+ if (reapTable != null && reapColumn != null)
+ new Reaper().start();
+ }
+
+ public static final int REAPER_INTERVAL_SECONDS = 60 * 60;
+
+ private class Reaper extends Thread {
+
+ public void run() {
+ while(true) {
+ try {
+ try { Thread.sleep(1000 * REAPER_INTERVAL_SECONDS); } catch (Exception e) { };
+ Log.warn(Reaper.class, filename + " reaping...");
+ long when = System.currentTimeMillis();
+ when -= 5 * 24 * 60 * 60 * 1000;
+ synchronized(SqliteTable.this) {
+ PreparedStatement ps = conn.prepareStatement("select count(*) from "+reapTable+" where "+reapColumn+"<?");
+ ps.setTimestamp(1, new Timestamp(when));
+ ResultSet rs = ps.executeQuery();
+ if (rs.next())
+ Log.warn(Reaper.class, filename + " reaping " + rs.getInt(1) + " entries");
+ Log.warn(Reaper.class, filename + ": " + "delete from "+reapTable+" where "+reapColumn+"<"+when);
+ ps = conn.prepareStatement("delete from "+reapTable+" where "+reapColumn+"<?");
+ ps.setTimestamp(1, new Timestamp(when));
+ int rows = ps.executeUpdate();
+ Log.warn(Reaper.class, filename + " done reaping; removed " + rows + " rows");
+ }
+ } catch (Exception e) { Log.error(Reaper.class, e); }
+ }
+ }
+ }
+
+}
\ No newline at end of file
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();