18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - test code 3051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c. 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Not used in production version. 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <assert.h> 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 1661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "utils/ext_password.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_peer/eap.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap_methods.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "utils/base64.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/wpa.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 27c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt#include "common/wpa_ctrl.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ctrl_iface.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pcsc_funcs.h" 30051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "wpas_glue.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_driver_ops *wpa_drivers[] = { NULL }; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct extra_radius_attr { 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 type; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char syntax; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *data; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct extra_radius_attr *next; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eapol_test_data { 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eapol_test_num_reauths; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int no_mppe_keys; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_mppe_ok, num_mppe_mismatch; 495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt int req_eap_key_name; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 radius_identifier; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *last_recv_radius; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct in_addr own_ip_addr; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_client_data *radius; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_radius_servers *radius_conf; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* last received EAP Response from Authentication Server */ 5861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *last_eap_radius; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 authenticator_pmk[PMK_LEN]; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t authenticator_pmk_len; 625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 authenticator_eap_key_name[256]; 635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t authenticator_eap_key_name_len; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int radius_access_accept_received; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int radius_access_reject_received; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int auth_timed_out; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *eap_identity; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t eap_identity_len; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *connect_info; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 own_addr[ETH_ALEN]; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct extra_radius_attr *extra_attrs; 741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt FILE *server_cert_file; 762271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 772271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt const char *pcsc_reader; 782271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt const char *pcsc_pin; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct eapol_test_data eapol_test; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx); 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int level, const char *txt, size_t len) 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr) 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR ": %s\n", 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr), txt); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s", txt); 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int add_extra_attr(struct radius_msg *msg, 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct extra_radius_attr *attr) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 val; 104a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt char buf[RADIUS_MAX_ATTR_LEN + 1]; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (attr->syntax) { 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 's': 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), "%s", attr->data); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(buf); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'n': 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = '\0'; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 1; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'x': 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = attr->data; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == '0' && pos[1] == 'x') 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = os_strlen(pos); 120a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if ((len & 1) || (len / 2) > RADIUS_MAX_ATTR_LEN) { 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Invalid extra attribute hexstring\n"); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len /= 2; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hexstr2bin(pos, (u8 *) buf, len) < 0) { 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Invalid extra attribute hexstring\n"); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'd': 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = htonl(atoi(attr->data)); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, &val, 4); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 4; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Incorrect extra attribute syntax specification\n"); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!radius_msg_add_attr(msg, attr->type, (u8 *) buf, len)) { 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not add attribute %d\n", attr->type); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int add_extra_attrs(struct radius_msg *msg, 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct extra_radius_attr *attrs) 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct extra_radius_attr *p; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (p = attrs; p; p = p->next) { 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (add_extra_attr(msg, p) < 0) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct extra_radius_attr * 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfind_extra_attr(struct extra_radius_attr *attrs, u8 type) 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct extra_radius_attr *p; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (p = attrs; p; p = p->next) { 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p->type == type) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *eap, size_t len) 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 177a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt char buf[RADIUS_MAX_ATTR_LEN + 1]; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct eap_hdr *hdr; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "packet"); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_identifier = radius_client_get_id(e->radius); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_identifier); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) { 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not create net RADIUS packet\n"); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_make_authenticator(msg, (u8 *) e, sizeof(*e)); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (const struct eap_hdr *) eap; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (hdr + 1); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE && 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[0] == EAP_TYPE_IDENTITY) { 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(e->eap_identity); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->eap_identity_len = len - sizeof(*hdr) - 1; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->eap_identity = os_malloc(e->eap_identity_len); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e->eap_identity) { 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(e->eap_identity, pos, e->eap_identity_len); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "Learned identity from " 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-Response-Identity", 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->eap_identity, e->eap_identity_len); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e->eap_identity && 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->eap_identity, e->eap_identity_len)) { 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not add User-Name\n"); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (e->req_eap_key_name && 2185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_EAP_KEY_NAME, (u8 *) "\0", 2195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 1)) { 2205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt printf("Could not add EAP-Key-Name\n"); 2215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt goto fail; 2225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 2235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_IP_ADDRESS) && 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &e->own_ip_addr, 4)) { 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not add NAS-IP-Address\n"); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(e->wpa_s->own_addr)); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CALLING_STATION_ID) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt && 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf, os_strlen(buf))) { 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not add Calling-Station-Id\n"); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: should probably check MTU from driver config; 2304 is max for 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.11, but use 1400 to avoid problems with too large packets 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_FRAMED_MTU) && 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not add Framed-MTU\n"); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_PORT_TYPE) && 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE, 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_NAS_PORT_TYPE_IEEE_802_11)) { 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not add NAS-Port-Type\n"); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), "%s", e->connect_info); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CONNECT_INFO) && 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf, os_strlen(buf))) { 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not add Connect-Info\n"); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (add_extra_attrs(msg, e->extra_attrs) < 0) 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap && !radius_msg_add_eap(msg, eap, len)) { 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not add EAP-Message\n"); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* State attribute must be copied if and only if this packet is 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Access-Request reply to the previous Access-Challenge */ 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e->last_recv_radius && 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_hdr(e->last_recv_radius)->code == 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_CODE_ACCESS_CHALLENGE) { 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = radius_msg_copy_attr(msg, e->last_recv_radius, 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RADIUS_ATTR_STATE); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Could not copy State attribute from previous " 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Access-Challenge\n"); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res > 0) { 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " Copied RADIUS State " 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Attribute"); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr) 29204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt < 0) 29304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto fail; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(msg); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eapol_test_eapol_send(void *ctx, int type, const u8 *buf, 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n", 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type, (unsigned long) len); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == IEEE802_1X_TYPE_EAP_PACKET) { 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len); 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_encapsulate_radius(&eapol_test, buf, len); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_test_set_config_blob(void *ctx, 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_config_blob *blob) 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct eapol_test_data *e = ctx; 3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_config_set_blob(e->wpa_s->conf, blob); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const struct wpa_config_blob * 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidteapol_test_get_config_blob(void *ctx, const char *name) 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct eapol_test_data *e = ctx; 3261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return wpa_config_get_blob(e->wpa_s->conf, name); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_test_eapol_done_cb(void *ctx) 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("WPA: EAPOL processing complete\n"); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_sm_reauth(void *eloop_ctx, void *timeout_ctx) 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_test_data *e = eloop_ctx; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("\n\n\n\n\neapol_test: Triggering EAP reauthentication\n\n"); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_access_accept_received = 0; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_eap_request_identity(e->wpa_s, NULL); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eapol_test_compare_pmk(struct eapol_test_data *e) 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 pmk[PMK_LEN]; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 1; 3495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt const u8 *sess_id; 3505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t sess_id_len; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) { 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) { 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("WARNING: PMK mismatch\n"); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "PMK from AS", 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->authenticator_pmk, PMK_LEN); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (e->radius_access_accept_received) 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (e->authenticator_pmk_len == 16 && 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) { 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) { 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("WARNING: PMK mismatch\n"); 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "PMK from AS", 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->authenticator_pmk, 16); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (e->radius_access_accept_received) 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (e->radius_access_accept_received && e->no_mppe_keys) { 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No keying material expected */ 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret && !e->no_mppe_keys) 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->num_mppe_mismatch++; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (!e->no_mppe_keys) 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->num_mppe_ok++; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt sess_id = eapol_sm_get_session_id(e->wpa_s->eapol, &sess_id_len); 3805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (!sess_id) 3815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return ret; 3825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (e->authenticator_eap_key_name_len == 0) { 3835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, "No EAP-Key-Name received from server"); 3845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt return ret; 3855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 3865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 3875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (e->authenticator_eap_key_name_len != sess_id_len || 3885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcmp(e->authenticator_eap_key_name, sess_id, sess_id_len) != 0) 3895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt { 3905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, 3915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "Locally derived EAP Session-Id does not match EAP-Key-Name from server"); 3925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP Session-Id", sess_id, sess_id_len); 3935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-Key-Name from server", 3945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt e->authenticator_eap_key_name, 3955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt e->authenticator_eap_key_name_len); 3965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 3975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt wpa_printf(MSG_INFO, 3985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "Locally derived EAP Session-Id matches EAP-Key-Name from server"); 3995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 4005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 405344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidtstatic void eapol_sm_cb(struct eapol_sm *eapol, enum eapol_supp_result result, 406344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt void *ctx) 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_test_data *e = ctx; 409344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt printf("eapol_sm_cb: result=%d\n", result); 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->eapol_test_num_reauths--; 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e->eapol_test_num_reauths < 0) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test_compare_pmk(e); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 100000, eapol_sm_reauth, e, NULL); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void eapol_test_write_cert(FILE *f, const char *subject, 4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const struct wpabuf *cert) 4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt unsigned char *encoded; 4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt encoded = base64_encode(wpabuf_head(cert), wpabuf_len(cert), NULL); 4261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (encoded == NULL) 4271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 4281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fprintf(f, "%s\n-----BEGIN CERTIFICATE-----\n%s" 4291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "-----END CERTIFICATE-----\n\n", subject, encoded); 4301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(encoded); 4311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 434051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 435051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtstatic void eapol_test_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field, 436051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt const char *default_txt) 437051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 438051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt struct eapol_test_data *e = ctx; 439051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt struct wpa_supplicant *wpa_s = e->wpa_s; 440051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 441051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt const char *field_name, *txt = NULL; 442051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt char *buf; 443051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt size_t buflen; 444051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int len; 445051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 446051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (ssid == NULL) 447051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return; 448051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 449051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt, 450051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt &txt); 451051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (field_name == NULL) { 452051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed", 453051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt field); 454051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return; 455051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 456051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 457051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt buflen = 100 + os_strlen(txt) + ssid->ssid_len; 458051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt buf = os_malloc(buflen); 459051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (buf == NULL) 460051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return; 461051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt len = os_snprintf(buf, buflen, 462051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt WPA_CTRL_REQ "%s-%d:%s needed for SSID ", 463051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt field_name, ssid->id, txt); 464051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (len < 0 || (size_t) len >= buflen) { 465051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_free(buf); 466051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return; 467051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 468051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (ssid->ssid && buflen > len + ssid->ssid_len) { 469051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_memcpy(buf + len, ssid->ssid, ssid->ssid_len); 470051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt len += ssid->ssid_len; 471051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt buf[len] = '\0'; 472051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 473051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt buf[buflen - 1] = '\0'; 474051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "%s", buf); 475051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_free(buf); 476051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 477051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 478051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#define eapol_test_eap_param_needed NULL 479051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 480051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 481051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 482c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtstatic void eapol_test_cert_cb(void *ctx, int depth, const char *subject, 483c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt const char *cert_hash, 484c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt const struct wpabuf *cert) 485c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt{ 486c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt struct eapol_test_data *e = ctx; 487c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 488c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT 489c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt "depth=%d subject='%s'%s%s", 490c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt depth, subject, 491c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt cert_hash ? " hash=" : "", 492c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt cert_hash ? cert_hash : ""); 493c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 494c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (cert) { 495c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt char *cert_hex; 496c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt size_t len = wpabuf_len(cert) * 2 + 1; 497c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt cert_hex = os_malloc(len); 498c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (cert_hex) { 499c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert), 500c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt wpabuf_len(cert)); 501c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt wpa_msg_ctrl(e->wpa_s, MSG_INFO, 502c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt WPA_EVENT_EAP_PEER_CERT 503c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt "depth=%d subject='%s' cert=%s", 504c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt depth, subject, cert_hex); 505c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt os_free(cert_hex); 506c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt } 5071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (e->server_cert_file) 5091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eapol_test_write_cert(e->server_cert_file, 5101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt subject, cert); 511c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt } 512c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt} 513c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 514c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 5154530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidtstatic void eapol_test_set_anon_id(void *ctx, const u8 *id, size_t len) 5164530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt{ 5174530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct eapol_test_data *e = ctx; 5184530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt struct wpa_supplicant *wpa_s = e->wpa_s; 5194530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt char *str; 5204530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt int res; 5214530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 5224530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity", 5234530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt id, len); 5244530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 5254530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (wpa_s->current_ssid == NULL) 5264530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 5274530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 5284530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (id == NULL) { 5294530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 5304530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt "NULL", 0) < 0) 5314530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 5324530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } else { 5334530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt str = os_malloc(len * 2 + 1); 5344530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (str == NULL) 5354530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 5364530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt wpa_snprintf_hex(str, len * 2 + 1, id, len); 5374530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 5384530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt str, 0); 5394530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt os_free(str); 5404530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt if (res < 0) 5414530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return; 5424530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt } 5434530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt} 5444530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 5454530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid) 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_config eapol_conf; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_ctx *ctx; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) { 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Failed to allocate EAPOL context.\n"); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ctx->ctx = e; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->msg_ctx = wpa_s; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->scard_ctx = wpa_s->scard; 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cb = eapol_sm_cb; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->cb_ctx = e; 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->eapol_send_ctx = wpa_s; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->preauth = 0; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->eapol_done_cb = eapol_test_eapol_done_cb; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->eapol_send = eapol_test_eapol_send; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->set_config_blob = eapol_test_set_config_blob; 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->get_config_blob = eapol_test_get_config_blob; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; 571051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ctx->eap_param_needed = eapol_test_eap_param_needed; 572c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt ctx->cert_cb = eapol_test_cert_cb; 5731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ctx->cert_in_cb = 1; 5744530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt ctx->set_anon_id = eapol_test_set_anon_id; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->eapol = eapol_sm_init(ctx); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->eapol == NULL) { 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Failed to initialize EAPOL state machines.\n"); 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = ssid; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&eapol_conf, 0, sizeof(eapol_conf)); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_conf.accept_802_1x_keys = 1; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_conf.required_keys = 0; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_conf.workaround = ssid->eap_workaround; 589051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt eapol_conf.external_sim = wpa_s->conf->external_sim; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_portValid(wpa_s->eapol, FALSE); 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 802.1X::portControl = Auto */ 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void test_eapol_clean(struct eapol_test_data *e, 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s) 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct extra_radius_attr *p, *prev; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_deinit(e->radius); 60861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(e->last_eap_radius); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(e->last_recv_radius); 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->last_recv_radius = NULL; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(e->eap_identity); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->eap_identity = NULL; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_deinit(wpa_s->eapol); 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->eapol = NULL; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e->radius_conf && e->radius_conf->auth_server) { 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(e->radius_conf->auth_server->shared_secret); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(e->radius_conf->auth_server); 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(e->radius_conf); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_conf = NULL; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scard_deinit(wpa_s->scard); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->ctrl_iface) { 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->ctrl_iface = NULL; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 62661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 62761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ext_password_deinit(wpa_s->ext_pw); 62861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->ext_pw = NULL; 62961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_free(wpa_s->conf); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = e->extra_attrs; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (p) { 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = p; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = p->next; 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx) 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[100], *pos; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *hdr; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr *eap; 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (struct ieee802_1x_hdr *) buf; 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->version = EAPOL_VERSION; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->type = IEEE802_1X_TYPE_EAP_PACKET; 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->length = htons(5); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = (struct eap_hdr *) (hdr + 1); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->code = EAP_CODE_REQUEST; 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->identifier = 0; 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->length = htons(5); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (u8 *) (eap + 1); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = EAP_TYPE_IDENTITY; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Sending fake EAP-Request-Identity\n"); 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf, 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(*hdr) + 5); 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx) 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_test_data *e = eloop_ctx; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("EAPOL test timed out\n"); 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->auth_timed_out = 1; 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic char *eap_type_text(u8 type) 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (type) { 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_IDENTITY: return "Identity"; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_NOTIFICATION: return "Notification"; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_NAK: return "Nak"; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_TLS: return "TLS"; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_TTLS: return "TTLS"; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_PEAP: return "PEAP"; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_SIM: return "SIM"; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_GTC: return "GTC"; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_MD5: return "MD5"; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_OTP: return "OTP"; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_FAST: return "FAST"; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_SAKE: return "SAKE"; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_TYPE_PSK: return "PSK"; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: return "Unknown"; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 69861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *eap; 69961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct eap_hdr *hdr; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_type = -1; 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[64]; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e->last_recv_radius == NULL) 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = e->last_recv_radius; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 70961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eap = radius_msg_get_eap(msg); 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) { 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3: 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * attribute */ 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "could not extract " 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-Message from RADIUS message"); 71661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(e->last_eap_radius); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->last_eap_radius = NULL; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 72161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpabuf_len(eap) < sizeof(*hdr)) { 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "too short EAP packet " 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received from authentication server"); 72461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(eap); 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 72861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpabuf_len(eap) > sizeof(*hdr)) 72961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)]; 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 73161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hdr = wpabuf_head(eap); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->code) { 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_REQUEST: 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_type >= 0 ? eap_type_text(eap_type) : "??", 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_type); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_RESPONSE: 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)", 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_type >= 0 ? eap_type_text(eap_type) : "??", 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_type); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_SUCCESS: 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, "EAP Success", sizeof(buf)); 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* LEAP uses EAP Success within an authentication, so must not 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * stop here with eloop_terminate(); */ 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_CODE_FAILURE: 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, "EAP Failure", sizeof(buf)); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(buf, "unknown EAP code", sizeof(buf)); 75461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_hexdump_buf(MSG_DEBUG, "Decapsulated EAP packet", eap); 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d " 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "id=%d len=%d) from RADIUS server: %s", 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code, hdr->identifier, ntohs(hdr->length), buf); 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */ 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 76361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(e->last_eap_radius); 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->last_eap_radius = eap; 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_1x_hdr *dot1x; 76861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap)); 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(dot1x != NULL); 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot1x->version = EAPOL_VERSION; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot1x->type = IEEE802_1X_TYPE_EAP_PACKET; 77261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dot1x->length = htons(wpabuf_len(eap)); 77361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap), 77461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_len(eap)); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid, 77661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt (u8 *) dot1x, 77761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(*dot1x) + wpabuf_len(eap)); 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(dot1x); 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ieee802_1x_get_keys(struct eapol_test_data *e, 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_msg *msg, struct radius_msg *req, 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *shared_secret, 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t shared_secret_len) 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_ms_mppe_keys *keys; 7895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt u8 *buf; 7905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt size_t len; 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys = radius_msg_get_ms_keys(msg, req, shared_secret, 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared_secret_len); 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keys && keys->send == NULL && keys->recv == NULL) { 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(keys); 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys = radius_msg_get_cisco_keys(msg, req, shared_secret, 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared_secret_len); 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keys) { 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keys->send) { 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)", 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->send, keys->send_len); 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keys->recv) { 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)", 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->recv, keys->recv_len); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->authenticator_pmk_len = 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->recv_len > PMK_LEN ? PMK_LEN : 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->recv_len; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(e->authenticator_pmk, keys->recv, 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->authenticator_pmk_len); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (e->authenticator_pmk_len == 16 && keys->send && 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->send_len == 16) { 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* MS-CHAP-v2 derives 16 octet keys */ 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key " 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to extend PMK to 32 octets"); 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(e->authenticator_pmk + 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->authenticator_pmk_len, 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->send, keys->send_len); 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->authenticator_pmk_len += keys->send_len; 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(keys->send); 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(keys->recv); 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(keys); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 8305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_EAP_KEY_NAME, &buf, &len, 8315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt NULL) == 0) { 8325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt os_memcpy(e->authenticator_eap_key_name, buf, len); 8335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt e->authenticator_eap_key_name_len = len; 8345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } else { 8355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt e->authenticator_eap_key_name_len = 0; 8365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt } 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Process the RADIUS frames from Authentication Server */ 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic RadiusRxResult 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *shared_secret, size_t shared_secret_len, 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *data) 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eapol_test_data *e = data; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct radius_hdr *hdr = radius_msg_get_hdr(msg); 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * present when packet contains an EAP-Message attribute */ 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->code == RADIUS_CODE_ACCESS_REJECT && 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) < 0 && 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Allowing RADIUS " 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Access-Reject without Message-Authenticator " 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "since it does not include EAP-Message\n"); 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (radius_msg_verify(msg, shared_secret, shared_secret_len, 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req, 1)) { 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Incoming RADIUS packet did not have correct " 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Message-Authenticator - dropped\n"); 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_UNKNOWN; 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code != RADIUS_CODE_ACCESS_REJECT && 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Unknown RADIUS message code\n"); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_UNKNOWN; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_identifier = -1; 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS packet matching with station"); 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_msg_free(e->last_recv_radius); 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->last_recv_radius = msg; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->code) { 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_ACCEPT: 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_access_accept_received = 1; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_get_keys(e, msg, req, shared_secret, 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt shared_secret_len); 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RADIUS_CODE_ACCESS_REJECT: 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_access_reject_received = 1; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_decapsulate_radius(e); 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hdr->code == RADIUS_CODE_ACCESS_ACCEPT && 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->eapol_test_num_reauths < 0) || 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->code == RADIUS_CODE_ACCESS_REJECT) { 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RADIUS_RX_QUEUED; 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_init_conf(struct eapol_test_data *e, 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s, const char *authsrv, 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int port, const char *secret, 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *cli_addr) 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_radius_server *as; 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->bssid[5] = 1; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN); 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->own_ip_addr.s_addr = htonl((127 << 24) | 1); 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(wpa_s->ifname, "test", sizeof(wpa_s->ifname)); 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers)); 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(e->radius_conf != NULL); 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_conf->num_auth_servers = 1; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt as = os_zalloc(sizeof(struct hostapd_radius_server)); 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(as != NULL); 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a[4]; 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (u8 *) &as->addr.u.v4; 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = a[0]; 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = a[1]; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = a[2]; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = a[3]; 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inet_aton(authsrv, &as->addr.u.v4); 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt as->addr.af = AF_INET; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt as->port = port; 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt as->shared_secret = (u8 *) os_strdup(secret); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt as->shared_secret_len = os_strlen(secret); 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_conf->auth_server = as; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_conf->auth_servers = as; 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_conf->msg_dumps = 1; 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cli_addr) { 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_parse_ip_addr(cli_addr, 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &e->radius_conf->client_addr) == 0) 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius_conf->force_client_addr = 1; 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid IP address '%s'", 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli_addr); 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(0); 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt e->radius = radius_client_init(wpa_s, e->radius_conf); 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(e->radius != NULL); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = radius_client_register(e->radius, RADIUS_AUTH, 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_receive_auth, e); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(res == 0); 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9602271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidtstatic int scard_test(struct eapol_test_data *e) 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct scard_data *scard; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char imsi[20]; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char _rand[16]; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PCSC_FUNCS 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char sres[4]; 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char kc[8]; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PCSC_FUNCS */ 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define num_triplets 5 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char rand_[num_triplets][16]; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char sres_[num_triplets][4]; 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char kc_[num_triplets][8]; 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, res; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define AKA_RAND_LEN 16 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define AKA_AUTN_LEN 16 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define AKA_AUTS_LEN 14 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RES_MAX_LEN 16 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IK_LEN 16 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define CK_LEN 16 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char aka_rand[AKA_RAND_LEN]; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char aka_autn[AKA_AUTN_LEN]; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char aka_auts[AKA_AUTS_LEN]; 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char aka_res[RES_MAX_LEN]; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t aka_res_len; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char aka_ik[IK_LEN]; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char aka_ck[CK_LEN]; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9912271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt scard = scard_init(e->pcsc_reader); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard == NULL) 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9942271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (scard_set_pin(scard, e->pcsc_pin)) { 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "PIN validation failed"); 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scard_deinit(scard); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(imsi); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_get_imsi(scard, imsi, &len)) 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* NOTE: Permanent Username: 1 | IMSI */ 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1006c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "SCARD: MNC length %d", 1007c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt scard_get_mnc_len(scard)); 1008c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(_rand, 0, sizeof(_rand)); 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_gsm_auth(scard, _rand, sres, kc)) 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(_rand, 0xff, sizeof(_rand)); 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_gsm_auth(scard, _rand, sres, kc)) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_triplets; i++) { 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(rand_[i], i, sizeof(rand_[i])); 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i])) 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_triplets; i++) { 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("1"); 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%c", imsi[j]); 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf(","); 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < 16; j++) 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%02X", rand_[i][j]); 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf(","); 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < 4; j++) 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%02X", sres_[i][j]); 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf(","); 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < 8; j++) 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%02X", kc_[i][j]); 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("\n"); 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication"); 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* seq 39 (0x28) */ 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(aka_rand, 0xaa, 16); 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf" 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16); 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len, 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aka_ik, aka_ck, aka_auts); 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 0) { 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "UMTS auth completed successfully"); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN); 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (res == -2) { 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization " 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failure"); 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "UMTS auth failed"); 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfailed: 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scard_deinit(scard); 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#undef num_triplets 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10692271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidtstatic int scard_get_triplets(struct eapol_test_data *e, int argc, char *argv[]) 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct scard_data *scard; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char imsi[20]; 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char _rand[16]; 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char sres[4]; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char kc[8]; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_triplets; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) { 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("invalid parameters for sim command\n"); 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) { 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* disable debug output */ 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_level = 99; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10912271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt scard = scard_init(e->pcsc_reader); 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard == NULL) { 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Failed to open smartcard connection\n"); 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_set_pin(scard, argv[0])) { 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "PIN validation failed"); 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scard_deinit(scard); 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(imsi); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_get_imsi(scard, imsi, &len)) { 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scard_deinit(scard); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_triplets; i++) { 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(_rand, i, sizeof(_rand)); 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scard_gsm_auth(scard, _rand, sres, kc)) 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IMSI:Kc:SRES:RAND */ 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%c", imsi[j]); 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf(":"); 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < 8; j++) 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%02X", kc[j]); 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf(":"); 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < 4; j++) 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%02X", sres[j]); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf(":"); 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < 16; j++) 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%02X", _rand[j]); 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("\n"); 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scard_deinit(scard); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eapol_test_terminate(int sig, void *signal_ctx) 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = signal_ctx; 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void usage(void) 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("usage:\n" 11455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt "eapol_test [-enWS] -c<conf> [-a<AS IP>] [-p<AS port>] " 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "[-s<AS secret>]\\\n" 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n" 11481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " [-M<client MAC address>] [-o<server cert file] \\\n" 11492271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt " [-N<attr spec>] [-R<PC/SC reader>] " 11502271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt "[-P<PC/SC PIN>] \\\n" 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " [-A<client IP>]\n" 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "eapol_test scard\n" 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "eapol_test sim <PIN> <num triplets> [debug]\n" 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n"); 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("options:\n" 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -c<conf> = configuration file\n" 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -a<AS IP> = IP address of the authentication server, " 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "default 127.0.0.1\n" 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -p<AS port> = UDP port of the authentication server, " 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "default 1812\n" 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -s<AS secret> = shared secret with the authentication " 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "server, default 'radius'\n" 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -A<client IP> = IP address of the client, default: select " 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "automatically\n" 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -r<count> = number of re-authentications\n" 11665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt " -e = Request EAP-Key-Name\n" 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -W = wait for a control interface monitor before starting\n" 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -S = save configuration after authentication\n" 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -n = no MPPE keys expected\n" 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -t<timeout> = sets timeout in seconds (default: 30 s)\n" 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -C<Connect-Info> = RADIUS Connect-Info (default: " 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CONNECT 11Mbps 802.11b)\n" 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -M<client MAC address> = Set own MAC address " 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Calling-Station-Id,\n" 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " default: 02:00:00:00:00:01)\n" 11761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " -o<server cert file> = Write received server certificate\n" 11771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " chain to the specified file\n" 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -N<attr spec> = send arbitrary attribute specified by:\n" 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " attr_id:syntax:value or attr_id\n" 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " attr_id - number id of the attribute\n" 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " syntax - one of: s, d, x\n" 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " s = string\n" 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " d = integer\n" 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " x = octet string\n" 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " value - attribute value.\n" 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " When only attr_id is specified, NULL will be used as " 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "value.\n" 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " Multiple attributes can be specified by using the " 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "option several times.\n"); 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[]) 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1195051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt struct wpa_global global; 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant wpa_s; 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int c, ret = 1, wait_for_monitor = 0, save_config = 0; 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *as_addr = "127.0.0.1"; 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int as_port = 1812; 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *as_secret = "radius"; 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *cli_addr = NULL; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *conf = NULL; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int timeout = 30; 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct extra_radius_attr *p = NULL, *p1; 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_program_init()) 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger_register_cb(hostapd_logger_cb); 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&eapol_test, 0, sizeof(eapol_test)); 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test.connect_info = "CONNECT 11Mbps 802.11b"; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN); 12152271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt eapol_test.pcsc_pin = "1234"; 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_level = 0; 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_show_keys = 1; 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (;;) { 12212271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt c = getopt(argc, argv, "a:A:c:C:eM:nN:o:p:P:r:R:s:St:W"); 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c < 0) 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (c) { 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'a': 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt as_addr = optarg; 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'A': 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli_addr = optarg; 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'c': 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf = optarg; 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'C': 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test.connect_info = optarg; 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt case 'e': 12385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt eapol_test.req_eap_key_name = 1; 12395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt break; 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'M': 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hwaddr_aton(optarg, eapol_test.own_addr)) { 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'n': 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test.no_mppe_keys++; 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case 'o': 12501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (eapol_test.server_cert_file) 12511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fclose(eapol_test.server_cert_file); 12521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eapol_test.server_cert_file = fopen(optarg, "w"); 12531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (eapol_test.server_cert_file == NULL) { 12541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt printf("Could not open '%s' for writing\n", 12551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt optarg); 12561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 12571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 12581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'p': 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt as_port = atoi(optarg); 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12622271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt case 'P': 12632271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt eapol_test.pcsc_pin = optarg; 12642271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt break; 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'r': 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test.eapol_test_num_reauths = atoi(optarg); 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12682271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt case 'R': 12692271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt eapol_test.pcsc_reader = optarg; 1270d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 's': 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt as_secret = optarg; 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'S': 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt save_config++; 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 't': 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = atoi(optarg); 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'W': 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wait_for_monitor++; 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'N': 1284a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt p1 = os_zalloc(sizeof(*p1)); 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p1 == NULL) 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!p) 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test.extra_attrs = p1; 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->next = p1; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = p1; 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->type = atoi(optarg); 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(optarg, ':'); 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) { 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->syntax = 'n'; 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->data = NULL; 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == '\0' || pos[1] != ':') { 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Incorrect format of attribute " 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "specification\n"); 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->syntax = pos[0]; 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->data = pos + 2; 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argc > optind && os_strcmp(argv[optind], "scard") == 0) { 13182271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return scard_test(&eapol_test); 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argc > optind && os_strcmp(argv[optind], "sim") == 0) { 13222271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return scard_get_triplets(&eapol_test, argc - optind - 1, 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &argv[optind + 1]); 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf == NULL) { 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Configuration file is required.\n"); 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_register_methods()) { 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_init()) { 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1342051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt os_memset(&global, 0, sizeof(global)); 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&wpa_s, 0, sizeof(wpa_s)); 1344051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_s.global = &global; 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test.wpa_s = &wpa_s; 1346051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt dl_list_init(&wpa_s.bss); 1347051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt dl_list_init(&wpa_s.bss_id); 134864f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt wpa_s.conf = wpa_config_read(conf, NULL); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s.conf == NULL) { 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Failed to parse configuration file '%s'.\n", conf); 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s.conf->ssid == NULL) { 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("No networks defined.\n"); 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13582271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt if (eapol_test.pcsc_reader) { 13592271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt os_free(wpa_s.conf->pcsc_reader); 13602271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt wpa_s.conf->pcsc_reader = os_strdup(eapol_test.pcsc_reader); 13612271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt } 13622271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret, 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli_addr); 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s); 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s.ctrl_iface == NULL) { 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Failed to initialize control interface '%s'.\n" 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "You may have another eapol_test process already " 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "running or the file was\n" 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "left by an unclean termination of eapol_test in " 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "which case you will need\n" 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to manually remove this file before starting " 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "eapol_test again.\n", 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s.conf->ctrl_interface); 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid)) 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpas_init_ext_pw(&wpa_s) < 0) 138461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 138561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wait_for_monitor) 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface); 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test, 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL); 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal_terminate(eapol_test_terminate, &wpa_s); 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s); 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_run(); 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL); 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL); 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_test_compare_pmk(&eapol_test) == 0 || 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test.no_mppe_keys) 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_test.auth_timed_out) 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -2; 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_test.radius_access_reject_received) 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -3; 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (save_config) 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_config_write(conf, wpa_s.conf); 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt test_eapol_clean(&eapol_test, &wpa_s); 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_unregister_methods(); 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_unregister_methods(); 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */ 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_destroy(); 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (eapol_test.server_cert_file) 14201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fclose(eapol_test.server_cert_file); 14211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("MPPE keys OK: %d mismatch: %d\n", 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch); 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eapol_test.num_mppe_mismatch) 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -4; 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("FAILURE\n"); 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("SUCCESS\n"); 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_program_deinit(); 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1435