More refactoring and filling out

This commit is contained in:
Samuel M Smith 2014-02-08 19:00:54 -07:00
parent 149186e07a
commit 8890668d11
8 changed files with 496 additions and 192 deletions

View File

@ -212,7 +212,7 @@ class ServerRaet(deeding.ParamDeed): # pylint: disable=W0232
'''
Set up server to transmit and recive on address
'''
connection.value = aiding.SocketNB(host=address.data.host, port=address.data.port)
connection.value = aiding.SocketUdpNb(host=address.data.host, port=address.data.port)
connection.value.reopen() # create socket connection
host, port = connection.value.ha
address.update(host=host, port=port, ha=(host, port))

View File

@ -17,106 +17,110 @@ except ImportError:
from ioflo.base.odicting import odict
from ioflo.base.aiding import packByte, unpackByte
from salt.transport import table
from . import raeting
class Stack(object):
''' RAET protocol stack object'''
def __init__(self):
''' Setup Stack instance'''
self.devices = odict() #devices managed by this stack
class Device(object):
''' RAET protocol endpoint device object'''
def __init__(self, did=0, stack=None, host='', port=raeting.RAET_PORT):
''' Setup Device instance'''
self.did = did # device id
self.stack = stack # Stack object that manages this device
self.host = socket.gethostbyname(host)
self.port = port
@property
def ha(self):
'''ha property that returns ip address (host, port) tuple'''
return (self.host, self.port)
from . import stacking
class Part(object):
'''
Base class for parts of a RAET packet
Should be subclassed
'''
def __init__(self, packet=None, kind=None, length=None, **kwa):
''' Setup Part instance '''
def __init__(self, packet=None, kind=None, **kwa):
'''
Setup Part instance
'''
self.packet = packet # Packet this Part belongs too
self.kind = kind # part kind
self.length = length # specified length of part not computed length
self.packed = ''
def __len__(self):
''' Return the size property '''
return self.size
'''
Returns the length of .packed
'''
return len(self.packed)
@property
def size(self):
''' size property returns the length of the .packed of this Part'''
return len(self.packed)
'''
Property is the length of this Part
'''
return self.__len__()
class Head(Part):
'''
RAET protocol packet header object
RAET protocol packet header class
Manages the header portion of a packet
'''
def __init__(self, **kwa):
''' Setup Head instance'''
'''
Setup Head instance
'''
super(Head, self).__init__(**kwa)
self.data = odict(raeting.HEAD_DEFAULTS) #ensures correct order
class TxHead(Head):
'''
RAET protocl transmit packet header class
'''
def pack(self):
''' Composes and returns .packed, which is the packed form of this part '''
'''
Composes and returns .packed, which is the packed form of this part
'''
self.packed = ''
self.data = odict(raeting.HEAD_DEFAULTS) # refresh
self.data['vn'] = self.packet.version
self.data['pk'] = self.packet.kind
self.kind= self.packet.data['hk']
data = self.packet.data # for speed
self.data['cf'] = self.packet.crdrFlag
self.data['mf'] = self.packet.multFlag
self.data['bf'] = self.packet.brstFlag
self.data['pf'] = self.packet.pendFlag
self.data['af'] = self.packet.allFlag
data['pk'] = self.packet.kind
data['nk'] = self.packet.neck.kind
data['nl'] = self.packet.neck.size
data['bk'] = self.packet.body.kind
data['bl'] = self.packet.body.size
data['tk'] = self.packet.tail.kind
data['tl'] = self.packet.tail.size
self.data['nk'] = self.packet.neck.kind
self.data['nl'] = self.packet.neck.size
self.data['bk'] = self.packet.body.kind
self.data['bl'] = self.packet.body.size
self.data['tk'] = self.packet.tail.kind
self.data['tl'] = self.packet.tail.size
self.data['fg'] = "{:02x}".format(self.packFlags())
data['fg'] = "{:02x}".format(self.packFlags())
# kit always includes header kind and length fields
kit = odict([('hk', self.kind), ('hl', 0)])
for k, v in raeting.HEAD_DEFAULTS.items():# include if not equal to default
if (self.data[k] != v) and (k not in raeting.PACKET_FLAGS ):
kit[k] = self.data[k]
for k, v in raeting.PACKET_DEFAULTS.items():# include if not equal to default
if ( (k in raeting.HEAD_FIELDS) and
(k not in raeting.PACKET_FLAGS ) and
(data[k] != v)):
kit[k] = data[k]
if self.kind == raeting.headKinds.json:
kit['hl'] = '00' # need hex string so fixed length and jsonable
packed = json.dumps(kit, separators=(',', ':'), encoding='ascii',)
packed = '{0}{1}'.format(packed, raeting.JSON_END)
self.length = len(packed)
if self.length > raeting.MAX_HEAD_LEN:
hl = len(packed)
if hl > raeting.MAX_HEAD_LEN:
self.packet.error = "Head length of {0}, exceeds max of {1}".format(hl, MAX_HEAD_LEN)
return self.packed
#subsitute true length converted to 2 byte hex string
self.packed = packed.replace('"hl":"00"', '"hl":"{0}"'.format("{0:02x}".format(self.length)[-2:]), 1)
self.packed = packed.replace('"hl":"00"', '"hl":"{0}"'.format("{0:02x}".format(hl)[-2:]), 1)
return self.packed
def packFlags(self):
'''
Packs all the flag fields into a single two char hex string
'''
values = []
for field in raeting.PACKET_FLAG_FIELDS:
values.append(1 if self.data.get(field, 0) else 0)
return packByte(format='11111111', fields=values)
class RxHead(Head):
'''
RAET protocl receive packet header class
'''
def parse(self, rest):
'''
Parses and removes head from packed rest and returns remainder
'''
self.packed = ''
self.data = odict(raeting.HEAD_DEFAULTS) # refresh
if rest.startswith('{"hk":1,') and raeting.JSON_END in rest: # json header
self.kind = raeting.headKinds.json
front, sep, back = rest.partition(raeting.JSON_END)
@ -133,8 +137,8 @@ class Head(Part):
self.packet.error = 'Recognized head kind does not match head field value.'
return rest
self.length = int(self.data['hl'], 16)
if self.length != self.size:
hl = int(self.data['hl'], 16)
if hl != self.size:
self.packet.error = 'Actual head length does not match head field value.'
else: # notify unrecognizible packet head
@ -143,41 +147,59 @@ class Head(Part):
return rest
def packFlags(self):
''' Packs all the flag fields into a single two char hex string '''
values = []
for field in raeting.PACKET_FLAG_FIELDS:
values.append(1 if self.data.get(field, 0) else 0)
return packByte(format='11111111', fields=values)
def unpackFlags(self, flags):
''' Unpacks all the flag fields from a single two char hex string '''
'''
Unpacks all the flag fields from a single two char hex string
'''
values = unpackByte(format='11111111', byte=int(flags, 16), boolean=False)
for i, field in enumerate(raeting.PACKET_FLAG_FIELDS):
if field in self.data:
self.data[field] = values[i]
class Neck(Part):
'''
RAET protocol packet neck object
RAET protocol packet neck class
Manages the signing or authentication of the packet
'''
def __init__(self, **kwa):
''' Setup Neck instance'''
'''
Setup Neck instance
'''
super(Neck, self).__init__(**kwa)
class TxNeck(Neck):
'''
RAET protocol transmit packet neck class
'''
def pack(self):
''' Composes and returns .packed, which is the packed form of this part '''
'''
Composes and returns .packed, which is the packed form of this part
'''
self.packed = ''
if self.kind == raeting.neckKinds.nada:
self.kind= self.packet.data['nk']
if self.kind not in raeting.NECK_KIND_NAMES:
self.kind = raeting.neckKinds.unknown
self.packet.error = "Unrecognizible packet neck."
return self.packed
if self.kind == raeting.neckKinds.nacl:
self.packed = "".rjust(raeting.neckSizes.nacl, '\x00')
elif self.kind == raeting.neckKinds.nada:
pass
return self.packed
class RxNeck(Neck):
'''
RAET protocol receive packet neck class
'''
def parse(self, rest):
''' Parses and removes neck from rest and returns rest '''
'''
Parses and removes neck from rest and returns rest
'''
self.packed = ''
self.kind = self.packet.head.data['nk']
@ -186,9 +208,9 @@ class Neck(Part):
self.packet.error = "Unrecognizible packet neck."
return rest
self.length = self.packet.head.data['nl']
self.packed = rest[:self.length]
rest = rest[self.length:]
nl = self.packet.head.data['nl']
self.packed = rest[:nl]
rest = rest[nl:]
if self.kind == raeting.neckKinds.nada:
pass
@ -196,23 +218,39 @@ class Neck(Part):
class Body(Part):
'''
RAET protocol packet body object
RAET protocol packet body class
Manages the messsage portion of the packet
'''
def __init__(self, data=None, **kwa):
''' Setup Body instance'''
'''
Setup Body instance
'''
super(Body, self).__init__(**kwa)
self.data = data or odict()
class TxBody(Body):
'''
RAET protocol tx packet body class
'''
def pack(self):
''' Composes and returns .packed, which is the packed form of this part'''
'''
Composes and returns .packed, which is the packed form of this part
'''
self.packed = ''
self.kind= self.packet.data['bk']
if self.kind == raeting.bodyKinds.json:
self.packed = json.dumps(self.data, separators=(',', ':'))
return self.packed
class RxBody(Body):
'''
RAET protocol rx packet body class
'''
def parse(self, rest):
''' Parses and removes head from rest and returns rest '''
'''
Parses and removes head from rest and returns rest
'''
self.packed = ''
self.kind = self.packet.head.data['bk']
@ -221,13 +259,13 @@ class Body(Part):
self.packet.error = "Unrecognizible packet body."
return rest
self.length = self.packet.head.data['bl']
self.packed = rest[:self.length]
rest = rest[self.length:]
bl = self.packet.head.data['bl']
self.packed = rest[:bl]
rest = rest[bl:]
self.data = odict()
if self.kind == raeting.bodyKinds.json:
if self.length:
if bl:
kit = json.loads(self.packed, object_pairs_hook=odict)
if not isinstance(kit, Mapping):
self.packet.error = "Packet body not a mapping."
@ -241,24 +279,37 @@ class Body(Part):
class Tail(Part):
'''
RAET protocol packet tail object
Manages the verification of the body portion of the packet
RAET protocol packet tail class
Supports encrypt/decrypt or other validation of body portion of packet
'''
def __init__(self, **kwa):
''' Setup Tail instal'''
super(Tail, self).__init__(**kwa)
class TxTail(Tail):
'''
RAET protocol tx packet tail class
'''
def pack(self):
'''
Composes and returns .packed, which is the packed form of this part
'''
self.packed = ''
self.kind= self.packet.data['tk']
if self.kind == raeting.tailKinds.nada:
pass
return self.packed
class RxTail(Tail):
'''
RAET protocol rx packet tail class
'''
def parse(self, rest):
''' Parses and removes tail from rest and returns rest '''
'''
Parses and removes tail from rest and returns rest
'''
self.packed = ''
self.kind = self.packet.head.data['tk']
@ -267,9 +318,9 @@ class Tail(Part):
self.packet.error = "Unrecognizible packet tail."
return rest
self.length = self.packet.head.data['tl']
self.packed = rest[:self.length]
rest = rest[self.length:]
tl = self.packet.head.data['tl']
self.packed = rest[:tl]
rest = rest[tl:]
if self.kind == raeting.tailKinds.nada:
pass
@ -277,70 +328,109 @@ class Tail(Part):
return rest
class Packet(object):
''' RAET protocol packet object '''
def __init__(self, stack=None, version=None, kind=None,
sh='', sp=raeting.RAET_PORT,
dh='127.0.0.1', dp=raeting.RAET_PORT,
body=None, data=None, raw=None):
'''
RAET protocol packet object
'''
def __init__(self, stack=None, kind=None, local=None, remote=None):
''' Setup Packet instance. Meta data for a packet. '''
self.stack = stack # stack that handles this packet
self.version = version or raeting.HEAD_DEFAULTS['vn']
self.kind = kind or raeting.HEAD_DEFAULTS['pk']
self.src = Device(host=sh, port=sp) # source device
self.dst = Device(host=dh, port=dp) # destination device
self.head = Head(packet=self)
self.neck = Neck(packet=self)
self.body = Body(packet=self, data=body)
self.tail = Tail(packet=self)
self.kind = kind or raeting.PACKET_DEFAULTS['pk']
if not local and self.stack:
local = self.stack.device
self.local = local or stacking.LocalDevice(stack=self.stack) # source device
self.remote = remote or stacking.RemoteDevice(stack=self.stack) # destination device
self.packed = '' #packed string
self.error = ''
if data:
self.load(data)
if raw:
self.parse(raw)
self.data = odict(raeting.PACKET_DEFAULTS)
@property
def size(self):
''' size property returns the length of the .packed of this Packet'''
'''
Property is the length of the .packed of this Packet
'''
return len(self.packed)
def load(self, data=None):
''' Loud up attributes of parts if provided '''
data = data or odict()
raeting.updateMissing(data, raeting.PACKET_DEFAULTS)
self.version = data['vn']
self.crdrFlag = data['cf']
self.multFlag = data['mf']
self.brstFlag = data['bf']
self.pendFlag = data['pf']
self.allFlag = data['af']
self.src.did = data['sd']
self.src.host = data['sh']
self.src.port = data['sp']
self.dst.did = data['dd']
self.dst.host = data['dh']
self.dst.port = data['dp']
self.head.kind=data['hk']
self.neck.kind=data['nk']
self.body.kind=data['bk']
self.tail.kind=data['tk']
def refresh(self, data=None):
'''
Refresh .data to defaults and update if data
'''
self.data = odict(raeting.PACKET_DEFAULTS)
if data:
self.data.update(data)
return self # so can method chain
class TxPacket(Packet):
'''
RAET Protocol Transmit Packet object
'''
def __init__(self, embody=None, data=None, **kwa):
'''
Setup TxPacket instance
'''
super(TxPacket, self).__init__(**kwa)
self.head = TxHead(packet=self)
self.neck = TxNeck(packet=self)
self.body = TxBody(packet=self, data=embody)
self.tail = TxTail(packet=self)
if data:
self.data.update(data)
if embody and data:
self.pack()
def pack(self):
''' pack the parts of the packet and then the full packet'''
'''
Pack the parts of the packet and then the full packet
'''
self.error = ''
self.body.pack()
self.tail.pack()
self.head.pack()
self.neck.pack()
self.head.pack()
self.packed = '{0}{1}{2}{3}'.format(self.head.packed, self.neck.packed, self.body.packed, self.tail.packed)
self.sign()
return self.packed
def sign(self):
'''
Sign .packed using neck
'''
return True
class RxPacket(Packet):
'''
RAET Protocol Receive Packet object
'''
def __init__(self, raw=None, **kwa):
'''
Setup RxPacket instance
'''
super(RxPacket, self).__init__(**kwa)
self.head = RxHead(packet=self)
self.neck = RxNeck(packet=self)
self.body = RxBody(packet=self)
self.tail = RxTail(packet=self)
if raw:
self.parse(raw)
def parse(self, raw):
''' Parses raw packet '''
'''
Parses raw packet
'''
self.error = ''
rest = self.head.parse(raw)
if self.head.data['vn'] not in raeting.VERSIONS.values():
self.error = ("Received incompatible version '{0}'"
"version '{1}'".format(self.head.data['vn']))
return
#self.version = self.head.data['vn']
self.crdrFlag = self.head.data['cf']
self.bcstFlag = self.head.data['bf']
self.scdtFlag = self.head.data['sf']
self.pendFlag = self.head.data['pf']
self.allFlag = self.head.data['af']
rest = self.neck.parse(rest)
if not self.vouch():
return
@ -351,14 +441,15 @@ class Packet(object):
return rest
def vouch(self):
''' Uses signature in neck to vouch for (authenticate) packet '''
return True
def verify(self):
''' Uses tail to verify body does not have errors '''
'''
Uses signature in neck to verify (authenticate) packet
'''
return True
def validate(self):
'''
Uses tail to validate body
'''
return True

