[Nym3-commit] r443 - in trunk/nymbaron: . Client Server
jr at conuropsis.org
jr at conuropsis.org
Mon Dec 19 23:22:56 CET 2005
Author: jr
Date: 2005-12-19 23:22:55 +0100 (Mon, 19 Dec 2005)
New Revision: 443
Modified:
trunk/nymbaron/Client/Account.py
trunk/nymbaron/Client/Main.py
trunk/nymbaron/Common.py
trunk/nymbaron/Server/User.py
Log:
- change the synbox format. Beware this is not thouroughfully tested yet. It
might break your accounts' format [client]
Modified: trunk/nymbaron/Client/Account.py
===================================================================
--- trunk/nymbaron/Client/Account.py 2005-12-15 16:02:42 UTC (rev 442)
+++ trunk/nymbaron/Client/Account.py 2005-12-19 22:22:55 UTC (rev 443)
@@ -22,30 +22,60 @@
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-"""nymbaron.Client.Acount
+"""nymbaron.Client.Account
This package contains user account information representation on the client
side and ways to create, access to and modify them."""
import copy
import os
-import nymbaron.Client.Keyring as Keyring
-import nymbaron.Mail as Mail
-import mixminion.Common
-import nymbaron.Common as Common
-import mixminion.Crypto as _cr
-import nymbaron.Message as Message
-import nymbaron.Crypto as Crypto
-#import mixminion.ClientAPI as mapi
import pickle
import tempfile
import time
#TODO debugging cruft associated to seqno display
import binascii
+import mixminion.Common
+import mixminion.Crypto as _cr
+#import mixminion.ClientAPI as mapi
+
+from nymbaron.Common import binsearch
+import nymbaron.Client.Keyring as Keyring
+import nymbaron.Mail as Mail
+import nymbaron.Common as Common
+import nymbaron.Message as Message
+import nymbaron.Crypto as Crypto
+
SEQNO_LEN = 20
SURB_LEN = 2104
+#TODO this helper function exists beause the necessity to convert old format
+#synbox to new format synbox. Once this conversion isn't required anymore, it
+#should be removed and its body should be placed in add_syn.
+def add_syn_to_synbox(h, l, xnymseq, mid, flag, syn, sorted = False):
+ """Adds a tuple (xnymseq, mid, flag, syn) corresponding to a syn to a synbox
+ (ie a tuple (dict, seq)."""
+ #Add to the hash
+ if h.has_key(mid):
+ #TODO what should be done here?
+ raise Exception("Bug mid not unique")
+ h[mid] = (xnymseq, flag, syn)
+ #Add to the list
+ #if sorted it is quick to insert from the end
+ if sorted:
+ i = len(l)
+ while i > 0:
+ if l[i-1][0] <= xnymseq:
+ l[i:i] = [mid]
+ return
+ i = i - 1
+ l[0:0] = [mid]
+ #else we use a binary search
+ else:
+ #look for the first mid whose seq number is greater than xnymseq
+ i = binsearch(l, lambda x: (h[x][0] > xnymseq))
+ l[i:i] = [mid]
+
class NoSuchAccount(Exception): pass
"""Exception thrown when a user identified by her nym can't be found"""
@@ -167,11 +197,17 @@
- 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
+ It was 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.
+ Due to the meaning of the mid the previous structure is deprecated and
+ replaced by a tuple (dic, seq) where
+ - dic is a hashtable mid -> (xnymseq, flag_is_present_on_server,
+ synopsis). In the new format xnymseq is an int whereas it was a str in
+ the old format
+ - seq is a list of dic.keys(), sorted by ascending xnymseq
- 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()
@@ -219,7 +255,7 @@
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'] = []
@@ -469,7 +505,7 @@
self.synbox_enc_status = 'encrypted'
f.close()
except IOError:
- self.synbox = {}
+ self.synbox = {}, []
self.synbox_enc_status = 'decrypted'
self.synbox_status = 'ok'
@@ -494,6 +530,20 @@
key = secring.get_key(self['admKey'])
self.synbox = pickle.loads(Crypto.nym_decrypt(self.synbox, key))
self.synbox_enc_status = 'decrypted'
+ #TODO the following code converts a synbox in the old format (dictionary
+ #to a synbox in the new format. Remove once we can assume the old format
+ #isn't used anymore.
+ if type(self.synbox) == dict:
+ synbox = {}, []
+ xnymseqs = self.synbox.keys()
+ xnymseqs = map(int, xnymseqs)
+ xnymseqs.sort()
+ for xnymseq in xnymseqs:
+ (mid, flag, syn) = self.synbox[str(xnymseq)]
+ add_syn_to_synbox(synbox[0], synbox[1], xnymseq,
+ mid, flag, syn, True)
+ self.synbox = synbox
+ self.synbox_status = 'dirty'
def get_synbox(self, secring):
"""return a copy of the synbox, trying to decrypt it if it is encrypted
@@ -512,21 +562,27 @@
return copy.deepcopy(self.journal)
def add_syn(self, secring, xnymseq, mid, flag, syn):
- """add a syn to the synbox"""
+ """add a syn to the synbox. The secring is used only if the synbox is
+ encrypted."""
self._decrypt_synbox(secring)
- self.synbox[str(xnymseq)] = (mid, flag, syn)
+ add_syn_to_synbox(self.synbox[0], self.synbox[1], xnymseq, mid, flag,
+ syn)
self.synbox_status = "dirty"
def delete_syn(self, secring, mid):
self._decrypt_synbox(secring)
- l = []
- for i, (m, flag, syn) in self.synbox.iteritems():
- if m == mid:
- l.append(i)
- if len(l) > 0:
- self.synbox_status = "dirty"
- for i in l:
- del(self.synbox[i])
+ h, l = self.synbox
+ if h.has_key(mid):
+ i = binsearch(l, lambda x: (x[0] >= h[mid][0]))
+ while h[l[i]][0] == h[mid][0]:
+ if l[i] == mid:
+ del(self.synbox[1][i])
+ del(self.synbox[0][mid])
+ self.synbox_status = "dirty"
+ return
+ raise Error("Bug : mid in the synbox hash but not sequence")
+ #TODO cruft -> output a warning here
+ print "mid %s not in the synbox, doing nothing" % binascii.hexlify(mid)
def add_msg(self, mid, msg):
self._load_mbox()
Modified: trunk/nymbaron/Client/Main.py
===================================================================
--- trunk/nymbaron/Client/Main.py 2005-12-15 16:02:42 UTC (rev 442)
+++ trunk/nymbaron/Client/Main.py 2005-12-19 22:22:55 UTC (rev 443)
@@ -177,12 +177,11 @@
def build_syn_index(secring, account):
"""Builds the index of synopses of the given account. secring must be
decrypted and contain the private admin key of account. Returns a hash
- containing the correspondance index -> mid, where index is a XNymSeq as a
- str"""
+ containing the correspondance index -> mid, index as a str"""
synbox = account.get_synbox(secring)
index = {}
- for xnymseq, (mid, flag, syn) in synbox.iteritems():
- index[xnymseq] = mid
+ for i, mid in enumerate(synbox[1]):
+ index[str(i)] = mid
return index
def build_mbox_index(account):
@@ -597,26 +596,20 @@
"No nickname given, abort\nUse -n <nickname>")
secring = decode_secring(config, ui)
synbox = account.get_synbox(secring)
- if len(synbox) == 0:
+ if len(synbox[0]) == 0:
ui.display("empty synbox")
return
+ print synbox
mbox = account.get_mbox()[0]
- # TODO here we need to go from str to int to str because the type of object
- # we chose as key in the dictionnary synbox is str, but we need int order
- # moving from int would break existing accounts. Should we add temporarily a
- # migration function, or is breaking some accounts ok?
- # for the time being, keep the same structure and convert data as we need
- xnymseqs = map(int, synbox.keys())
- xnymseqs.sort()
- for xnymseq in xnymseqs:
- (mid, flag, syn) = synbox[str(xnymseq)]
+ for i, mid in enumerate(synbox[1]):
+ (xnymseq, flag, syn) = synbox[0][mid]
if mbox.has_key(mid):
avail = "email available"
elif flag:
avail = "email available on server"
else:
avail = "email not available"
- ui.display("%d %s %s" % (xnymseq, binascii.hexlify(mid), avail))
+ ui.display("%d %s %s" % (i, binascii.hexlify(mid), avail))
if summarize:
ui.display(Mail.syn_summary(syn))
else:
Modified: trunk/nymbaron/Common.py
===================================================================
--- trunk/nymbaron/Common.py 2005-12-15 16:02:42 UTC (rev 442)
+++ trunk/nymbaron/Common.py 2005-12-19 22:22:55 UTC (rev 443)
@@ -43,3 +43,22 @@
"ShutdownPhrase"]
"""The accepted strings identifying userPolicies"""
+#functions
+
+def binsearch(l, prop):
+ """Returns the first index i of l for which l[i] is true,
+ assuming prop is increasing over l"""
+ min = 0
+ max = len(l) - 1
+ if not prop(l[max]): return IndexError
+ if prop(l[min]): return min
+
+ current = (max + min) / 2
+ while max - min > 1:
+ if prop(l[current]):
+ max = current
+ current = (max + min) / 2
+ else:
+ min = current
+ current = (max + min) / 2
+ return max
Modified: trunk/nymbaron/Server/User.py
===================================================================
--- trunk/nymbaron/Server/User.py 2005-12-15 16:02:42 UTC (rev 442)
+++ trunk/nymbaron/Server/User.py 2005-12-19 22:22:55 UTC (rev 443)
@@ -31,20 +31,23 @@
import re
import os
import sys
-import nymbaron.Server.Config as Config
-import nymbaron.Mail as Mail
-import nymbaron.Crypto as Crypto
-import nymbaron.Message as Message
import pickle
import string
import time
import calendar
+
import mixminion.Common
-from nymbaron.Message import intToStrBE
import mixminion.Crypto as _cr
from mixminion.Packet import parseReplyBlocks, ParseError, compressData
import mixminion.Fragments
+from nymbaron.Common import binsearch
+from nymbaron.Message import intToStrBE
+import nymbaron.Server.Config as Config
+import nymbaron.Mail as Mail
+import nymbaron.Crypto as Crypto
+import nymbaron.Message as Message
+
maxSynPerBlob = 16
# See nym-spec, § 4.4.3
@@ -81,24 +84,6 @@
return p.n * p.nChunks
-def binsearch(l, prop):
- """Returns the first index i of l for which l[i] is true,
- assuming prop is increasing over l"""
- min = 0
- max = len(l) - 1
- if not prop(l[max]): return IndexError
- if prop(l[min]): return min
-
- current = (max + min) / 2
- while max - min > 1:
- if prop(l[current]):
- max = current
- current = (max + min) / 2
- else:
- min = current
- current = (max + min) / 2
- return max
-
def check_surb(surb):
"""Returns True if the surb is usable, False if it was already used or is
out of date"""
More information about the Nym3-commit
mailing list