diff --git a/FPE/FlexPE.py b/FPE/FlexPE.py index f769d4c..698081c 100755 --- a/FPE/FlexPE.py +++ b/FPE/FlexPE.py @@ -15,16 +15,27 @@ class FlexPE: config = None destinations = [] interfaces = [] - configdir = os.path.expanduser("~")+"/.flexpe" - configpath = configdir+"/config" + configdir = os.path.expanduser("~")+"/.flexpe" + configpath = "" + storagepath = "" + cachepath = "" + + # TODO: Move this to Transport + packetlist = [] - packetlist = [] + def __init__(self,configdir=None): + if configdir != None: + FlexPE.configdir = configdir + + FlexPE.configpath = FlexPE.configdir+"/config" + FlexPE.storagepath = FlexPE.configdir+"/storage" + FlexPE.cachepath = FlexPE.configdir+"/storage/cache" - def __init__(self,config=None): - if config != None: - self.configpath = config - else: - self.configpath = FlexPE.configpath + if not os.path.isdir(FlexPE.storagepath): + os.makedirs(FlexPE.storagepath) + + if not os.path.isdir(FlexPE.cachepath): + os.makedirs(FlexPE.cachepath) if os.path.isfile(self.configpath): self.config = ConfigObj(self.configpath) @@ -34,6 +45,7 @@ class FlexPE: self.createDefaultConfig() self.applyConfig() + FPE.Identity.loadKnownDestinations() FlexPE.router = self @staticmethod @@ -41,23 +53,6 @@ class FlexPE: destination.MTU = FlexPE.MTU FlexPE.destinations.append(destination) - @staticmethod - def incoming(data): - packet_hash = FPE.Identity.fullHash(data) - - if not packet_hash in FlexPE.packetlist: - FlexPE.packetlist.append(packet_hash) - packet = FPE.Packet(None, data) - packet.unpack() - - if packet.packet_type == FPE.Packet.ANNOUNCE: - FPE.Identity.validateAnnounce(packet) - - if packet.packet_type == FPE.Packet.RESOURCE: - for destination in FlexPE.destinations: - if destination.hash == packet.destination_hash and destination.type == packet.destination_type: - destination.receive(packet.data) - @staticmethod def outbound(raw): for interface in FlexPE.interfaces: @@ -76,7 +71,7 @@ class FlexPE: try: if c["type"] == "UdpInterface": interface = UdpInterface.UdpInterface( - self, + FPE.Transport, c["listen_ip"], int(c["listen_port"]), c["forward_ip"], @@ -91,7 +86,7 @@ class FlexPE: if c["type"] == "SerialInterface": interface = SerialInterface.SerialInterface( - self, + FPE.Transport, c["port"], int(c["speed"]), int(c["databits"]), diff --git a/FPE/Identity.py b/FPE/Identity.py index f2a9960..33f7d8d 100644 --- a/FPE/Identity.py +++ b/FPE/Identity.py @@ -2,6 +2,9 @@ import base64 import math import os import FPE +import time +import atexit +import cPickle from cryptography.hazmat.primitives import hashes from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization @@ -19,9 +22,9 @@ class Identity: PADDINGSIZE= 336; # Storage - remembered_destinations = {} + known_destinations = {} - def __init__(self): + def __init__(self,public_only=False): # Initialize keys to none self.prv = None self.pub = None @@ -30,17 +33,36 @@ class Identity: self.hash = None self.hexhash = None - self.createKeys() + if not public_only: + self.createKeys() @staticmethod def remember(hash, public_key, app_data = None): FPE.log("Remembering "+FPE.hexrep(hash, False), FPE.LOG_VERBOSE) - Identity.remembered_destinations[hash] = [public_key, app_data] + Identity.known_destinations[hash] = [time.time(), public_key, app_data] @staticmethod def recall(identity): pass + @staticmethod + def saveKnownDestinations(): + FPE.log("Saving known destinations to storage...", FPE.LOG_VERBOSE) + file = open(FPE.FlexPE.storagepath+"/known_destinations","w") + cPickle.dump(Identity.known_destinations, file) + file.close() + FPE.log("Done saving known destinations to storage", FPE.LOG_VERBOSE) + + @staticmethod + def loadKnownDestinations(): + if os.path.isfile(FPE.FlexPE.storagepath+"/known_destinations"): + file = open(FPE.FlexPE.storagepath+"/known_destinations","r") + Identity.known_destinations = cPickle.load(file) + file.close() + FPE.log("Loaded "+str(len(Identity.known_destinations))+" known destinations from storage", FPE.LOG_VERBOSE) + else: + FPE.log("Destinations file does not exist, so no known destinations loaded", FPE.LOG_VERBOSE) + @staticmethod def fullHash(data): digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) @@ -69,7 +91,7 @@ class Identity: signed_data = destination_hash+public_key+random_hash+app_data - announced_identity = Identity() + announced_identity = Identity(public_only=True) announced_identity.loadPublicKey(public_key) if announced_identity.validate(signature, signed_data): @@ -219,3 +241,8 @@ class Identity: def getRandomHash(self): return self.truncatedHash(os.urandom(10)) + +def identityExithandler(): + Identity.saveKnownDestinations() + +atexit.register(identityExithandler) \ No newline at end of file diff --git a/FPE/Interfaces/SerialInterface.py b/FPE/Interfaces/SerialInterface.py index c816ed5..3c851b3 100755 --- a/FPE/Interfaces/SerialInterface.py +++ b/FPE/Interfaces/SerialInterface.py @@ -62,7 +62,7 @@ class SerialInterface(Interface): def processIncoming(self, data): - self.owner.__class__.incoming(data) + self.owner.inbound(data) def processOutgoing(self,data): diff --git a/FPE/Interfaces/UdpInterface.py b/FPE/Interfaces/UdpInterface.py index 3f8d0ac..bb29ad9 100755 --- a/FPE/Interfaces/UdpInterface.py +++ b/FPE/Interfaces/UdpInterface.py @@ -36,7 +36,7 @@ class UdpInterface(Interface): def processIncoming(self, data): - self.owner.__class__.incoming(data) + self.owner.inbound(data) def processOutgoing(self,data): udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) diff --git a/FPE/Transport.py b/FPE/Transport.py index f8d37c8..f474d1d 100755 --- a/FPE/Transport.py +++ b/FPE/Transport.py @@ -8,10 +8,29 @@ class Transport: TUNNEL = 0x03; types = [BROADCAST, TRANSPORT, RELAY, TUNNEL] + packet_hashlist = [] + @staticmethod def outbound(raw): FPE.FlexPE.outbound(raw) + @staticmethod + def inbound(raw): + packet_hash = FPE.Identity.fullHash(raw) + + if not packet_hash in Transport.packet_hashlist: + Transport.packet_hashlist.append(packet_hash) + packet = FPE.Packet(None, raw) + packet.unpack() + + if packet.packet_type == FPE.Packet.ANNOUNCE: + FPE.Identity.validateAnnounce(packet) + + if packet.packet_type == FPE.Packet.RESOURCE: + for destination in FlexPE.destinations: + if destination.hash == packet.destination_hash and destination.type == packet.destination_type: + destination.receive(packet.data) + @staticmethod def registerDestination(destination): FPE.FlexPE.addDestination(destination) \ No newline at end of file diff --git a/Notes/Header format b/Notes/Header format index 9b373a8..b0f8d39 100644 --- a/Notes/Header format +++ b/Notes/Header format @@ -3,7 +3,7 @@ header types type 1 00 One byte header, one 10 byte address field type 2 01 One byte header, two 10 byte address fields type 3 10 Reserved -type 4 11 Reserved +type 4 11 Reserved for extended packet format propagation types @@ -24,7 +24,7 @@ link 11 packet types ----------------- -message 00 -resource 01 +resource 00 +announce 01 link request 10 proof 11 diff --git a/t.py b/t.py index d7209b4..9014ce2 100755 --- a/t.py +++ b/t.py @@ -12,7 +12,7 @@ def testCallback(message, receiver): print("----------") -#fpe = FlexPE(config=os.path.expanduser("~")+"/.flexpe/config.test") +#fpe = FlexPE(configdir=os.path.expanduser("~")+"/.flexpe2") fpe = FlexPE() identity = Identity()