70 lines
1.9 KiB
Python
Executable file
70 lines
1.9 KiB
Python
Executable file
"""
|
|
Exports Wi-Fi networks configuration stored in pass
|
|
into a format readable by Nix.
|
|
"""
|
|
|
|
# TODO EAP ca_cert=/etc/ssl/... probably won't work. Example fix:
|
|
# builtins.fetchurl {
|
|
# url = "https://letsencrypt.org/certs/isrgrootx1.pem";
|
|
# sha256 = "sha256:1la36n2f31j9s03v847ig6ny9lr875q3g7smnq33dcsmf2i5gd92";
|
|
# }
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
|
|
import yaml
|
|
|
|
# passpy doesn't handle encoding properly, so doing this with calls
|
|
|
|
PASSWORD_STORE = os.environ["PASSWORD_STORE_DIR"]
|
|
SUBFOLDER = "wifi"
|
|
|
|
|
|
def list_networks() -> list[str]:
|
|
paths = []
|
|
pass_folder = os.path.join(PASSWORD_STORE, SUBFOLDER)
|
|
for filename in os.listdir(pass_folder):
|
|
if not filename.endswith(".gpg"):
|
|
continue
|
|
filepath = os.path.join(pass_folder, filename)
|
|
if not os.path.isfile(filepath):
|
|
continue
|
|
|
|
file = filename[:-4]
|
|
path = os.path.join(SUBFOLDER, file)
|
|
paths.append(path)
|
|
paths.sort()
|
|
return paths
|
|
|
|
|
|
networks: list[dict[str, str | list[str] | int]] = list()
|
|
for path in list_networks():
|
|
proc = subprocess.run(["pass", path], stdout=subprocess.PIPE)
|
|
proc.check_returncode()
|
|
|
|
raw = proc.stdout.decode()
|
|
split = raw.split("\n")
|
|
|
|
password = split[0]
|
|
data = yaml.safe_load("\n".join(split[1:])) or dict()
|
|
|
|
# Helpers to prevent repetition
|
|
suffixes = data.pop("suffixes", [""])
|
|
data.setdefault("key_mgmt", ["WPA-PSK"] if password else ["NONE"])
|
|
if password:
|
|
if any(map(lambda m: "PSK" in m.split("-"), data["key_mgmt"])):
|
|
data["psk"] = password
|
|
if any(map(lambda m: "EAP" in m.split("-"), data["key_mgmt"])):
|
|
data["password"] = password
|
|
assert "ssid" in data, f"{path}: Missing SSID"
|
|
data.setdefault("disabled", 0)
|
|
|
|
for suffix in suffixes:
|
|
network = data.copy()
|
|
network["ssid"] += suffix
|
|
networks.append(network)
|
|
|
|
with open("wireless_networks.json", "w") as fd:
|
|
json.dump(networks, fd, indent=4)
|