RaspAP / raspap-webgui

Simple wireless AP setup & management for Debian-based devices
https://raspap.com/
GNU General Public License v3.0
4.45k stars 789 forks source link

Warn user when he enters a wrong WiFi password #142

Open emmanuelgeoffray opened 6 years ago

emmanuelgeoffray commented 6 years ago

I think it would be super useful if the user would be warned if he enters a wrong password in the "Configure Wifi Client" section.

I would be glad to help on this feature. What do you think would be the best implementation? From what I have seen, the password and SSID are stored in wpa_supplicant.conf. Before doing this, may be the app should try to switch wifi and retrieve errors if any? Not sure how to switch wifi though, but I can search a command line for that.

Best, Emmanuel

emmanuelgeoffray commented 6 years ago

hey @billz any thoughts on that? I am still needing this feature, so I think I will impement it pretty soon.

Thank you, Emmanuel

emmanuelgeoffray commented 5 years ago

hey @billz thanks for all the recent updates any thoughts on that? I am still needing this feature, and did not have time to implement it! But if you have an idea on how to do it, let's do it! I see many humans entering wrong passwords!

Thank you, Emmanuel

dalmago commented 5 years ago

I also would enjoy this feature, but in my opinion it's a little hard to implement.

Is it possible to verify the password while the WiFi is still in AP mode?

If you switch to client mode, you'd have to reconnect your device to the Pi after verifying, and it could also take several seconds to change to client mode, verify the password and change back to AP mode.

gabrielstuff commented 5 years ago

Indeed it does not look trivia but feasible : https://unix.stackexchange.com/q/407168, https://superuser.com/a/903893, https://raspberrypi.stackexchange.com/a/61137 Many people complains about detecting wrong password and switching from one wifi to an other depending on the password entered.

Maybe, this kind of behaviour could be an option in the global settings. If you activate it, it took more times but it is safe for every human.

I think that waiting some seconds before getting an error could be understandable if you guarantee the connectivity.

glaszig commented 5 years ago

this could be implemented as an asynchronous process.

first i thought about websockets but that would require an actively runnig php server process. right now, lighty just execute raspap on each request. on the other hand, i could write some sort of control server in go and hook that up as a websocket source to the ui. then we can do other fancy real-time stuff. that control server could also be running with elevated privileges to do things without that sudo dance. i mean, we give sudo access to "arbitrary" scripts that my contain anything anyway.

also: we could move everything over to the go server, piece by piece, and in the end have only one binary to deploy.

wangkai88 commented 5 years ago

我在客户端设置界面输入连接wifi密码连接一直都是提示报错,

密码长度需要介于8~63个字符

无法更改连接WiFi

dejang commented 1 week ago

Not sure where this is but I think I could help. Unfortunately I know only Javascript and Rust. My Bash game is weak and I haven't written a line of PHP code in more than a decade. But with some guidance and if Rust is an option I could start making some contributions.

billz commented 1 week ago

@dejang thanks for the offer to help. This one is somewhat tricky in that wpa_cli operates in two modes (man wpa_cli):

wpa_cli supports two modes: interactive and command line. Both modes share the same command set and the main difference is in interactive mode providing access to unsolicited messages (event messages, username/password requests).

In command line mode, enabling a network with an incorrect PSK will only return OK, likely due to timing issues while the cli attempts to complete the 4-way handshake. Thus only interactive mode is capable of returning PSK failure messages. For example:

$ sudo wpa_cli -i wlan1
wpa_cli v2.10
Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi> and contributors

This software may be distributed under the terms of the BSD license.
See README for more details.

Interactive mode

> list_networks
network id / ssid / bssid / flags
0   My-Router   any 
> set_network 0 psk "IncorrectPassphrase"
OK
> enable_network 0
OK
<3>CTRL-EVENT-SCAN-STARTED 
<3>CTRL-EVENT-SCAN-RESULTS 
<3>SME: Trying to authenticate with 68:a3:ff:ff:ff:ff (SSID='My-Router' freq=2437 MHz)
<3>Trying to associate with 68:a3:ff:ff:ff:ff (SSID='My-Router' freq=2437 MHz)
<3>Associated with 68:a3:ff:ff:ff:ff
<3>CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
<3>CTRL-EVENT-DISCONNECTED bssid=68:a3:ff:ff:ff:ff reason=15
<3>WPA: 4-Way Handshake failed - pre-shared key may be incorrect
<3>CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="My-Router" auth_failures=1 duration=10 reason=WRONG_KEY

One possible hacky solution is to run wpa_cli in a script and fool it into thinking it's in interactive mode. A better alternative might be to enable and parse wpa_supplicant's logs, as @glaszig suggests, or use dbus-monitor with wpa_supplicant's dbus interface.

/lib/systemd/system/wpa_supplicant.service:

[Service]
Type=dbus
BusName=fi.w1.wpa_supplicant1
ExecStart=/sbin/wpa_supplicant -u -s -O "DIR=/run/wpa_supplicant GROUP=netdev"
ExecReload=/bin/kill -HUP $MAINPID

The latter is speculative and untested.

dejang commented 2 days ago

Thank you for the detailed answer @billz. I believe there are ways to run interactive processes from PHP, NodeJS, Rust, Python etc. and intercept the input/output streams. So based on that, spawning a child process from the programming language used (PHP/NodeJS/Rust) of wpa_cli in interactive mode and monitoring the streams programmatically should be a pretty robust and straightforward solution. There is no need, in my opinion, to exit the programming language in which the web interface is written. Bonus, this can be implemented as a XHR request for a nice visual feedback in the UI and is independent of Linux flavor as long as the binary is in path.

glaszig commented 2 days ago

there you go: proc_open().

billz commented 1 day ago

there you go: proc_open()

yup, that could work. @dejang in terms of the implementation, it would be great to use our existing stack wherever possible rather than adding new dependencies to the project. Glad to collaborate on a PR / proof of concept.