From a82349347dae59de16599def8e80527d6246d0dd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 22 Jun 2017 14:52:28 +0300 Subject: [PATCH] DPP: Add an example python script for QR Code operations This script can be used to process Android logcat information for scanned QR Codes (e.g., from Barcode Scanner app) and also to display QR Codes for locally generated bootstrap keys. Signed-off-by: Jouni Malinen --- wpa_supplicant/examples/dpp-qrcode.py | 130 ++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100755 wpa_supplicant/examples/dpp-qrcode.py diff --git a/wpa_supplicant/examples/dpp-qrcode.py b/wpa_supplicant/examples/dpp-qrcode.py new file mode 100755 index 000000000..e2a00c910 --- /dev/null +++ b/wpa_supplicant/examples/dpp-qrcode.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# +# Example Android logcat to wpa_supplicant wrapper for QR Code scans +# Copyright (c) 2017, Qualcomm Atheros, Inc. +# +# This software may be distributed under the terms of the BSD license. +# See README for more details. + +import os +import sys +import argparse +import logging +import qrcode + +scriptsdir = os.path.dirname(os.path.realpath(sys.modules[__name__].__file__)) +sys.path.append(os.path.join(scriptsdir, '..', '..', 'wpaspy')) + +import wpaspy + +wpas_ctrl = '/var/run/wpa_supplicant' + +def wpas_connect(): + ifaces = [] + if os.path.isdir(wpas_ctrl): + try: + ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)] + except OSError, error: + print "Could not find wpa_supplicant: ", error + return None + + if len(ifaces) < 1: + print "No wpa_supplicant control interface found" + return None + + for ctrl in ifaces: + try: + wpas = wpaspy.Ctrl(ctrl) + return wpas + except Exception, e: + pass + return None + +def dpp_logcat(): + for line in iter(sys.stdin.readline, ''): + if "ResultHandler: Launching intent: Intent" not in line: + continue + if "act=android.intent.action.VIEW" not in line: + continue + uri = None + for val in line.split(' '): + if val.startswith('dat='): + uri = val.split('=', 1)[1] + break + if not uri: + continue + if not uri.startswith('DPP:'): + continue + print "Found DPP bootstrap info URI:" + print uri + wpas = wpas_connect() + if not wpas: + print "Could not connect to wpa_supplicant" + print + continue + res = wpas.request("DPP_QR_CODE " + uri); + try: + id = int(res) + except ValueError: + print "QR Code URI rejected" + continue + print "QR Code URI accepted - ID=%d" % id + print wpas.request("DPP_BOOTSTRAP_INFO %d" % id) + del wpas + +def dpp_display(curve): + wpas = wpas_connect() + if not wpas: + print "Could not connect to wpa_supplicant" + return + res = wpas.request("STATUS") + addr = None + for line in res.splitlines(): + if line.startswith("address="): + addr = line.split('=')[1] + break + cmd = "DPP_BOOTSTRAP_GEN type=qrcode" + cmd += " chan=81/1" + if addr: + cmd += " mac=" + addr.replace(':','') + if curve: + cmd += " curve=" + curve + res = wpas.request(cmd) + try: + id = int(res) + except ValueError: + print "Failed to generate bootstrap info URI" + return + print "Bootstrap information - ID=%d" % id + print wpas.request("DPP_BOOTSTRAP_INFO %d" % id) + uri = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id) + print uri + print "ID=%d" % id + qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_M, + border=3) + qr.add_data(uri, optimize=5) + qr.print_ascii(tty=True) + print "ID=%d" % id + del wpas + +def main(): + parser = argparse.ArgumentParser(description='Android logcat to wpa_supplicant integration for DPP QR Code operations') + parser.add_argument('-d', const=logging.DEBUG, default=logging.INFO, + action='store_const', dest='loglevel', + help='verbose debug output') + parser.add_argument('--curve', '-c', + help='set a specific curve (P-256, P-384, P-521, BP-256R1, BP-384R1, BP-512R1) for key generation') + parser.add_argument('command', choices=['logcat', + 'display'], + nargs='?') + args = parser.parse_args() + + logging.basicConfig(level=args.loglevel) + + if args.command == "logcat": + dpp_logcat() + elif args.command == "display": + dpp_display(args.curve) + +if __name__ == '__main__': + main()