0

ハードウェア デバイスの Web インターフェイスを作成しており、現在ネットワーク構成ウィザードを実行しています。ユーザーに SSID を選択してもらい、セキュリティで保護されている場合はパスワードを入力します。ウィザードをこれ以上進めずに、パスワードが正しいことをその場で確認したい。

wpa_supplicant詳細をスローしてログ出力を解析するよりも簡単な方法はありますか?

4

1 に答える 1

0

まあ、多分私のGoogle 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 に答える