dotfiles/os/wireless/import.py

73 lines
2 KiB
Python

"""Exports Wi-Fi networks from password store."""
# 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 pathlib
import subprocess
import yaml
# passpy doesn't handle encoding properly, so doing this with calls
PASSWORD_STORE = pathlib.Path(os.environ["PASSWORD_STORE_DIR"])
SUBFOLDER = "wifi"
def list_networks() -> list[pathlib.Path]:
paths = []
pass_folder = PASSWORD_STORE / SUBFOLDER
for filename in os.listdir(pass_folder):
if not filename.endswith(".gpg"):
continue
filepath = pass_folder / filename
if not filepath.is_file():
continue
file = filename[:-4]
path = pathlib.Path(SUBFOLDER, file)
paths.append(path)
paths.sort()
return paths
networks: list[dict[str, str | list[str] | int]] = []
for path in list_networks():
proc = subprocess.run(
["pass", path], # noqa: S607
stdout=subprocess.PIPE,
check=True,
)
raw = proc.stdout.decode()
split = raw.split("\n")
password = split[0]
data = yaml.safe_load("\n".join(split[1:])) or {}
# Helpers to prevent repetition
suffixes = data.pop("suffixes", [""])
data.setdefault("key_mgmt", ["WPA-PSK"] if password else ["NONE"])
if password:
if any("PSK" in m.split("-") for m in data["key_mgmt"]):
data["psk"] = password
if any("EAP" in m.split("-") for m in data["key_mgmt"]):
data["password"] = password
if "ssid" not in data:
msg = f"{path}: Missing SSID"
raise KeyError(msg)
data.setdefault("disabled", 0)
for suffix in suffixes:
network = data.copy()
network["ssid"] += suffix
networks.append(network)
with pathlib.Path("wireless_networks.json").open("w") as fd:
json.dump(networks, fd, indent=4)