0

我正在为硬件设备编写 Web 界面,目前正在执行网络配置向导。我想让用户选择 SSID,如果它是安全的,然后输入密码。我想在那里检查密码是否正确,而无需在向导中进行任何进一步的操作。

有没有比抛出细节wpa_supplicant和解析日志输出更简单的方法呢?

4

1 回答 1

0

嗯,可以找到很多,也许我的谷歌 fu 很烂。我最终制作了这个脚本来为我做这件事。它用于wpa_supplicant尝试连接,然后解析日志以查找指示身份验证失败或成功的某些字符串。仅使用v2.3测试,如果其他版本的日志输出不同,可能无法正常工作。

它总是会导致您正在测试的无线接口上的当前连接暂时断开,但一旦wpa_supplicant该脚本启动被退出的脚本杀死,它就会立即恢复。

#!/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
于 2016-04-12T21:02:53.500 回答