Added page authentication

This commit is contained in:
Mark Qvist 2022-04-06 20:34:49 +02:00
parent 886c23c21f
commit 3eaeb42bf6
4 changed files with 97 additions and 16 deletions

View File

@ -32,7 +32,7 @@ class Directory:
packed_list = []
for source_hash in self.directory_entries:
e = self.directory_entries[source_hash]
packed_list.append((e.source_hash, e.display_name, e.trust_level, e.hosts_node, e.preferred_delivery))
packed_list.append((e.source_hash, e.display_name, e.trust_level, e.hosts_node, e.preferred_delivery, e.identify))
directory = {
"entry_list": packed_list,
@ -65,7 +65,12 @@ class Directory:
else:
preferred_delivery = None
entries[e[0]] = DirectoryEntry(e[0], e[1], e[2], hosts_node, preferred_delivery=preferred_delivery)
if len(e) > 5:
identify = e[5]
else:
identify = False
entries[e[0]] = DirectoryEntry(e[0], e[1], e[2], hosts_node, preferred_delivery=preferred_delivery, identify_on_connect=identify)
self.directory_entries = entries
@ -183,6 +188,18 @@ class Directory:
except Exception as e:
return False
def should_identify_on_connect(self, source_hash):
if source_hash in self.directory_entries:
entry = self.directory_entries[source_hash]
return entry.identify
else:
return False
def set_identify_on_connect(self, source_hash, state):
if source_hash in self.directory_entries:
entry = self.directory_entries[source_hash]
entry.identify = state
def known_nodes(self):
node_list = []
for eh in self.directory_entries:
@ -214,7 +231,7 @@ class DirectoryEntry:
DIRECT = 0x01
PROPAGATED = 0x02
def __init__(self, source_hash, display_name=None, trust_level=UNKNOWN, hosts_node=False, preferred_delivery=None):
def __init__(self, source_hash, display_name=None, trust_level=UNKNOWN, hosts_node=False, preferred_delivery=None, identify_on_connect=False):
if len(source_hash) == RNS.Identity.TRUNCATED_HASHLENGTH//8:
self.source_hash = source_hash
self.display_name = display_name
@ -228,5 +245,6 @@ class DirectoryEntry:
self.trust_level = trust_level
self.hosts_node = hosts_node
self.identify = identify_on_connect
else:
raise TypeError("Attempt to add invalid source hash to directory")

View File

@ -79,6 +79,7 @@ class Node:
directories = [file for file in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, file)) and file[:1] != "."]
for file in files:
if not file.endswith(".allowed"):
self.servedpages.append(base_path+"/"+file)
for directory in directories:
@ -96,8 +97,51 @@ class Node:
def serve_page(self, path, data, request_id, remote_identity, requested_at):
RNS.log("Page request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE)
file_path = path.replace("/page", self.app.pagespath, 1)
allowed_path = file_path+".allowed"
request_allowed = False
if os.path.isfile(allowed_path):
allowed_list = []
try:
if os.access(allowed_path, os.X_OK):
allowed_result = subprocess.run([allowed_path], stdout=subprocess.PIPE)
allowed_input = allowed_result.stdout
else:
fh = open(allowed_path, "rb")
allowed_input = fh.read()
fh.close()
allowed_hash_strs = allowed_input.splitlines()
for hash_str in allowed_hash_strs:
if len(hash_str) == RNS.Identity.TRUNCATED_HASHLENGTH//8*2:
try:
allowed_hash = bytes.fromhex(hash_str.decode("utf-8"))
allowed_list.append(allowed_hash)
except Exception as e:
RNS.log("Could not decode RNS Identity hash from: "+str(hash_str), RNS.LOG_DEBUG)
RNS.log("The contained exception was: "+str(e), RNS.LOG_DEBUG)
except Exception as e:
RNS.log("Error while fetching list of allowed identities for request: "+str(e), RNS.LOG_ERROR)
if remote_identity.hash in allowed_list:
request_allowed = True
else:
request_allowed = False
RNS.log("Denying request, remote identity was not in list of allowed identities", RNS.LOG_VERBOSE)
else:
request_allowed = True
try:
if request_allowed:
RNS.log("Serving page: "+file_path, RNS.LOG_VERBOSE)
if os.access(file_path, os.X_OK):
generated = subprocess.run([file_path], stdout=subprocess.PIPE)
@ -107,6 +151,9 @@ class Node:
response_data = fh.read()
fh.close()
return response_data
else:
RNS.log("Request denied", RNS.LOG_VERBOSE)
return DEFAULT_NOTALLOWED.encode("utf-8")
except Exception as e:
RNS.log("Error occurred while handling request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_ERROR)
@ -161,3 +208,8 @@ This node is serving pages, but the home page file (index.mu) was not found in t
If you are the node operator, you can define your own home page by creating a file named `*index.mu`* in the page storage directory.
'''
DEFAULT_NOTALLOWED = '''>Request Not Allowed
You are not authorised to carry out the request.
'''

View File

@ -643,6 +643,10 @@ class Browser:
def link_established(self, link):
self.status = Browser.LINK_ESTABLISHED
if self.app.directory.should_identify_on_connect(self.destination_hash):
RNS.log("Link established, identifying to remote system...", RNS.LOG_VERBOSE)
self.link.identify(self.app.identity)
def link_closed(self, link):
if self.status == Browser.DISCONECTED or self.status == Browser.DONE:

View File

@ -443,7 +443,11 @@ class KnownNodeInfo(urwid.WidgetWrap):
def pn_change(sender, userdata):
self.pn_changed = True
def ident_change(sender, userdata):
pass
propagation_node_checkbox = urwid.CheckBox("Use as default propagation node", state=(self.app.get_user_selected_propagation_node() == source_hash), on_state_change=pn_change)
connect_identify_checkbox = urwid.CheckBox("Identify when connecting", state=self.app.directory.should_identify_on_connect(source_hash), on_state_change=ident_change)
def save_node(sender):
if self.pn_changed:
@ -461,7 +465,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
display_str = e_name.get_edit_text()
node_entry = DirectoryEntry(source_hash, display_name=display_str, trust_level=trust_level, hosts_node=True)
node_entry = DirectoryEntry(source_hash, display_name=display_str, trust_level=trust_level, hosts_node=True, identify_on_connect=connect_identify_checkbox.get_state())
self.app.directory.remember(node_entry)
self.app.ui.main_display.sub_displays.network_display.directory_change_callback()
show_known_nodes(None)
@ -479,6 +483,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
# urwid.Text(["Trust : ", (style, trust_str)], align="left"),
urwid.Divider(g["divider1"]),
propagation_node_checkbox,
connect_identify_checkbox,
urwid.Divider(g["divider1"]),
r_untrusted,
r_unknown,
@ -793,7 +798,8 @@ class LocalPeer(urwid.WidgetWrap):
if display_name == None:
display_name = ""
t_id = urwid.Text("Addr : "+RNS.hexrep(self.app.lxmf_destination.hash, delimit=False))
t_id = urwid.Text("LXMF Addr : "+RNS.prettyhexrep(self.app.lxmf_destination.hash))
i_id = urwid.Text("Identity : "+RNS.prettyhexrep(self.app.identity.hash))
e_name = urwid.Edit(caption="Name : ", edit_text=display_name)
def save_query(sender):
@ -858,6 +864,7 @@ class LocalPeer(urwid.WidgetWrap):
self.display_widget = urwid.Pile(
[
t_id,
i_id,
e_name,
urwid.Divider(g["divider1"]),
self.t_last_announce,