如果我在连接 WiFi 网络时输入了错误的密码,是否有办法检测出我无法连接的原因是密码错误(而不是其他可能导致无法连接的原因之一)。
例如,我在这里添加了一个网络,但故意指定了错误的密码。如果我检查状态,我只会看到它SCANNING
# wpa_cli add_network
Selected interface 'wlan0'
1
# wpa_cli set_network 1 ssid \"MyPlace\"
Selected interface 'wlan0'
OK
# wpa_cli set_network 1 psk \"SuperSecret\"
Selected interface 'wlan0'
OK
# wpa_cli select_network 1
Selected interface 'wlan0'
OK
# wpa_cli status
Selected interface 'wlan0'
wpa_state=SCANNING
p2p_device_address=fe:c2:de:37:93:11
address=fc:c2:de:37:93:11
如果我编写一个脚本在选择网络后重复运行,wpa_cli status
我可以看到它经历以下阶段:
SCANNING
ASSOCIATING
4WAY_HANDSHAKE
DISCONNECTED
SCANNING
那么,有没有办法发现由于密码错误而导致关联/握手阶段失败?例如,断开连接事件是否会报告一些存储的原因,然后我可以查询这些原因?
答案1
如果我们看看wpa_supplicant/events.c:2326
我们看:
if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) {
wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
"pre-shared key may be incorrect");
if (wpas_p2p_4way_hs_failed(wpa_s) > 0)
return; /* P2P group removed */
wpas_auth_failed(wpa_s, "WRONG_KEY");
}
因此,当满足此逻辑时,它会记录WPA: 4-Way Handshake failed - pre-shared key may be incorrect
。
然后它继续wpa_supplicant/wpa_supplicant.c:5136
我们看到:
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
"id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
ssid->auth_failures, dur, reason);
因此这里<3>CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="MyPlace" auth_failures=1 duration=10 reason=WRONG_KEY
记录下来。
因此,我可以确保它wpa_supplicant
已启动,以便将其输出记录到文件中,然后grep
将此类消息记录下来。
或者我可以wpa_cli
在交互模式下运行 - 当处于此模式时,它将订阅并输出任何wpa_supplicant
消息。
因此,我想到的一个非常棘手的解决方案是运行wpa_cli
一个脚本并欺骗它认为它处于交互模式:
#!/bin/bash
function poke {
while true
do
printf '\n'
sleep 1
done
}
function watch {
(poke) | wpa_cli | while read line
do
case "$line" in
*'4-Way Handshake failed'*)
echo "incorrect key"
return
;;
*'CTRL-EVENT-CONNECTED'*)
echo "connected"
return
;;
esac
done
}
wpa_cli disable_network 0 > /dev/null
wpa_cli enable_network 0 > /dev/null
watch
wpa_cli
仅在发生某些用户输入后才会输出收到的任何消息,因此该poke
函数提供了此功能。
该脚本启用第 0 个网络并查看wpa_supplicant
执行此操作时的输出。
就像我说的,这很古怪,但是确实有效。