[Nym3-commit] r298 - trunk/nym3/Client

jr at conuropsis.org jr at conuropsis.org
Tue Jun 14 18:50:02 CEST 2005


Author: jr
Date: 2005-06-14 18:50:00 +0200 (Tue, 14 Jun 2005)
New Revision: 298

Modified:
   trunk/nym3/Client/Account.py
   trunk/nym3/Client/Main.py
Log:
-change the journalKey into an admKey(Client.Account)
-use nym_encrypt instead of pk_encrypt for the journal items(Client.Account)
-change the representation of the synbox(Client.Account)
-adapt the client implementation to this representation


Modified: trunk/nym3/Client/Account.py
===================================================================
--- trunk/nym3/Client/Account.py	2005-06-12 10:31:50 UTC (rev 297)
+++ trunk/nym3/Client/Account.py	2005-06-14 16:50:00 UTC (rev 298)
@@ -30,11 +30,13 @@
 import copy
 import os
 import nym3.Client.Config as Config
+import nym3.Client.Keyring as Keyring
 import nym3.Mail as Mail
 import mixminion.Common
 import nym3.Common as Common
 import mixminion.Crypto as _cr
 import nym3.Message as Message
+import nym3.Crypto as Crypto
 #import mixminion.ClientAPI as mapi
 import pickle
 import tempfile
@@ -143,6 +145,11 @@
 	- data is the hash that contains all of this
 	- datafile() is the file where we pickle from and to the data hash
 	- synbox is the synopsis box, stored in synboxfile()
+	  It is a hashtable that associates to a XNymSeq a t-uple
+	  (mid, flag_is_present_on server, synopsis)
+	  it may be represented by a string : the encrypted pickled hashtable
+	  (status = 'encrypted') or a hashtable (status = decrypted).
+	  When saved, it is put in the encrypted form.
 	- mbox is the couple of a hash mid to message and a list of the keys of
 	  the hash to order these keys, stored in mboxfile()
 	- a journal which is a hash of seqno -> encrypted (message, time sent)		  and is pickled from/to journalfile()
@@ -182,11 +189,12 @@
 	    self.journal_status = 'dirty'
 	    self.mbox = {}, []
 	    self.mbox_status = 'dirty'
-	    self.synbox = []
+	    self.synbox = {}
 	    self.synbox_status = 'dirty'
+	    self.synbox_enc_status = 'decrypted'
 	    self['encKeys'] = []
 	    self.idKey = None
-	    self.journalKey = None
+	    self.admKey = None 
 	    self.pendingKey = None
 	else:
 	    self.data_status = 'unloaded'
@@ -199,6 +207,7 @@
 	    self.journal = None
 	    self.mbox = None
 	    self.synbox = None
+	    self.synbox_enc_status = None
 	self.succeeded = True
 	self._lock()
 
@@ -290,14 +299,17 @@
         h.fromData(self.data['username'], seqno, sig)
         return str(h)
 
+    def get_admPubKey(self):
+	pubring = Keyring.Keyring(self.config.pubring_path, create = False)
+	pubring.decrypt("nym3")
+	return pubring.get_key(self['admKey'])
+    
     def record(self, seqno, msg):
 	"""Store a control message in the journal"""
 	if self.journal_status == 'unloaded': self._load_journal()
 	clear = pickle.dumps((msg, int(time.time())))
-	pubring = Keyring.Keyring(self.config.pubring_path, create = False)
-	pubring.decrypt("nym3")
-	key = pubring.get_key(self.journalKey)
-	self.journal[seqno] = _cr.pk_encrypt(clear, key)
+	key = self.get_admPubKey()
+	self.journal[seqno] = Crypto.nym_encrypt(clear, key)
 	self.journal_status = 'dirty'
 
     def acknowledge(self, seqno_list):
@@ -341,7 +353,13 @@
 	if not self.synbox_status == 'dirty': return
 	synbox = self.synboxfile()
 	f = open(synbox, 'w')
