Skip to content

Instantly share code, notes, and snippets.

@penguinpowernz
Last active April 12, 2016 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save penguinpowernz/4566e7b3ec300cbd6fe24e65b6a8dc65 to your computer and use it in GitHub Desktop.
Save penguinpowernz/4566e7b3ec300cbd6fe24e65b6a8dc65 to your computer and use it in GitHub Desktop.
A ruby script to check if wifi AP authentication details are correct

Wifi Auth Test Script

This script will attempt to check the authentication details for an AP to see if they are correct. It should be called like so:

$ ruby wpa_auth_test.rb "FBISurveillanceVan4" "stingrays 4 eva"
I, [2000-01-02T02:36:27.925647 #14255]  INFO -- : Starting WPA Supplicant
I, [2000-01-02T02:36:28.097044 #14255]  INFO -- : Searching WPA log for authentication state
I, [2000-01-02T02:36:37.943307 #14255]  INFO -- : Found authentication state in 10.02 seconds
I, [2000-01-02T02:36:37.947201 #14255]  INFO -- : Killing WPA on PID 14268
E, [2000-01-02T02:36:37.961020 #14255] ERROR -- : Authentication failed

It will give a return status of 1 for auth failure or 0 for success, as well as logging some information to the console.

It has a built in timeout (default 15sec) in case something holds the script up (on a BeagleboneBlack this typically took ~10s for a failed auth, and ~2s for a successful auth). In most cases the WPA supplicant was killed before DHCP could configure the interface.

In the case where the interface is already connected to an AP and configured via WPA/DHCP, this script will cause that connection to drop, regardless of AP auth success or failure. With the latter the connection is promptly restored after the script is finished, however with the former the connection may be momentarily reconfigured via DHCP to the new APs details, before control is given back to the original WPA process. It is unclear if this disconnection can be avoided.

This has only been tested with wpa_supplicant v2.3, the log output from other versions may be different and so may require adjusting of the parse_log method.

#!/usr/bin env ruby
# This script will run WPA to check authentication to a Wifi AP. It will return status 0 for success
# or status 1 for failure, as well as logging some information about what the script is doing.
#
# It has a built in timeout (default 15sec) in case something holds the script up, on a BeagleboneBlack
# this typically took ~10s for a failed auth, and ~2s for a successful auth. In most cases the WPA
# supplicant was killed before DHCP could configure the interface.
#
# In the case where the interface is already connected to an AP and configured via WPA/DHCP, this script
# will cause that connection to drop, regardless of AP auth success or failure. With the latter the
# connection is promptly restored after the script is finished, however with the former the connection
# may be momentarily reconfigured via DHCP to the new APs details, before control is given back to the
# original WPA process. It is unclear if this disconnection can be avoided.
#
# This has only been tested with wpa_supplicant v2.3, the log output from other versions may be different
# and so may require adjusting of the parse_log method.
require 'logger'
require 'fileutils'
LOG_FILE = "/tmp/wpalog"
PIDFILE = "/tmp/wpapid"
LOG = Logger.new(STDOUT)
ssid = ARGV[0]
pass = ARGV[1]
timeout = 15
dev = "wlan0"
abort "Usage: #{$0} <ssid> <pass>" if ssid.nil? or pass.nil?
File.write(LOG_FILE, "")
# make sure we don't leave wpa running
at_exit do
kill_wpa!
end
# kill the auth process if it's pidfile exists
def kill_wpa!
if File.exist?(PIDFILE)
pid = File.read(PIDFILE).strip
LOG.info "Killing WPA on PID #{pid}"
Process.kill 9, pid.to_i
FileUtils.rm PIDFILE
end
end
# parse the log for indications of auth success/failure
def parse_log
log = File.read(LOG_FILE)
if log.include? "WPA: Key negotiation completed"
return true
end
if log.include?("pre-shared key may be incorrect") || log.include?("auth_failures=1")
return false
end
nil
end
# timeout so we don't keep going forever if theres some issue
Thread.new do
sleep timeout
LOG.fatal "Operation timed out"
exit
end
# run the process to try to auth to the AP
s = Time.now
LOG.info "Starting WPA Supplicant"
system "bash -c 'wpa_supplicant -Dwext -c <(wpa_passphrase \"#{ssid}\" \"#{pass}\") -B -P #{PIDFILE} -f #{LOG_FILE} -i #{dev} 2>/dev/null'"
result = nil
# loop until the parse_log gives us a non nil result indicating auth success or failure
LOG.info "Searching WPA log for authentication state"
loop do
result = parse_log
sleep 0.2 and next if result.nil?
break
end
f = Time.now
duration = (f - s).to_f.round(2)
LOG.info "Found authentication state in #{duration} seconds"
# kill WPA ASAP before DHCP takes over and changes the interface config
kill_wpa!
if result
LOG.info "Authentication successful"
else
LOG.error "Authentication failed"
end
# empty the log in case there are creds in it
File.write(LOG_FILE, "")
# use return values to signal auth failure or success
exit result ? 0 : 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment