Eh bien, pourrait trouver beaucoup, peut-être mon Google fu suce. J'ai fini par faire ce script pour le faire pour moi. Il utilise wpa_supplicant
pour essayer de se connecter, puis analyse les journaux pour rechercher certaines chaînes indiquant l'échec ou le succès de l'authentification. Il est uniquement testé avec v2.3, si la sortie du journal est différente dans d'autres versions, il peut ne pas fonctionner correctement.
La connexion en cours sur l'interface sans fil à partir de laquelle vous testez est toujours interrompue, mais elle sera rétablie dès que le script wpa_supplicant
démarré par ce script sera détruit par le script existant.
#!/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
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