View File

@ -39,14 +39,14 @@ header data =
sd: Source Device ID (SDID)
dd: Destination Device ID (DDID)
cf: Corresponder Flag (CrdrFlag) Default 0
mf: Multicast Flag (MultFlag) Default 0
bf: BroadCast Flag (BcstFlag) Default 0
si: Session ID (SID) Default 0
ti: Transaction ID (TID) Default 0
sk: Service Kind (SrvcKind)
pk: Packet Kind (PcktKind)
bf: Burst Flag (BrstFlag) Default 0
Send segments or ordered packets without waiting for interleaved acks
sf: Succedent Flag (ScdtFlag) Default 0
Send segments or ordered packets without waiting for interleafed acks
oi: order index (OrdrIndx) Default 0
dt: Datetime Stamp (Datetime) Default 0
@ -69,7 +69,7 @@ header data =
tl: tail length (TailLen) Default 0
fg: flags packed (Flags) Default '00' hs
2 char Hex string with bits (0, 0, af, pf, 0, bf, mf, cf)
2 char Hex string with bits (0, 0, af, pf, 0, sf, bf, cf)
Zeros are TBD flags
}
@ -108,14 +108,16 @@ headKinds = HeadKind(**HEAD_KINDS) # headKinds.json is '00'
VERSIONS = odict([('0.1', 0)])
VERSION_NAMES = odict((v, k) for k, v in VERSIONS.iteritems())
NECK_KINDS = odict([('nada', 0), ('sodium', 1), ('sha2', 2),
VERSION = VERSIONS.values()[0]
NECK_KINDS = odict([('nada', 0), ('nacl', 1), ('sha2', 2),
('crc64', 2), ('unknown', 255)])
NECK_KIND_NAMES = odict((v, k) for k, v in NECK_KINDS.iteritems()) # inverse map
NeckKind = namedtuple('NeckKind', NECK_KINDS.keys())
neckKinds = NeckKind(**NECK_KINDS)
# bytes
NECK_SIZES = odict([('nada', 0), ('sodium', 0), ('sha2', 0),
NECK_SIZES = odict([('nada', 0), ('nacl', 64), ('sha2', 0),
('crc64', 8), ('unknown', 0)])
NeckSize = namedtuple('NeckSize', NECK_SIZES.keys())
neckSizes = NeckSize(**NECK_SIZES)
@ -131,7 +133,8 @@ TailKind = namedtuple('TailKind', TAIL_KINDS.keys())
tailKinds = TailKind(**TAIL_KINDS)
# bytes
TAIL_SIZES = odict([('nada', 0), ('crc16', 2), ('crc64', 8), ('unknown', 0)])
TAIL_SIZES = odict([('nada', 0), ('nacl', 16), ('crc16', 2), ('crc64', 8),
('unknown', 0)])
TailSize = namedtuple('TailSize', TAIL_SIZES.keys())
tailSizes = TailSize(**TAIL_SIZES)
@ -149,44 +152,49 @@ packetKinds = PacketKind(**PACKET_KINDS)
# head fields that may be included in json header if not default value
HEAD_DEFAULTS = odict([
('hk', 0),
('hl', 0),
('vn', 0),
('sd', 0),
('dd', 0),
('cf', 0),
('mf', 0),
('si', 0),
('ti', 0),
('sk', 0),
('pk', 0),
('bf', 0),
('oi', 0),
('dt', 0),
('sn', 0),
('sc', 1),
('pf', 0),
('af', 0),
('nk', 0),
('nl', 0),
('bk', 0),
('bl', 0),
('tk', 0),
('tl', 0),
('fg', '00'),
])
PACKET_DEFAULTS = odict([
('sh', ''),
('sp', 7530),
('dh', '127.0.0.1'),
('dp', 7530),
])
PACKET_DEFAULTS.update(HEAD_DEFAULTS)
('hk', 0),
('hl', 0),
('vn', 0),
('sd', 0),
('dd', 0),
('cf', 0),
('bf', 0),
('si', 0),
('ti', 0),
('sk', 0),
('pk', 0),
('sf', 0),
('oi', 0),
('dt', 0),
('sn', 0),
('sc', 1),
('pf', 0),
('af', 0),
('nk', 0),
('nl', 0),
('bk', 0),
('bl', 0),
('tk', 0),
('tl', 0),
('fg', '00'),
])
PACKET_FLAGS = ['af', 'pf', 'bf', 'mf', 'cf']
PACKET_FLAG_FIELDS = ['', '', 'af', 'pf', '', 'bf', 'mf', 'cf']
PACKET_FIELDS = [ 'sh', 'sp', 'dh', 'dp',
'hk', 'hl', 'vn', 'sd', 'dd', 'cf', 'bf', 'si', 'ti', 'sk', 'pk',
'sf', 'oi', 'dt', 'sn', 'sc', 'pf', 'af',
'nk', 'nl', 'bk', 'bl', 'tk', 'tl', 'fg']
HEAD_FIELDS = [ 'hk', 'hl', 'vn', 'sd', 'dd', 'cf', 'bf', 'si', 'ti', 'sk', 'pk',
'sf', 'oi', 'dt', 'sn', 'sc', 'pf', 'af',
'nk', 'nl', 'bk', 'bl','tk', 'tl', 'fg']
PACKET_FLAGS = ['af', 'pf', 'sf', 'bf', 'cf']
PACKET_FLAG_FIELDS = ['', '', 'af', 'pf', '', 'sf', 'bf', 'cf']
def defaultData(data=None):

View File

@ -4,8 +4,8 @@ stacking.py raet protocol stacking classes
'''
# Import python libs
from collections import deque
import socket
from collections import deque, namedtuple, Mapping
try:
import simplejson as json
except ImportError:
@ -13,11 +13,184 @@ except ImportError:
# Import ioflo libs
from ioflo.base.odicting import odict
from ioflo.base.globaling import *
from ioflo.base import aiding
from ioflo.base import storing
from ioflo.base import deeding
from salt.transport.table.public import pynacl
from . import raeting
from . import nacling
from ioflo.base.consoling import getConsole
console = getConsole()
class Stack(object):
'''
RAET protocol stack object
'''
def __init__( self,
version=raeting.VERSION,
device=None, ha=("", raeting.RAET_PORT)):
'''
Setup Stack instance
'''
self.version = version
# local device for this stack
self.device = device or Device(stack=self, ha=ha)
# remote devices attached to this stack
self.devices = odict()
self.transactions = odict() #transactions
self.serverUdp = aiding.SocketUdpNb(ha=self.device.ha)
self.serverUdp.reopen() # open socket
class Device(object):
'''
RAET protocol endpoint device object
'''
Did = 0 # class attribute
def __init__( self, stack=None, did=None, sid=0, tid=0,
host="", port=raeting.RAET_PORT, ha=None, ):
'''
Setup Device instance
'''
self.stack = stack # Stack object that manages this device
if did is None:
did = Device.Did
Device.Did += 1
self.did = did # device ID
self.sid = sid # current session ID
self.tid = tid # current transaction ID
if ha: #takes precendence
host, port = ha
self.host = socket.gethostbyname(host)
self.port = port
@property
def ha(self):
'''
property that returns ip address (host, port) tuple
'''
return (self.host, self.port)
def nextSid(self):
'''
Generates next session id number.
'''
self.sid += 1
if (self.sid > 0xffffffffL):
self.sid = 1 # rollover to 1
return self.sid
def nextTid(self):
'''
Generates next session id number.
'''
self.tid += 1
if (self.tid > 0xffffffffL):
self.tid = 1 # rollover to 1
return self.tid
class LocalDevice(Device):
'''
RAET protocol endpoint local device object
Maintains signer for signing and privateer for encrypt/decript
'''
def __init__(self, signkey=None, prikey=None, **kwa):
'''
Setup Device instance
signkey is either nacl SigningKey or hex encoded key
prikey is either nacl PrivateKey or hex encoded key
'''
super(LocalDevice, self).__init__(**kwa)
self.signer = nacling.Signer(signkey)
self.privateer = nacling.Privateer(key)
class RemoteDevice(Device):
'''
RAET protocol endpoint remote device object
Maintains verifier for verifying signatures and publican for encrypt/decript
'''
def __init__(self, verikey=None, pubkey=None, **kwa):
'''
Setup Device instance
verikey is either nacl VerifyKey or hex encoded key
pubkey is either nacl PublicKey or hex encoded key
'''
if 'host' not in kwa and 'ha' not in kwa:
kwa['ha'] = ('127.0.0.1', raeting.RAET_PORT)
super(LocalDevice, self).__init__(**kwa)
self.verifier = nacling.Verifier(verikey)
self.publican = nacling.Publican(pubkey)
class Transaction(object):
'''
RAET protocol transaction class
'''
def __init__(self, stack=None, kind=None, sdid=None, ddid=None,
crdr=None, bcst=False, sid=None, tid=None, ):
'''
Setup Transaction instance
'''
self.stack = stack
self.kind = kind or raeting.PACKET_DEFAULTS['sk']
self.sdid = sdid
self.ddid = ddid
self.crdr = crdr
self.bcst = bcst
self.sid = sid
self.tid = tid
def start(self):
return None # next packet or None
class Initiator(Transaction):
'''
RAET protocol initiator transaction class
'''
def __init__(self, sdid=None, crdr=False, **kwa):
'''
Setup Transaction instance
'''
if sdid is None:
sdid = self.stack.device.did
crdr = False # force crdr to False
super(Initiator, self).__init__(sdid, crdr, **kwa)
class Corresponder(Transaction):
'''
RAET protocol corresponder transaction class
'''
def __init__(self, ddid=None, crdr=True, **kwa):
'''
Setup Transaction instance
'''
if ddid is None:
ddid = self.stack.device.did
crdr = True # force crdr to True
super(Corresponder, self).__init__(ddid, crdr, **kwa)
class Join(Initiator):
'''
RAET protocol Join transaction class
'''
def __init__(self, ddid=None, **kwa):
'''
Setup Transaction instance
'''
if ddid is None:
ddid = self.stack.devices.values()[0].did # first is channel master
super(Initiator, self).__init__(ddid, **kwa)
def start(self)
'''
Build first packet
'''
return None

View File

@ -185,6 +185,12 @@ class Public(object):
'''
return self._key.sign(msg)
def signature(self, msg):
'''
Return only the signature string resulting from signing the message
'''
return self._key.signature(msg)
def verify(self, signed):
'''
Verify that the signed message is valid

View File

@ -135,6 +135,15 @@ class Key(object):
sig = self.sign_key.sign(hash_)
return sig + msg
def signature(self, msg):
'''
Return only signature string resulting from signing the msg
'''
hash_ = Crypto.Hash.SHA.new()
hash_.update(msg)
sig = self.sign_key.sign(hash_)
return sig
def verify(self, msg):
'''
Verify a message

View File

@ -104,6 +104,12 @@ class Key(object):
'''
return self.sign_key.sign(msg)
def signature(self, msg):
'''
Return only the signature string resulting from signing the message
'''
return self.sign(msg).signature
def verify(self, msg):
'''
Verify the message

View File

@ -4,20 +4,31 @@ Tests to try out table. Potentially ephemeral
'''
import json
from salt.transport import table
def test_table():
bob_pub = table.Public()
print bob_pub.backend
print bob_pub.sec_backend
print bob_pub.keydata
print bob_pub.public
print bob_pub.secret
print json.dumps(bob_pub.keydata, indent=2)
#print bob_pub.backend
#print bob_pub.sec_backend
#print bob_pub.public
#print bob_pub.secret
signed = bob_pub.sign("What have we here.")
print type(signed)
print len(signed.message)
print len(signed.signature)
print type(signed.signature)
print signed.message
print signed.signature
print signed
signature = bob_pub.signature("What have we here.")
print signature
print signature == signed.signature
if __name__ == "__main__":