From 4ea15567c257765eed08fdfbb14b1fd0ef358ed8 Mon Sep 17 00:00:00 2001 From: gcw_4spBpAfv Date: Wed, 13 May 2026 16:38:24 +0800 Subject: [PATCH] wpa_supplicant_conf.py --- wpa_supplicant_conf.py | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 wpa_supplicant_conf.py diff --git a/wpa_supplicant_conf.py b/wpa_supplicant_conf.py new file mode 100644 index 0000000..2cc3269 --- /dev/null +++ b/wpa_supplicant_conf.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +生成 wpa_supplicant STA 配置(不经过 shell / wpa_passphrase),避免中文 SSID 在 /bin/sh 传参时被破坏。 + +与 wpa_passphrase 一致:PMK = PBKDF2-SHA1(password_utf8, ssid_utf8, 4096, 32), +ssid 行使用 UTF-8 字节的十六进制(无引号),与 wpa_supplicant 文档一致。 +""" +from __future__ import annotations + +import hashlib + +_CTRL_HEADER = ( + "ctrl_interface=/var/run/wpa_supplicant\n" + "update_config=1\n\n" +) + + +def _ssid_utf8_bytes(ssid: str) -> bytes: + b = (ssid or "").encode("utf-8") + if not b: + raise ValueError("SSID 为空") + if len(b) > 32: + raise ValueError("SSID UTF-8 超过 32 字节") + return b + + +def build_sta_conf_psk(ssid: str, password: str) -> str: + """WPA2-PSK STA:完整 wpa_supplicant.conf 文本。""" + ssid_b = _ssid_utf8_bytes(ssid) + pw = (password or "").encode("utf-8") + if len(pw) < 8 or len(pw) > 63: + raise ValueError("WPA2-PSK 密码长度应为 8–63 字节(UTF-8)") + pmk = hashlib.pbkdf2_hmac("sha1", pw, ssid_b, 4096, 32) + net = ( + "network={\n" + f"\tssid={ssid_b.hex()}\n" + f"\tpsk={pmk.hex()}\n" + "}\n" + ) + return _CTRL_HEADER + net + + +def build_sta_conf_open(ssid: str) -> str: + """开放网络 STA:完整 wpa_supplicant.conf 文本。""" + ssid_b = _ssid_utf8_bytes(ssid) + net = ( + "network={\n" + f"\tssid={ssid_b.hex()}\n" + "\tkey_mgmt=NONE\n" + "}\n" + ) + return _CTRL_HEADER + net