[Nym3-commit] r32 - trunk
nym3-devel@lists.noreply.org
nym3-devel@lists.noreply.org
Wed, 28 Jul 2004 18:12:14 +0200
Author: jr
Date: 2004-07-28 18:12:13 +0200 (Wed, 28 Jul 2004)
New Revision: 32
Modified:
trunk/message.py
Log:
commands from the client to the server :
the classes are implanted and we can build objects
from program data or from a string being read with StrReader.
it compiles but has not been tested
Todo : next things to be done in message.py
Modified: trunk/message.py
===================================================================
--- trunk/message.py 2004-07-27 09:55:49 UTC (rev 31)
+++ trunk/message.py 2004-07-28 16:12:13 UTC (rev 32)
@@ -1,4 +1,4 @@
-class BadMessage(Exception):
+class ParseError(Exception):
def __init__(self,value):
self.value=value
def __str__(self):
@@ -10,64 +10,387 @@
def __str__(self):
return repr(self.value)
-
+def strToIntBE(s):
+ """return the Int coded by the string s with the big endian convention"""
+ def aux(s,ac):
+ if(s == ""):
+ return ac
+ else:
+ return aux(s[1:],256*ac+ord(s[0]))
+ return aux(s,0)
+
+def intToStrBE(n,mod):
+ """return a string coding the n modulo 256^mod in big endian"""
+ def aux(n,ac,mod):
+ if(mod == 0):
+ return ac
+ else:
+ return aux(n/256,chr(n%256)+ac,mod-1)
+ return aux(n,"",mod)
+
+def isMsgIdList(l):
+ def isMsgId(e):
+ if(len(e)==20): # et son type str?
+ return True
+ else:
+ return False
+ lb=map(isMsgId,l)
+ if(reduce(lambda x,y : x and y,lb)):
+ return True
+ else:
+ return False
+
+surbLength = 2104
sigLength = 256
seqNoLength = 20
+msgIdLength = 20
class StrReader:
+ """wraps a string and gives method to read it chunk by chunk"""
def __init__(self,s):
+ """initialize by wrapping a string"""
self.s = s
self.a = 0
self.b = 0
- def sub(self):
- return self.s[self.a:self.b]
+ def isEnd(self):
+ return (b == len(s))
def next(self,n):
- self.a = self.b
+ """return the next n characters"""
+ if(n<0):
+ raise BadArgument("StrReader.next : n < 0")
+ self.a = self.b
self.b = self.b + n
+ return self.s[self.a:self.b]
+ def readHeader(self):
+ return Header.read(self)
+ def readCommandCToS(self):
+ try:
+ ct = ord(self.next(1))
+ cs = strToIntBE(self.next(3))
+ if (ct == 0):
+ a=Create()
+ elif (ct == 1):
+ a=Create2()
+ elif (ct == 2):
+ a=Surb()
+ elif (ct == 3):
+ a=Newpk()
+ elif (ct == 4):
+ a=Relay()
+ elif (ct == 5):
+ a=Get()
+ elif (ct == 6):
+ a=Summarize()
+ elif (ct == 7):
+ a=Delete()
+ elif (ct == 8):
+ a=Policy()
+ else:
+ raise ParseError("Undefined Command Type")
+ a.fromStrReader(self,cs)
+ return a
+ except IndexError:
+ raise ParseError("Bad Formed Command")
+ def readNym(self,start,cs):
+ nl = ord (self.next(1))
+ if(self.b + nl - start > cs):
+ raise ParseError("Bad Formed Command")
+ return self.next(nl)
+ def readNymList(self,start,cs):
+ try:
+ l = []
+ while(self.b < start + cs):
+ l.append(self.readNym(start,cs))
+ return l
+ except ParseError: #is it really necessary?
+ raise
+ def readMsgId(self,start,cs):
+ if(self.b + msgIdLength - start > cs):
+ raise ParseError("Bad Formed Command")
+ return self.next(msgIdLength)
+ def readMsgIdList(self,start,cs):
+ try:
+ l = []
+ while(self.b < start + cs):
+ l.append(self.readMsgId(start,cs))
+ return l
+ except ParseError: #is it really necessary?
+ raise
+
+class Header:
+ def __init__(self):
+ """Build a Header empty object"""
+ pass
+ def fromData(self,nym,seqNo,sig=""):
+ """Fill a Header Object from a nym and sequence number and sig if provided
+ sig : signature
+ nl : nym length
+ nym : nym
+ seqNo : sequence number which identifies the message
+ length : header length"""
+ if(len(seqNo) != seqNoLength):
+ raise BadArgument("Buildheader.__init__ : seqNo length doesn't match seqNoLength")
+ if(sig == ""):
+ self.sig = chr(0) * sigLength
+ else:
+ if(len(sig) != sigLength):
+ raise BadArgument("Buildheader.__init__ : sig length doesn't match sigLength")
+ self.nl = len(nym)
+ self.nym = nym
+ self.seqNo = seqNo
+ #self.length = sigLength + 1 + self.nl + seqNoLength
+ def __str__(self):
+ return self.sig + chr(self.nl) + self.nym + self.seqNo
+ def fromStrReader(self,sr):
+ """Fill a Header from a StrReader
+ sig : signature
+ nl : nym length
+ nym : nym
+ seqNo : sequence number which identifies the message
+ length : header length"""
+ try:
+ self.sig = sr.next(sigLength)
+ self.nl = ord(sr.next(1))
+ self.nym = sr.next(nl)
+ self.seqNo = sr.next(seqNoLength)
+ except IndexError:
+ raise ParseError("Header too short")
-class Header:
- def __str__(self):
- return self.sig + chr(self.nl) + self.nym + self.seqNo
+## class ReadHeader(Header):
+## def __init__(self,sr):
+## """builds a header from a StrReader
+## sig : signature
+## nl : nym length
+## nym : nym
+## seqNo : sequence number which identifies the message
+## length : header length"""
+## try:
+## self.sig = sr.next(sigLength)
+## self.nl = ord(sr.next(1))
+## self.nym = sr.next(nl)
+## self.seqNo = sr.next(seqNoLength)
+## self.length = sr.b
+## except IndexError:
+## raise ParseError("Parse Error : Header too short")
+
+## class BuiltHeader(Header):
+## def __init__(self,nym,seqNo):
+## """Builds a header from a nym and and sequence number
+## sig : signature
+## nl : nym length
+## nym : nym
+## seqNo : sequence number which identifies the message
+## length : header length"""
+## if(len(seqNo) != seqNoLength):
+## raise BadArgument("Buildheader.__init__ : seqNo length doesn't match seqNoLength")
+## self.sig = chr(0) * sigLength
+## self.nl = len(nym)
+## self.nym = nym
+## self.seqNo = seqNo
+## self.length = sigLength + 1 + self.nl + seqNoLength
-class ReadHeader(Header):
- def __init__(self,header):
- """builds a header from the beginning of a string
- sig : signature
- nl : nym length
- nym : nym
- seqNo : sequence number which identifies the message
- length : header length"""
- try:
- sr = StrReader(header)
- sr.next(sigLength)
- self.sig = sr.sub()
- sr.next(1)
- self.nl = ord(sr.sub())
- sr.next(nl)
- self.nym = sr.sub()
- sr.next(seqNoLength)
- self.seqNo = sr.sub()
- self.length = sr.b
- except IndexError:
- raise BadMessage("Bad formed message : header too short")
-
-class BuiltHeader(Header):
- def __init__(self,nym,seqNo):
- """Builds a header from a nym and and sequence number
- sig : signature
- nl : nym length
- nym : nym
- seqNo : sequence number which identifies the message
- length : header length"""
- if(len(seqNo) != seqNoLength):
- raise BadArgument("Buildheader.__init__ : seqNo length doesn't match seqNoLength")
- self.sig = chr(0) * sigLength
- self.nl = len(nym)
- self.nym = nym
- self.seqNo = seqNo
- self.length = sigLength + 1 + self.nl + seqNoLength
-
-
-H= BuiltHeader("JR","01234567890123456789")
+class CommandCToS:
+ pass
+
+class Create(CommandCToS):
+ """Create command"""
+ def __init__(self):
+ """Build a Create empty object"""
+ pass
+ def fromData(self,l,pw=""):
+ """Fill a Create Object from a list of nyms and a proof of work"""
+ self.list=l
+ self.pw=pw
+ def fromStrReader(self,sr,cs):
+ """Fill a Create command from a StrReader
+ raise ParseError if it is malformed"""
+ start=sr.b
+ nNym = ord(sr.next(1))
+ self.pW = "" #what is a proof of work?
+ try:
+ self.nymList = sr.readNymList(start,cs)
+ except ParseError:
+ raise ParseError("Bad Formed Command : Create")
+ #nNym is redundant, we use it to make sure the message is well formed
+ if(nNym != len(self.nymList)):
+ raise ParseError("Bad Formed Command : Create")
+
+
+class Create2(CommandCToS):
+ """Create2 command"""
+ def __init__(self):
+ """Build a Create2 empty object"""
+ pass
+ def fromData(self,cr):
+ """Fill Create2 from a string containing the response to a challenge"""
+ self.cr=cr
+ def fromStrReader(self,sr,cs):
+ """Fill a Create2 command from a StrReader
+ raise ParseError if it is malformed"""
+ self.cr=sr.next(cs)
+
+class Surb(CommandCToS):
+ """Surb command"""
+ def __init__(self):
+ """Build a Surb empty object"""
+ pass
+ def fromData(self,s):
+ """Fill a Surb Object from a string containing Surbs"""
+ self.surbs=s
+ def fromStrReader(self,sr,cs):
+ """Fill a Surb Object from a StrReader
+ raise ParseError if it is malformed"""
+ if(cs%surbLength != 0):
+ raise ParseError("Bad Formed Command : Surb")
+ self.surbs=sr.next(cs)
+
+class Newpk(CommandCToS):
+ """Newpk command"""
+ def __init__(self):
+ """Build a Newpk empty object"""
+ pass
+ def fromData(self,sid,senc):
+ """Fill a Newpk Object from 2 strings containing an ASN-1 encoded RSA key"""
+ self.kid=sid
+ self.kenc=senc
+ def fromStrReader(self,sr,cs):
+ """Fill a Newpk Object from a StrReader
+ raise ParseError if it is malformed"""
+ try:
+ id_l=strToIntBE(sr.next(2))
+ if( (id_l != 128) and (id_l != 256)):
+ raise ParseError("Bad Formed Command : Newpk")
+ idl_2=cs-2-id_l
+ if( (id_l2 != 128) and (id_l2 != 256)):
+ raise ParseError("Bad Formed Command : Newpk")
+ self.kid=sr.next(id_l)
+ self.kenc=sr.next(id_l2)
+ except IndexError:
+ raise ParseError("Bad Formed Command : Newpk")
+class Relay(CommandCToS):
+ """Relay command"""
+ def __init__(self):
+ """Build a Relay empty object"""
+ pass
+ def fromData(self,rt,ri,body):
+ """Fill a Relay Object from a 3 strings : routing type(2 octets) routing info and body"""
+ if(len(rt) !=2):
+ raise BadArgument("Relay.fromData : RT size isn't 2 bytes")
+ self.rt=rt
+ self.rs=len(ri)
+ self.ri=ri
+ self.body=body
+ def fromStrReader(self,sr,cs):
+ """Fill a Relay Object from a StrReader
+ raise ParseError if it is malformed"""
+ try:
+ self.rs=strToIntBE(sr.next(2))
+ self.rt=sr.next(2)
+ self.ri=sr.next(self.rs)
+ self.body=sr.next(cs-4-self.rs)
+ except (BadArgument, IndexError):
+ raise ParseError("Bad Formed Command : Relay")
+
+class Get(CommandCToS):
+ """Get command"""
+ def __init__(self):
+ """Build a Get empty object"""
+ pass
+ def fromData(self,li):
+ """Fill a Get Object from a list of message id (=string of len 20)"""
+ #check that each element of the list has 20 bytes
+ if( not isMsgIdList(li)):
+ raise BadArgument("Get.fromData : li is not a list of message id")
+ self.l=li
+ def fromStrReader(self,sr,cs):
+ """Fill a Get Object from a StrReader
+ raise ParseError if it is malformed"""
+ start=sr.b
+ try:
+ self.l=sr.readMsgIdList(self,start,cs)
+ except (ParseError,IndexError):
+ raise ParseError("Bad Formed Command : Get")
+
+class Summarize(CommandCToS):
+ """Summarize command"""
+ def __init__(self):
+ """Build a Summarize empty object"""
+ pass
+ def fromData(self,n,m):
+ """Fill a Summarize Object from the max number of synopsis to retrieve (int) and the message id of a message older than the messages we want the synopsis from (string of len 20)
+ the int is considered modulo 256^2"""
+ n_mod=n % (256*256)
+ self.num=n_mod
+ if(len(m)!=msgIdLength): # or m is not a str
+ raise BadArgument(" Summarize.fromData : m is not a valid message ID")
+ self.after=m
+ def fromStrReader(self,sr,cs):
+ """Fill a Summarize Object from a StrReader
+ raise ParseError if it is malformed"""
+ if(cs != 2+msgIdLength):
+ raise ParseError("Bad Formed Command : Summarize")
+ try:
+ self.num=strToIntBE(sr.next(2))
+ self.after=sr.next(msgIdLength)
+ except IndexError:
+ raise ParseError("Bad Formed Command : Summarize")
+
+class Delete(CommandCToS):
+ """Delete command"""
+ def __init__(self):
+ """Build a Delete empty object"""
+ pass
+ def fromData(self,):
+ """Fill a Delete Object from a list of message ID (string of length msgIdLength"""
+ #check that each element of the list has 20 bytes
+ if( not isMsgIdList(li)):
+ raise BadArgument("Delete.fromData : li is not a list of message id")
+ self.l=li
+ def fromStrReader(self,sr,cs):
+ """Fill a Delete Object from a StrReader
+ raise ParseError if it is malformed"""
+ start=sr.b
+ try:
+ self.l=sr.readMsgIdList(self,start,cs)
+ except (ParseError,IndexError):
+ raise ParseError("Bad Formed Command : Delete")
+
+class Policy(CommandCToS):
+ """Policy command"""
+ def __init__(self):
+ """Build a Policy empty object"""
+ pass
+ def fromData(self,opt,val):
+ """Fill a Policy Object from 2 str : the option name and its value
+ It is the caller work to convert adequatly into a string the value he wants to be sent"""
+ #do we check the option names' validity?
+ self.opt=opt
+ self.val=val
+ def fromStrReader(self,sr,cs):
+ """Fill a Policy Object from a StrReader
+ raise ParseError if it is malformed"""
+ try:
+ le=ord(sr.next(1))
+ self.opt=sr.next(le)
+ self.val=sr.next(cs-1-le)
+ except (IndexError,BadArgument):
+ raise ParseError("Bad Formed Command : Policy")
+
+#empty class will be used as a framework fo CommandSToC classes
+class Frame(CommandCToS):
+ """command"""
+ def __init__(self):
+ """Build a empty object"""
+ pass
+ def fromData(self,):
+ """Fill a Object from """
+ def fromStrReader(self,sr,cs):
+ """Fill a Object from a StrReader
+ raise ParseError if it is malformed"""
+
+
+H= Header()
+H.fromData("JR","01234567890123456789")
print H
+del H