| #!/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 as 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 as 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() |