Improved sanitization of nonsensical interface discovery IFAC announce data

This commit is contained in:
Mark Qvist 2026-09-29 14:32:49 +02:00
parent 1d9ebe8c38
commit 135e941fa2
No known key found for this signature in database
2 changed files with 37 additions and 11 deletions

View file

@ -234,8 +234,8 @@ class InterfaceAnnouncer():
info[MODULATION] = self.sanitize(interface.discovery_modulation)
if interface.discovery_publish_ifac == True:
info[IFAC_NETNAME] = self.sanitize(interface.ifac_netname)
info[IFAC_NETKEY] = self.sanitize(interface.ifac_netkey)
if interface.ifac_netname: info[IFAC_NETNAME] = self.sanitize(interface.ifac_netname)
if interface.ifac_netkey: info[IFAC_NETKEY] = self.sanitize(interface.ifac_netkey)
packed = msgpack.packb(info)
infohash = RNS.Identity.full_hash(packed)
@ -375,8 +375,8 @@ class InterfaceAnnounceHandler:
"longitude": unpacked[LONGITUDE],
"height": unpacked[HEIGHT]}
if IFAC_NETNAME in unpacked: info["ifac_netname"] = str(unpacked[IFAC_NETNAME])
if IFAC_NETKEY in unpacked: info["ifac_netkey"] = str(unpacked[IFAC_NETKEY])
if IFAC_NETNAME in unpacked and unpacked[IFAC_NETNAME] and type(unpacked[IFAC_NETNAME]) == str: info["ifac_netname"] = str(unpacked[IFAC_NETNAME])
if IFAC_NETKEY in unpacked and unpacked[IFAC_NETKEY] and type(unpacked[IFAC_NETKEY]) == str: info["ifac_netkey"] = str(unpacked[IFAC_NETKEY])
if interface_type in ["BackboneInterface", "TCPServerInterface"]:
backbone_support = not RNS.vendor.platformutils.is_windows() and not RNS.vendor.platformutils.is_darwin()
@ -532,7 +532,16 @@ class InterfaceDiscovery():
should_remove = False
heard_delta = now-info["last_heard"]
info["name"] = InterfaceAnnounceHandler.sanitize_name(info["name"])
# TODO: Temporary measure to sanitize invalidly persisted "None" values
# for incorrect IFAC parameters published due to unguarded nonsensical
# node-side configuration. Potentially remove once nodes upgrade to RNS
# versions that guard against the configuration mismatch.
try:
if "ifac_netname" in info and info["ifac_netname"] == "None": info.pop("ifac_netname")
if "ifac_netkey" in info and info["ifac_netkey"] == "None": info.pop("ifac_netkey")
except Exception as e: RNS.log(f"Error while sanitizing discovery info: {e}", RNS.LOG_ERROR)
if heard_delta > self.THRESHOLD_REMOVE: should_remove = True
elif not "transport_id" in info or not info["transport_id"]: should_remove = True
elif not "network_id" in info or not info["network_id"]: should_remove = True
@ -788,8 +797,16 @@ class InterfaceDiscovery():
config_entry = info["config_entry"]
interface_config = {}
interface_config["name"] = f"{interface_name}"
ifac_netname = info["ifac_netname"] if "ifac_netname" in info else None
ifac_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
# TODO: Temporary measure to sanitize invalidly persisted "None" values
# for incorrect IFAC parameters published due to unguarded nonsensical
# node-side configuration. Potentially remove once nodes upgrade to RNS
# versions that guard against the configuration mismatch.
if "ifac_netname" in info and info["ifac_netname"] == "None": info["ifac_netname"] = None
if "ifac_netkey" in info and info["ifac_netkey"] == "None": info["ifac_netkey"] = None
ifac_netname = info["ifac_netname"] if "ifac_netname" in info and info["ifac_netname"] else None
ifac_netkey = info["ifac_netkey"] if "ifac_netkey" in info and info["ifac_netkey"] else None
interface = None
if interface_type == "BackboneInterface":

View file

@ -882,15 +882,19 @@ class Reticulum:
ifac_netname = None
if "networkname" in c:
if c["networkname"] != "": ifac_netname = c["networkname"]
if c["networkname"] == "None": RNS.log("Ambiguous IFAC network name \"None\", this value is ignored and an IFAC network name has NOT been set", RNS.LOG_WARNING)
if c["networkname"] != "" and c["networkname"] != "None": ifac_netname = c["networkname"]
if "network_name" in c:
if c["network_name"] != "": ifac_netname = c["network_name"]
if c["network_name"] == "None": RNS.log("Ambiguous IFAC network name \"None\", this value is ignored and an IFAC network name has NOT been set", RNS.LOG_WARNING)
if c["network_name"] != "" and c["network_name"] != "None": ifac_netname = c["network_name"]
ifac_netkey = None
if "passphrase" in c:
if c["passphrase"] != "": ifac_netkey = c["passphrase"]
if c["passphrase"] == "None": RNS.log("Ambiguous IFAC passphrase \"None\", this value is ignored and an IFAC passphrase has NOT been set", RNS.LOG_WARNING)
if c["passphrase"] != "" and c["passphrase"] != "None": ifac_netkey = c["passphrase"]
if "pass_phrase" in c:
if c["pass_phrase"] != "": ifac_netkey = c["pass_phrase"]
if c["pass_phrase"] == "None": RNS.log("Ambiguous IFAC passphrase \"None\", this value is ignored and an IFAC passphrase has NOT been set", RNS.LOG_WARNING)
if c["pass_phrase"] != "" and c["pass_phrase"] != "None": ifac_netkey = c["pass_phrase"]
ingress_control = True
if "ingress_control" in c: ingress_control = c.as_bool("ingress_control")
@ -1083,6 +1087,11 @@ class Reticulum:
interface.ifac_identity = RNS.Identity.from_bytes(interface.ifac_key)
interface.ifac_signature = interface.ifac_identity.sign(RNS.Identity.full_hash(interface.ifac_key))
elif interface.discoverable and interface.discovery_publish_ifac:
RNS.log(f"IFAC publishing was enabled for discoverable interface {interface}, but neither IFAC netname nor passphrase is configured", RNS.LOG_WARNING)
RNS.log(f"Disabling IFAC publishing for {interface}", RNS.LOG_WARNING)
interface.discovery_publish_ifac = False
RNS.Transport.add_interface(interface)
interface.final_init()