Skip to content

fix(wifi): allow non-ascii characters in wifi ssids (#3365)#3375

Open
MattDHill wants to merge 2 commits into
masterfrom
fix/wifi-ssid-non-ascii
Open

fix(wifi): allow non-ascii characters in wifi ssids (#3365)#3375
MattDHill wants to merge 2 commits into
masterfrom
fix/wifi-ssid-non-ascii

Conversation

@MattDHill

Copy link
Copy Markdown
Member

Closes #3365.

Summary

Adding, connecting to, or removing a WiFi network whose SSID contains a non-ASCII character (e.g. an accented letter or a typographic apostrophe ') failed with "WiFi Internal Error SSID may not have special characters".

The cause is an if !ssid.is_ascii() guard at all three WiFi RPC entry points (add, connect, remove) in net/wifi.rs. 802.11 defines an SSID as 0–32 arbitrary octets — non-ASCII is valid, and plenty of real networks use it. This guard is unchanged from 0.3.5.1, so the restriction is live in 0.4.0.

This drops the SSID guard at all three sites. The SSID is handed to NetworkManager (nmcli) as a direct argv argument — a Rust String is always valid UTF-8 and NetworkManager handles UTF-8 SSIDs natively — so there's no quoting/shell hazard.

The passphrase is_ascii() check is intentionally kept: WPA-PSK passphrases must be 8–63 printable ASCII characters per 802.11i.

The now-unused net.wifi.ssid-no-special-characters i18n key is removed from all five locales.

Notes

  • A plain straight apostrophe (', ASCII) was already accepted; the reporter's error implies a non-ASCII character (most likely a typographic ' auto-substituted by their device).
  • Changelog entry added under 0.4.0-beta.10 (StartOS).

WiFi SSIDs are 0-32 arbitrary octets per 802.11; the is_ascii() guard wrongly
rejected valid SSIDs containing non-ASCII characters (e.g. accented letters or a
typographic apostrophe). NetworkManager receives the SSID as an argv argument, so
non-ASCII is passed through safely.

The WPA passphrase ASCII check is kept, since WPA-PSK passphrases must be ASCII.
Removes the now-unused net.wifi.ssid-no-special-characters i18n key.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dr-bonez

Copy link
Copy Markdown
Member

@helix-nine verify that NetworkManager handles UTF-8 wifi SSIDs and passwords properly

@helix-nine

Copy link
Copy Markdown
Contributor

Verified empirically. I ran the real NetworkManager daemon (nmcli 1.42.4) and replicated exactly how wifi.rs calls it — SSID/PSK passed as direct argv args, no shell — using the SSID café'net (accented é = c3 a9, typographic apostrophe ' = e2 80 99).

SSIDs — UTF-8 handled correctly. The 11 input octets 63 61 66 c3 a9 e2 80 99 6e 65 74 came back out of NM byte-for-byte as the stored 802.11 SSID array:

nmcli con add con-name "café'net" type wifi ssid "café'net"   → Connection successfully added
# persisted keyfile:
ssid=99;97;102;195;169;226;128;153;110;101;116;   # = 63 61 66 c3 a9 e2 80 99 6e 65 74

No corruption, no truncation, no quoting hazard — confirming the PR's reasoning. Two things to know about why this works and its one inherent limit:

  • A Rust String is always valid UTF-8, and tokio::process::Command::arg hands it to nmcli as a single argv element (no shell), so the bytes reach NM intact.
  • 802.11 SSIDs are opaque octets with no encoding indicator. NM stores whatever bytes you give it and matches the scanned AP by those bytes. So this works for any AP that broadcasts its SSID in UTF-8 — the modern standard and the real-world common case. It cannot match an AP that broadcasts a legacy non-UTF-8 encoding (Latin-1, Shift-JIS) from a typed name, but nothing can, and the old is_ascii() guard never helped that case — it only blocked the common UTF-8 one. So this is a strict improvement.

Passwords — keeping the ASCII guard is correct. WPA-PSK passphrases are 8–63 printable ASCII per 802.11i, and NM enforces this itself:

nmcli con modify … wifi-sec.psk "myAsciiPass123"   → OK
nmcli con modify … wifi-sec.psk "café"             → Error: 802-11-wireless-security.psk: property is invalid

So the PR's decision to retain if !password.is_ascii() is right — NM would reject a non-ASCII passphrase anyway with that opaque error; the StartOS check turns it into a clean, localized message first.

One unrelated note I checked while in there (not introduced by this PR): list_networks_low parses nmcli -t c show by splitting on :. UTF-8 SSIDs are safe there (multibyte sequences never contain byte 0x3a); only a literal ASCII : in an SSID would mis-parse, and that was already allowed pre-PR — so it's a pre-existing, out-of-scope edge case, not a regression here.

LGTM on the UTF-8 behavior.

@dr-bonez

Copy link
Copy Markdown
Member

we should probably fix the : in an SSID issue, even if it was pre-existing

nmcli `-t`/`-g` terse output escapes `:` as `\:` and `\` as `\\` within
a field, but `list_networks_low`/`list_wifi_low` split on raw `:`, so an
SSID containing a colon was split into the wrong fields — the connection
then failed the `wireless` type check and vanished from the list, leaving
connect/remove/active-detection unable to find it.

Add `split_nmcli_terse_line`, which splits on unescaped colons and
unescapes `\:`/`\\`, and route both parsers through it. Also drop a
leftover `JCWM` debug log.
@helix-nine

Copy link
Copy Markdown
Contributor

Done — pushed 1dcaec6e4.

The root cause: nmcli -t/-g terse output escapes : as \: and \ as \\ within a field (I confirmed this against the real daemon — an SSID my:wifi\x comes out as my\:wifi\\x). But list_networks_low and list_wifi_low were splitting on the raw :, so a colon in the SSID got split into extra fields — the row then failed the wireless/field checks and silently dropped out of the list, which left connect / remove / active-network detection unable to find that network.

Fix adds a small split_nmcli_terse_line helper that splits on unescaped colons and unescapes \:/\\, and routes both parsers through it. Added a unit test covering the escaped-colon/backslash and plain cases (cargo test -p start-core terse_line passes), and updated the changelog. Also dropped a leftover JCWM: debug log that was sitting in list_networks_low.

cargo check -p start-core is clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow special characters in WiFi SSID

3 participants