package org.ibex.mail; // todo: periodically flush out old graylist entries import java.sql.*; import java.net.*; import java.io.*; import java.util.*; import java.sql.Timestamp; public class Graylist extends SqliteDB { public Graylist(String filename) throws SQLException { super(filename); SqliteTable whitelist = getTable("whitelist", "(ip unique)"); SqliteTable graylist = getTable("graylist", "(ip,fromaddr,toaddr,date,PRIMARY KEY(ip,fromaddr,toaddr))"); graylist.reap("date"); } public synchronized void addWhitelist(InetAddress ip) { try { PreparedStatement add = conn.prepareStatement("insert or replace into 'whitelist' values(?)"); add.setString(1, ip.getHostAddress()); add.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } } public synchronized boolean isWhitelisted(InetAddress ip) { try { PreparedStatement check = conn.prepareStatement("select * from 'whitelist' where ip=?"); check.setString(1, ip.getHostAddress()); ResultSet rs = null; boolean ret; try { rs = check.executeQuery(); ret = !rs.isAfterLast(); } finally { close(rs); } return ret; } catch (SQLException e) { throw new RuntimeException(e); } } public synchronized long getGrayListTimestamp(InetAddress ip, String from, String to) { try { PreparedStatement check = conn.prepareStatement("select date from graylist where ip=? and fromaddr=? and toaddr=?"); check.setString(1, graylistAddress(ip)); check.setString(2, from); check.setString(3, to); ResultSet rs = null; try { rs = check.executeQuery(); if (rs.isAfterLast()) return 0; return rs.getTimestamp(1).getTime(); } finally { close(rs); } } catch (SQLException e) { throw new RuntimeException(e); } } public synchronized void setGrayListTimestamp(InetAddress ip, String from, String to, long date) { try { PreparedStatement check = conn.prepareStatement("insert or replace into graylist (ip,fromaddr,toaddr,date) values(?,?,?,?)"); check.setString(1, graylistAddress(ip)); check.setString(2, from); check.setString(3, to); check.setTimestamp(4, new Timestamp(date)); check.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } } // // this is mostly to deal with comcast's pathetic retry policy and // rotating pool of outbound servers // see: http://lists.puremagic.com/pipermail/greylist-users/2006-November/001255.html // private static String graylistAddress(InetAddress ipa) { byte[] ip = ipa.getAddress(); return (ip[0] & 0xff)+"."+ (ip[1] & 0xff)+"."+ (ip[2] & 0xff)+"."+ ".0"; } }