2024-06-08 15:54:33 +02:00
|
|
|
"""
|
2024-06-17 15:23:25 +02:00
|
|
|
Add the networks saved in wireless_networks to wpa_supplicant,
|
|
|
|
without restarting it or touching its config file.
|
2024-06-08 15:54:33 +02:00
|
|
|
"""
|
|
|
|
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
NETWORKS_FILE = "/etc/keys/wireless_networks.json"
|
|
|
|
|
|
|
|
|
|
|
|
def wpa_cli(command: list[str]) -> list[bytes]:
|
|
|
|
command.insert(0, "wpa_cli")
|
|
|
|
process = subprocess.run(command, stdout=subprocess.PIPE)
|
|
|
|
process.check_returncode()
|
|
|
|
lines = process.stdout.splitlines()
|
|
|
|
while lines[0].startswith(b"Selected interface"):
|
|
|
|
lines.pop(0)
|
|
|
|
return lines
|
|
|
|
|
|
|
|
|
|
|
|
network_numbers: dict[str, int] = dict()
|
|
|
|
networks_tsv = wpa_cli(["list_networks"])
|
|
|
|
networks_tsv.pop(0)
|
|
|
|
for network_line in networks_tsv:
|
|
|
|
split = network_line.split(b"\t")
|
|
|
|
number = int(split[0])
|
|
|
|
ssid_bytes = split[1]
|
|
|
|
ssid = re.sub(
|
|
|
|
rb"\\x([0-9a-f]{2})",
|
|
|
|
lambda d: int(d[1], base=16).to_bytes(),
|
|
|
|
ssid_bytes,
|
|
|
|
).decode()
|
|
|
|
network_numbers[ssid] = number
|
|
|
|
|
|
|
|
if os.path.isfile(NETWORKS_FILE):
|
|
|
|
with open(NETWORKS_FILE) as fd:
|
|
|
|
networks = json.load(fd)
|
|
|
|
|
|
|
|
for network in networks:
|
|
|
|
ssid = network["ssid"]
|
|
|
|
if ssid in network_numbers:
|
|
|
|
number = network_numbers[ssid]
|
|
|
|
else:
|
|
|
|
number = int(wpa_cli(["add_network"])[0])
|
|
|
|
number_str = str(number)
|
|
|
|
for key, value in network.items():
|
|
|
|
if isinstance(value, str):
|
|
|
|
value_str = f'"{value}"'
|
|
|
|
elif isinstance(value, list):
|
|
|
|
value_str = " ".join(value)
|
|
|
|
else:
|
|
|
|
value_str = str(value)
|
|
|
|
ret = wpa_cli(["set_network", number_str, key, value_str])
|
|
|
|
if ret[0] != b"OK":
|
|
|
|
raise RuntimeError(f"Couldn't set {key} for {ssid}, got {ret}")
|