Author: dbkr
Date: 2006-07-31 19:30:04 +0000 (Mon, 31 Jul 2006)
New Revision: 9839
Modified:
trunk/apps/Freemail/src/freemail/AccountManager.java
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/RTSFetcher.java
trunk/apps/Freemail/src/freemail/SingleAccountWatcher.java
trunk/apps/Freemail/src/freemail/fcp/HighLevelFCPClient.java
trunk/apps/Freemail/src/freemail/utils/EmailAddress.java
Log:
Half-finished KSK mailsite support until I know whether to make proper USK
redirects work in Freenet work or use a custom mechanism. Also lots of general
tidy-ups.
Modified: trunk/apps/Freemail/src/freemail/AccountManager.java
===================================================================
--- trunk/apps/Freemail/src/freemail/AccountManager.java 2006-07-31
15:11:58 UTC (rev 9838)
+++ trunk/apps/Freemail/src/freemail/AccountManager.java 2006-07-31
19:30:04 UTC (rev 9839)
@@ -37,6 +37,7 @@
private static final int ASYM_KEY_CERTAINTY = 80;
public static final String MAILSITE_SUFFIX = "mailsite";
+ public static final String MAILSITE_VERSION = "1";
public static void Create(String username) throws IOException {
Modified: trunk/apps/Freemail/src/freemail/MailSite.java
===================================================================
--- trunk/apps/Freemail/src/freemail/MailSite.java 2006-07-31 15:11:58 UTC
(rev 9838)
+++ trunk/apps/Freemail/src/freemail/MailSite.java 2006-07-31 19:30:04 UTC
(rev 9839)
@@ -1,13 +1,16 @@
package freemail;
import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
import freemail.utils.PropsFile;
import freemail.fcp.HighLevelFCPClient;
+import freemail.fcp.FCPInsertErrorMessage;
public class MailSite {
private final PropsFile accprops;
public static final String MAILPAGE = "mailpage";
+ public static final String ALIAS_SUFFIX = "-mailsite";
MailSite(PropsFile a) {
this.accprops = a;
@@ -71,6 +74,34 @@
this.accprops.put("mailsite.slot", new
Integer(actualslot).toString());
+ // leave this out for now, until we know whether we're doing it
+ // with real USK redirects or fake put-a-USK-in-a-KSK redirect
+ // are we set up to use a KSK domain alias too?
+ /*String alias = this.accprops.get("domain_alias");
+ if (alias != null) {
+ String targetKey = this.accprops.get("mailsite.pubkey");
+ if (targetKey == null) return -1;
+ FreenetURI furi;
+ try {
+ furi = new FreenetURI(targetKey);
+ } catch (MalformedURLException mfue) {
+ return -1;
+ }
+ targetKey =
"USK@"+furi.getKeyBody()+"/"+AccountManager.MAILSITE_SUFFIX+"/-1/"+MAILPAGE;
+
+ System.out.println("Inserting mailsite redirect from
"+"KSK@"+alias+ALIAS_SUFFIX+" to "+targetKey);
+
+ FCPInsertErrorMessage err =
cli.putRedirect("KSK@"+alias+ALIAS_SUFFIX, targetKey);
+
+ if (err == null) {
+ System.out.println("Mailsite redirect inserted
successfully");
+ } else if (err.errorcode ==
FCPInsertErrorMessage.COLLISION) {
+ System.out.println("Mailsite alias collided -
somebody is already using that alias! Choose another one!");
+ } else {
+ System.out.println("Mailsite redirect insert
failed, but did not collide.");
+ }
+ }*/
+
return actualslot;
}
}
Modified: trunk/apps/Freemail/src/freemail/MessageSender.java
===================================================================
--- trunk/apps/Freemail/src/freemail/MessageSender.java 2006-07-31 15:11:58 UTC
(rev 9838)
+++ trunk/apps/Freemail/src/freemail/MessageSender.java 2006-07-31 19:30:04 UTC
(rev 9839)
@@ -75,7 +75,6 @@
outbox.mkdir();
this.sendDir(files[i], outbox);
- this.checkCTSs(files[i]);
}
// don't spin around the loop if nothing's
// going on
@@ -90,27 +89,6 @@
}
}
- private void checkCTSs(File accdir) {
- File contactsdir = new File(accdir,
SingleAccountWatcher.CONTACTS_DIR);
-
- File outbounddir = new File(contactsdir,
SingleAccountWatcher.OUTBOUND_DIR);
-
- if (!outbounddir.exists())
- outbounddir.mkdir();
-
- File[] contacts = outbounddir.listFiles();
-
- int i;
- for (i = 0; i < contacts.length; i++) {
- OutboundContact outboundcontact = new
OutboundContact(accdir, contacts[i]);
-
- try {
- outboundcontact.checkCTS();
- } catch (OutboundContactFatalException obctfe) {
- }
- }
- }
-
private void sendDir(File accdir, File dir) {
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
@@ -135,7 +113,7 @@
return;
}
- if (addr.domain.equalsIgnoreCase("nim.freemail")) {
+ if (addr.is_nim_address()) {
HighLevelFCPClient cli = new HighLevelFCPClient();
if (cli.SlotInsert(msg,
NIM_KEY_PREFIX+addr.user+"-"+DateStringFactory.getKeyString(), 1, "") > -1) {
Modified: trunk/apps/Freemail/src/freemail/OutboundContact.java
===================================================================
--- trunk/apps/Freemail/src/freemail/OutboundContact.java 2006-07-31
15:11:58 UTC (rev 9838)
+++ trunk/apps/Freemail/src/freemail/OutboundContact.java 2006-07-31
19:30:04 UTC (rev 9839)
@@ -225,17 +225,13 @@
}
private byte[] getAESParams() {
- byte[] retval = new byte[AES_KEY_LENGTH + AES_BLOCK_LENGTH];
-
String params = this.contactfile.get("aesparams");
if (params != null) {
return Base64.decode(params);
}
SecureRandom rnd = new SecureRandom();
-
- byte[] aes_iv_and_key = new byte[AES_KEY_LENGTH +
AES_BLOCK_LENGTH];
-
+ byte[] retval = new byte[AES_KEY_LENGTH + AES_BLOCK_LENGTH];
rnd.nextBytes(retval);
// save them for next time (if insertion fails) so we can
@@ -266,7 +262,6 @@
StringBuffer rtsmessage = new StringBuffer();
// the public part of the SSK keypair we generated
- // put this first to avoid messages with the same first block,
since we don't (currently) use CBC
rtsmessage.append("commssk="+commssk.pubkey+"\r\n");
rtsmessage.append("ackssk="+ackssk.privkey+"\r\n");
@@ -375,12 +370,11 @@
private boolean fetchMailSite() throws OutboundContactFatalException {
HighLevelFCPClient cli = new HighLevelFCPClient();
- System.out.println("Attempting to fetch
"+this.getMailpageKey());
- File mailsite_file = cli.fetch(this.getMailpageKey());
+ System.out.println("Attempting to fetch
"+this.address.getMailpageKey());
+ File mailsite_file = cli.fetch(this.address.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);
+ System.out.println("Failed to retrieve mailsite
"+this.address.getMailpageKey());
return false;
}
@@ -408,14 +402,10 @@
return true;
}
- private String getMailpageKey() {
- return
"USK@"+this.address.getMailsiteKey()+"/"+AccountManager.MAILSITE_SUFFIX+"/1/"+MailSite.MAILPAGE;
- }
-
private String popNextSlot() {
String slot = this.contactfile.get("nextslot");
if (slot == null) {
- slot = this.contactfile.get("initialslot");
+ slot = this.getInitialSlot();
}
SHA256Digest sha256 = new SHA256Digest();
sha256.update(Base32.decode(slot), 0,
Base32.decode(slot).length);
@@ -440,16 +430,6 @@
}
public boolean sendMessage(File body) {
- if (!this.contactfile.exists()) {
- try {
- this.init();
- } catch (OutboundContactFatalException fe) {
- if (Postman.bounceMessage(body, new
MessageBank(this.accdir.getName()), fe.getMessage())) {
- return true;
- }
- }
- }
-
int uid = this.popNextUid();
// create a new file that contains the complete Freemail
@@ -501,6 +481,10 @@
public void doComm() {
this.sendQueued();
this.pollAcks();
+ try {
+ this.checkCTS();
+ } catch (OutboundContactFatalException fe) {
+ }
}
private void sendQueued() {
Modified: trunk/apps/Freemail/src/freemail/RTSFetcher.java
===================================================================
--- trunk/apps/Freemail/src/freemail/RTSFetcher.java 2006-07-31 15:11:58 UTC
(rev 9838)
+++ trunk/apps/Freemail/src/freemail/RTSFetcher.java 2006-07-31 19:30:04 UTC
(rev 9839)
@@ -127,6 +127,8 @@
NaturalSlotManager sm = new NaturalSlotManager(this, cbdata,
log.getSlots(date));
+ sm.setPollAhead(POLL_AHEAD);
+
int slot;
while ( (slot = sm.getNextSlotNat()) > 0) {
System.out.println("trying to fetch "+keybase+slot);
@@ -270,7 +272,7 @@
if (!their_mailsite.endsWith("/")) {
their_mailsite += "/";
}
- their_mailsite += "1/"+MailSite.MAILPAGE;
+ their_mailsite +=
AccountManager.MAILSITE_VERSION+"/"+MailSite.MAILPAGE;
System.out.println("Trying to fetch sender's mailsite:
"+their_mailsite);
@@ -335,7 +337,10 @@
rtsfile.delete();
return false;
}
- if (!rtsprops.get("to").equals(our_mailsite_keybody)) {
+
+ String our_domain_alias = this.accprops.get("domain_alias");
+
+ if (!rtsprops.get("to").equals(our_mailsite_keybody) &&
our_domain_alias != null && !rtsprops.get("to").equals(our_domain_alias)) {
System.out.println("Recieved an RTS message that was
not intended for the recipient. Discarding.");
msfile.delete();
rtsfile.delete();
Modified: trunk/apps/Freemail/src/freemail/SingleAccountWatcher.java
===================================================================
--- trunk/apps/Freemail/src/freemail/SingleAccountWatcher.java 2006-07-31
15:11:58 UTC (rev 9838)
+++ trunk/apps/Freemail/src/freemail/SingleAccountWatcher.java 2006-07-31
19:30:04 UTC (rev 9839)
@@ -24,6 +24,11 @@
this.accdir = accdir;
this.accprops = AccountManager.getAccountFile(accdir);
File contacts_dir = new File(accdir, CONTACTS_DIR);
+
+ if (!contacts_dir.exists()) {
+ contacts_dir.mkdir();
+ }
+
this.ibctdir = new File(contacts_dir, INBOUND_DIR);
this.obctdir = new File(contacts_dir, OUTBOUND_DIR);
this.mailsite_last_upload = 0;
@@ -54,6 +59,7 @@
while (true) {
long start = System.currentTimeMillis();
+ // is it time we inserted the mailsite?
if (System.currentTimeMillis() >
this.mailsite_last_upload + MAILSITE_UPLOAD_INTERVAL) {
MailSite ms = new MailSite(this.accprops);
if (ms.Publish() > 0) {
Modified: trunk/apps/Freemail/src/freemail/fcp/HighLevelFCPClient.java
===================================================================
--- trunk/apps/Freemail/src/freemail/fcp/HighLevelFCPClient.java
2006-07-31 15:11:58 UTC (rev 9838)
+++ trunk/apps/Freemail/src/freemail/fcp/HighLevelFCPClient.java
2006-07-31 19:30:04 UTC (rev 9839)
@@ -9,6 +9,8 @@
import freemail.Freemail;
public class HighLevelFCPClient implements FCPClient {
+ private static final int FCP_PERMANANT_REDIRECT = 27;
+
private FCPConnection conn;
private FCPMessage donemsg;
@@ -50,6 +52,16 @@
if (this.donemsg.getType().equalsIgnoreCase("AllData")) {
return this.donemsg.getData();
+ } else if
(this.donemsg.getType().equalsIgnoreCase("GetFailed")) {
+ String s_code =
(String)this.donemsg.headers.get("Code");
+ if (s_code == null) return null;
+ int code = Integer.parseInt(s_code);
+ if (code == FCP_PERMANANT_REDIRECT) {
+ String newuri = (String)
this.donemsg.headers.get("RedirectURI");
+ if (newuri == null) return null;
+ return this.fetch(newuri);
+ }
+ return null;
} else {
return null;
}
@@ -125,6 +137,42 @@
}
}
+ public synchronized FCPInsertErrorMessage putRedirect(String fromKey,
String targetKey) {
+ FCPMessage msg = this.conn.getMessage("ClientPut");
+ msg.headers.put("URI", fromKey);
+ msg.headers.put("Persistence", "connection");
+ msg.headers.put("UploadFrom", "redirect");
+ msg.headers.put("TargetURI", targetKey);
+
+ while (true) {
+ try {
+ this.conn.doRequest(this, msg);
+ break;
+ } catch (NoNodeConnectionException nnce) {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException ie) {
+ }
+ } catch (FCPBadFileException bfe) {
+ // impossible
+ }
+ }
+
+ this.donemsg = null;
+ while (this.donemsg == null) {
+ try {
+ this.wait();
+ } catch (InterruptedException ie) {
+ }
+ }
+
+ if (this.donemsg.getType().equalsIgnoreCase("PutSuccessful")) {
+ return null;
+ } else {
+ return new FCPInsertErrorMessage(donemsg);
+ }
+ }
+
public int SlotInsert(File data, String basekey, int minslot, String
suffix) {
int slot = minslot;
boolean carryon = true;
Modified: trunk/apps/Freemail/src/freemail/utils/EmailAddress.java
===================================================================
--- trunk/apps/Freemail/src/freemail/utils/EmailAddress.java 2006-07-31
15:11:58 UTC (rev 9838)
+++ trunk/apps/Freemail/src/freemail/utils/EmailAddress.java 2006-07-31
19:30:04 UTC (rev 9839)
@@ -1,8 +1,13 @@
package freemail.utils;
+import freemail.AccountManager;
+import freemail.MailSite;
+
import org.archive.util.Base32;
public class EmailAddress {
+ private static final int SSK_PART_LENGTH = 43;
+
public String realname;
public String user;
public String domain;
@@ -53,18 +58,57 @@
public boolean is_freemail_address() {
if (this.domain == null) return false;
if (!this.domain.endsWith(".freemail")) return false;
- if (this.getMailsiteKey() == null) return false;
return true;
}
- public String getMailsiteKey() {
+ public boolean is_nim_address() {
+ if (!this.is_freemail_address()) {
+ return false;
+ }
+ return this.getSubDomain().equalsIgnoreCase("nim");
+ }
+
+ private boolean is_ssk_address() {
+ if (!this.is_freemail_address()) return false;
+ String key;
+ try {
+ key = new String(Base32.decode(this.getSubDomain()));
+ } catch (Exception e) {
+ return false;
+ }
+
+ String[] parts = key.split(",", 3);
+
+ if (parts.length < 3) return false;
+ if (parts[0].length() != SSK_PART_LENGTH || parts[1].length()
!= SSK_PART_LENGTH) return false;
+ return true;
+ }
+
+ // get the part of the domain before the '.freemail'
+ private String getSubDomain() {
String[] domparts = this.domain.split("\\.", 2);
if (domparts.length < 2) return null;
- return new String (Base32.decode(domparts[0]));
+ return domparts[0];
}
+ public String getMailsiteKey() {
+ if (this.is_ssk_address()) {
+ return new String (Base32.decode(this.getSubDomain()));
+ } else {
+ return this.getSubDomain();
+ }
+ }
+
+ public String getMailpageKey() {
+ if (this.is_ssk_address()) {
+ return "USK@"+new String
(Base32.decode(this.getSubDomain()))+"/"+AccountManager.MAILSITE_SUFFIX+"/"+AccountManager.MAILSITE_VERSION+"/"+MailSite.MAILPAGE;
+ } else {
+ return "KSK@"+this.getSubDomain()+MailSite.ALIAS_SUFFIX;
+ }
+ }
+
public String toString() {
return this.user+"@"+this.domain;
}