5

If I specify an incorrect password when connecting to a WiFi network is there anyway to detect that the reason I can't connect is the incorrect password (rather than one of the many other possible reasons that one might not be able to connect).

E.g. here I add a network but deliberately specify the wrong password. If I check the status I just see that it's 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

If I write a script to run wpa_cli status repeatedly after selecting the network I can see it goes through the phases:

SCANNING
ASSOCIATING
4WAY_HANDSHAKE
DISCONNECTED
SCANNING

So is there some way to discover that the association/handshake phase failed due to an incorrect password? E.g. does the disconnect event report some reason that's stored and which I can then query?

1 Answers1

5

If we look at wpa_supplicant/events.c:2326 we see:

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");
}

So when this logic is hit it logs WPA: 4-Way Handshake failed - pre-shared key may be incorrect.

Then it carries on to wpa_supplicant/wpa_supplicant.c:5136 and we see:

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);

So here <3>CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="MyPlace" auth_failures=1 duration=10 reason=WRONG_KEY is logged.

So I can either ensure that wpa_supplicant is started such that it logs its output to a file and then grep for such messages.

Or I can run wpa_cli in interactive mode - when it's in this mode it will subscribe for and output any wpa_supplicant messages.

So the very hacky solution I came up with was to run wpa_cli in a script and fool it into thinking it's in interactive mode:

#!/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 will only output any messages it has received after some user input has occurred, so the poke function provides this.

This script enables the 0th network and looks at what wpa_supplicant outputs while doing this.

Like I said this is pretty hacky but it works.