-	pickle.dump(self.synbox, f)
+	if self.synbox_enc_status == 'decrypted':
+	    key = self.get_admPubKey()
+	    s = Crypto.nym_encrypt(pickle.dumps(self.synbox), key)
+	else:
+	    assert self.synbox_enc_status == 'encrypted'
+	    s = self.synbox
+	f.write(s)
 	f.close()
 	self.synbox_status = 'ok'
 
@@ -393,10 +411,12 @@
 	synbox = self.synboxfile()
 	try:
 	    f = open(synbox, 'r')
-	    self.synbox = pickle.load(f)
+	    self.synbox = f.read()
+	    self.synbox_enc_status = 'encrypted'
 	    f.close()
 	except IOError:
-	    self.synbox = []
+	    self.synbox = {}
+	    self.synbox_enc_status = 'decrypted'
 	self.synbox_status = 'ok'
 
     def _load_journal(self):
@@ -411,9 +431,20 @@
 	    self.journal = {}
 	self.journal_status = 'ok'
 
-    def get_synbox(self):
-	"""return a copy of the synbox"""
+    def _decrypt_synbox(self, secring):
+	"""After a call to this method synbox is loaded and decrypted.
+	secring contains the private admKey"""
 	self._load_synbox()
+	if self.synbox_enc_status == 'decrypted': return
+	assert self.synbox_enc_status == 'encrypted'
+	key = secring.get_key(self['admKey'])
+	self.synbox = pickle.loads(Crypto.nym_decrypt(self.synbox, key))
+	self.synbox_enc_status = 'decrypted'
+	
+    def get_synbox(self, secring):
+	"""return a copy of the synbox, trying to decrypt it if it is encrypted
+	"""
+	self._decrypt_synbox(secring)
 	return copy.deepcopy(self.synbox)
 
     def get_mbox(self):
@@ -426,10 +457,10 @@
 	self._load_journal()
 	return copy.deepcopy(self.journal)
 
-    def add_synset(self, midlist, bf, synset):
-	self._load_synbox()
-	t = (midlist, bf, synset)
-	self.synbox.append(t)
+    def add_syn(self, secring, xnymseq, mid, flag, syn):
+	"""add a set of syn to the"""
+	self._decrypt_synbox(secring)
+	self.synbox[str(xnymseq)] = (mid, flag, syn)
 	self.synbox_status = "dirty"
 
     def add_msg(self, mid, msg):

Modified: trunk/nym3/Client/Main.py
===================================================================
--- trunk/nym3/Client/Main.py	2005-06-12 10:31:50 UTC (rev 297)
+++ trunk/nym3/Client/Main.py	2005-06-14 16:50:00 UTC (rev 298)
@@ -144,26 +144,11 @@
     """Builds the index of synopses of the given account, using ui to get
     the password to decrypt the keyring. Returns a hash containing the
     correspondance index -> mid, where index is a XNymSeq as a str"""
-    synbox = account.get_synbox()
     secring = decode_secring(config, ui)
+    synbox = account.get_synbox(secring)
     index = {}
-    for (midlist, bf, enc_synset) in synbox:
-	bflist = Mail.bf2list(bf)
-	synset = decipher_string(enc_synset, secring, account['encKeys'])
-	if synset == None:
-	    ui.display("unable to decipher a synopses blob, lost keys?")
-	    #TODO remove the blob?
-	    #TODO if yes remove the following line
-	else:
-	    for mid in midlist:
-		synlen = Message.strToIntBE(synset[20: 22])
-		syn = synset[22: 22 + synlen]
-		synset = synset[22 + synlen:]
-		try:
-		    index[str(Mail.XNymSeq(syn))] = mid
-		except:
-		    #there was a problem determining the XNymSeq: bug
-		    raise Exception("unable to determine XNymSeq")
+    for xnymseq, (mid, flag, syn) in synbox.iteritems():
+	index[xnymseq] = mid
     return index
 
 def build_mbox_index(account):
