fixed Security Protocol Settings #17

Merged
Koda merged 1 commits from security-protocols into main 2026-07-14 00:47:23 +01:00
5 changed files with 159 additions and 28 deletions
Showing only changes of commit 0defe795c4 - Show all commits
+1
View File
@@ -260,6 +260,7 @@ static void build_radio_table(struct json_object *root,
json_object_object_add(o, "nss", json_object_new_int(r->nss)); json_object_object_add(o, "nss", json_object_new_int(r->nss));
json_object_object_add(o, "tx_power", json_object_new_int(r->tx_power)); json_object_object_add(o, "tx_power", json_object_new_int(r->tx_power));
json_object_object_add(o, "radio_caps", json_object_new_int(r->radio_caps)); json_object_object_add(o, "radio_caps", json_object_new_int(r->radio_caps));
json_object_object_add(o, "radio_caps2", json_object_new_int(r->radio_caps2));
json_object_object_add(o, "antenna_gain", json_object_new_int(r->antenna_gain)); json_object_object_add(o, "antenna_gain", json_object_new_int(r->antenna_gain));
json_object_object_add(o, "he_enabled", json_object_new_boolean(r->he_enabled)); json_object_object_add(o, "he_enabled", json_object_new_boolean(r->he_enabled));
json_object_object_add(o, "builtin_antenna", json_object_new_boolean(true)); json_object_object_add(o, "builtin_antenna", json_object_new_boolean(true));
+13 -13
View File
@@ -27,9 +27,9 @@
U6 InWall — 5 ports GbE + WiFi 6 (2.4+5 GHz) U6 InWall — 5 ports GbE + WiFi 6 (2.4+5 GHz)
═══════════════════════════════════════════════════════════════════ */ ═══════════════════════════════════════════════════════════════════ */
static const uf_radio_t u6iw_radios[] = { static const uf_radio_t u6iw_radios[] = {
/* name radio ch ht min max nss pwr caps ant he */ /* name radio ch ht min max nss pwr caps caps2 ant he */
{ "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 0, true }, { "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 0, 0, true },
{ "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 0, true }, { "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 0, 0, true },
}; };
/* 5 ports: port 0 as uplink, port 1-4 as LAN */ /* 5 ports: port 0 as uplink, port 1-4 as LAN */
@@ -76,8 +76,8 @@ const uf_model_t model_u6inwall = {
U6 Lite — 1 port GbE + WiFi 6 (2.4+5 GHz) U6 Lite — 1 port GbE + WiFi 6 (2.4+5 GHz)
═══════════════════════════════════════════════════════════════════ */ ═══════════════════════════════════════════════════════════════════ */
static const uf_radio_t u6lite_radios[] = { static const uf_radio_t u6lite_radios[] = {
{ "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 0, true }, { "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 1, 0, true },
{ "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 0, true }, { "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 1, 0, true },
}; };
static const uf_port_t u6lite_ports[] = { static const uf_port_t u6lite_ports[] = {
{ "eth0", "eth0", 0, 255, "GE", 1000, false, true, true }, { "eth0", "eth0", 0, 255, "GE", 1000, false, true, true },
@@ -87,10 +87,10 @@ static const uf_radio_map_t u6lite_rmap[] = {
{ "ng", "radio0" }, { "na", "radio1" }, { "ng", "radio0" }, { "na", "radio1" },
}; };
const uf_model_t model_u6lite = { const uf_model_t model_u6lite = {
.model="U6LITE", .model_display="U6 Lite", .display_name="U6-Lite", .model="UAL6", .model_display="U6 Lite", .display_name="U6-Lite",
.platform="U6LITE", .board_rev=3, .has_eth1=false, .platform="UAL6", .board_rev=15, .has_eth1=false,
.fw_pre="U6LITE.mt7622_5_4.v", .fw_ver="6.6.55.14430", .fw_pre="BZ.mt7621.v", .fw_ver="6.6.55.15189",
.fw_buildtime="230901.1200", .fw_factoryver="6.6.55.14430", .fw_buildtime="231127.1804", .fw_factoryver="6.6.55.15189",
.radio_table=u6lite_radios, .radio_table_len=2, .radio_table=u6lite_radios, .radio_table_len=2,
.port_table=u6lite_ports, .port_table_len=1, .port_table=u6lite_ports, .port_table_len=1,
.ethernet_table=u6lite_eth, .ethernet_table_len=1, .ethernet_table=u6lite_eth, .ethernet_table_len=1,
@@ -101,7 +101,7 @@ const uf_model_t model_u6lite = {
UAP Gen 1 — 1 port Fast Ethernet + WiFi N 2.4 GHz UAP Gen 1 — 1 port Fast Ethernet + WiFi N 2.4 GHz
═══════════════════════════════════════════════════════════════════ */ ═══════════════════════════════════════════════════════════════════ */
static const uf_radio_t uapg1_radios[] = { static const uf_radio_t uapg1_radios[] = {
{ "wifi0", "ng", 6, "HT20", 5, 23, 2, 20, 4, 0, false }, { "wifi0", "ng", 6, "HT20", 5, 23, 2, 20, 4, 0, 0, false },
}; };
static const uf_port_t uapg1_ports[] = { static const uf_port_t uapg1_ports[] = {
{ "eth0", "eth0", 0, 255, "GE", 100, false, true, true }, { "eth0", "eth0", 0, 255, "GE", 100, false, true, true },
@@ -123,7 +123,7 @@ const uf_model_t model_uapg1 = {
UAP Gen 1 LR UAP Gen 1 LR
═══════════════════════════════════════════════════════════════════ */ ═══════════════════════════════════════════════════════════════════ */
static const uf_radio_t uapg1lr_radios[] = { static const uf_radio_t uapg1lr_radios[] = {
{ "wifi0", "ng", 6, "HT20", 5, 23, 2, 22, 4, 0, false }, { "wifi0", "ng", 6, "HT20", 5, 23, 2, 22, 4, 0, 0, false },
}; };
static const uf_port_t uapg1lr_ports[] = { static const uf_port_t uapg1lr_ports[] = {
{ "eth0", "eth0", 0, 255, "GE", 100, false, true, true }, { "eth0", "eth0", 0, 255, "GE", 100, false, true, true },
@@ -145,8 +145,8 @@ const uf_model_t model_uapg1lr = {
UAP AC LR — 1 port GbE + WiFi AC dual-band UAP AC LR — 1 port GbE + WiFi AC dual-band
═══════════════════════════════════════════════════════════════════ */ ═══════════════════════════════════════════════════════════════════ */
static const uf_radio_t uapg2aclr_radios[] = { static const uf_radio_t uapg2aclr_radios[] = {
{ "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 0, false }, { "wifi0", "ng", 6, "HT40", 5, 23, 2, 20, 4, 0, 0, false },
{ "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 0, false }, { "wifi1", "na", 36, "HT80", 5, 23, 2, 20, 7, 0, 0, false },
}; };
static const uf_port_t uapg2aclr_ports[] = { static const uf_port_t uapg2aclr_ports[] = {
{ "eth0", "eth0", 0, 255, "GE", 1000, false, true, true }, { "eth0", "eth0", 0, 255, "GE", 1000, false, true, true },
+1 -1
View File
@@ -3,7 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#define OPENUF_CONFIG_SCHEMA 3 #define OPENUF_CONFIG_SCHEMA 6
typedef struct { typedef struct {
bool adopted; bool adopted;
+2 -1
View File
@@ -14,6 +14,7 @@ typedef struct {
int nss; int nss;
int tx_power; int tx_power;
int radio_caps; int radio_caps;
int radio_caps2;
int antenna_gain; int antenna_gain;
bool he_enabled; bool he_enabled;
} uf_radio_t; } uf_radio_t;
@@ -45,7 +46,7 @@ typedef struct {
/* ─── Full model descriptor ───────────────────────────────────────── */ /* ─── Full model descriptor ───────────────────────────────────────── */
typedef struct { typedef struct {
const char *model; /* "U6IW", "U6LITE" */ const char *model; /* "U6IW", "UAL6" */
const char *model_display; /* "U6 IW" */ const char *model_display; /* "U6 IW" */
const char *display_name; /* "U6-IW" */ const char *display_name; /* "U6-IW" */
const char *platform; /* used in announce PKT_PLATFORM */ const char *platform; /* used in announce PKT_PLATFORM */
+140 -11
View File
@@ -853,11 +853,32 @@ static int apply_vap(struct uci_context *ctx,
const char *essid = ""; const char *essid = "";
const char *security = "wpa2psk"; const char *security = "wpa2psk";
const char *pass = ""; const char *pass = "";
const char *auth_server = NULL;
const char *auth_secret = NULL;
const char *acct_server = NULL;
const char *acct_secret = NULL;
int auth_port = 1812;
int acct_port = 1813;
if (json_object_object_get_ex(vap_json, "essid", &v)) essid = json_object_get_string(v); if (json_object_object_get_ex(vap_json, "essid", &v)) essid = json_object_get_string(v);
if (json_object_object_get_ex(vap_json, "security", &v)) security = json_object_get_string(v); if (json_object_object_get_ex(vap_json, "security", &v)) security = json_object_get_string(v);
if (json_object_object_get_ex(vap_json, "x_passphrase",&v)) pass = json_object_get_string(v); if (json_object_object_get_ex(vap_json, "x_passphrase",&v)) pass = json_object_get_string(v);
int enterprise = !strcmp(security, "wpa2enterprise") ||
!strcmp(security, "wpa3enterprise");
if (json_object_object_get_ex(vap_json, "auth_server", &v))
auth_server = json_object_get_string(v);
if (json_object_object_get_ex(vap_json, "auth_secret", &v))
auth_secret = json_object_get_string(v);
if (json_object_object_get_ex(vap_json, "auth_port", &v))
auth_port = json_object_get_int(v);
if (json_object_object_get_ex(vap_json, "acct_server", &v))
acct_server = json_object_get_string(v);
if (json_object_object_get_ex(vap_json, "acct_secret", &v))
acct_secret = json_object_get_string(v);
if (json_object_object_get_ex(vap_json, "acct_port", &v))
acct_port = json_object_get_int(v);
/* Resolve the final network before creating the VAP; never fail open. */ /* Resolve the final network before creating the VAP; never fail open. */
int vid = 0; int vid = 0;
char target_network[32] = "lan"; char target_network[32] = "lan";
@@ -908,9 +929,50 @@ static int apply_vap(struct uci_context *ctx,
UCI_SET(ctx, "wireless", sec_name, "openuf_vap_id", vap_id); UCI_SET(ctx, "wireless", sec_name, "openuf_vap_id", vap_id);
/* Password */ /* Password */
if (pass && pass[0] && strcmp(security,"open") != 0) if (!enterprise && pass && pass[0] && strcmp(security,"open") != 0)
UCI_SET(ctx, "wireless", sec_name, "key", pass); UCI_SET(ctx, "wireless", sec_name, "key", pass);
if (enterprise) {
if (!auth_server || !auth_server[0] ||
!auth_secret || !auth_secret[0]) {
printf("[openuf] Refusing Enterprise VAP '%s': missing RADIUS "
"authentication server or secret\n", essid);
return -1;
}
char path[256];
char port[16];
snprintf(path, sizeof(path), "wireless.%s.auth_server", sec_name);
snprintf(port, sizeof(port), "%d", auth_port > 0 ? auth_port : 1812);
if (uci_add_list_val(ctx, path, auth_server) != 0 ||
uci_set_required(ctx, pkg, sec_name, "auth_port", port) != 0 ||
uci_set_required(ctx, pkg, sec_name, "auth_secret",
auth_secret) != 0) {
printf("[openuf] Failed to store RADIUS authentication for "
"VAP '%s'\n", essid);
return -1;
}
if (acct_server && acct_server[0]) {
if (!acct_secret || !acct_secret[0]) {
printf("[openuf] Refusing Enterprise VAP '%s': accounting "
"server has no secret\n", essid);
return -1;
}
snprintf(path, sizeof(path), "wireless.%s.acct_server", sec_name);
snprintf(port, sizeof(port), "%d",
acct_port > 0 ? acct_port : 1813);
if (uci_add_list_val(ctx, path, acct_server) != 0 ||
uci_set_required(ctx, pkg, sec_name, "acct_port", port) != 0 ||
uci_set_required(ctx, pkg, sec_name, "acct_secret",
acct_secret) != 0) {
printf("[openuf] Failed to store RADIUS accounting for "
"VAP '%s'\n", essid);
return -1;
}
}
}
/* hidden SSID */ /* hidden SSID */
int hidden = 0; int hidden = 0;
if (json_object_object_get_ex(vap_json, "hide_ssid", &v)) if (json_object_object_get_ex(vap_json, "hide_ssid", &v))
@@ -931,17 +993,18 @@ static int apply_vap(struct uci_context *ctx,
/* ── PMF (Protected Management Frames / 802.11w) ────────────── /* ── PMF (Protected Management Frames / 802.11w) ──────────────
* "disabled" → 0, "optional" → 1, "required" → 2 * "disabled" → 0, "optional" → 1, "required" → 2
* WPA3 (sae/sae-mixed) always requires "optional" or " required" ieee80211w=2 */ * WPA3-only requires PMF. WPA2/WPA3 transition mode must leave PMF
* optional so WPA2-only clients can still associate. */
int pmf = 0; int pmf = 0;
if (json_object_object_get_ex(vap_json, "pmf_mode", &v)) { if (json_object_object_get_ex(vap_json, "pmf_mode", &v)) {
const char *pm = json_object_get_string(v); const char *pm = json_object_get_string(v);
if (!strcmp(pm, "optional")) pmf = 1; if (!strcmp(pm, "optional")) pmf = 1;
if (!strcmp(pm, "required")) pmf = 2; if (!strcmp(pm, "required")) pmf = 2;
} }
/* WPA3 forces PMF=2 */ if (!strcmp(security,"wpa3") || !strcmp(security,"wpa3enterprise"))
if (!strcmp(security,"wpa3") || !strcmp(security,"wpa3transition") ||
!strcmp(security,"wpa3enterprise"))
pmf = 2; pmf = 2;
else if (!strcmp(security,"wpa3transition") && pmf < 1)
pmf = 1;
UCI_SET_INT(ctx, "wireless", sec_name, "ieee80211w", pmf); UCI_SET_INT(ctx, "wireless", sec_name, "ieee80211w", pmf);
/* ── Fast Roaming (802.11r FT) ──────────────────────────────── /* ── Fast Roaming (802.11r FT) ────────────────────────────────
@@ -1028,7 +1091,7 @@ static int apply_vap(struct uci_context *ctx,
"could not be stored\n", essid); "could not be stored\n", essid);
return -1; return -1;
} }
if (pass && pass[0] && strcmp(security, "open") != 0 && if (!enterprise && pass && pass[0] && strcmp(security, "open") != 0 &&
uci_set_required(ctx, pkg, sec_name, "key", pass) != 0) { uci_set_required(ctx, pkg, sec_name, "key", pass) != 0) {
printf("[openuf] Refusing unsecured VAP '%s': key could not be stored\n", printf("[openuf] Refusing unsecured VAP '%s': key could not be stored\n",
essid); essid);
@@ -1413,15 +1476,81 @@ int wlan_apply_system_cfg(const char *system_cfg,
band = "na"; band = "na";
json_object_object_add(vap, "radio", json_object_new_string(band)); json_object_object_add(vap, "radio", json_object_new_string(band));
char passphrase[256] = {0};
snprintf(key, sizeof(key), "aaa.%d.wpa.psk", i); snprintf(key, sizeof(key), "aaa.%d.wpa.psk", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value))) { int has_passphrase = system_cfg_get(system_cfg, key, passphrase,
sizeof(passphrase));
if (!has_passphrase) {
snprintf(key, sizeof(key), "aaa.%d.sae.psk.1.psk", i);
has_passphrase = system_cfg_get(system_cfg, key, passphrase,
sizeof(passphrase));
}
char key_mgmt[256] = {0};
snprintf(key, sizeof(key), "aaa.%d.wpa.key.1.mgmt", i);
int has_key_mgmt = system_cfg_get(system_cfg, key, key_mgmt,
sizeof(key_mgmt));
int wpa3_support = 0;
snprintf(key, sizeof(key), "aaa.%d.wpa3.support", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value)))
wpa3_support = feature_text_enabled(value);
int wpa3_transition = 0;
snprintf(key, sizeof(key), "aaa.%d.wpa3.transition", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value)))
wpa3_transition = feature_text_enabled(value);
const char *security = "open";
if (has_key_mgmt && strstr(key_mgmt, "WPA-EAP")) {
security = wpa3_support ? "wpa3enterprise" : "wpa2enterprise";
} else if (has_key_mgmt && strstr(key_mgmt, "SAE")) {
/* A transition BSS permits both WPA2-PSK and SAE. */
security = wpa3_transition || strstr(key_mgmt, "WPA-PSK")
? "wpa3transition" : "wpa3";
} else if (has_passphrase) {
security = "wpa2psk";
}
json_object_object_add(vap, "security", json_object_object_add(vap, "security",
json_object_new_string("wpa2psk")); json_object_new_string(security));
int enterprise = !strcmp(security, "wpa2enterprise") ||
!strcmp(security, "wpa3enterprise");
if (has_passphrase && !enterprise) {
json_object_object_add(vap, "x_passphrase", json_object_object_add(vap, "x_passphrase",
json_object_new_string(passphrase));
}
if (enterprise) {
snprintf(key, sizeof(key), "aaa.%d.radius.auth.1.ip", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value)))
json_object_object_add(vap, "auth_server",
json_object_new_string(value));
snprintf(key, sizeof(key), "aaa.%d.radius.auth.1.port", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value)))
json_object_object_add(vap, "auth_port",
json_object_new_int(atoi(value)));
snprintf(key, sizeof(key), "aaa.%d.radius.auth.1.secret", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value)))
json_object_object_add(vap, "auth_secret",
json_object_new_string(value));
snprintf(key, sizeof(key), "aaa.%d.radius.acct.1.ip", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value)))
json_object_object_add(vap, "acct_server",
json_object_new_string(value));
snprintf(key, sizeof(key), "aaa.%d.radius.acct.1.port", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value)))
json_object_object_add(vap, "acct_port",
json_object_new_int(atoi(value)));
snprintf(key, sizeof(key), "aaa.%d.radius.acct.1.secret", i);
if (system_cfg_get(system_cfg, key, value, sizeof(value)))
json_object_object_add(vap, "acct_secret",
json_object_new_string(value)); json_object_new_string(value));
} else {
json_object_object_add(vap, "security",
json_object_new_string("open"));
} }
snprintf(key, sizeof(key), "aaa.%d.hide_ssid", i); snprintf(key, sizeof(key), "aaa.%d.hide_ssid", i);