139beb93cSSam Leffler /* 239beb93cSSam Leffler * WPA Supplicant - test code 339beb93cSSam Leffler * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 439beb93cSSam Leffler * 539beb93cSSam Leffler * This program is free software; you can redistribute it and/or modify 639beb93cSSam Leffler * it under the terms of the GNU General Public License version 2 as 739beb93cSSam Leffler * published by the Free Software Foundation. 839beb93cSSam Leffler * 939beb93cSSam Leffler * Alternatively, this software may be distributed under the terms of BSD 1039beb93cSSam Leffler * license. 1139beb93cSSam Leffler * 1239beb93cSSam Leffler * See README and COPYING for more details. 1339beb93cSSam Leffler * 1439beb93cSSam Leffler * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c. 1539beb93cSSam Leffler * Not used in production version. 1639beb93cSSam Leffler */ 1739beb93cSSam Leffler 1839beb93cSSam Leffler #include "includes.h" 1939beb93cSSam Leffler #include <assert.h> 2039beb93cSSam Leffler 2139beb93cSSam Leffler #include "common.h" 2239beb93cSSam Leffler #include "config.h" 2339beb93cSSam Leffler #include "eapol_supp/eapol_supp_sm.h" 2439beb93cSSam Leffler #include "eap_peer/eap.h" 2539beb93cSSam Leffler #include "eloop.h" 2639beb93cSSam Leffler #include "wpa.h" 2739beb93cSSam Leffler #include "eap_peer/eap_i.h" 2839beb93cSSam Leffler #include "wpa_supplicant_i.h" 2939beb93cSSam Leffler #include "radius/radius.h" 3039beb93cSSam Leffler #include "radius/radius_client.h" 3139beb93cSSam Leffler #include "ctrl_iface.h" 3239beb93cSSam Leffler #include "pcsc_funcs.h" 3339beb93cSSam Leffler 3439beb93cSSam Leffler 3539beb93cSSam Leffler extern int wpa_debug_level; 3639beb93cSSam Leffler extern int wpa_debug_show_keys; 3739beb93cSSam Leffler 3839beb93cSSam Leffler struct wpa_driver_ops *wpa_supplicant_drivers[] = { NULL }; 3939beb93cSSam Leffler 4039beb93cSSam Leffler 4139beb93cSSam Leffler struct extra_radius_attr { 4239beb93cSSam Leffler u8 type; 4339beb93cSSam Leffler char syntax; 4439beb93cSSam Leffler char *data; 4539beb93cSSam Leffler struct extra_radius_attr *next; 4639beb93cSSam Leffler }; 4739beb93cSSam Leffler 4839beb93cSSam Leffler struct eapol_test_data { 4939beb93cSSam Leffler struct wpa_supplicant *wpa_s; 5039beb93cSSam Leffler 5139beb93cSSam Leffler int eapol_test_num_reauths; 5239beb93cSSam Leffler int no_mppe_keys; 5339beb93cSSam Leffler int num_mppe_ok, num_mppe_mismatch; 5439beb93cSSam Leffler 5539beb93cSSam Leffler u8 radius_identifier; 5639beb93cSSam Leffler struct radius_msg *last_recv_radius; 5739beb93cSSam Leffler struct in_addr own_ip_addr; 5839beb93cSSam Leffler struct radius_client_data *radius; 5939beb93cSSam Leffler struct hostapd_radius_servers *radius_conf; 6039beb93cSSam Leffler 6139beb93cSSam Leffler u8 *last_eap_radius; /* last received EAP Response from Authentication 6239beb93cSSam Leffler * Server */ 6339beb93cSSam Leffler size_t last_eap_radius_len; 6439beb93cSSam Leffler 6539beb93cSSam Leffler u8 authenticator_pmk[PMK_LEN]; 6639beb93cSSam Leffler size_t authenticator_pmk_len; 6739beb93cSSam Leffler int radius_access_accept_received; 6839beb93cSSam Leffler int radius_access_reject_received; 6939beb93cSSam Leffler int auth_timed_out; 7039beb93cSSam Leffler 7139beb93cSSam Leffler u8 *eap_identity; 7239beb93cSSam Leffler size_t eap_identity_len; 7339beb93cSSam Leffler 7439beb93cSSam Leffler char *connect_info; 7539beb93cSSam Leffler u8 own_addr[ETH_ALEN]; 7639beb93cSSam Leffler struct extra_radius_attr *extra_attrs; 7739beb93cSSam Leffler }; 7839beb93cSSam Leffler 7939beb93cSSam Leffler static struct eapol_test_data eapol_test; 8039beb93cSSam Leffler 8139beb93cSSam Leffler 8239beb93cSSam Leffler static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx); 8339beb93cSSam Leffler 8439beb93cSSam Leffler 8539beb93cSSam Leffler static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, 8639beb93cSSam Leffler int level, const char *txt, size_t len) 8739beb93cSSam Leffler { 8839beb93cSSam Leffler if (addr) 8939beb93cSSam Leffler wpa_printf(MSG_DEBUG, "STA " MACSTR ": %s\n", 9039beb93cSSam Leffler MAC2STR(addr), txt); 9139beb93cSSam Leffler else 9239beb93cSSam Leffler wpa_printf(MSG_DEBUG, "%s", txt); 9339beb93cSSam Leffler } 9439beb93cSSam Leffler 9539beb93cSSam Leffler 9639beb93cSSam Leffler static int add_extra_attr(struct radius_msg *msg, 9739beb93cSSam Leffler struct extra_radius_attr *attr) 9839beb93cSSam Leffler { 9939beb93cSSam Leffler size_t len; 10039beb93cSSam Leffler char *pos; 10139beb93cSSam Leffler u32 val; 10239beb93cSSam Leffler char buf[128]; 10339beb93cSSam Leffler 10439beb93cSSam Leffler switch (attr->syntax) { 10539beb93cSSam Leffler case 's': 10639beb93cSSam Leffler os_snprintf(buf, sizeof(buf), "%s", attr->data); 10739beb93cSSam Leffler len = os_strlen(buf); 10839beb93cSSam Leffler break; 10939beb93cSSam Leffler case 'n': 11039beb93cSSam Leffler buf[0] = '\0'; 11139beb93cSSam Leffler len = 1; 11239beb93cSSam Leffler break; 11339beb93cSSam Leffler case 'x': 11439beb93cSSam Leffler pos = attr->data; 11539beb93cSSam Leffler if (pos[0] == '0' && pos[1] == 'x') 11639beb93cSSam Leffler pos += 2; 11739beb93cSSam Leffler len = os_strlen(pos); 11839beb93cSSam Leffler if ((len & 1) || (len / 2) > sizeof(buf)) { 11939beb93cSSam Leffler printf("Invalid extra attribute hexstring\n"); 12039beb93cSSam Leffler return -1; 12139beb93cSSam Leffler } 12239beb93cSSam Leffler len /= 2; 12339beb93cSSam Leffler if (hexstr2bin(pos, (u8 *) buf, len) < 0) { 12439beb93cSSam Leffler printf("Invalid extra attribute hexstring\n"); 12539beb93cSSam Leffler return -1; 12639beb93cSSam Leffler } 12739beb93cSSam Leffler break; 12839beb93cSSam Leffler case 'd': 12939beb93cSSam Leffler val = htonl(atoi(attr->data)); 13039beb93cSSam Leffler os_memcpy(buf, &val, 4); 13139beb93cSSam Leffler len = 4; 13239beb93cSSam Leffler break; 13339beb93cSSam Leffler default: 13439beb93cSSam Leffler printf("Incorrect extra attribute syntax specification\n"); 13539beb93cSSam Leffler return -1; 13639beb93cSSam Leffler } 13739beb93cSSam Leffler 13839beb93cSSam Leffler if (!radius_msg_add_attr(msg, attr->type, (u8 *) buf, len)) { 13939beb93cSSam Leffler printf("Could not add attribute %d\n", attr->type); 14039beb93cSSam Leffler return -1; 14139beb93cSSam Leffler } 14239beb93cSSam Leffler 14339beb93cSSam Leffler return 0; 14439beb93cSSam Leffler } 14539beb93cSSam Leffler 14639beb93cSSam Leffler 14739beb93cSSam Leffler static int add_extra_attrs(struct radius_msg *msg, 14839beb93cSSam Leffler struct extra_radius_attr *attrs) 14939beb93cSSam Leffler { 15039beb93cSSam Leffler struct extra_radius_attr *p; 15139beb93cSSam Leffler for (p = attrs; p; p = p->next) { 15239beb93cSSam Leffler if (add_extra_attr(msg, p) < 0) 15339beb93cSSam Leffler return -1; 15439beb93cSSam Leffler } 15539beb93cSSam Leffler return 0; 15639beb93cSSam Leffler } 15739beb93cSSam Leffler 15839beb93cSSam Leffler 15939beb93cSSam Leffler static struct extra_radius_attr * 16039beb93cSSam Leffler find_extra_attr(struct extra_radius_attr *attrs, u8 type) 16139beb93cSSam Leffler { 16239beb93cSSam Leffler struct extra_radius_attr *p; 16339beb93cSSam Leffler for (p = attrs; p; p = p->next) { 16439beb93cSSam Leffler if (p->type == type) 16539beb93cSSam Leffler return p; 16639beb93cSSam Leffler } 16739beb93cSSam Leffler return NULL; 16839beb93cSSam Leffler } 16939beb93cSSam Leffler 17039beb93cSSam Leffler 17139beb93cSSam Leffler static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, 17239beb93cSSam Leffler const u8 *eap, size_t len) 17339beb93cSSam Leffler { 17439beb93cSSam Leffler struct radius_msg *msg; 17539beb93cSSam Leffler char buf[128]; 17639beb93cSSam Leffler const struct eap_hdr *hdr; 17739beb93cSSam Leffler const u8 *pos; 17839beb93cSSam Leffler 17939beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " 18039beb93cSSam Leffler "packet"); 18139beb93cSSam Leffler 18239beb93cSSam Leffler e->radius_identifier = radius_client_get_id(e->radius); 18339beb93cSSam Leffler msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, 18439beb93cSSam Leffler e->radius_identifier); 18539beb93cSSam Leffler if (msg == NULL) { 18639beb93cSSam Leffler printf("Could not create net RADIUS packet\n"); 18739beb93cSSam Leffler return; 18839beb93cSSam Leffler } 18939beb93cSSam Leffler 19039beb93cSSam Leffler radius_msg_make_authenticator(msg, (u8 *) e, sizeof(*e)); 19139beb93cSSam Leffler 19239beb93cSSam Leffler hdr = (const struct eap_hdr *) eap; 19339beb93cSSam Leffler pos = (const u8 *) (hdr + 1); 19439beb93cSSam Leffler if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE && 19539beb93cSSam Leffler pos[0] == EAP_TYPE_IDENTITY) { 19639beb93cSSam Leffler pos++; 19739beb93cSSam Leffler os_free(e->eap_identity); 19839beb93cSSam Leffler e->eap_identity_len = len - sizeof(*hdr) - 1; 19939beb93cSSam Leffler e->eap_identity = os_malloc(e->eap_identity_len); 20039beb93cSSam Leffler if (e->eap_identity) { 20139beb93cSSam Leffler os_memcpy(e->eap_identity, pos, e->eap_identity_len); 20239beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "Learned identity from " 20339beb93cSSam Leffler "EAP-Response-Identity", 20439beb93cSSam Leffler e->eap_identity, e->eap_identity_len); 20539beb93cSSam Leffler } 20639beb93cSSam Leffler } 20739beb93cSSam Leffler 20839beb93cSSam Leffler if (e->eap_identity && 20939beb93cSSam Leffler !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, 21039beb93cSSam Leffler e->eap_identity, e->eap_identity_len)) { 21139beb93cSSam Leffler printf("Could not add User-Name\n"); 21239beb93cSSam Leffler goto fail; 21339beb93cSSam Leffler } 21439beb93cSSam Leffler 21539beb93cSSam Leffler if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_IP_ADDRESS) && 21639beb93cSSam Leffler !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, 21739beb93cSSam Leffler (u8 *) &e->own_ip_addr, 4)) { 21839beb93cSSam Leffler printf("Could not add NAS-IP-Address\n"); 21939beb93cSSam Leffler goto fail; 22039beb93cSSam Leffler } 22139beb93cSSam Leffler 22239beb93cSSam Leffler os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 22339beb93cSSam Leffler MAC2STR(e->wpa_s->own_addr)); 22439beb93cSSam Leffler if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CALLING_STATION_ID) 22539beb93cSSam Leffler && 22639beb93cSSam Leffler !radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 22739beb93cSSam Leffler (u8 *) buf, os_strlen(buf))) { 22839beb93cSSam Leffler printf("Could not add Calling-Station-Id\n"); 22939beb93cSSam Leffler goto fail; 23039beb93cSSam Leffler } 23139beb93cSSam Leffler 23239beb93cSSam Leffler /* TODO: should probably check MTU from driver config; 2304 is max for 23339beb93cSSam Leffler * IEEE 802.11, but use 1400 to avoid problems with too large packets 23439beb93cSSam Leffler */ 23539beb93cSSam Leffler if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_FRAMED_MTU) && 23639beb93cSSam Leffler !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { 23739beb93cSSam Leffler printf("Could not add Framed-MTU\n"); 23839beb93cSSam Leffler goto fail; 23939beb93cSSam Leffler } 24039beb93cSSam Leffler 24139beb93cSSam Leffler if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_PORT_TYPE) && 24239beb93cSSam Leffler !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE, 24339beb93cSSam Leffler RADIUS_NAS_PORT_TYPE_IEEE_802_11)) { 24439beb93cSSam Leffler printf("Could not add NAS-Port-Type\n"); 24539beb93cSSam Leffler goto fail; 24639beb93cSSam Leffler } 24739beb93cSSam Leffler 24839beb93cSSam Leffler os_snprintf(buf, sizeof(buf), "%s", e->connect_info); 24939beb93cSSam Leffler if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CONNECT_INFO) && 25039beb93cSSam Leffler !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 25139beb93cSSam Leffler (u8 *) buf, os_strlen(buf))) { 25239beb93cSSam Leffler printf("Could not add Connect-Info\n"); 25339beb93cSSam Leffler goto fail; 25439beb93cSSam Leffler } 25539beb93cSSam Leffler 25639beb93cSSam Leffler if (add_extra_attrs(msg, e->extra_attrs) < 0) 25739beb93cSSam Leffler goto fail; 25839beb93cSSam Leffler 25939beb93cSSam Leffler if (eap && !radius_msg_add_eap(msg, eap, len)) { 26039beb93cSSam Leffler printf("Could not add EAP-Message\n"); 26139beb93cSSam Leffler goto fail; 26239beb93cSSam Leffler } 26339beb93cSSam Leffler 26439beb93cSSam Leffler /* State attribute must be copied if and only if this packet is 26539beb93cSSam Leffler * Access-Request reply to the previous Access-Challenge */ 26639beb93cSSam Leffler if (e->last_recv_radius && e->last_recv_radius->hdr->code == 26739beb93cSSam Leffler RADIUS_CODE_ACCESS_CHALLENGE) { 26839beb93cSSam Leffler int res = radius_msg_copy_attr(msg, e->last_recv_radius, 26939beb93cSSam Leffler RADIUS_ATTR_STATE); 27039beb93cSSam Leffler if (res < 0) { 27139beb93cSSam Leffler printf("Could not copy State attribute from previous " 27239beb93cSSam Leffler "Access-Challenge\n"); 27339beb93cSSam Leffler goto fail; 27439beb93cSSam Leffler } 27539beb93cSSam Leffler if (res > 0) { 27639beb93cSSam Leffler wpa_printf(MSG_DEBUG, " Copied RADIUS State " 27739beb93cSSam Leffler "Attribute"); 27839beb93cSSam Leffler } 27939beb93cSSam Leffler } 28039beb93cSSam Leffler 28139beb93cSSam Leffler radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr); 28239beb93cSSam Leffler return; 28339beb93cSSam Leffler 28439beb93cSSam Leffler fail: 28539beb93cSSam Leffler radius_msg_free(msg); 28639beb93cSSam Leffler os_free(msg); 28739beb93cSSam Leffler } 28839beb93cSSam Leffler 28939beb93cSSam Leffler 29039beb93cSSam Leffler static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf, 29139beb93cSSam Leffler size_t len) 29239beb93cSSam Leffler { 29339beb93cSSam Leffler /* struct wpa_supplicant *wpa_s = ctx; */ 29439beb93cSSam Leffler printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n", 29539beb93cSSam Leffler type, (unsigned long) len); 29639beb93cSSam Leffler if (type == IEEE802_1X_TYPE_EAP_PACKET) { 29739beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len); 29839beb93cSSam Leffler ieee802_1x_encapsulate_radius(&eapol_test, buf, len); 29939beb93cSSam Leffler } 30039beb93cSSam Leffler return 0; 30139beb93cSSam Leffler } 30239beb93cSSam Leffler 30339beb93cSSam Leffler 30439beb93cSSam Leffler static void eapol_test_set_config_blob(void *ctx, 30539beb93cSSam Leffler struct wpa_config_blob *blob) 30639beb93cSSam Leffler { 30739beb93cSSam Leffler struct wpa_supplicant *wpa_s = ctx; 30839beb93cSSam Leffler wpa_config_set_blob(wpa_s->conf, blob); 30939beb93cSSam Leffler } 31039beb93cSSam Leffler 31139beb93cSSam Leffler 31239beb93cSSam Leffler static const struct wpa_config_blob * 31339beb93cSSam Leffler eapol_test_get_config_blob(void *ctx, const char *name) 31439beb93cSSam Leffler { 31539beb93cSSam Leffler struct wpa_supplicant *wpa_s = ctx; 31639beb93cSSam Leffler return wpa_config_get_blob(wpa_s->conf, name); 31739beb93cSSam Leffler } 31839beb93cSSam Leffler 31939beb93cSSam Leffler 32039beb93cSSam Leffler static void eapol_test_eapol_done_cb(void *ctx) 32139beb93cSSam Leffler { 32239beb93cSSam Leffler printf("WPA: EAPOL processing complete\n"); 32339beb93cSSam Leffler } 32439beb93cSSam Leffler 32539beb93cSSam Leffler 32639beb93cSSam Leffler static void eapol_sm_reauth(void *eloop_ctx, void *timeout_ctx) 32739beb93cSSam Leffler { 32839beb93cSSam Leffler struct eapol_test_data *e = eloop_ctx; 32939beb93cSSam Leffler printf("\n\n\n\n\neapol_test: Triggering EAP reauthentication\n\n"); 33039beb93cSSam Leffler e->radius_access_accept_received = 0; 33139beb93cSSam Leffler send_eap_request_identity(e->wpa_s, NULL); 33239beb93cSSam Leffler } 33339beb93cSSam Leffler 33439beb93cSSam Leffler 33539beb93cSSam Leffler static int eapol_test_compare_pmk(struct eapol_test_data *e) 33639beb93cSSam Leffler { 33739beb93cSSam Leffler u8 pmk[PMK_LEN]; 33839beb93cSSam Leffler int ret = 1; 33939beb93cSSam Leffler 34039beb93cSSam Leffler if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) { 34139beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN); 34239beb93cSSam Leffler if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) { 34339beb93cSSam Leffler printf("WARNING: PMK mismatch\n"); 34439beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "PMK from AS", 34539beb93cSSam Leffler e->authenticator_pmk, PMK_LEN); 34639beb93cSSam Leffler } else if (e->radius_access_accept_received) 34739beb93cSSam Leffler ret = 0; 34839beb93cSSam Leffler } else if (e->authenticator_pmk_len == 16 && 34939beb93cSSam Leffler eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) { 35039beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16); 35139beb93cSSam Leffler if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) { 35239beb93cSSam Leffler printf("WARNING: PMK mismatch\n"); 35339beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "PMK from AS", 35439beb93cSSam Leffler e->authenticator_pmk, 16); 35539beb93cSSam Leffler } else if (e->radius_access_accept_received) 35639beb93cSSam Leffler ret = 0; 35739beb93cSSam Leffler } else if (e->radius_access_accept_received && e->no_mppe_keys) { 35839beb93cSSam Leffler /* No keying material expected */ 35939beb93cSSam Leffler ret = 0; 36039beb93cSSam Leffler } 36139beb93cSSam Leffler 36239beb93cSSam Leffler if (ret && !e->no_mppe_keys) 36339beb93cSSam Leffler e->num_mppe_mismatch++; 36439beb93cSSam Leffler else if (!e->no_mppe_keys) 36539beb93cSSam Leffler e->num_mppe_ok++; 36639beb93cSSam Leffler 36739beb93cSSam Leffler return ret; 36839beb93cSSam Leffler } 36939beb93cSSam Leffler 37039beb93cSSam Leffler 37139beb93cSSam Leffler static void eapol_sm_cb(struct eapol_sm *eapol, int success, void *ctx) 37239beb93cSSam Leffler { 37339beb93cSSam Leffler struct eapol_test_data *e = ctx; 37439beb93cSSam Leffler printf("eapol_sm_cb: success=%d\n", success); 37539beb93cSSam Leffler e->eapol_test_num_reauths--; 37639beb93cSSam Leffler if (e->eapol_test_num_reauths < 0) 37739beb93cSSam Leffler eloop_terminate(); 37839beb93cSSam Leffler else { 37939beb93cSSam Leffler eapol_test_compare_pmk(e); 38039beb93cSSam Leffler eloop_register_timeout(0, 100000, eapol_sm_reauth, e, NULL); 38139beb93cSSam Leffler } 38239beb93cSSam Leffler } 38339beb93cSSam Leffler 38439beb93cSSam Leffler 38539beb93cSSam Leffler static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, 38639beb93cSSam Leffler struct wpa_ssid *ssid) 38739beb93cSSam Leffler { 38839beb93cSSam Leffler struct eapol_config eapol_conf; 38939beb93cSSam Leffler struct eapol_ctx *ctx; 39039beb93cSSam Leffler 39139beb93cSSam Leffler ctx = os_zalloc(sizeof(*ctx)); 39239beb93cSSam Leffler if (ctx == NULL) { 39339beb93cSSam Leffler printf("Failed to allocate EAPOL context.\n"); 39439beb93cSSam Leffler return -1; 39539beb93cSSam Leffler } 39639beb93cSSam Leffler ctx->ctx = wpa_s; 39739beb93cSSam Leffler ctx->msg_ctx = wpa_s; 39839beb93cSSam Leffler ctx->scard_ctx = wpa_s->scard; 39939beb93cSSam Leffler ctx->cb = eapol_sm_cb; 40039beb93cSSam Leffler ctx->cb_ctx = e; 40139beb93cSSam Leffler ctx->eapol_send_ctx = wpa_s; 40239beb93cSSam Leffler ctx->preauth = 0; 40339beb93cSSam Leffler ctx->eapol_done_cb = eapol_test_eapol_done_cb; 40439beb93cSSam Leffler ctx->eapol_send = eapol_test_eapol_send; 40539beb93cSSam Leffler ctx->set_config_blob = eapol_test_set_config_blob; 40639beb93cSSam Leffler ctx->get_config_blob = eapol_test_get_config_blob; 40739beb93cSSam Leffler #ifdef EAP_TLS_OPENSSL 40839beb93cSSam Leffler ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; 40939beb93cSSam Leffler ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; 41039beb93cSSam Leffler ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; 41139beb93cSSam Leffler #endif /* EAP_TLS_OPENSSL */ 41239beb93cSSam Leffler 41339beb93cSSam Leffler wpa_s->eapol = eapol_sm_init(ctx); 41439beb93cSSam Leffler if (wpa_s->eapol == NULL) { 41539beb93cSSam Leffler os_free(ctx); 41639beb93cSSam Leffler printf("Failed to initialize EAPOL state machines.\n"); 41739beb93cSSam Leffler return -1; 41839beb93cSSam Leffler } 41939beb93cSSam Leffler 42039beb93cSSam Leffler wpa_s->current_ssid = ssid; 42139beb93cSSam Leffler os_memset(&eapol_conf, 0, sizeof(eapol_conf)); 42239beb93cSSam Leffler eapol_conf.accept_802_1x_keys = 1; 42339beb93cSSam Leffler eapol_conf.required_keys = 0; 42439beb93cSSam Leffler eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; 42539beb93cSSam Leffler eapol_conf.workaround = ssid->eap_workaround; 42639beb93cSSam Leffler eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf); 42739beb93cSSam Leffler eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); 42839beb93cSSam Leffler 42939beb93cSSam Leffler 43039beb93cSSam Leffler eapol_sm_notify_portValid(wpa_s->eapol, FALSE); 43139beb93cSSam Leffler /* 802.1X::portControl = Auto */ 43239beb93cSSam Leffler eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); 43339beb93cSSam Leffler 43439beb93cSSam Leffler return 0; 43539beb93cSSam Leffler } 43639beb93cSSam Leffler 43739beb93cSSam Leffler 43839beb93cSSam Leffler static void test_eapol_clean(struct eapol_test_data *e, 43939beb93cSSam Leffler struct wpa_supplicant *wpa_s) 44039beb93cSSam Leffler { 44139beb93cSSam Leffler struct extra_radius_attr *p, *prev; 44239beb93cSSam Leffler 44339beb93cSSam Leffler radius_client_deinit(e->radius); 44439beb93cSSam Leffler os_free(e->last_eap_radius); 44539beb93cSSam Leffler if (e->last_recv_radius) { 44639beb93cSSam Leffler radius_msg_free(e->last_recv_radius); 44739beb93cSSam Leffler os_free(e->last_recv_radius); 44839beb93cSSam Leffler } 44939beb93cSSam Leffler os_free(e->eap_identity); 45039beb93cSSam Leffler e->eap_identity = NULL; 45139beb93cSSam Leffler eapol_sm_deinit(wpa_s->eapol); 45239beb93cSSam Leffler wpa_s->eapol = NULL; 45339beb93cSSam Leffler if (e->radius_conf && e->radius_conf->auth_server) { 45439beb93cSSam Leffler os_free(e->radius_conf->auth_server->shared_secret); 45539beb93cSSam Leffler os_free(e->radius_conf->auth_server); 45639beb93cSSam Leffler } 45739beb93cSSam Leffler os_free(e->radius_conf); 45839beb93cSSam Leffler e->radius_conf = NULL; 45939beb93cSSam Leffler scard_deinit(wpa_s->scard); 46039beb93cSSam Leffler if (wpa_s->ctrl_iface) { 46139beb93cSSam Leffler wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); 46239beb93cSSam Leffler wpa_s->ctrl_iface = NULL; 46339beb93cSSam Leffler } 46439beb93cSSam Leffler wpa_config_free(wpa_s->conf); 46539beb93cSSam Leffler 46639beb93cSSam Leffler p = e->extra_attrs; 46739beb93cSSam Leffler while (p) { 46839beb93cSSam Leffler prev = p; 46939beb93cSSam Leffler p = p->next; 47039beb93cSSam Leffler os_free(prev); 47139beb93cSSam Leffler } 47239beb93cSSam Leffler } 47339beb93cSSam Leffler 47439beb93cSSam Leffler 47539beb93cSSam Leffler static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx) 47639beb93cSSam Leffler { 47739beb93cSSam Leffler struct wpa_supplicant *wpa_s = eloop_ctx; 47839beb93cSSam Leffler u8 buf[100], *pos; 47939beb93cSSam Leffler struct ieee802_1x_hdr *hdr; 48039beb93cSSam Leffler struct eap_hdr *eap; 48139beb93cSSam Leffler 48239beb93cSSam Leffler hdr = (struct ieee802_1x_hdr *) buf; 48339beb93cSSam Leffler hdr->version = EAPOL_VERSION; 48439beb93cSSam Leffler hdr->type = IEEE802_1X_TYPE_EAP_PACKET; 48539beb93cSSam Leffler hdr->length = htons(5); 48639beb93cSSam Leffler 48739beb93cSSam Leffler eap = (struct eap_hdr *) (hdr + 1); 48839beb93cSSam Leffler eap->code = EAP_CODE_REQUEST; 48939beb93cSSam Leffler eap->identifier = 0; 49039beb93cSSam Leffler eap->length = htons(5); 49139beb93cSSam Leffler pos = (u8 *) (eap + 1); 49239beb93cSSam Leffler *pos = EAP_TYPE_IDENTITY; 49339beb93cSSam Leffler 49439beb93cSSam Leffler printf("Sending fake EAP-Request-Identity\n"); 49539beb93cSSam Leffler eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf, 49639beb93cSSam Leffler sizeof(*hdr) + 5); 49739beb93cSSam Leffler } 49839beb93cSSam Leffler 49939beb93cSSam Leffler 50039beb93cSSam Leffler static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx) 50139beb93cSSam Leffler { 50239beb93cSSam Leffler struct eapol_test_data *e = eloop_ctx; 50339beb93cSSam Leffler printf("EAPOL test timed out\n"); 50439beb93cSSam Leffler e->auth_timed_out = 1; 50539beb93cSSam Leffler eloop_terminate(); 50639beb93cSSam Leffler } 50739beb93cSSam Leffler 50839beb93cSSam Leffler 50939beb93cSSam Leffler static char *eap_type_text(u8 type) 51039beb93cSSam Leffler { 51139beb93cSSam Leffler switch (type) { 51239beb93cSSam Leffler case EAP_TYPE_IDENTITY: return "Identity"; 51339beb93cSSam Leffler case EAP_TYPE_NOTIFICATION: return "Notification"; 51439beb93cSSam Leffler case EAP_TYPE_NAK: return "Nak"; 51539beb93cSSam Leffler case EAP_TYPE_TLS: return "TLS"; 51639beb93cSSam Leffler case EAP_TYPE_TTLS: return "TTLS"; 51739beb93cSSam Leffler case EAP_TYPE_PEAP: return "PEAP"; 51839beb93cSSam Leffler case EAP_TYPE_SIM: return "SIM"; 51939beb93cSSam Leffler case EAP_TYPE_GTC: return "GTC"; 52039beb93cSSam Leffler case EAP_TYPE_MD5: return "MD5"; 52139beb93cSSam Leffler case EAP_TYPE_OTP: return "OTP"; 52239beb93cSSam Leffler case EAP_TYPE_FAST: return "FAST"; 52339beb93cSSam Leffler case EAP_TYPE_SAKE: return "SAKE"; 52439beb93cSSam Leffler case EAP_TYPE_PSK: return "PSK"; 52539beb93cSSam Leffler default: return "Unknown"; 52639beb93cSSam Leffler } 52739beb93cSSam Leffler } 52839beb93cSSam Leffler 52939beb93cSSam Leffler 53039beb93cSSam Leffler static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) 53139beb93cSSam Leffler { 53239beb93cSSam Leffler u8 *eap; 53339beb93cSSam Leffler size_t len; 53439beb93cSSam Leffler struct eap_hdr *hdr; 53539beb93cSSam Leffler int eap_type = -1; 53639beb93cSSam Leffler char buf[64]; 53739beb93cSSam Leffler struct radius_msg *msg; 53839beb93cSSam Leffler 53939beb93cSSam Leffler if (e->last_recv_radius == NULL) 54039beb93cSSam Leffler return; 54139beb93cSSam Leffler 54239beb93cSSam Leffler msg = e->last_recv_radius; 54339beb93cSSam Leffler 54439beb93cSSam Leffler eap = radius_msg_get_eap(msg, &len); 54539beb93cSSam Leffler if (eap == NULL) { 54639beb93cSSam Leffler /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3: 54739beb93cSSam Leffler * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message 54839beb93cSSam Leffler * attribute */ 54939beb93cSSam Leffler wpa_printf(MSG_DEBUG, "could not extract " 55039beb93cSSam Leffler "EAP-Message from RADIUS message"); 55139beb93cSSam Leffler os_free(e->last_eap_radius); 55239beb93cSSam Leffler e->last_eap_radius = NULL; 55339beb93cSSam Leffler e->last_eap_radius_len = 0; 55439beb93cSSam Leffler return; 55539beb93cSSam Leffler } 55639beb93cSSam Leffler 55739beb93cSSam Leffler if (len < sizeof(*hdr)) { 55839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "too short EAP packet " 55939beb93cSSam Leffler "received from authentication server"); 56039beb93cSSam Leffler os_free(eap); 56139beb93cSSam Leffler return; 56239beb93cSSam Leffler } 56339beb93cSSam Leffler 56439beb93cSSam Leffler if (len > sizeof(*hdr)) 56539beb93cSSam Leffler eap_type = eap[sizeof(*hdr)]; 56639beb93cSSam Leffler 56739beb93cSSam Leffler hdr = (struct eap_hdr *) eap; 56839beb93cSSam Leffler switch (hdr->code) { 56939beb93cSSam Leffler case EAP_CODE_REQUEST: 57039beb93cSSam Leffler os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", 57139beb93cSSam Leffler eap_type >= 0 ? eap_type_text(eap_type) : "??", 57239beb93cSSam Leffler eap_type); 57339beb93cSSam Leffler break; 57439beb93cSSam Leffler case EAP_CODE_RESPONSE: 57539beb93cSSam Leffler os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)", 57639beb93cSSam Leffler eap_type >= 0 ? eap_type_text(eap_type) : "??", 57739beb93cSSam Leffler eap_type); 57839beb93cSSam Leffler break; 57939beb93cSSam Leffler case EAP_CODE_SUCCESS: 58039beb93cSSam Leffler os_strlcpy(buf, "EAP Success", sizeof(buf)); 58139beb93cSSam Leffler /* LEAP uses EAP Success within an authentication, so must not 58239beb93cSSam Leffler * stop here with eloop_terminate(); */ 58339beb93cSSam Leffler break; 58439beb93cSSam Leffler case EAP_CODE_FAILURE: 58539beb93cSSam Leffler os_strlcpy(buf, "EAP Failure", sizeof(buf)); 58639beb93cSSam Leffler eloop_terminate(); 58739beb93cSSam Leffler break; 58839beb93cSSam Leffler default: 58939beb93cSSam Leffler os_strlcpy(buf, "unknown EAP code", sizeof(buf)); 59039beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "Decapsulated EAP packet", eap, len); 59139beb93cSSam Leffler break; 59239beb93cSSam Leffler } 59339beb93cSSam Leffler wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d " 59439beb93cSSam Leffler "id=%d len=%d) from RADIUS server: %s", 59539beb93cSSam Leffler hdr->code, hdr->identifier, ntohs(hdr->length), buf); 59639beb93cSSam Leffler 59739beb93cSSam Leffler /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */ 59839beb93cSSam Leffler 59939beb93cSSam Leffler os_free(e->last_eap_radius); 60039beb93cSSam Leffler e->last_eap_radius = eap; 60139beb93cSSam Leffler e->last_eap_radius_len = len; 60239beb93cSSam Leffler 60339beb93cSSam Leffler { 60439beb93cSSam Leffler struct ieee802_1x_hdr *dot1x; 60539beb93cSSam Leffler dot1x = os_malloc(sizeof(*dot1x) + len); 60639beb93cSSam Leffler assert(dot1x != NULL); 60739beb93cSSam Leffler dot1x->version = EAPOL_VERSION; 60839beb93cSSam Leffler dot1x->type = IEEE802_1X_TYPE_EAP_PACKET; 60939beb93cSSam Leffler dot1x->length = htons(len); 61039beb93cSSam Leffler os_memcpy((u8 *) (dot1x + 1), eap, len); 61139beb93cSSam Leffler eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid, 61239beb93cSSam Leffler (u8 *) dot1x, sizeof(*dot1x) + len); 61339beb93cSSam Leffler os_free(dot1x); 61439beb93cSSam Leffler } 61539beb93cSSam Leffler } 61639beb93cSSam Leffler 61739beb93cSSam Leffler 61839beb93cSSam Leffler static void ieee802_1x_get_keys(struct eapol_test_data *e, 61939beb93cSSam Leffler struct radius_msg *msg, struct radius_msg *req, 62039beb93cSSam Leffler u8 *shared_secret, size_t shared_secret_len) 62139beb93cSSam Leffler { 62239beb93cSSam Leffler struct radius_ms_mppe_keys *keys; 62339beb93cSSam Leffler 62439beb93cSSam Leffler keys = radius_msg_get_ms_keys(msg, req, shared_secret, 62539beb93cSSam Leffler shared_secret_len); 62639beb93cSSam Leffler if (keys && keys->send == NULL && keys->recv == NULL) { 62739beb93cSSam Leffler os_free(keys); 62839beb93cSSam Leffler keys = radius_msg_get_cisco_keys(msg, req, shared_secret, 62939beb93cSSam Leffler shared_secret_len); 63039beb93cSSam Leffler } 63139beb93cSSam Leffler 63239beb93cSSam Leffler if (keys) { 63339beb93cSSam Leffler if (keys->send) { 63439beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)", 63539beb93cSSam Leffler keys->send, keys->send_len); 63639beb93cSSam Leffler } 63739beb93cSSam Leffler if (keys->recv) { 63839beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)", 63939beb93cSSam Leffler keys->recv, keys->recv_len); 64039beb93cSSam Leffler e->authenticator_pmk_len = 64139beb93cSSam Leffler keys->recv_len > PMK_LEN ? PMK_LEN : 64239beb93cSSam Leffler keys->recv_len; 64339beb93cSSam Leffler os_memcpy(e->authenticator_pmk, keys->recv, 64439beb93cSSam Leffler e->authenticator_pmk_len); 64539beb93cSSam Leffler if (e->authenticator_pmk_len == 16 && keys->send && 64639beb93cSSam Leffler keys->send_len == 16) { 64739beb93cSSam Leffler /* MS-CHAP-v2 derives 16 octet keys */ 64839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key " 64939beb93cSSam Leffler "to extend PMK to 32 octets"); 65039beb93cSSam Leffler os_memcpy(e->authenticator_pmk + 65139beb93cSSam Leffler e->authenticator_pmk_len, 65239beb93cSSam Leffler keys->send, keys->send_len); 65339beb93cSSam Leffler e->authenticator_pmk_len += keys->send_len; 65439beb93cSSam Leffler } 65539beb93cSSam Leffler } 65639beb93cSSam Leffler 65739beb93cSSam Leffler os_free(keys->send); 65839beb93cSSam Leffler os_free(keys->recv); 65939beb93cSSam Leffler os_free(keys); 66039beb93cSSam Leffler } 66139beb93cSSam Leffler } 66239beb93cSSam Leffler 66339beb93cSSam Leffler 66439beb93cSSam Leffler /* Process the RADIUS frames from Authentication Server */ 66539beb93cSSam Leffler static RadiusRxResult 66639beb93cSSam Leffler ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, 66739beb93cSSam Leffler u8 *shared_secret, size_t shared_secret_len, 66839beb93cSSam Leffler void *data) 66939beb93cSSam Leffler { 67039beb93cSSam Leffler struct eapol_test_data *e = data; 67139beb93cSSam Leffler 67239beb93cSSam Leffler /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be 67339beb93cSSam Leffler * present when packet contains an EAP-Message attribute */ 67439beb93cSSam Leffler if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT && 67539beb93cSSam Leffler radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 67639beb93cSSam Leffler 0) < 0 && 67739beb93cSSam Leffler radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { 67839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Allowing RADIUS " 67939beb93cSSam Leffler "Access-Reject without Message-Authenticator " 68039beb93cSSam Leffler "since it does not include EAP-Message\n"); 68139beb93cSSam Leffler } else if (radius_msg_verify(msg, shared_secret, shared_secret_len, 68239beb93cSSam Leffler req, 1)) { 68339beb93cSSam Leffler printf("Incoming RADIUS packet did not have correct " 68439beb93cSSam Leffler "Message-Authenticator - dropped\n"); 68539beb93cSSam Leffler return RADIUS_RX_UNKNOWN; 68639beb93cSSam Leffler } 68739beb93cSSam Leffler 68839beb93cSSam Leffler if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 68939beb93cSSam Leffler msg->hdr->code != RADIUS_CODE_ACCESS_REJECT && 69039beb93cSSam Leffler msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { 69139beb93cSSam Leffler printf("Unknown RADIUS message code\n"); 69239beb93cSSam Leffler return RADIUS_RX_UNKNOWN; 69339beb93cSSam Leffler } 69439beb93cSSam Leffler 69539beb93cSSam Leffler e->radius_identifier = -1; 69639beb93cSSam Leffler wpa_printf(MSG_DEBUG, "RADIUS packet matching with station"); 69739beb93cSSam Leffler 69839beb93cSSam Leffler if (e->last_recv_radius) { 69939beb93cSSam Leffler radius_msg_free(e->last_recv_radius); 70039beb93cSSam Leffler os_free(e->last_recv_radius); 70139beb93cSSam Leffler } 70239beb93cSSam Leffler 70339beb93cSSam Leffler e->last_recv_radius = msg; 70439beb93cSSam Leffler 70539beb93cSSam Leffler switch (msg->hdr->code) { 70639beb93cSSam Leffler case RADIUS_CODE_ACCESS_ACCEPT: 70739beb93cSSam Leffler e->radius_access_accept_received = 1; 70839beb93cSSam Leffler ieee802_1x_get_keys(e, msg, req, shared_secret, 70939beb93cSSam Leffler shared_secret_len); 71039beb93cSSam Leffler break; 71139beb93cSSam Leffler case RADIUS_CODE_ACCESS_REJECT: 71239beb93cSSam Leffler e->radius_access_reject_received = 1; 71339beb93cSSam Leffler break; 71439beb93cSSam Leffler } 71539beb93cSSam Leffler 71639beb93cSSam Leffler ieee802_1x_decapsulate_radius(e); 71739beb93cSSam Leffler 71839beb93cSSam Leffler if ((msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT && 71939beb93cSSam Leffler e->eapol_test_num_reauths < 0) || 72039beb93cSSam Leffler msg->hdr->code == RADIUS_CODE_ACCESS_REJECT) { 72139beb93cSSam Leffler eloop_terminate(); 72239beb93cSSam Leffler } 72339beb93cSSam Leffler 72439beb93cSSam Leffler return RADIUS_RX_QUEUED; 72539beb93cSSam Leffler } 72639beb93cSSam Leffler 72739beb93cSSam Leffler 72839beb93cSSam Leffler static void wpa_init_conf(struct eapol_test_data *e, 72939beb93cSSam Leffler struct wpa_supplicant *wpa_s, const char *authsrv, 73039beb93cSSam Leffler int port, const char *secret, 73139beb93cSSam Leffler const char *cli_addr) 73239beb93cSSam Leffler { 73339beb93cSSam Leffler struct hostapd_radius_server *as; 73439beb93cSSam Leffler int res; 73539beb93cSSam Leffler 73639beb93cSSam Leffler wpa_s->bssid[5] = 1; 73739beb93cSSam Leffler os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN); 73839beb93cSSam Leffler e->own_ip_addr.s_addr = htonl((127 << 24) | 1); 73939beb93cSSam Leffler os_strlcpy(wpa_s->ifname, "test", sizeof(wpa_s->ifname)); 74039beb93cSSam Leffler 74139beb93cSSam Leffler e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers)); 74239beb93cSSam Leffler assert(e->radius_conf != NULL); 74339beb93cSSam Leffler e->radius_conf->num_auth_servers = 1; 74439beb93cSSam Leffler as = os_zalloc(sizeof(struct hostapd_radius_server)); 74539beb93cSSam Leffler assert(as != NULL); 74639beb93cSSam Leffler #if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) 74739beb93cSSam Leffler { 74839beb93cSSam Leffler int a[4]; 74939beb93cSSam Leffler u8 *pos; 75039beb93cSSam Leffler sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 75139beb93cSSam Leffler pos = (u8 *) &as->addr.u.v4; 75239beb93cSSam Leffler *pos++ = a[0]; 75339beb93cSSam Leffler *pos++ = a[1]; 75439beb93cSSam Leffler *pos++ = a[2]; 75539beb93cSSam Leffler *pos++ = a[3]; 75639beb93cSSam Leffler } 75739beb93cSSam Leffler #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 75839beb93cSSam Leffler inet_aton(authsrv, &as->addr.u.v4); 75939beb93cSSam Leffler #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 76039beb93cSSam Leffler as->addr.af = AF_INET; 76139beb93cSSam Leffler as->port = port; 76239beb93cSSam Leffler as->shared_secret = (u8 *) os_strdup(secret); 76339beb93cSSam Leffler as->shared_secret_len = os_strlen(secret); 76439beb93cSSam Leffler e->radius_conf->auth_server = as; 76539beb93cSSam Leffler e->radius_conf->auth_servers = as; 76639beb93cSSam Leffler e->radius_conf->msg_dumps = 1; 76739beb93cSSam Leffler if (cli_addr) { 76839beb93cSSam Leffler if (hostapd_parse_ip_addr(cli_addr, 76939beb93cSSam Leffler &e->radius_conf->client_addr) == 0) 77039beb93cSSam Leffler e->radius_conf->force_client_addr = 1; 77139beb93cSSam Leffler else { 77239beb93cSSam Leffler wpa_printf(MSG_ERROR, "Invalid IP address '%s'", 77339beb93cSSam Leffler cli_addr); 77439beb93cSSam Leffler assert(0); 77539beb93cSSam Leffler } 77639beb93cSSam Leffler } 77739beb93cSSam Leffler 77839beb93cSSam Leffler e->radius = radius_client_init(wpa_s, e->radius_conf); 77939beb93cSSam Leffler assert(e->radius != NULL); 78039beb93cSSam Leffler 78139beb93cSSam Leffler res = radius_client_register(e->radius, RADIUS_AUTH, 78239beb93cSSam Leffler ieee802_1x_receive_auth, e); 78339beb93cSSam Leffler assert(res == 0); 78439beb93cSSam Leffler } 78539beb93cSSam Leffler 78639beb93cSSam Leffler 78739beb93cSSam Leffler static int scard_test(void) 78839beb93cSSam Leffler { 78939beb93cSSam Leffler struct scard_data *scard; 79039beb93cSSam Leffler size_t len; 79139beb93cSSam Leffler char imsi[20]; 79239beb93cSSam Leffler unsigned char _rand[16]; 79339beb93cSSam Leffler #ifdef PCSC_FUNCS 79439beb93cSSam Leffler unsigned char sres[4]; 79539beb93cSSam Leffler unsigned char kc[8]; 79639beb93cSSam Leffler #endif /* PCSC_FUNCS */ 79739beb93cSSam Leffler #define num_triplets 5 79839beb93cSSam Leffler unsigned char rand_[num_triplets][16]; 79939beb93cSSam Leffler unsigned char sres_[num_triplets][4]; 80039beb93cSSam Leffler unsigned char kc_[num_triplets][8]; 80139beb93cSSam Leffler int i, res; 80239beb93cSSam Leffler size_t j; 80339beb93cSSam Leffler 80439beb93cSSam Leffler #define AKA_RAND_LEN 16 80539beb93cSSam Leffler #define AKA_AUTN_LEN 16 80639beb93cSSam Leffler #define AKA_AUTS_LEN 14 80739beb93cSSam Leffler #define RES_MAX_LEN 16 80839beb93cSSam Leffler #define IK_LEN 16 80939beb93cSSam Leffler #define CK_LEN 16 81039beb93cSSam Leffler unsigned char aka_rand[AKA_RAND_LEN]; 81139beb93cSSam Leffler unsigned char aka_autn[AKA_AUTN_LEN]; 81239beb93cSSam Leffler unsigned char aka_auts[AKA_AUTS_LEN]; 81339beb93cSSam Leffler unsigned char aka_res[RES_MAX_LEN]; 81439beb93cSSam Leffler size_t aka_res_len; 81539beb93cSSam Leffler unsigned char aka_ik[IK_LEN]; 81639beb93cSSam Leffler unsigned char aka_ck[CK_LEN]; 81739beb93cSSam Leffler 81839beb93cSSam Leffler scard = scard_init(SCARD_TRY_BOTH); 81939beb93cSSam Leffler if (scard == NULL) 82039beb93cSSam Leffler return -1; 82139beb93cSSam Leffler if (scard_set_pin(scard, "1234")) { 82239beb93cSSam Leffler wpa_printf(MSG_WARNING, "PIN validation failed"); 82339beb93cSSam Leffler scard_deinit(scard); 82439beb93cSSam Leffler return -1; 82539beb93cSSam Leffler } 82639beb93cSSam Leffler 82739beb93cSSam Leffler len = sizeof(imsi); 82839beb93cSSam Leffler if (scard_get_imsi(scard, imsi, &len)) 82939beb93cSSam Leffler goto failed; 83039beb93cSSam Leffler wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len); 83139beb93cSSam Leffler /* NOTE: Permanent Username: 1 | IMSI */ 83239beb93cSSam Leffler 83339beb93cSSam Leffler os_memset(_rand, 0, sizeof(_rand)); 83439beb93cSSam Leffler if (scard_gsm_auth(scard, _rand, sres, kc)) 83539beb93cSSam Leffler goto failed; 83639beb93cSSam Leffler 83739beb93cSSam Leffler os_memset(_rand, 0xff, sizeof(_rand)); 83839beb93cSSam Leffler if (scard_gsm_auth(scard, _rand, sres, kc)) 83939beb93cSSam Leffler goto failed; 84039beb93cSSam Leffler 84139beb93cSSam Leffler for (i = 0; i < num_triplets; i++) { 84239beb93cSSam Leffler os_memset(rand_[i], i, sizeof(rand_[i])); 84339beb93cSSam Leffler if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i])) 84439beb93cSSam Leffler goto failed; 84539beb93cSSam Leffler } 84639beb93cSSam Leffler 84739beb93cSSam Leffler for (i = 0; i < num_triplets; i++) { 84839beb93cSSam Leffler printf("1"); 84939beb93cSSam Leffler for (j = 0; j < len; j++) 85039beb93cSSam Leffler printf("%c", imsi[j]); 85139beb93cSSam Leffler printf(","); 85239beb93cSSam Leffler for (j = 0; j < 16; j++) 85339beb93cSSam Leffler printf("%02X", rand_[i][j]); 85439beb93cSSam Leffler printf(","); 85539beb93cSSam Leffler for (j = 0; j < 4; j++) 85639beb93cSSam Leffler printf("%02X", sres_[i][j]); 85739beb93cSSam Leffler printf(","); 85839beb93cSSam Leffler for (j = 0; j < 8; j++) 85939beb93cSSam Leffler printf("%02X", kc_[i][j]); 86039beb93cSSam Leffler printf("\n"); 86139beb93cSSam Leffler } 86239beb93cSSam Leffler 86339beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication"); 86439beb93cSSam Leffler 86539beb93cSSam Leffler /* seq 39 (0x28) */ 86639beb93cSSam Leffler os_memset(aka_rand, 0xaa, 16); 86739beb93cSSam Leffler os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf" 86839beb93cSSam Leffler "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16); 86939beb93cSSam Leffler 87039beb93cSSam Leffler res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len, 87139beb93cSSam Leffler aka_ik, aka_ck, aka_auts); 87239beb93cSSam Leffler if (res == 0) { 87339beb93cSSam Leffler wpa_printf(MSG_DEBUG, "UMTS auth completed successfully"); 87439beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len); 87539beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN); 87639beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN); 87739beb93cSSam Leffler } else if (res == -2) { 87839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization " 87939beb93cSSam Leffler "failure"); 88039beb93cSSam Leffler wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN); 88139beb93cSSam Leffler } else { 88239beb93cSSam Leffler wpa_printf(MSG_DEBUG, "UMTS auth failed"); 88339beb93cSSam Leffler } 88439beb93cSSam Leffler 88539beb93cSSam Leffler failed: 88639beb93cSSam Leffler scard_deinit(scard); 88739beb93cSSam Leffler 88839beb93cSSam Leffler return 0; 88939beb93cSSam Leffler #undef num_triplets 89039beb93cSSam Leffler } 89139beb93cSSam Leffler 89239beb93cSSam Leffler 89339beb93cSSam Leffler static int scard_get_triplets(int argc, char *argv[]) 89439beb93cSSam Leffler { 89539beb93cSSam Leffler struct scard_data *scard; 89639beb93cSSam Leffler size_t len; 89739beb93cSSam Leffler char imsi[20]; 89839beb93cSSam Leffler unsigned char _rand[16]; 89939beb93cSSam Leffler unsigned char sres[4]; 90039beb93cSSam Leffler unsigned char kc[8]; 90139beb93cSSam Leffler int num_triplets; 90239beb93cSSam Leffler int i; 90339beb93cSSam Leffler size_t j; 90439beb93cSSam Leffler 90539beb93cSSam Leffler if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) { 90639beb93cSSam Leffler printf("invalid parameters for sim command\n"); 90739beb93cSSam Leffler return -1; 90839beb93cSSam Leffler } 90939beb93cSSam Leffler 91039beb93cSSam Leffler if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) { 91139beb93cSSam Leffler /* disable debug output */ 91239beb93cSSam Leffler wpa_debug_level = 99; 91339beb93cSSam Leffler } 91439beb93cSSam Leffler 91539beb93cSSam Leffler scard = scard_init(SCARD_GSM_SIM_ONLY); 91639beb93cSSam Leffler if (scard == NULL) { 91739beb93cSSam Leffler printf("Failed to open smartcard connection\n"); 91839beb93cSSam Leffler return -1; 91939beb93cSSam Leffler } 92039beb93cSSam Leffler if (scard_set_pin(scard, argv[0])) { 92139beb93cSSam Leffler wpa_printf(MSG_WARNING, "PIN validation failed"); 92239beb93cSSam Leffler scard_deinit(scard); 92339beb93cSSam Leffler return -1; 92439beb93cSSam Leffler } 92539beb93cSSam Leffler 92639beb93cSSam Leffler len = sizeof(imsi); 92739beb93cSSam Leffler if (scard_get_imsi(scard, imsi, &len)) { 92839beb93cSSam Leffler scard_deinit(scard); 92939beb93cSSam Leffler return -1; 93039beb93cSSam Leffler } 93139beb93cSSam Leffler 93239beb93cSSam Leffler for (i = 0; i < num_triplets; i++) { 93339beb93cSSam Leffler os_memset(_rand, i, sizeof(_rand)); 93439beb93cSSam Leffler if (scard_gsm_auth(scard, _rand, sres, kc)) 93539beb93cSSam Leffler break; 93639beb93cSSam Leffler 93739beb93cSSam Leffler /* IMSI:Kc:SRES:RAND */ 93839beb93cSSam Leffler for (j = 0; j < len; j++) 93939beb93cSSam Leffler printf("%c", imsi[j]); 94039beb93cSSam Leffler printf(":"); 94139beb93cSSam Leffler for (j = 0; j < 8; j++) 94239beb93cSSam Leffler printf("%02X", kc[j]); 94339beb93cSSam Leffler printf(":"); 94439beb93cSSam Leffler for (j = 0; j < 4; j++) 94539beb93cSSam Leffler printf("%02X", sres[j]); 94639beb93cSSam Leffler printf(":"); 94739beb93cSSam Leffler for (j = 0; j < 16; j++) 94839beb93cSSam Leffler printf("%02X", _rand[j]); 94939beb93cSSam Leffler printf("\n"); 95039beb93cSSam Leffler } 95139beb93cSSam Leffler 95239beb93cSSam Leffler scard_deinit(scard); 95339beb93cSSam Leffler 95439beb93cSSam Leffler return 0; 95539beb93cSSam Leffler } 95639beb93cSSam Leffler 95739beb93cSSam Leffler 95839beb93cSSam Leffler static void eapol_test_terminate(int sig, void *eloop_ctx, 95939beb93cSSam Leffler void *signal_ctx) 96039beb93cSSam Leffler { 96139beb93cSSam Leffler struct wpa_supplicant *wpa_s = eloop_ctx; 96239beb93cSSam Leffler wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); 96339beb93cSSam Leffler eloop_terminate(); 96439beb93cSSam Leffler } 96539beb93cSSam Leffler 96639beb93cSSam Leffler 96739beb93cSSam Leffler static void usage(void) 96839beb93cSSam Leffler { 96939beb93cSSam Leffler printf("usage:\n" 97039beb93cSSam Leffler "eapol_test [-nWS] -c<conf> [-a<AS IP>] [-p<AS port>] " 97139beb93cSSam Leffler "[-s<AS secret>]\\\n" 97239beb93cSSam Leffler " [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n" 97339beb93cSSam Leffler " [-M<client MAC address>] \\\n" 97439beb93cSSam Leffler " [-N<attr spec>] \\\n" 97539beb93cSSam Leffler " [-A<client IP>]\n" 97639beb93cSSam Leffler "eapol_test scard\n" 97739beb93cSSam Leffler "eapol_test sim <PIN> <num triplets> [debug]\n" 97839beb93cSSam Leffler "\n"); 97939beb93cSSam Leffler printf("options:\n" 98039beb93cSSam Leffler " -c<conf> = configuration file\n" 98139beb93cSSam Leffler " -a<AS IP> = IP address of the authentication server, " 98239beb93cSSam Leffler "default 127.0.0.1\n" 98339beb93cSSam Leffler " -p<AS port> = UDP port of the authentication server, " 98439beb93cSSam Leffler "default 1812\n" 98539beb93cSSam Leffler " -s<AS secret> = shared secret with the authentication " 98639beb93cSSam Leffler "server, default 'radius'\n" 98739beb93cSSam Leffler " -A<client IP> = IP address of the client, default: select " 98839beb93cSSam Leffler "automatically\n" 98939beb93cSSam Leffler " -r<count> = number of re-authentications\n" 99039beb93cSSam Leffler " -W = wait for a control interface monitor before starting\n" 99139beb93cSSam Leffler " -S = save configuration after authentication\n" 99239beb93cSSam Leffler " -n = no MPPE keys expected\n" 99339beb93cSSam Leffler " -t<timeout> = sets timeout in seconds (default: 30 s)\n" 99439beb93cSSam Leffler " -C<Connect-Info> = RADIUS Connect-Info (default: " 99539beb93cSSam Leffler "CONNECT 11Mbps 802.11b)\n" 99639beb93cSSam Leffler " -M<client MAC address> = Set own MAC address " 99739beb93cSSam Leffler "(Calling-Station-Id,\n" 99839beb93cSSam Leffler " default: 02:00:00:00:00:01)\n" 99939beb93cSSam Leffler " -N<attr spec> = send arbitrary attribute specified by:\n" 100039beb93cSSam Leffler " attr_id:syntax:value or attr_id\n" 100139beb93cSSam Leffler " attr_id - number id of the attribute\n" 100239beb93cSSam Leffler " syntax - one of: s, d, x\n" 100339beb93cSSam Leffler " s = string\n" 100439beb93cSSam Leffler " d = integer\n" 100539beb93cSSam Leffler " x = octet string\n" 100639beb93cSSam Leffler " value - attribute value.\n" 100739beb93cSSam Leffler " When only attr_id is specified, NULL will be used as " 100839beb93cSSam Leffler "value.\n" 100939beb93cSSam Leffler " Multiple attributes can be specified by using the " 101039beb93cSSam Leffler "option several times.\n"); 101139beb93cSSam Leffler } 101239beb93cSSam Leffler 101339beb93cSSam Leffler 101439beb93cSSam Leffler int main(int argc, char *argv[]) 101539beb93cSSam Leffler { 101639beb93cSSam Leffler struct wpa_supplicant wpa_s; 101739beb93cSSam Leffler int c, ret = 1, wait_for_monitor = 0, save_config = 0; 101839beb93cSSam Leffler char *as_addr = "127.0.0.1"; 101939beb93cSSam Leffler int as_port = 1812; 102039beb93cSSam Leffler char *as_secret = "radius"; 102139beb93cSSam Leffler char *cli_addr = NULL; 102239beb93cSSam Leffler char *conf = NULL; 102339beb93cSSam Leffler int timeout = 30; 102439beb93cSSam Leffler char *pos; 102539beb93cSSam Leffler struct extra_radius_attr *p = NULL, *p1; 102639beb93cSSam Leffler 102739beb93cSSam Leffler if (os_program_init()) 102839beb93cSSam Leffler return -1; 102939beb93cSSam Leffler 103039beb93cSSam Leffler hostapd_logger_register_cb(hostapd_logger_cb); 103139beb93cSSam Leffler 103239beb93cSSam Leffler os_memset(&eapol_test, 0, sizeof(eapol_test)); 103339beb93cSSam Leffler eapol_test.connect_info = "CONNECT 11Mbps 802.11b"; 103439beb93cSSam Leffler os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN); 103539beb93cSSam Leffler 103639beb93cSSam Leffler wpa_debug_level = 0; 103739beb93cSSam Leffler wpa_debug_show_keys = 1; 103839beb93cSSam Leffler 103939beb93cSSam Leffler for (;;) { 104039beb93cSSam Leffler c = getopt(argc, argv, "a:A:c:C:M:nN:p:r:s:St:W"); 104139beb93cSSam Leffler if (c < 0) 104239beb93cSSam Leffler break; 104339beb93cSSam Leffler switch (c) { 104439beb93cSSam Leffler case 'a': 104539beb93cSSam Leffler as_addr = optarg; 104639beb93cSSam Leffler break; 104739beb93cSSam Leffler case 'A': 104839beb93cSSam Leffler cli_addr = optarg; 104939beb93cSSam Leffler break; 105039beb93cSSam Leffler case 'c': 105139beb93cSSam Leffler conf = optarg; 105239beb93cSSam Leffler break; 105339beb93cSSam Leffler case 'C': 105439beb93cSSam Leffler eapol_test.connect_info = optarg; 105539beb93cSSam Leffler break; 105639beb93cSSam Leffler case 'M': 105739beb93cSSam Leffler if (hwaddr_aton(optarg, eapol_test.own_addr)) { 105839beb93cSSam Leffler usage(); 105939beb93cSSam Leffler return -1; 106039beb93cSSam Leffler } 106139beb93cSSam Leffler break; 106239beb93cSSam Leffler case 'n': 106339beb93cSSam Leffler eapol_test.no_mppe_keys++; 106439beb93cSSam Leffler break; 106539beb93cSSam Leffler case 'p': 106639beb93cSSam Leffler as_port = atoi(optarg); 106739beb93cSSam Leffler break; 106839beb93cSSam Leffler case 'r': 106939beb93cSSam Leffler eapol_test.eapol_test_num_reauths = atoi(optarg); 107039beb93cSSam Leffler break; 107139beb93cSSam Leffler case 's': 107239beb93cSSam Leffler as_secret = optarg; 107339beb93cSSam Leffler break; 107439beb93cSSam Leffler case 'S': 107539beb93cSSam Leffler save_config++; 107639beb93cSSam Leffler break; 107739beb93cSSam Leffler case 't': 107839beb93cSSam Leffler timeout = atoi(optarg); 107939beb93cSSam Leffler break; 108039beb93cSSam Leffler case 'W': 108139beb93cSSam Leffler wait_for_monitor++; 108239beb93cSSam Leffler break; 108339beb93cSSam Leffler case 'N': 108439beb93cSSam Leffler p1 = os_zalloc(sizeof(p1)); 108539beb93cSSam Leffler if (p1 == NULL) 108639beb93cSSam Leffler break; 108739beb93cSSam Leffler if (!p) 108839beb93cSSam Leffler eapol_test.extra_attrs = p1; 108939beb93cSSam Leffler else 109039beb93cSSam Leffler p->next = p1; 109139beb93cSSam Leffler p = p1; 109239beb93cSSam Leffler 109339beb93cSSam Leffler p->type = atoi(optarg); 109439beb93cSSam Leffler pos = os_strchr(optarg, ':'); 109539beb93cSSam Leffler if (pos == NULL) { 109639beb93cSSam Leffler p->syntax = 'n'; 109739beb93cSSam Leffler p->data = NULL; 109839beb93cSSam Leffler break; 109939beb93cSSam Leffler } 110039beb93cSSam Leffler 110139beb93cSSam Leffler pos++; 110239beb93cSSam Leffler if (pos[0] == '\0' || pos[1] != ':') { 110339beb93cSSam Leffler printf("Incorrect format of attribute " 110439beb93cSSam Leffler "specification\n"); 110539beb93cSSam Leffler break; 110639beb93cSSam Leffler } 110739beb93cSSam Leffler 110839beb93cSSam Leffler p->syntax = pos[0]; 110939beb93cSSam Leffler p->data = pos + 2; 111039beb93cSSam Leffler break; 111139beb93cSSam Leffler default: 111239beb93cSSam Leffler usage(); 111339beb93cSSam Leffler return -1; 111439beb93cSSam Leffler } 111539beb93cSSam Leffler } 111639beb93cSSam Leffler 111739beb93cSSam Leffler if (argc > optind && os_strcmp(argv[optind], "scard") == 0) { 111839beb93cSSam Leffler return scard_test(); 111939beb93cSSam Leffler } 112039beb93cSSam Leffler 112139beb93cSSam Leffler if (argc > optind && os_strcmp(argv[optind], "sim") == 0) { 112239beb93cSSam Leffler return scard_get_triplets(argc - optind - 1, 112339beb93cSSam Leffler &argv[optind + 1]); 112439beb93cSSam Leffler } 112539beb93cSSam Leffler 112639beb93cSSam Leffler if (conf == NULL) { 112739beb93cSSam Leffler usage(); 112839beb93cSSam Leffler printf("Configuration file is required.\n"); 112939beb93cSSam Leffler return -1; 113039beb93cSSam Leffler } 113139beb93cSSam Leffler 113239beb93cSSam Leffler if (eap_peer_register_methods()) { 113339beb93cSSam Leffler wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 113439beb93cSSam Leffler return -1; 113539beb93cSSam Leffler } 113639beb93cSSam Leffler 113739beb93cSSam Leffler if (eloop_init(&wpa_s)) { 113839beb93cSSam Leffler wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 113939beb93cSSam Leffler return -1; 114039beb93cSSam Leffler } 114139beb93cSSam Leffler 114239beb93cSSam Leffler os_memset(&wpa_s, 0, sizeof(wpa_s)); 114339beb93cSSam Leffler eapol_test.wpa_s = &wpa_s; 114439beb93cSSam Leffler wpa_s.conf = wpa_config_read(conf); 114539beb93cSSam Leffler if (wpa_s.conf == NULL) { 114639beb93cSSam Leffler printf("Failed to parse configuration file '%s'.\n", conf); 114739beb93cSSam Leffler return -1; 114839beb93cSSam Leffler } 114939beb93cSSam Leffler if (wpa_s.conf->ssid == NULL) { 115039beb93cSSam Leffler printf("No networks defined.\n"); 115139beb93cSSam Leffler return -1; 115239beb93cSSam Leffler } 115339beb93cSSam Leffler 115439beb93cSSam Leffler wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret, 115539beb93cSSam Leffler cli_addr); 115639beb93cSSam Leffler wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s); 115739beb93cSSam Leffler if (wpa_s.ctrl_iface == NULL) { 115839beb93cSSam Leffler printf("Failed to initialize control interface '%s'.\n" 115939beb93cSSam Leffler "You may have another eapol_test process already " 116039beb93cSSam Leffler "running or the file was\n" 116139beb93cSSam Leffler "left by an unclean termination of eapol_test in " 116239beb93cSSam Leffler "which case you will need\n" 116339beb93cSSam Leffler "to manually remove this file before starting " 116439beb93cSSam Leffler "eapol_test again.\n", 116539beb93cSSam Leffler wpa_s.conf->ctrl_interface); 116639beb93cSSam Leffler return -1; 116739beb93cSSam Leffler } 116839beb93cSSam Leffler if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) 116939beb93cSSam Leffler return -1; 117039beb93cSSam Leffler 117139beb93cSSam Leffler if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid)) 117239beb93cSSam Leffler return -1; 117339beb93cSSam Leffler 117439beb93cSSam Leffler if (wait_for_monitor) 117539beb93cSSam Leffler wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface); 117639beb93cSSam Leffler 117739beb93cSSam Leffler eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test, 117839beb93cSSam Leffler NULL); 117939beb93cSSam Leffler eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL); 118039beb93cSSam Leffler eloop_register_signal_terminate(eapol_test_terminate, NULL); 118139beb93cSSam Leffler eloop_register_signal_reconfig(eapol_test_terminate, NULL); 118239beb93cSSam Leffler eloop_run(); 118339beb93cSSam Leffler 118439beb93cSSam Leffler eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL); 118539beb93cSSam Leffler eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL); 118639beb93cSSam Leffler 118739beb93cSSam Leffler if (eapol_test_compare_pmk(&eapol_test) == 0 || 118839beb93cSSam Leffler eapol_test.no_mppe_keys) 118939beb93cSSam Leffler ret = 0; 119039beb93cSSam Leffler if (eapol_test.auth_timed_out) 119139beb93cSSam Leffler ret = -2; 119239beb93cSSam Leffler if (eapol_test.radius_access_reject_received) 119339beb93cSSam Leffler ret = -3; 119439beb93cSSam Leffler 119539beb93cSSam Leffler if (save_config) 119639beb93cSSam Leffler wpa_config_write(conf, wpa_s.conf); 119739beb93cSSam Leffler 119839beb93cSSam Leffler test_eapol_clean(&eapol_test, &wpa_s); 119939beb93cSSam Leffler 120039beb93cSSam Leffler eap_peer_unregister_methods(); 120139beb93cSSam Leffler 120239beb93cSSam Leffler eloop_destroy(); 120339beb93cSSam Leffler 120439beb93cSSam Leffler printf("MPPE keys OK: %d mismatch: %d\n", 120539beb93cSSam Leffler eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch); 120639beb93cSSam Leffler if (eapol_test.num_mppe_mismatch) 120739beb93cSSam Leffler ret = -4; 120839beb93cSSam Leffler if (ret) 120939beb93cSSam Leffler printf("FAILURE\n"); 121039beb93cSSam Leffler else 121139beb93cSSam Leffler printf("SUCCESS\n"); 121239beb93cSSam Leffler 121339beb93cSSam Leffler os_program_deinit(); 121439beb93cSSam Leffler 121539beb93cSSam Leffler return ret; 121639beb93cSSam Leffler } 1217