wpa_supplicant - 检测到我的密码不正确?

Geo*_*ins 4 linux wireless-networking wpa2-psk wpa-supplicant

如果我在连接到 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
Run Code Online (Sandbox Code Playgroud)

如果我编写一个脚本wpa_cli status在选择网络后重复运行,我可以看到它经历了以下阶段:

SCANNING
ASSOCIATING
4WAY_HANDSHAKE
DISCONNECTED
SCANNING
Run Code Online (Sandbox Code Playgroud)

那么有没有办法发现关联/握手阶段由于密码错误而失败?例如,断开连接事件是否报告了一些存储的原因,然后我可以查询这些原因?

Geo*_*ins 5

如果我们看一下,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");
}
Run Code Online (Sandbox Code Playgroud)

所以当这个逻辑被击中时,它会记录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);
Run Code Online (Sandbox Code Playgroud)

所以这里<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消息。

所以我想出的非常hacky的解决方案是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
Run Code Online (Sandbox Code Playgroud)

wpa_cli将仅输出在发生某些用户输入后收到的任何消息,因此该poke函数提供了这一点。

此脚本启用第 0网络并在wpa_supplicant执行此操作时查看输出。

就像我说的这很hacky,但它有效。