Author: dbkr
Date: 2006-07-22 23:57:24 +0000 (Sat, 22 Jul 2006)
New Revision: 9729
Added:
trunk/apps/Freemail/src/freemail/AckProcrastinator.java
Modified:
trunk/apps/Freemail/src/freemail/AccountManager.java
trunk/apps/Freemail/src/freemail/BadFreemailAddressException.java
trunk/apps/Freemail/src/freemail/Freemail.java
trunk/apps/Freemail/src/freemail/InboundContact.java
trunk/apps/Freemail/src/freemail/MailSite.java
trunk/apps/Freemail/src/freemail/MessageSender.java
trunk/apps/Freemail/src/freemail/NIMFetcher.java
trunk/apps/Freemail/src/freemail/OutboundContact.java
trunk/apps/Freemail/src/freemail/OutboundContactFatalException.java
trunk/apps/Freemail/src/freemail/RTSFetcher.java
trunk/apps/Freemail/src/freemail/fcp/FCPBadFileException.java
trunk/apps/Freemail/src/freemail/fcp/NoNodeConnectionException.java
trunk/apps/Freemail/src/freemail/imap/IMAPBadMessageException.java
trunk/apps/Freemail/src/freemail/smtp/SMTPBadCommandException.java
trunk/apps/Freemail/src/freemail/utils/EmailAddress.java
trunk/apps/Freemail/src/freemail/utils/PropsFile.java
trunk/apps/Freemail/src/freenet/support/io/TooLongException.java
Log:
* Insert ACKs (CTS messages), delayed by a random amount of time
* Use bouncycastle's digest functions so it works with GCJ out of the box
* Tidy up unused imports that should have been committed separately for want of
Internet access at the time.
Modified: trunk/apps/Freemail/src/freemail/AccountManager.java
===================================================================
--- trunk/apps/Freemail/src/freemail/AccountManager.java 2006-07-22
23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/AccountManager.java 2006-07-22
23:57:24 UTC (rev 9729)
@@ -1,17 +1,14 @@
package freemail;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.math.BigInteger;
+import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
@@ -72,12 +69,7 @@
}
public static void ChangePassword(String username, String newpassword)
throws Exception {
- MessageDigest md = null;
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException alge) {
- throw new Exception("No MD5 implementation available -
sorry, Freemail cannot work!");
- }
+ MD5Digest md5 = new MD5Digest();
File accountdir = new File(DATADIR, username);
if (!accountdir.exists()) {
@@ -86,7 +78,9 @@
PropsFile accfile = getAccountFile(accountdir);
- byte[] md5passwd = md.digest(newpassword.getBytes());
+ md5.update(newpassword.getBytes(), 0,
newpassword.getBytes().length);
+ byte[] md5passwd = new byte[md5.getDigestSize()];
+ md5.doFinal(md5passwd, 0);
String strmd5 = new String(Hex.encode(md5passwd));
accfile.put("md5passwd", strmd5);
@@ -197,14 +191,10 @@
String realmd5str = accfile.get("md5passwd");
if (realmd5str == null) return false;
- MessageDigest md = null;
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException alge) {
- System.out.println("No MD5 implementation available -
logins will not work!");
- return false;
- }
- byte[] givenmd5 = md.digest(password.getBytes());
+ MD5Digest md5 = new MD5Digest();
+ md5.update(password.getBytes(), 0, password.getBytes().length);
+ byte[] givenmd5 = new byte[md5.getDigestSize()];
+ md5.doFinal(givenmd5, 0);
String givenmd5str = new String(Hex.encode(givenmd5));
Added: trunk/apps/Freemail/src/freemail/AckProcrastinator.java
===================================================================
--- trunk/apps/Freemail/src/freemail/AckProcrastinator.java 2006-07-22
23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/AckProcrastinator.java 2006-07-22
23:57:24 UTC (rev 9729)
@@ -0,0 +1,106 @@
+package freemail;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.lang.InterruptedException;
+import java.util.Random;
+
+import freemail.utils.PropsFile;
+import freemail.fcp.HighLevelFCPClient;
+import freemail.fcp.FCPBadFileException;
+
+/** Takes simple pieces of data to insert to keys and inserts them at some
point
+ * randomly within a given time frame in order to disguise the time at which
messages
+ * were received. This is by no means infalliable, and will only work
effectively if
+ * Freemail is run more or less permanantly.
+ */
+public class AckProcrastinator implements Runnable {
+ private static final long MAX_DELAY = 12 * 60 * 60 * 1000;
+
+ private static File ackdir;
+ private static Random rnd;
+
+ public AckProcrastinator() {
+ rnd = new Random();
+ File ackdir = getAckDir();
+ if (!ackdir.exists()) {
+ ackdir.mkdir();
+ }
+ }
+
+ private static File getAckDir() {
+ return AckProcrastinator.ackdir;
+ }
+
+ public static void setAckDir(File dir) {
+ AckProcrastinator.ackdir = dir;
+ if (!dir.exists()) {
+ dir.mkdir();
+ }
+ }
+
+ public void run() {
+ while (true) {
+ File[] acks = getAckDir().listFiles();
+
+ int i;
+ for (i = 0; i < acks.length; i++) {
+ PropsFile ack = new PropsFile(acks[i]);
+
+ String s_it = ack.get("nominalInsertTime");
+ String key = ack.get("key");
+ String data = ack.get("data");
+ if (s_it == null || key == null || data ==
null) {
+ acks[i].delete();
+ continue;
+ }
+ long instime = Long.parseLong(s_it);
+
+ if (instime < System.currentTimeMillis()) {
+ HighLevelFCPClient fcpcli = new
HighLevelFCPClient();
+
+ ByteArrayInputStream bis = new
ByteArrayInputStream(data.getBytes());
+
+ try {
+ if (fcpcli.put(bis, key) !=
null)
+ acks[i].delete();
+ } catch (FCPBadFileException bfe) {
+ // won't occur
+ }
+ }
+ }
+
+ try {
+ Thread.sleep(2 * 60 * 1000);
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+
+ /** Insert some data at some random point in the future, but ideally
before
+ * 'by' (in milliseconds).
+ */
+ public static synchronized void put(String key, String data) {
+ // this could be a parameter if desired in the future
+ long by = System.currentTimeMillis() + MAX_DELAY;
+
+ try {
+ PropsFile ackfile= new
PropsFile(File.createTempFile("delayed-ack", "", getAckDir()));
+
+ ackfile.put("key", key);
+ ackfile.put("data", data);
+ ackfile.put("by", Long.toString(by));
+
+ long insertTime = System.currentTimeMillis();
+
+ insertTime += rnd.nextFloat() * by;
+
+ ackfile.put("nominalInsertTime",
Long.toString(insertTime));
+ } catch (IOException ioe) {
+ System.out.println("IO Error whilst trying to schedule
ACK for insertion! ACK will not be inserted!");
+ ioe.printStackTrace();
+ }
+
+ }
+}
Modified: trunk/apps/Freemail/src/freemail/BadFreemailAddressException.java
===================================================================
--- trunk/apps/Freemail/src/freemail/BadFreemailAddressException.java
2006-07-22 23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/BadFreemailAddressException.java
2006-07-22 23:57:24 UTC (rev 9729)
@@ -1,5 +1,5 @@
package freemail;
public class BadFreemailAddressException extends Exception {
-
+ static final long serialVersionUID = -1;
}
Modified: trunk/apps/Freemail/src/freemail/Freemail.java
===================================================================
--- trunk/apps/Freemail/src/freemail/Freemail.java 2006-07-22 23:50:41 UTC
(rev 9728)
+++ trunk/apps/Freemail/src/freemail/Freemail.java 2006-07-22 23:57:24 UTC
(rev 9729)
@@ -10,6 +10,9 @@
public class Freemail {
private static final String TEMPDIRNAME = "temp";
+ private static final String DATADIR = "data";
+ private static final String GLOBALDATADIR = "globaldata";
+ private static final String ACKDIR = "delayedacks";
private static File datadir;
private static File tempdir;
private static FCPConnection fcpconn;
@@ -99,8 +102,13 @@
return;
}
+ File globaldatadir = new File(GLOBALDATADIR);
+ if (!globaldatadir.exists()) {
+ globaldatadir.mkdir();
+ }
+
// start a SingleAccountWatcher for each account
- Freemail.datadir = new File("data");
+ Freemail.datadir = new File(DATADIR);
if (!Freemail.datadir.exists()) {
System.out.println("Starting Freemail for the first
time.");
System.out.println("You will probably want to add an
account by running Freemail with arguments --newaccount <username>");
@@ -122,23 +130,32 @@
if (files[i].getName().equals(".") ||
files[i].getName().equals(".."))
continue;
- Thread t = new Thread(new
SingleAccountWatcher(files[i]));
+ Thread t = new Thread(new
SingleAccountWatcher(files[i]), "Account Watcher for "+files[i].getName());
t.setDaemon(true);
t.start();
}
// and a sender thread
MessageSender sender = new MessageSender(Freemail.datadir);
- Thread senderthread = new Thread(sender);
+ Thread senderthread = new Thread(sender, "Message sender");
senderthread.setDaemon(true);
senderthread.start();
// start the SMTP Listener
SMTPListener smtpl = new SMTPListener(sender);
- Thread smtpthread = new Thread(smtpl);
+ Thread smtpthread = new Thread(smtpl, "SMTP Listener");
smtpthread.setDaemon(true);
smtpthread.start();
+ // start the delayed ACK inserter
+ File ackdir = new File(globaldatadir, ACKDIR);
+ AckProcrastinator.setAckDir(ackdir);
+ AckProcrastinator ackinserter = new AckProcrastinator();
+ Thread ackinsthread = new Thread(ackinserter, "Delayed ACK
Inserter");
+ ackinsthread.setDaemon(true);
+ ackinsthread.start();
+
+
// start the IMAP listener
IMAPListener imapl = new IMAPListener();
imapl.run();
Modified: trunk/apps/Freemail/src/freemail/InboundContact.java
===================================================================
--- trunk/apps/Freemail/src/freemail/InboundContact.java 2006-07-22
23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/InboundContact.java 2006-07-22
23:57:24 UTC (rev 9729)
@@ -27,4 +27,8 @@
public void setProp(String key, String val) {
this.ibct_props.put(key, val);
}
+
+ public String getProp(String key) {
+ return this.ibct_props.get(key);
+ }
}
Modified: trunk/apps/Freemail/src/freemail/MailSite.java
===================================================================
--- trunk/apps/Freemail/src/freemail/MailSite.java 2006-07-22 23:50:41 UTC
(rev 9728)
+++ trunk/apps/Freemail/src/freemail/MailSite.java 2006-07-22 23:57:24 UTC
(rev 9729)
@@ -1,6 +1,5 @@
package freemail;
-import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import freemail.utils.PropsFile;
@@ -66,7 +65,7 @@
minslot = 1;
}
- int actualslot = cli.SlotInsert(mailpage, key, 1, "/"+MAILPAGE);
+ int actualslot = cli.SlotInsert(mailpage, key, minslot,
"/"+MAILPAGE);
this.accprops.put("mailsite.slot", new
Integer(actualslot).toString());
Modified: trunk/apps/Freemail/src/freemail/MessageSender.java
===================================================================
--- trunk/apps/Freemail/src/freemail/MessageSender.java 2006-07-22 23:50:41 UTC
(rev 9728)
+++ trunk/apps/Freemail/src/freemail/MessageSender.java 2006-07-22 23:57:24 UTC
(rev 9729)
@@ -3,14 +3,11 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Vector;
import java.util.Enumeration;
import freemail.fcp.HighLevelFCPClient;
-import freemail.fcp.FCPInsertErrorMessage;
-import freemail.fcp.FCPBadFileException;
import freemail.utils.EmailAddress;
import freemail.utils.DateStringFactory;
Modified: trunk/apps/Freemail/src/freemail/NIMFetcher.java
===================================================================
--- trunk/apps/Freemail/src/freemail/NIMFetcher.java 2006-07-22 23:50:41 UTC
(rev 9728)
+++ trunk/apps/Freemail/src/freemail/NIMFetcher.java 2006-07-22 23:57:24 UTC
(rev 9729)
@@ -1,6 +1,5 @@
package freemail;
-import freemail.fcp.FCPConnection;
import freemail.fcp.HighLevelFCPClient;
import freemail.utils.DateStringFactory;
@@ -13,11 +12,7 @@
import java.util.Date;
import java.util.Calendar;
import java.util.TimeZone;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import org.bouncycastle.util.encoders.Hex;
-
public class NIMFetcher {
private final MessageBank mb;
private File contact_dir;
@@ -78,8 +73,8 @@
if (result != null) {
System.out.println(keybase+i+": got message!");
try {
- String checksum =
this.storeMessage(result);
- log.addMessage(i, checksum);
+ this.storeMessage(result);
+ log.addMessage(i, "received");
} catch (IOException ioe) {
continue;
}
@@ -89,17 +84,9 @@
}
}
- private String storeMessage(File file) throws IOException {
+ private void storeMessage(File file) throws IOException {
MailMessage newmsg = this.mb.createMessage();
- MessageDigest md;
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException alge) {
- System.out.println("No MD5 implementation available -
can't checksum messages - not storing message.");
- return null;
- }
-
// add our own headers first
// recieved and date
newmsg.addHeader("Received", "(Freemail); "+this.sdf.format(new
Date()));
@@ -118,8 +105,5 @@
newmsg.commit();
rdr.close();
file.delete();
-
- byte[] checksum = md.digest();
- return new String(Hex.encode(checksum));
}
}
Modified: trunk/apps/Freemail/src/freemail/OutboundContact.java
===================================================================
--- trunk/apps/Freemail/src/freemail/OutboundContact.java 2006-07-22
23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/OutboundContact.java 2006-07-22
23:57:24 UTC (rev 9729)
@@ -2,11 +2,8 @@
import java.io.File;
import java.io.ByteArrayOutputStream;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.util.Random;
import freemail.utils.EmailAddress;
@@ -16,6 +13,7 @@
import freemail.fcp.HighLevelFCPClient;
import freemail.fcp.SSKKeyPair;
+import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.engines.RSAEngine;
@@ -181,16 +179,11 @@
// sign the message
- MessageDigest md = null;
- try {
- md = MessageDigest.getInstance("SHA-256");
- } catch (NoSuchAlgorithmException alge) {
- System.out.println("No SHA 256 implementation available
- no mail can be sent!");
- return false;
- }
+ SHA256Digest sha256 = new SHA256Digest();
+ sha256.update(rtsmessage.toString().getBytes(), 0,
rtsmessage.toString().getBytes().length);
+ byte[] hash = new byte[sha256.getDigestSize()];
+ sha256.doFinal(hash, 0);
- byte[] hash = md.digest(rtsmessage.toString().getBytes());
-
RSAKeyParameters our_priv_key =
AccountManager.getPrivateKey(this.accdir);
AsymmetricBlockCipher sigcipher = new RSAEngine();
Modified: trunk/apps/Freemail/src/freemail/OutboundContactFatalException.java
===================================================================
--- trunk/apps/Freemail/src/freemail/OutboundContactFatalException.java
2006-07-22 23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/OutboundContactFatalException.java
2006-07-22 23:57:24 UTC (rev 9729)
@@ -1,6 +1,7 @@
package freemail;
public class OutboundContactFatalException extends Exception {
+ static final long serialVersionUID = -1;
public OutboundContactFatalException(String msg) {
super(msg);
}
Modified: trunk/apps/Freemail/src/freemail/RTSFetcher.java
===================================================================
--- trunk/apps/Freemail/src/freemail/RTSFetcher.java 2006-07-22 23:50:41 UTC
(rev 9728)
+++ trunk/apps/Freemail/src/freemail/RTSFetcher.java 2006-07-22 23:57:24 UTC
(rev 9729)
@@ -1,6 +1,5 @@
package freemail;
-import freemail.fcp.FCPConnection;
import freemail.fcp.HighLevelFCPClient;
import freemail.utils.DateStringFactory;
import freemail.utils.PropsFile;
@@ -11,30 +10,25 @@
import java.io.FileOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.BufferedReader;
import java.io.PrintStream;
-import java.io.FileReader;
-import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;
import java.util.TimeZone;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.math.BigInteger;
import java.net.MalformedURLException;
-import org.bouncycastle.util.encoders.Hex;
+import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.engines.RSAEngine;
import org.bouncycastle.crypto.InvalidCipherTextException;
import freenet.support.io.LineReadingInputStream;
+import freenet.support.io.TooLongException;
public class RTSFetcher {
private String rtskey;
private File contact_dir;
- private final SimpleDateFormat sdf;
private static final int POLL_AHEAD = 3;
private static final int PASSES_PER_DAY = 3;
private static final int MAX_DAYS_BACK = 30;
@@ -47,7 +41,6 @@
RTSFetcher(String key, File ctdir, File ad) {
this.rtskey = key;
- this.sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z");
this.contact_dir = ctdir;
this.accdir = ad;
this.accprops = AccountManager.getAccountFile(this.accdir);
@@ -176,7 +169,13 @@
String line;
while (true) {
- line = lis.readLine(200, 200);
+ try {
+ line = lis.readLine(200, 200);
+ } catch (TooLongException tle) {
+ System.out.println("RTS message has
lines that are too long. Discarding.");
+ rtsfile.delete();
+ return true;
+ }
messagebytes += lis.getLastBytesRead();
if (line == null || line.equals("")) break;
@@ -229,15 +228,10 @@
// verify the signature
String their_mailsite_raw = rtsprops.get("mailsite");
- MessageDigest md = null;
- try {
- md = MessageDigest.getInstance("SHA-256");
- } catch (NoSuchAlgorithmException alge) {
- System.out.println("No SHA 256 implementation available
- Freemail cannot work!");
- return false;
- }
- md.update(plaintext, 0, messagebytes);
- byte[] our_hash = md.digest();
+ SHA256Digest sha256 = new SHA256Digest();
+ sha256.update(plaintext, 0, messagebytes);
+ byte[] our_hash = new byte[sha256.getDigestSize()];
+ sha256.doFinal(our_hash, 0);
HighLevelFCPClient fcpcli = new HighLevelFCPClient();
@@ -334,8 +328,11 @@
ibct.setProp("commssk", rtsprops.get("commssk"));
ibct.setProp("ackssk", rtsprops.get("ackssk"));
- ibct.setProp("ctsksk", rtsprops.get("ctsksk"));
+ //ibct.setProp("ctsksk", rtsprops.get("ctsksk"));
+ // insert the cts at some point
+ AckProcrastinator.put(rtsprops.get("ctsksk"),
"messagetype=cts");
+
msfile.delete();
rtsfile.delete();
Modified: trunk/apps/Freemail/src/freemail/fcp/FCPBadFileException.java
===================================================================
--- trunk/apps/Freemail/src/freemail/fcp/FCPBadFileException.java
2006-07-22 23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/fcp/FCPBadFileException.java
2006-07-22 23:57:24 UTC (rev 9729)
@@ -1,5 +1,5 @@
package freemail.fcp;
public class FCPBadFileException extends Exception {
-
+ static final long serialVersionUID = -1;
}
Modified: trunk/apps/Freemail/src/freemail/fcp/NoNodeConnectionException.java
===================================================================
--- trunk/apps/Freemail/src/freemail/fcp/NoNodeConnectionException.java
2006-07-22 23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/fcp/NoNodeConnectionException.java
2006-07-22 23:57:24 UTC (rev 9729)
@@ -1,6 +1,8 @@
package freemail.fcp;
public class NoNodeConnectionException extends Exception {
+ static final long serialVersionUID = -1;
+
NoNodeConnectionException() {
super();
}
Modified: trunk/apps/Freemail/src/freemail/imap/IMAPBadMessageException.java
===================================================================
--- trunk/apps/Freemail/src/freemail/imap/IMAPBadMessageException.java
2006-07-22 23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/imap/IMAPBadMessageException.java
2006-07-22 23:57:24 UTC (rev 9729)
@@ -1,5 +1,6 @@
package freemail.imap;;
public class IMAPBadMessageException extends Exception {
+ static final long serialVersionUID = -1;
// no, this isn't the most exciting class in the world.
}
Modified: trunk/apps/Freemail/src/freemail/smtp/SMTPBadCommandException.java
===================================================================
--- trunk/apps/Freemail/src/freemail/smtp/SMTPBadCommandException.java
2006-07-22 23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/smtp/SMTPBadCommandException.java
2006-07-22 23:57:24 UTC (rev 9729)
@@ -1,5 +1,5 @@
package freemail.smtp;
public class SMTPBadCommandException extends Exception {
-
+ static final long serialVersionUID = -1;
}
Modified: trunk/apps/Freemail/src/freemail/utils/EmailAddress.java
===================================================================
--- trunk/apps/Freemail/src/freemail/utils/EmailAddress.java 2006-07-22
23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/utils/EmailAddress.java 2006-07-22
23:57:24 UTC (rev 9729)
@@ -1,7 +1,5 @@
package freemail.utils;
-import org.bouncycastle.util.encoders.Hex;
-
import org.archive.util.Base32;
public class EmailAddress {
Modified: trunk/apps/Freemail/src/freemail/utils/PropsFile.java
===================================================================
--- trunk/apps/Freemail/src/freemail/utils/PropsFile.java 2006-07-22
23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freemail/utils/PropsFile.java 2006-07-22
23:57:24 UTC (rev 9729)
@@ -72,6 +72,7 @@
try {
this.write();
} catch (IOException ioe) {
+ ioe.printStackTrace();
return false;
}
return true;
Modified: trunk/apps/Freemail/src/freenet/support/io/TooLongException.java
===================================================================
--- trunk/apps/Freemail/src/freenet/support/io/TooLongException.java
2006-07-22 23:50:41 UTC (rev 9728)
+++ trunk/apps/Freemail/src/freenet/support/io/TooLongException.java
2006-07-22 23:57:24 UTC (rev 9729)
@@ -4,5 +4,5 @@
/** Exception thrown by a LineReadingInputStream when a line is too long. */
public class TooLongException extends IOException {
-
+ static final long serialVersionUID = -1;
}
\ No newline at end of file