1d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#!/usr/bin/env python2 2d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt# 3d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt# eapol_test controller 4d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt# Copyright (c) 2015, Jouni Malinen <j@w1.fi> 5d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt# 6d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt# This software may be distributed under the terms of the BSD license. 7d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt# See README for more details. 8d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 9d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtimport argparse 10d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtimport logging 11d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtimport os 12d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtimport Queue 13d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtimport sys 14d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtimport threading 15d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 16d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtlogger = logging.getLogger() 17d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtdir = os.path.dirname(os.path.realpath(sys.modules[__name__].__file__)) 18d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtsys.path.append(os.path.join(dir, '..', 'wpaspy')) 19d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtimport wpaspy 20d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtwpas_ctrl = '/tmp/eapol_test' 21d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 22d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtclass eapol_test: 23d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt def __init__(self, ifname): 24d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt self.ifname = ifname 25d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt self.ctrl = wpaspy.Ctrl(os.path.join(wpas_ctrl, ifname)) 26d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if "PONG" not in self.ctrl.request("PING"): 27d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt raise Exception("Failed to connect to eapol_test (%s)" % ifname) 28d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt self.mon = wpaspy.Ctrl(os.path.join(wpas_ctrl, ifname)) 29d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt self.mon.attach() 30d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 31d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt def add_network(self): 32d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = self.request("ADD_NETWORK") 33d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if "FAIL" in id: 34d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt raise Exception("ADD_NETWORK failed") 35d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return int(id) 36d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 37d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt def remove_network(self, id): 38d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = self.request("REMOVE_NETWORK " + str(id)) 39d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if "FAIL" in id: 40d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt raise Exception("REMOVE_NETWORK failed") 41d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return None 42d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 43d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt def set_network(self, id, field, value): 44d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = self.request("SET_NETWORK " + str(id) + " " + field + " " + value) 45d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if "FAIL" in res: 46d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt raise Exception("SET_NETWORK failed") 47d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return None 48d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 49d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt def set_network_quoted(self, id, field, value): 50d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = self.request("SET_NETWORK " + str(id) + " " + field + ' "' + value + '"') 51d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if "FAIL" in res: 52d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt raise Exception("SET_NETWORK failed") 53d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return None 54d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 55d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt def request(self, cmd, timeout=10): 56d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return self.ctrl.request(cmd, timeout=timeout) 57d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 58d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt def wait_event(self, events, timeout=10): 59d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt start = os.times()[4] 60d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while True: 61d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while self.mon.pending(): 62d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ev = self.mon.recv() 63d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt logger.debug(self.ifname + ": " + ev) 64d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for event in events: 65d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if event in ev: 66d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return ev 67d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt now = os.times()[4] 68d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt remaining = start + timeout - now 69d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if remaining <= 0: 70d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break 71d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if not self.mon.pending(timeout=remaining): 72d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break 73d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return None 74d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 75d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtdef run(ifname, count, no_fast_reauth, res): 76d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et = eapol_test(ifname) 77d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 78d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.request("AP_SCAN 0") 79d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if no_fast_reauth: 80d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.request("SET fast_reauth 0") 81d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else: 82d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.request("SET fast_reauth 1") 83d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt id = et.add_network() 84d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network(id, "key_mgmt", "IEEE8021X") 85d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network(id, "eapol_flags", "0") 86d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network(id, "eap", "TLS") 87d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network_quoted(id, "identity", "user") 88d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network_quoted(id, "ca_cert", 'ca.pem') 89d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network_quoted(id, "client_cert", 'client.pem') 90d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network_quoted(id, "private_key", 'client.key') 91d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network_quoted(id, "private_key_passwd", 'whatever') 92d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.set_network(id, "disabled", "0") 93d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 94d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fail = False 95d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for i in range(count): 96d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.request("REASSOCIATE") 97d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ev = et.wait_event(["CTRL-EVENT-CONNECTED", "CTRL-EVENT-EAP-FAILURE"]) 98d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if ev is None or "CTRL-EVENT-CONNECTED" not in ev: 99d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fail = True 100d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break 101d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 102d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt et.remove_network(id) 103d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 104d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if fail: 105d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res.put("FAIL (%d OK)" % i) 106d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else: 107d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res.put("PASS %d" % (i + 1)) 108d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 109d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtdef main(): 110d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt parser = argparse.ArgumentParser(description='eapol_test controller') 111d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt parser.add_argument('--ctrl', help='control interface directory') 112d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt parser.add_argument('--num', help='number of processes') 113d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt parser.add_argument('--iter', help='number of iterations') 114d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt parser.add_argument('--no-fast-reauth', action='store_true', 115d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt dest='no_fast_reauth', 116d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt help='disable TLS session resumption') 117d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt args = parser.parse_args() 118d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 119d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt num = int(args.num) 120d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iter = int(args.iter) 121d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if args.ctrl: 122d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt global wpas_ctrl 123d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpas_ctrl = args.ctrl 124d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 125d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt t = {} 126d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res = {} 127d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for i in range(num): 128d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt res[i] = Queue.Queue() 129d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt t[i] = threading.Thread(target=run, args=(str(i), iter, 130d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt args.no_fast_reauth, res[i])) 131d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for i in range(num): 132d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt t[i].start() 133d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for i in range(num): 134d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt t[i].join() 135d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt try: 136d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt results = res[i].get(False) 137d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt except: 138d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt results = "N/A" 139d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt print "%d: %s" % (i, results) 140d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 141d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtif __name__ == "__main__": 142d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt main() 143