diff --git a/LXMF/LXMPeer.py b/LXMF/LXMPeer.py index aee5263..7cc5c20 100644 --- a/LXMF/LXMPeer.py +++ b/LXMF/LXMPeer.py @@ -18,6 +18,7 @@ class LXMPeer: RESOURCE_TRANSFERRING = 0x05 ERROR_NO_IDENTITY = 0xf0 + ERROR_NO_ACCESS = 0xf1 # Maximum amount of time a peer can # be unreachable before it is removed diff --git a/LXMF/LXMRouter.py b/LXMF/LXMRouter.py index 932e4cf..ff51254 100644 --- a/LXMF/LXMRouter.py +++ b/LXMF/LXMRouter.py @@ -38,6 +38,8 @@ class LXMRouter: PR_RECEIVING = 0x05 PR_RESPONSE_RECEIVED = 0x06 PR_COMPLETE = 0x07 + PR_NO_IDENTITY_RCVD = 0xf0 + PR_NO_ACCESS = 0xf1 PR_ALL_MESSAGES = 0x00 @@ -55,6 +57,8 @@ class LXMRouter: self.delivery_destinations = {} self.ignored_list = [] + self.allowed_list = [] + self.auth_required = False self.processing_outbound = False self.processing_inbound = False @@ -160,6 +164,26 @@ class LXMRouter: def get_outbound_propagation_node(self): return self.outbound_propagation_node + def set_authentication(self, required=None): + if required != None: + self.auth_required = required + + def requires_authentication(self): + return self.auth_required + + def allow(self, identity_hash=None): + if isinstance(identity_hash, bytes) and len(identity_hash) == RNS.Identity.TRUNCATED_HASHLENGTH//8: + self.allowed_list.append(identity_hash) + else: + raise ValueError("Allowed identity hash must be "+str(RNS.Identity.TRUNCATED_HASHLENGTH//8)+" bytes") + + def disallow(self, identity_hash=None): + if isinstance(identity_hash, bytes) and len(identity_hash) == RNS.Identity.TRUNCATED_HASHLENGTH//8: + if identity_hash in self.allowed_list: + self.allowed_list.pop(identity_hash) + else: + raise ValueError("Disallowed identity hash must be "+str(RNS.Identity.TRUNCATED_HASHLENGTH//8)+" bytes") + def request_messages_from_propagation_node(self, identity, max_messages = PR_ALL_MESSAGES): if max_messages == None: max_messages = LXMRouter.PR_ALL_MESSAGES @@ -208,7 +232,7 @@ class LXMRouter: self.outbound_propagation_link.teardown() self.outbound_propagation_link = None - self.acknowledge_sync_completion() + self.acknowledge_sync_completion(reset_state=True) def enable_propagation(self): try: @@ -552,9 +576,23 @@ class LXMRouter: RNS.log("Propagation node path request timed out", RNS.LOG_DEBUG) self.acknowledge_sync_completion() + def identity_allowed(self, identity): + if self.auth_required: + if identity.hash in self.allowed_list: + return True + else: + return False + + else: + return True + def message_get_request(self, path, data, request_id, remote_identity, requested_at): if remote_identity == None: return LXMPeer.ERROR_NO_IDENTITY + + elif not self.identity_allowed(remote_identity): + return LXMPeer.ERROR_NO_ACCESS + else: try: remote_destination = RNS.Destination(remote_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "delivery") @@ -622,8 +660,16 @@ class LXMRouter: RNS.log("Propagation node indicated missing identification on list request, tearing down link.", RNS.LOG_DEBUG) if self.outbound_propagation_link != None: self.outbound_propagation_link.teardown() + self.propagation_transfer_state = LXMRouter.PR_NO_IDENTITY_RCVD + + elif request_receipt.response == LXMPeer.ERROR_NO_ACCESS: + RNS.log("Propagation node did not allow list request, tearing down link.", RNS.LOG_DEBUG) + if self.outbound_propagation_link != None: + self.outbound_propagation_link.teardown() + self.propagation_transfer_state = LXMRouter.PR_NO_ACCESS + else: - if request_receipt.response != None: + if request_receipt.response != None and isinstance(request_receipt.response, list): haves = [] wants = [] if len(request_receipt.response) > 0: @@ -682,8 +728,10 @@ class LXMRouter: if self.outbound_propagation_link != None: self.outbound_propagation_link.teardown() - def acknowledge_sync_completion(self): - self.propagation_transfer_state = LXMRouter.PR_IDLE + def acknowledge_sync_completion(self, reset_state=False): + if reset_state or self.propagation_transfer_state <= LXMRouter.PR_COMPLETE: + self.propagation_transfer_state = LXMRouter.PR_IDLE + self.propagation_transfer_progress = 0.0 self.propagation_transfer_last_result = None self.wants_download_on_path_available_from = None diff --git a/setup.py b/setup.py index 8a090d1..54c22ed 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="lxmf", - version="0.1.6", + version="0.1.7", author="Mark Qvist", author_email="mark@unsigned.io", description="Lightweight Extensible Message Format for Reticulum",