import os import re import time from datetime import datetime from subprocess import run import json CHANGES_REQUIRING_RESTART = ['wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_delta_chat', 'butterbox_hostname'] # 'ssh_access_settings', 'root_account_settings'] def lock_root_account(): result = run(["sudo", "passwd", "-l", "root"]) if result.returncode != 0: return False return True def enable_service(service: str): is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True) if 'not_found' in is_enabled.stdout: return False if 'disabled' in is_enabled.stdout: enable = run(["sudo", "systemctl", "enable", service], capture_output = True, text = True) if enable.returncode != 0: return False return True def disable_service(service: str): is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True) if 'not_found' in is_enabled.stdout: return False if 'enabled' in is_enabled.stdout: result = run(["sudo", "systemctl", "disable", service]) if result.returncode != 0: return False return True def load_setting(setting): with open("./app/settings.txt", "r") as f: settings = json.load(f) return settings[setting] def change_service_status(setting, service): if load_setting(setting) == "true": enable_service(service) else: disable_service(service) def change_keanu_weblite_config(new_hostname): regex = re.compile('qdt ?= ?"([^"]*)"') target_file = "/var/www/html/chat/assets/index-CD0QtET8.js" with open(target_file, "r") as f: lines = f.readlines() for line in enumerate(lines): match = regex.search(line) if match: old_hostname = match.group(1) if old_hostname != new_hostname: re.sub(old_hostname, new_hostname, lines[line]) def change_line_in_file(target_file: str, regex: str, replacement: str): print(f"Changing line in file {target_file}") regex = re.compile(regex) if not os.path.isfile(target_file): raise FileNotFoundError(f"File {target_file} does not exist") else: with open(target_file, "r") as f: lines = f.readlines() for i, line in enumerate(lines): match = re.fullmatch(replacement, line) if match: print("Line already exists!") return for i, line in enumerate(lines): match = re.fullmatch(regex, line) if match: lines.pop(i) break try: lines.append(replacement) except NameError: raise NameError(f"File {target_file} is empty.") new_lines = "".join(lines) with open(target_file, "w") as f: f.write(new_lines) def check_settings(raspap_installed: bool): if not os.path.exists("./settings.txt"): return last_modified = os.path.getmtime('./settings.txt') diff_in_minutes = (datetime.now().timestamp() - last_modified)/60 if diff_in_minutes < 2: for s in CHANGES_REQUIRING_RESTART: if s == "wifi_password" and raspap_installed: regex_wpa_method = "wpa=.*?\n" if load_setting("wifi_password") == "": change_line_in_file("/etc/hostapd/hostapd.conf", regex_wpa_method, f"wpa=none\n") else: change_line_in_file("/etc/hostapd/hostapd.conf", regex_wpa_method, f"wpa=3\n") regex_pass = "wpa_passphrase=.*?\n" change_line_in_file("/etc/hostapd/hostapd.conf", regex_pass, f"wpa_passphrase={load_setting("wifi_password")}\n") if s == "ssid" and raspap_installed: regex_ssid = "ssid=.*?\n" change_line_in_file("/etc/hostapd/hostapd.conf", regex_ssid, f"ssid={load_setting("ssid")}\n") if s == "enable_chat": change_service_status("enable_chat", "dendrite") if s == "enable_access_point" and raspap_installed: change_service_status("enable_access_point", "raspapd") if s == "enable_delta_chat": change_service_status("enable_delta_chat", "madmail") if s == "butterbox_hostname": pass # change in butterbox-dendrite.conf regex_matrix_server = "server_name:.*?.local\n" change_line_in_file("../dendrite/butterbox-dendrite.conf", regex_matrix_server, f"server_name: {load_setting("butterbox_hostname")}.local\n") # change in butterbox-dnsmasq.conf if raspap_installed: regex_dns = "address=/.*?.local/10.3.141.1\n" change_line_in_file("/etc/dnsmasq.d/butterbox-dnsmasq.conf", regex_dns, f"address=/{load_setting("butterbox_hostname")}.local/10.3.141.1\n") # change in keanu-weblite compiled assets change_keanu_weblite_config(load_setting("butterbox_hostname")) if s == "ssh_access_settings": change_service_status("ssh_enabled", "ssh") if load_setting("ssh_access_settings") == "enable_ssh_with_password": regex_password_auth = "PasswordAuthentication.*?\n" change_line_in_file("test/sshd/sshd.conf", regex_password_auth, f"PasswordAuthentication yes\n") regex_root_login = "PermitRootLogin.*?\n" change_line_in_file("test/sshd/sshd.conf", regex_root_login, f"PermitRootLogin yes\n") elif load_setting("ssh_access_settings") == "enable_ssh_with_public_key": regex_password_auth = "PasswordAuthentication.*?\n" change_line_in_file("test/sshd/sshd.conf", regex_password_auth, f"PasswordAuthentication no\n") regex_root_login = "PermitRootLogin.*?\n" change_line_in_file("test/sshd/sshd.conf", regex_root_login, f"PermitRootLogin prohibit-password\n") # append here new key!!! if s == "root_account_settings": if load_setting("root_account_settings") == "lock_root_account": lock_root_account() else: # root password implementation here pass if __name__ == "__main__": raspap_installed = os.path.exists("/var/www/html/raspapd") while True: check_settings(raspap_installed) time.sleep(30)