@@ -177,10 +162,10 @@
     containing the correspondance index -> seqno, index as a str"""
     journal = account.get_journal()
     secring = decode_secring(config, ui)
-    key = secring.get_key(account['journalKey'])
+    key = secring.get_key(account['admKey'])
     l = []
     for seqno in journal.keys():
-	clear = _cr.pk_decrypt(journal[seqno], key)
+	clear = Crypto.nym_decrypt(journal[seqno], key)
 	m, t = pickle.loads(clear)
 	l.append((seqno, m, t))
     l.sort(journal_time_cmp)
@@ -256,7 +241,7 @@
     comList = sr.readCommandSToCList()
     try:
 	account = Account.Account(config, nickname)
-    except NoSuchAccount:
+    except Account.NoSuchAccount:
 	ui.display("%s: no account corresponding to this nickname" % nickname)
 	sys.exit(1)
     for com in comList:
@@ -287,15 +272,21 @@
 	    if not clear:
 		ui.display("Could not decrypt synopsis")
 		sys.exit(1)
-	    midlist = []
+	    index = 0
+	    bflist = Mail.bf2list(com.bf)
 	    while len(clear) > 0:
 		mid = clear[:20]
 		synlen = Message.strToIntBE(clear[20:22])
-		midlist.append(mid)
+		syn = clear[22:22 + synlen]
 		clear = clear[22 + synlen:]
-	    #debugging cruft. TODO remove?
-	    print "number of received syn: %d" % len(midlist)
-	    account.add_synset(midlist, com.bf, com.synSet)
+		try:
+		    xnymseq = Mail.XNymSeq(syn)
+		except:
+		    #there was a problem determining the XNymSeq: bug
+		    #TODO is it the right play?
+		    raise Exception("unable to determine XNymSeq")
+		account.add_syn(secring, xnymseq, mid, index in bflist, syn)
+		index += 1
 	elif (com.ct() == SToCCODE['Msg']):
 	    account.add_msg(com.mid, com.msg)
 	elif (com.ct() == SToCCODE['Dropped']):
@@ -333,7 +324,7 @@
     ui.display("Please wait, generating keys for this account...")
     idKey = _cr.pk_generate(bits=config.idkey_length)
     encKey = _cr.pk_generate(bits=config.enckey_length)
-    journalKey = _cr.pk_generate()
+    admKey = _cr.pk_generate()
     # We have gathered the relevant information for this account, except for
     # the policy which we don't let the user change at this point for the sake
     # of simplicity. So, let's store all of that in the account and prepare the
@@ -365,13 +356,13 @@
     
     idtag = secring.store(_cr.pk_encode_private_key(idKey))
     enctag = secring.store(_cr.pk_encode_private_key(encKey))
-    journaltag = secring.store(_cr.pk_encode_private_key(journalKey))
+    admtag = secring.store(_cr.pk_encode_private_key(admKey))
     account.add_enckey(enctag)
     account['idKey'] = idtag
-    account['journalKey'] = journaltag
+    account['admKey'] = admtag
     pubring.update_key(idtag, _cr.pk_encode_public_key(idKey))
     pubring.update_key(enctag, _cr.pk_encode_public_key(encKey))
-    pubring.update_key(journaltag, _cr.pk_encode_public_key(journalKey))
+    pubring.update_key(admtag, _cr.pk_encode_public_key(admKey))
     secring.save(passphrase1)
     pubring.save("nym3")
     createc = Message.Create()
@@ -520,9 +511,9 @@
 	ui.display(str(inst))
 	sys.exit(1)
     secring = decode_secring(config, ui)
-    key = secring.get_key(account['journalKey'])
+    key = secring.get_key(account['admKey'])
     for seqno in seqnolist:
-	clear = _cr.pk_decrypt(journal[seqno], key)
+	clear = Crypto.nym_decrypt(journal[seqno], key)
 	m, t = pickle.loads(clear)
 	account.send(m)
 	account.record(seqno, m)
@@ -541,61 +532,24 @@
     surbc.fromData(account.generateSurbs(number))
     account.sendControl([surbc], idKey)
 
-def list_syn(ui, config, nickname = None):
+def list_syn(ui, config, nickname = None, summarize = True):
     account = get_account_from_nickname(ui, config, nickname,
 	    "No nickname given, abort\nUse -n <nickname>")
-    synbox = account.get_synbox()
-    mbox = account.get_mbox()[0]
     secring = decode_secring(config, ui)
-    for (midlist, bf, enc_synset) in synbox:
-	bflist = Mail.bf2list(bf)
-	synset = decipher_string(enc_synset, secring, account['encKeys'])
-	if synset == None:
-	    ui.display("unable to decipher a synopses blob, lost keys?")
-	    #TODO remove the blob?
-	    #TODO if yes remove the following line
-	else:
-	    for i, mid in enumerate(midlist):
-		synlen = Message.strToIntBE(synset[20: 22])
-		syn = synset[22: 22 + synlen]
-		synset = synset[22 + synlen:]
-		if mbox.has_key(mid):
-		    avail = "email available"
-		elif i in bflist:
-		    avail = "email available on server"
-		else:
-		    avail = "email not available"
-		index = Mail.XNymSeq(syn)
-		ui.display("%d %s %s" % (index, binascii.hexlify(mid), avail))
-		ui.display(Mail.syn_summary(syn))
-
-def dump_syn(ui, config, nickname = None):
-    account = get_account_from_nickname(ui, config, nickname,
-	    "No nickname given, abort\nUse -n <nickname>")
-    synbox = account.get_synbox()
+    synbox = account.get_synbox(secring)
     mbox = account.get_mbox()[0]
-    secring = decode_secring(config, ui)
-    for (midlist, bf, enc_synset) in synbox:
-	bflist = Mail.bf2list(bf)
-	synset = decipher_string(enc_synset, secring, account['encKeys'])
-	if synset == None:
-	    ui.display("unable to decipher a synopses blob, lost keys?")
-	    #TODO remove the blob?
-	    #TODO if yes remove the following line
+    for xnymseq, (mid, flag, syn) in synbox.iteritems():
+	if mbox.has_key(mid):
+	    avail = "email available"
+	elif flag:
+	    avail = "email available on server"
 	else:
-	    for i, mid in enumerate(midlist):
-		synlen = Message.strToIntBE(synset[20: 22])
-		syn = synset[22: 22 + synlen]
-		synset = synset[22 + synlen:]
-		if mbox.has_key(mid):
-		    avail = "email available"
-		elif i in bflist:
-		    avail = "email available on server"
-		else:
-		    avail = "email not available"
-		index = Mail.XNymSeq(syn)
-		ui.display("%d %s %s" % (index, binascii.hexlify(mid), avail))
-		ui.display(syn)
+	    avail = "email not available"
+	ui.display("%s %s %s" % (xnymseq, binascii.hexlify(mid), avail))
+	if summarize:
+	    ui.display(Mail.syn_summary(syn))
+	else:
+	    ui.display(syn)
 
 def list_mbox(ui, config, nickname = None):
     account = get_account_from_nickname(ui, config, nickname,
@@ -617,10 +571,10 @@
 	    "No nickname given, abort\nUse -n <nickname>")
     journal = account.get_journal()
     secring = decode_secring(config, ui)
-    key = secring.get_key(account['journalKey'])
+    key = secring.get_key(account['admKey'])
     l = []
     for seqno in journal.keys():
-	clear = _cr.pk_decrypt(journal[seqno], key)
+	clear = Crypto.nym_decrypt(journal[seqno], key)
 	m, t = pickle.loads(clear)
 	l.append((seqno, m, t))
     l.sort(journal_time_cmp)
@@ -805,7 +759,7 @@
 	(options, args) = parser.parse_args(args[2:])
 	ui = CLI()
 	config = Config.Config()
-	dump_syn(ui, config, options.nickname)
+	list_syn(ui, config, options.nickname, summarize = False)
 	sys.exit(0)
 
     if args[1] == "list-mbox":



More information about the Nym3-commit mailing list