Author: dbkr
Date: 2006-06-23 12:50:43 +0000 (Fri, 23 Jun 2006)
New Revision: 9364
Modified:
trunk/apps/Freemail/src/freemail/MailSite.java
trunk/apps/Freemail/src/freemail/MessageSender.java
trunk/apps/Freemail/src/freemail/OutboundContact.java
trunk/apps/Freemail/src/freemail/fcp/HighLevelFCPClient.java
Log:
Fix issue with slot inserting. Improve outbound contact initialisation.
Modified: trunk/apps/Freemail/src/freemail/MailSite.java
===================================================================
--- trunk/apps/Freemail/src/freemail/MailSite.java 2006-06-23 12:48:04 UTC
(rev 9363)
+++ trunk/apps/Freemail/src/freemail/MailSite.java 2006-06-23 12:50:43 UTC
(rev 9364)
@@ -53,8 +53,6 @@
mailpage = mailsite_s.getBytes();
}
- ByteArrayInputStream bis = new ByteArrayInputStream(mailpage);
-
String key = this.accprops.get("mailsite.privkey");
if (key == null) return -1;
@@ -68,7 +66,7 @@
minslot = 1;
}
- int actualslot = cli.SlotInsert(bis, key, 1, "/"+MAILPAGE);
+ int actualslot = cli.SlotInsert(mailpage, key, 1, "/"+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-06-23 12:48:04 UTC
(rev 9363)
+++ trunk/apps/Freemail/src/freemail/MessageSender.java 2006-06-23 12:50:43 UTC
(rev 9364)
@@ -119,14 +119,7 @@
if (addr.domain.equalsIgnoreCase("nim.freemail")) {
HighLevelFCPClient cli = new HighLevelFCPClient();
- FileInputStream fis;
- try {
- fis = new FileInputStream(msg);
- } catch (FileNotFoundException fnfe) {
- return;
- }
-
- if (cli.SlotInsert(fis,
NIM_KEY_PREFIX+addr.user+"-"+DateStringFactory.getKeyString(), 1, "") > -1) {
+ if (cli.SlotInsert(msg,
NIM_KEY_PREFIX+addr.user+"-"+DateStringFactory.getKeyString(), 1, "") > -1) {
msg.delete();
}
} else {
@@ -146,7 +139,7 @@
return true;
}
boolean ready;
- if (!ct.exists()) {
+ if (!ct.ready()) {
try {
System.out.println("initing outbound contact");
ready = ct.init();
Modified: trunk/apps/Freemail/src/freemail/OutboundContact.java
===================================================================
--- trunk/apps/Freemail/src/freemail/OutboundContact.java 2006-06-23
12:48:04 UTC (rev 9363)
+++ trunk/apps/Freemail/src/freemail/OutboundContact.java 2006-06-23
12:50:43 UTC (rev 9364)
@@ -24,7 +24,7 @@
private final File accdir;
private final EmailAddress address;
private static final String OUTBOUND_DIR = "outbound";
-
+
public OutboundContact(File accdir, EmailAddress a) throws
BadFreemailAddressException {
this.address = a;
@@ -46,44 +46,88 @@
}
}
- public boolean exists() {
- return this.contactfile.exists();
+ /*
+ * Whether or not we're ready to communicate with the other party
+ */
+ public boolean ready() {
+ if (!this.contactfile.exists()) return false;
+
+ String status = this.contactfile.get("status");
+ if (status == null) return false;
+ // don't wait for an ack before inserting the message, but be
ready to insert it again
+ // if the ack never arrives
+ if (status.equals("rts-sent")) return true;
+ return false;
}
- /**
- * Set up an outbound contact. Fetch the mailsite, generate a new SSK
keypair and post an RTS message to the appropriate KSK.
- * Will block for mailsite retrieval and RTS insertion
- *
- * @return true for success
- */
- public boolean init() throws OutboundContactFatalException {
- HighLevelFCPClient cli = new HighLevelFCPClient();
+ private SSKKeyPair getCommKeyPair() {
+ SSKKeyPair ssk = new SSKKeyPair();
- System.out.println("Attempting to fetch
"+this.getMailpageKey());
- File mailsite_file = cli.fetch(this.getMailpageKey());
+ ssk.pubkey = this.contactfile.get("commssk.privkey");
+ ssk.privkey = this.contactfile.get("commssk.pubkey");
- if (mailsite_file == null) {
- // TODO: Give up for now, try later, count number of
and limit attempts
- System.out.println("Failed to retrieve mailsite for
"+this.address);
- return false;
+
+ if (ssk.pubkey == null || ssk.privkey == null) {
+ HighLevelFCPClient cli = new HighLevelFCPClient();
+ ssk = cli.makeSSK();
+
+ this.contactfile.put("commssk.privkey", ssk.privkey);
+ this.contactfile.put("commssk.pubkey", ssk.pubkey);
+ // we've just generated a new SSK, so the other party
definately doesn't know about it
+ this.contactfile.put("status", "notsent");
+ } else {
+ ssk = new SSKKeyPair();
}
- System.out.println("got mailsite");
+ return ssk;
+ }
+
+ private RSAKeyParameters getPubKey() throws
OutboundContactFatalException {
+ String mod_str = this.contactfile.get("asymkey.modulus");
+ String exp_str = this.contactfile.get("asymkey.pubexponent");
- PropsFile mailsite = new PropsFile(mailsite_file);
+ if (mod_str == null || exp_str == null) {
+ // we don't have their mailsite - fetch it
+ if (this.fetchMailSite()) {
+ mod_str =
this.contactfile.get("asymkey.modulus");
+ exp_str =
this.contactfile.get("asymkey.pubexponent");
+
+ // must be present now, or exception would have
been thrown
+ } else {
+ return null;
+ }
+ }
- String rtskey = mailsite.get("rtsksk");
- String keymod_str = mailsite.get("asymkey.modulus");
- String keyexp_str = mailsite.get("asymkey.pubexponent");
+ return new RSAKeyParameters(false, new BigInteger(mod_str, 10),
new BigInteger(exp_str, 10));
+ }
+
+ private String getRtsKsk() throws OutboundContactFatalException {
+ String rtsksk = this.contactfile.get("rtsksk");
- if (rtskey == null || keymod_str == null || keyexp_str == null)
{
- // TODO: More failure mechanisms - this is fatal.
- System.out.println("Mailsite for "+this.address+" does
not contain all necessary iformation!");
- throw new OutboundContactFatalException("Mailsite for
"+this.address+" does not contain all necessary iformation!");
+ if (rtsksk == null) {
+ // get it from their mailsite
+ if (!this.fetchMailSite()) return null;
+
+ rtsksk = this.contactfile.get("rtsksk");
}
- mailsite_file.delete();
- SSKKeyPair ssk = cli.makeSSK();
+ return rtsksk;
+ }
+
+ /**
+ * Set up an outbound contact. Fetch the mailsite, generate a new SSK
keypair and post an RTS message to the appropriate KSK.
+ * Will block for mailsite retrieval and RTS insertion
+ *
+ * @return true for success
+ */
+ public boolean init() throws OutboundContactFatalException {
+ // try to fetch get all necessary info. will fetch mailsite /
generate new keys if necessary
+ SSKKeyPair ssk = this.getCommKeyPair();
+ if (ssk == null) return false;
+ RSAKeyParameters their_pub_key = this.getPubKey();
+ if (their_pub_key == null) return false;
+ String rtsksk = this.getRtsKsk();
+ if (rtsksk == null) return false;
StringBuffer rtsmessage = new StringBuffer();
@@ -137,13 +181,6 @@
}
// now encrypt it
-
- BigInteger keymodulus = new BigInteger(keymod_str, 10);
- BigInteger keyexponent = new BigInteger(keyexp_str, 10);
-
- // is not private
- RSAKeyParameters their_pub_key = new RSAKeyParameters(false,
keymodulus, keyexponent);
-
AsymmetricBlockCipher enccipher = new RSAEngine();
enccipher.init(true, their_pub_key);
byte[] encmsg = null;
@@ -155,17 +192,49 @@
}
// insert it!
- ByteArrayInputStream bis = new
ByteArrayInputStream(bos.toByteArray());
+ HighLevelFCPClient cli = new HighLevelFCPClient();
+ if (cli.SlotInsert(encmsg,
"KSK@"+rtsksk+"-"+DateStringFactory.getKeyString(), 1, "") < 0) {
+ return false;
+ }
- if (cli.SlotInsert(bis,
"KSK@"+rtskey+"-"+DateStringFactory.getKeyString(), 1, "") < 0) {
+ // remember the fact that we have successfully inserted the rts
+ this.contactfile.put("status", "rts-sent");
+
+ return true;
+ }
+
+ private boolean fetchMailSite() throws OutboundContactFatalException {
+ HighLevelFCPClient cli = new HighLevelFCPClient();
+
+ System.out.println("Attempting to fetch
"+this.getMailpageKey());
+ File mailsite_file = cli.fetch(this.getMailpageKey());
+
+ if (mailsite_file == null) {
+ // TODO: Give up for now, try later, count number of
and limit attempts
+ System.out.println("Failed to retrieve mailsite for
"+this.address);
return false;
}
- // now we can create a new outbound contact file
- this.contactfile.put("rtskey", rtskey);
+ System.out.println("got mailsite");
+
+ PropsFile mailsite = new PropsFile(mailsite_file);
+
+ String rtsksk = mailsite.get("rtsksk");
+ String keymod_str = mailsite.get("asymkey.modulus");
+ String keyexp_str = mailsite.get("asymkey.pubexponent");
+
+ mailsite_file.delete();
+
+ if (rtsksk == null || keymod_str == null || keyexp_str == null)
{
+ // TODO: More failure mechanisms - this is fatal.
+ System.out.println("Mailsite for "+this.address+" does
not contain all necessary iformation!");
+ throw new OutboundContactFatalException("Mailsite for
"+this.address+" does not contain all necessary iformation!");
+ }
+
+ // add this to a new outbound contact file
+ this.contactfile.put("rtsksk", rtsksk);
this.contactfile.put("asymkey.modulus", keymod_str);
- this.contactfile.put("asymnkey.exponent", keyexp_str);
- this.contactfile.put("commssk", ssk.privkey);
+ this.contactfile.put("asymkey.pubexponent", keyexp_str);
return true;
}
Modified: trunk/apps/Freemail/src/freemail/fcp/HighLevelFCPClient.java
===================================================================
--- trunk/apps/Freemail/src/freemail/fcp/HighLevelFCPClient.java
2006-06-23 12:48:04 UTC (rev 9363)
+++ trunk/apps/Freemail/src/freemail/fcp/HighLevelFCPClient.java
2006-06-23 12:50:43 UTC (rev 9364)
@@ -2,6 +2,9 @@
import java.io.File;
import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
import freemail.Freemail;
@@ -122,15 +125,22 @@
}
}
- public int SlotInsert(InputStream data, String basekey, int minslot,
String suffix) {
+ public int SlotInsert(File data, String basekey, int minslot, String
suffix) {
int slot = minslot;
boolean carryon = true;
+ FileInputStream fis;
while (carryon) {
System.out.println("trying slotinsert to
"+basekey+"-"+slot+suffix);
+ try {
+ fis = new FileInputStream(data);
+ } catch (FileNotFoundException fnfe) {
+ return -1;
+ }
+
FCPInsertErrorMessage emsg;
try {
- emsg = this.put(data, basekey+"-"+slot+suffix);
+ emsg = this.put(fis, basekey+"-"+slot+suffix);
} catch (FCPBadFileException bfe) {
return -1;
}
@@ -149,6 +159,36 @@
return -1;
}
+ public int SlotInsert(byte[] data, String basekey, int minslot, String
suffix) {
+ int slot = minslot;
+ boolean carryon = true;
+ ByteArrayInputStream bis;
+ while (carryon) {
+ System.out.println("trying slotinsert to
"+basekey+"-"+slot+suffix);
+
+ bis = new ByteArrayInputStream(data);
+
+ FCPInsertErrorMessage emsg;
+ try {
+ emsg = this.put(bis, basekey+"-"+slot+suffix);
+ } catch (FCPBadFileException bfe) {
+ return -1;
+ }
+ if (emsg == null) {
+ System.out.println("insert successful");
+ return slot;
+ } else if (emsg.errorcode ==
FCPInsertErrorMessage.COLLISION) {
+ slot++;
+ System.out.println("collision");
+ } else {
+ System.out.println("nope - error code is
"+emsg.errorcode);
+ // try again later
+ return -1;
+ }
+ }
+ return -1;
+ }
+
public void requestStatus(FCPMessage msg) {
}