package thaw.plugins.webOfTrust; import java.util.Hashtable; import java.util.Observable; import java.util.Observer; import java.util.Date; import java.io.File; import java.sql.*; import thaw.core.Config; import thaw.core.Logger; import thaw.fcp.FCPQueueManager; import thaw.fcp.FCPClientGet; import thaw.fcp.FCPMetaTransferQuery; import thaw.fcp.FreenetURIHelper; import thaw.plugins.Hsqldb; import thaw.plugins.signatures.Identity; import thaw.plugins.Signatures; /** * Will start ULPR on all the non-obsolete keys (I think I know what I'm doing) * and do also active polling * @author jflesch */ public class TrustListDownloader implements Observer, Signatures.SignaturesObserver { public final static long KEY_OBSOLETE_AFTER = 2 /* week */ *7 /* days */ * 24 /* hour */ * 60 /*min */ * 60 /* sec */ * 1000 /* ms */; public final static int CLIENTGET_PRIORITY = 3; public final static int MAX_SIZE = 102400; /* 100 KB */ public final static int MIN_TRUSTLEVEL = 0; private final Hsqldb db; private final FCPMetaTransferQuery metaQuery; private Hashtable ulprs; public TrustListDownloader(Hsqldb db, FCPQueueManager queueManager, Config config) { this.db = db; this.metaQuery = new FCPMetaTransferQuery(queueManager); ulprs = new Hashtable(); metaQuery.addObserver(this); Signatures.addObserver(this); } public boolean startULPR(String key, Identity identity) { WotIdentity id = new WotIdentity(identity); int tl = id.getTrustLevel(); if (tl <= MIN_TRUSTLEVEL || tl == Identity.trustLevelInt[0] /* dev */) return false; Logger.notice(this, "Starting ULPR for the identity : '"+identity.toString()+"'"); if (ulprs.get(FreenetURIHelper.getComparablePart(key)) != null) { Logger.notice(this, "An ulpr is already running for this key"); return false; } if (id.currentTrustListHasAlreadyBeenDownloaded()) { /* increment the revision of one */ key = FreenetURIHelper.changeUSKRevision(key, 0, 1); } FCPClientGet get = new FCPClientGet(key, CLIENTGET_PRIORITY, /* <= priority */ FCPClientGet.PERSISTENCE_UNTIL_DISCONNECT, false, /* <= globalQueue */ -1, /* maxRetries => -1 => ULPR */ System.getProperty("java.io.tmpdir"), /* destination directory */ MAX_SIZE, /* max size */ true /* <= noDDA */); ulprs.put(FreenetURIHelper.getComparablePart(key), get); metaQuery.start(get); return true; } public boolean stopULPR(String key) { FCPClientGet get = (FCPClientGet)ulprs.get(FreenetURIHelper.getComparablePart(key)); metaQuery.stop(get); ulprs.remove(FreenetURIHelper.getComparablePart(key)); return true; } public void init() { synchronized(db.dbLock) { try { PreparedStatement st; /* select all the non-obsolete keys */ st = db.getConnection().prepareStatement("SELECT publicKey, sigId FROM wotKeys WHERE keyDate IS NULL OR keyDate >= ?"); st.setTimestamp(1, new java.sql.Timestamp(new Date().getTime() - KEY_OBSOLETE_AFTER)); ResultSet set = st.executeQuery(); while(set.next()) { String key = set.getString("publicKey"); int sigId = set.getInt("sigId"); String filename = FreenetURIHelper.getFilenameFromKey(key); if (filename == null || "".equals(filename.trim())) { if (!key.endsWith("/")) key += "/"; key += "trustList.xml"; } Identity id = Identity.getIdentity(db, sigId); startULPR(key, id); } st.close(); } catch(SQLException e) { Logger.error(this, "Error while starting ULPRs : "+e.toString()); e.printStackTrace(); } } } public synchronized void process() { } public void stop() { metaQuery.stopAll(); ulprs = new Hashtable(); } public synchronized void update(Observable o, Object param) { if (o == metaQuery && param instanceof FCPClientGet) { FCPClientGet q = (FCPClientGet)param; if (q.isFinished() && q.isSuccessful()) { /* the meta query already forgot this query, so we don't have to care of this point */ File f = new File(q.getPath()); WotIdentity expectedIdentity = WotIdentity.getIdentity(db, q.getFileKey()); if (expectedIdentity == null) { Logger.notice(this, "can't find the identity corresponding to the wot key ... :'("); f.delete(); return; } stopULPR(q.getFileKey()); if (expectedIdentity.getTrustLevel() > 0 /* trust level may have changed during the download */ && expectedIdentity.doSecurityChecks(f)) { Logger.notice(this, "Parsing trust list of '"+expectedIdentity.toString()+"'"); if (expectedIdentity.loadTrustList(f)) { expectedIdentity.updateInfos(q.getFileKey(), new java.util.Date()); startULPR(q.getFileKey(), expectedIdentity); } } f.delete(); } } } public void identityUpdated(Identity i) { if (i.getTrustLevel() < 0) { /* someone has been marked as BAD */ WotIdentity id = new WotIdentity(i); String key; if ( (key = id.getWoTPublicKey()) != null) { id.purgeTrustList(); stopULPR(key); } } else if (i.getTrustLevel() > 0) { WotIdentity id = new WotIdentity(i); String key; if ( (key = id.getWoTPublicKey()) != null) { startULPR(key, id); } } } public void privateIdentityAdded(Identity i) { } public void publicIdentityAdded(Identity i) { } }