1 1.1 christos /* 2 1.1 christos * WPA Supplicant - test code 3 1.1.1.4 christos * Copyright (c) 2003-2013, Jouni Malinen <j (at) w1.fi> 4 1.1 christos * 5 1.1.1.3 christos * This software may be distributed under the terms of the BSD license. 6 1.1.1.3 christos * See README for more details. 7 1.1 christos * 8 1.1 christos * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c. 9 1.1 christos * Not used in production version. 10 1.1 christos */ 11 1.1 christos 12 1.1 christos #include "includes.h" 13 1.1 christos #include <assert.h> 14 1.1 christos 15 1.1 christos #include "common.h" 16 1.1.1.3 christos #include "utils/ext_password.h" 17 1.1.1.6 christos #include "common/version.h" 18 1.1.1.8 christos #include "crypto/crypto.h" 19 1.1.1.7 christos #include "crypto/tls.h" 20 1.1 christos #include "config.h" 21 1.1 christos #include "eapol_supp/eapol_supp_sm.h" 22 1.1 christos #include "eap_peer/eap.h" 23 1.1.1.2 christos #include "eap_server/eap_methods.h" 24 1.1 christos #include "eloop.h" 25 1.1.1.2 christos #include "utils/base64.h" 26 1.1 christos #include "rsn_supp/wpa.h" 27 1.1 christos #include "wpa_supplicant_i.h" 28 1.1 christos #include "radius/radius.h" 29 1.1 christos #include "radius/radius_client.h" 30 1.1.1.2 christos #include "common/wpa_ctrl.h" 31 1.1 christos #include "ctrl_iface.h" 32 1.1 christos #include "pcsc_funcs.h" 33 1.1.1.4 christos #include "wpas_glue.h" 34 1.1 christos 35 1.1 christos 36 1.1.1.6 christos const struct wpa_driver_ops *const wpa_drivers[] = { NULL }; 37 1.1 christos 38 1.1 christos 39 1.1 christos struct extra_radius_attr { 40 1.1 christos u8 type; 41 1.1 christos char syntax; 42 1.1 christos char *data; 43 1.1 christos struct extra_radius_attr *next; 44 1.1 christos }; 45 1.1 christos 46 1.1 christos struct eapol_test_data { 47 1.1 christos struct wpa_supplicant *wpa_s; 48 1.1 christos 49 1.1 christos int eapol_test_num_reauths; 50 1.1 christos int no_mppe_keys; 51 1.1 christos int num_mppe_ok, num_mppe_mismatch; 52 1.1.1.4 christos int req_eap_key_name; 53 1.1 christos 54 1.1 christos u8 radius_identifier; 55 1.1 christos struct radius_msg *last_recv_radius; 56 1.1 christos struct in_addr own_ip_addr; 57 1.1 christos struct radius_client_data *radius; 58 1.1 christos struct hostapd_radius_servers *radius_conf; 59 1.1 christos 60 1.1.1.3 christos /* last received EAP Response from Authentication Server */ 61 1.1.1.3 christos struct wpabuf *last_eap_radius; 62 1.1 christos 63 1.1 christos u8 authenticator_pmk[PMK_LEN]; 64 1.1 christos size_t authenticator_pmk_len; 65 1.1.1.4 christos u8 authenticator_eap_key_name[256]; 66 1.1.1.4 christos size_t authenticator_eap_key_name_len; 67 1.1 christos int radius_access_accept_received; 68 1.1 christos int radius_access_reject_received; 69 1.1 christos int auth_timed_out; 70 1.1 christos 71 1.1 christos u8 *eap_identity; 72 1.1 christos size_t eap_identity_len; 73 1.1 christos 74 1.1 christos char *connect_info; 75 1.1 christos u8 own_addr[ETH_ALEN]; 76 1.1 christos struct extra_radius_attr *extra_attrs; 77 1.1.1.2 christos 78 1.1.1.2 christos FILE *server_cert_file; 79 1.1.1.4 christos 80 1.1.1.4 christos const char *pcsc_reader; 81 1.1.1.4 christos const char *pcsc_pin; 82 1.1.1.6 christos 83 1.1.1.6 christos unsigned int ctrl_iface:1; 84 1.1.1.6 christos unsigned int id_req_sent:1; 85 1.1 christos }; 86 1.1 christos 87 1.1 christos static struct eapol_test_data eapol_test; 88 1.1 christos 89 1.1 christos 90 1.1 christos static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx); 91 1.1 christos 92 1.1 christos 93 1.1 christos static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, 94 1.1 christos int level, const char *txt, size_t len) 95 1.1 christos { 96 1.1 christos if (addr) 97 1.1 christos wpa_printf(MSG_DEBUG, "STA " MACSTR ": %s\n", 98 1.1 christos MAC2STR(addr), txt); 99 1.1 christos else 100 1.1 christos wpa_printf(MSG_DEBUG, "%s", txt); 101 1.1 christos } 102 1.1 christos 103 1.1 christos 104 1.1 christos static int add_extra_attr(struct radius_msg *msg, 105 1.1 christos struct extra_radius_attr *attr) 106 1.1 christos { 107 1.1 christos size_t len; 108 1.1 christos char *pos; 109 1.1 christos u32 val; 110 1.1.1.3 christos char buf[RADIUS_MAX_ATTR_LEN + 1]; 111 1.1 christos 112 1.1 christos switch (attr->syntax) { 113 1.1 christos case 's': 114 1.1 christos os_snprintf(buf, sizeof(buf), "%s", attr->data); 115 1.1 christos len = os_strlen(buf); 116 1.1 christos break; 117 1.1 christos case 'n': 118 1.1 christos buf[0] = '\0'; 119 1.1 christos len = 1; 120 1.1 christos break; 121 1.1 christos case 'x': 122 1.1 christos pos = attr->data; 123 1.1 christos if (pos[0] == '0' && pos[1] == 'x') 124 1.1 christos pos += 2; 125 1.1 christos len = os_strlen(pos); 126 1.1.1.3 christos if ((len & 1) || (len / 2) > RADIUS_MAX_ATTR_LEN) { 127 1.1 christos printf("Invalid extra attribute hexstring\n"); 128 1.1 christos return -1; 129 1.1 christos } 130 1.1 christos len /= 2; 131 1.1 christos if (hexstr2bin(pos, (u8 *) buf, len) < 0) { 132 1.1 christos printf("Invalid extra attribute hexstring\n"); 133 1.1 christos return -1; 134 1.1 christos } 135 1.1 christos break; 136 1.1 christos case 'd': 137 1.1 christos val = htonl(atoi(attr->data)); 138 1.1 christos os_memcpy(buf, &val, 4); 139 1.1 christos len = 4; 140 1.1 christos break; 141 1.1 christos default: 142 1.1 christos printf("Incorrect extra attribute syntax specification\n"); 143 1.1 christos return -1; 144 1.1 christos } 145 1.1 christos 146 1.1 christos if (!radius_msg_add_attr(msg, attr->type, (u8 *) buf, len)) { 147 1.1 christos printf("Could not add attribute %d\n", attr->type); 148 1.1 christos return -1; 149 1.1 christos } 150 1.1 christos 151 1.1 christos return 0; 152 1.1 christos } 153 1.1 christos 154 1.1 christos 155 1.1 christos static int add_extra_attrs(struct radius_msg *msg, 156 1.1 christos struct extra_radius_attr *attrs) 157 1.1 christos { 158 1.1 christos struct extra_radius_attr *p; 159 1.1 christos for (p = attrs; p; p = p->next) { 160 1.1 christos if (add_extra_attr(msg, p) < 0) 161 1.1 christos return -1; 162 1.1 christos } 163 1.1 christos return 0; 164 1.1 christos } 165 1.1 christos 166 1.1 christos 167 1.1 christos static struct extra_radius_attr * 168 1.1 christos find_extra_attr(struct extra_radius_attr *attrs, u8 type) 169 1.1 christos { 170 1.1 christos struct extra_radius_attr *p; 171 1.1 christos for (p = attrs; p; p = p->next) { 172 1.1 christos if (p->type == type) 173 1.1 christos return p; 174 1.1 christos } 175 1.1 christos return NULL; 176 1.1 christos } 177 1.1 christos 178 1.1 christos 179 1.1 christos static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, 180 1.1 christos const u8 *eap, size_t len) 181 1.1 christos { 182 1.1 christos struct radius_msg *msg; 183 1.1.1.3 christos char buf[RADIUS_MAX_ATTR_LEN + 1]; 184 1.1 christos const struct eap_hdr *hdr; 185 1.1 christos const u8 *pos; 186 1.1 christos 187 1.1 christos wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " 188 1.1 christos "packet"); 189 1.1 christos 190 1.1 christos e->radius_identifier = radius_client_get_id(e->radius); 191 1.1 christos msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, 192 1.1 christos e->radius_identifier); 193 1.1 christos if (msg == NULL) { 194 1.1 christos printf("Could not create net RADIUS packet\n"); 195 1.1 christos return; 196 1.1 christos } 197 1.1 christos 198 1.1.1.8 christos if (!radius_msg_add_msg_auth(msg)) 199 1.1.1.8 christos goto fail; 200 1.1.1.8 christos 201 1.1.1.6 christos radius_msg_make_authenticator(msg); 202 1.1 christos 203 1.1 christos hdr = (const struct eap_hdr *) eap; 204 1.1 christos pos = (const u8 *) (hdr + 1); 205 1.1 christos if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE && 206 1.1 christos pos[0] == EAP_TYPE_IDENTITY) { 207 1.1 christos pos++; 208 1.1 christos os_free(e->eap_identity); 209 1.1 christos e->eap_identity_len = len - sizeof(*hdr) - 1; 210 1.1 christos e->eap_identity = os_malloc(e->eap_identity_len); 211 1.1 christos if (e->eap_identity) { 212 1.1 christos os_memcpy(e->eap_identity, pos, e->eap_identity_len); 213 1.1 christos wpa_hexdump(MSG_DEBUG, "Learned identity from " 214 1.1 christos "EAP-Response-Identity", 215 1.1 christos e->eap_identity, e->eap_identity_len); 216 1.1 christos } 217 1.1 christos } 218 1.1 christos 219 1.1 christos if (e->eap_identity && 220 1.1 christos !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, 221 1.1 christos e->eap_identity, e->eap_identity_len)) { 222 1.1 christos printf("Could not add User-Name\n"); 223 1.1 christos goto fail; 224 1.1 christos } 225 1.1 christos 226 1.1.1.4 christos if (e->req_eap_key_name && 227 1.1.1.4 christos !radius_msg_add_attr(msg, RADIUS_ATTR_EAP_KEY_NAME, (u8 *) "\0", 228 1.1.1.4 christos 1)) { 229 1.1.1.4 christos printf("Could not add EAP-Key-Name\n"); 230 1.1.1.4 christos goto fail; 231 1.1.1.4 christos } 232 1.1.1.4 christos 233 1.1 christos if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_IP_ADDRESS) && 234 1.1 christos !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, 235 1.1 christos (u8 *) &e->own_ip_addr, 4)) { 236 1.1 christos printf("Could not add NAS-IP-Address\n"); 237 1.1 christos goto fail; 238 1.1 christos } 239 1.1 christos 240 1.1 christos os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 241 1.1 christos MAC2STR(e->wpa_s->own_addr)); 242 1.1 christos if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CALLING_STATION_ID) 243 1.1 christos && 244 1.1 christos !radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 245 1.1 christos (u8 *) buf, os_strlen(buf))) { 246 1.1 christos printf("Could not add Calling-Station-Id\n"); 247 1.1 christos goto fail; 248 1.1 christos } 249 1.1 christos 250 1.1 christos /* TODO: should probably check MTU from driver config; 2304 is max for 251 1.1 christos * IEEE 802.11, but use 1400 to avoid problems with too large packets 252 1.1 christos */ 253 1.1 christos if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_FRAMED_MTU) && 254 1.1 christos !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { 255 1.1 christos printf("Could not add Framed-MTU\n"); 256 1.1 christos goto fail; 257 1.1 christos } 258 1.1 christos 259 1.1 christos if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_PORT_TYPE) && 260 1.1 christos !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE, 261 1.1 christos RADIUS_NAS_PORT_TYPE_IEEE_802_11)) { 262 1.1 christos printf("Could not add NAS-Port-Type\n"); 263 1.1 christos goto fail; 264 1.1 christos } 265 1.1 christos 266 1.1.1.6 christos if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_SERVICE_TYPE) && 267 1.1.1.6 christos !radius_msg_add_attr_int32(msg, RADIUS_ATTR_SERVICE_TYPE, 268 1.1.1.6 christos RADIUS_SERVICE_TYPE_FRAMED)) { 269 1.1.1.6 christos printf("Could not add Service-Type\n"); 270 1.1.1.6 christos goto fail; 271 1.1.1.6 christos } 272 1.1.1.6 christos 273 1.1 christos os_snprintf(buf, sizeof(buf), "%s", e->connect_info); 274 1.1 christos if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CONNECT_INFO) && 275 1.1 christos !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 276 1.1 christos (u8 *) buf, os_strlen(buf))) { 277 1.1 christos printf("Could not add Connect-Info\n"); 278 1.1 christos goto fail; 279 1.1 christos } 280 1.1 christos 281 1.1 christos if (add_extra_attrs(msg, e->extra_attrs) < 0) 282 1.1 christos goto fail; 283 1.1 christos 284 1.1 christos if (eap && !radius_msg_add_eap(msg, eap, len)) { 285 1.1 christos printf("Could not add EAP-Message\n"); 286 1.1 christos goto fail; 287 1.1 christos } 288 1.1 christos 289 1.1 christos /* State attribute must be copied if and only if this packet is 290 1.1 christos * Access-Request reply to the previous Access-Challenge */ 291 1.1 christos if (e->last_recv_radius && 292 1.1 christos radius_msg_get_hdr(e->last_recv_radius)->code == 293 1.1 christos RADIUS_CODE_ACCESS_CHALLENGE) { 294 1.1 christos int res = radius_msg_copy_attr(msg, e->last_recv_radius, 295 1.1 christos RADIUS_ATTR_STATE); 296 1.1 christos if (res < 0) { 297 1.1 christos printf("Could not copy State attribute from previous " 298 1.1 christos "Access-Challenge\n"); 299 1.1 christos goto fail; 300 1.1 christos } 301 1.1 christos if (res > 0) { 302 1.1 christos wpa_printf(MSG_DEBUG, " Copied RADIUS State " 303 1.1 christos "Attribute"); 304 1.1 christos } 305 1.1 christos } 306 1.1 christos 307 1.1.1.2 christos if (radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr) 308 1.1.1.2 christos < 0) 309 1.1.1.2 christos goto fail; 310 1.1 christos return; 311 1.1 christos 312 1.1 christos fail: 313 1.1 christos radius_msg_free(msg); 314 1.1 christos } 315 1.1 christos 316 1.1 christos 317 1.1 christos static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf, 318 1.1 christos size_t len) 319 1.1 christos { 320 1.1 christos printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n", 321 1.1 christos type, (unsigned long) len); 322 1.1 christos if (type == IEEE802_1X_TYPE_EAP_PACKET) { 323 1.1 christos wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len); 324 1.1 christos ieee802_1x_encapsulate_radius(&eapol_test, buf, len); 325 1.1 christos } 326 1.1 christos return 0; 327 1.1 christos } 328 1.1 christos 329 1.1 christos 330 1.1 christos static void eapol_test_set_config_blob(void *ctx, 331 1.1 christos struct wpa_config_blob *blob) 332 1.1 christos { 333 1.1.1.2 christos struct eapol_test_data *e = ctx; 334 1.1.1.2 christos wpa_config_set_blob(e->wpa_s->conf, blob); 335 1.1 christos } 336 1.1 christos 337 1.1 christos 338 1.1 christos static const struct wpa_config_blob * 339 1.1 christos eapol_test_get_config_blob(void *ctx, const char *name) 340 1.1 christos { 341 1.1.1.2 christos struct eapol_test_data *e = ctx; 342 1.1.1.2 christos return wpa_config_get_blob(e->wpa_s->conf, name); 343 1.1 christos } 344 1.1 christos 345 1.1 christos 346 1.1 christos static void eapol_test_eapol_done_cb(void *ctx) 347 1.1 christos { 348 1.1.1.6 christos struct eapol_test_data *e = ctx; 349 1.1.1.6 christos 350 1.1 christos printf("WPA: EAPOL processing complete\n"); 351 1.1.1.6 christos wpa_supplicant_cancel_auth_timeout(e->wpa_s); 352 1.1.1.6 christos wpa_supplicant_set_state(e->wpa_s, WPA_COMPLETED); 353 1.1 christos } 354 1.1 christos 355 1.1 christos 356 1.1 christos static void eapol_sm_reauth(void *eloop_ctx, void *timeout_ctx) 357 1.1 christos { 358 1.1 christos struct eapol_test_data *e = eloop_ctx; 359 1.1 christos printf("\n\n\n\n\neapol_test: Triggering EAP reauthentication\n\n"); 360 1.1 christos e->radius_access_accept_received = 0; 361 1.1 christos send_eap_request_identity(e->wpa_s, NULL); 362 1.1 christos } 363 1.1 christos 364 1.1 christos 365 1.1 christos static int eapol_test_compare_pmk(struct eapol_test_data *e) 366 1.1 christos { 367 1.1 christos u8 pmk[PMK_LEN]; 368 1.1 christos int ret = 1; 369 1.1.1.4 christos const u8 *sess_id; 370 1.1.1.4 christos size_t sess_id_len; 371 1.1 christos 372 1.1 christos if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) { 373 1.1 christos wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN); 374 1.1 christos if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) { 375 1.1 christos printf("WARNING: PMK mismatch\n"); 376 1.1 christos wpa_hexdump(MSG_DEBUG, "PMK from AS", 377 1.1 christos e->authenticator_pmk, PMK_LEN); 378 1.1 christos } else if (e->radius_access_accept_received) 379 1.1 christos ret = 0; 380 1.1 christos } else if (e->authenticator_pmk_len == 16 && 381 1.1 christos eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) { 382 1.1 christos wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16); 383 1.1 christos if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) { 384 1.1 christos printf("WARNING: PMK mismatch\n"); 385 1.1 christos wpa_hexdump(MSG_DEBUG, "PMK from AS", 386 1.1 christos e->authenticator_pmk, 16); 387 1.1 christos } else if (e->radius_access_accept_received) 388 1.1 christos ret = 0; 389 1.1 christos } else if (e->radius_access_accept_received && e->no_mppe_keys) { 390 1.1 christos /* No keying material expected */ 391 1.1 christos ret = 0; 392 1.1 christos } 393 1.1 christos 394 1.1 christos if (ret && !e->no_mppe_keys) 395 1.1 christos e->num_mppe_mismatch++; 396 1.1 christos else if (!e->no_mppe_keys) 397 1.1 christos e->num_mppe_ok++; 398 1.1 christos 399 1.1.1.4 christos sess_id = eapol_sm_get_session_id(e->wpa_s->eapol, &sess_id_len); 400 1.1.1.4 christos if (!sess_id) 401 1.1.1.4 christos return ret; 402 1.1.1.4 christos if (e->authenticator_eap_key_name_len == 0) { 403 1.1.1.4 christos wpa_printf(MSG_INFO, "No EAP-Key-Name received from server"); 404 1.1.1.4 christos return ret; 405 1.1.1.4 christos } 406 1.1.1.4 christos 407 1.1.1.4 christos if (e->authenticator_eap_key_name_len != sess_id_len || 408 1.1.1.4 christos os_memcmp(e->authenticator_eap_key_name, sess_id, sess_id_len) != 0) 409 1.1.1.4 christos { 410 1.1.1.4 christos wpa_printf(MSG_INFO, 411 1.1.1.4 christos "Locally derived EAP Session-Id does not match EAP-Key-Name from server"); 412 1.1.1.4 christos wpa_hexdump(MSG_DEBUG, "EAP Session-Id", sess_id, sess_id_len); 413 1.1.1.4 christos wpa_hexdump(MSG_DEBUG, "EAP-Key-Name from server", 414 1.1.1.4 christos e->authenticator_eap_key_name, 415 1.1.1.4 christos e->authenticator_eap_key_name_len); 416 1.1.1.4 christos } else { 417 1.1.1.4 christos wpa_printf(MSG_INFO, 418 1.1.1.4 christos "Locally derived EAP Session-Id matches EAP-Key-Name from server"); 419 1.1.1.4 christos } 420 1.1.1.4 christos 421 1.1 christos return ret; 422 1.1 christos } 423 1.1 christos 424 1.1 christos 425 1.1.1.4 christos static void eapol_sm_cb(struct eapol_sm *eapol, enum eapol_supp_result result, 426 1.1.1.4 christos void *ctx) 427 1.1 christos { 428 1.1 christos struct eapol_test_data *e = ctx; 429 1.1.1.4 christos printf("eapol_sm_cb: result=%d\n", result); 430 1.1.1.6 christos e->id_req_sent = 0; 431 1.1.1.6 christos if (e->ctrl_iface) 432 1.1.1.6 christos return; 433 1.1 christos e->eapol_test_num_reauths--; 434 1.1 christos if (e->eapol_test_num_reauths < 0) 435 1.1 christos eloop_terminate(); 436 1.1 christos else { 437 1.1 christos eapol_test_compare_pmk(e); 438 1.1 christos eloop_register_timeout(0, 100000, eapol_sm_reauth, e, NULL); 439 1.1 christos } 440 1.1 christos } 441 1.1 christos 442 1.1 christos 443 1.1.1.2 christos static void eapol_test_write_cert(FILE *f, const char *subject, 444 1.1.1.2 christos const struct wpabuf *cert) 445 1.1.1.2 christos { 446 1.1.1.8 christos char *encoded; 447 1.1.1.2 christos 448 1.1.1.2 christos encoded = base64_encode(wpabuf_head(cert), wpabuf_len(cert), NULL); 449 1.1.1.2 christos if (encoded == NULL) 450 1.1.1.2 christos return; 451 1.1.1.2 christos fprintf(f, "%s\n-----BEGIN CERTIFICATE-----\n%s" 452 1.1.1.2 christos "-----END CERTIFICATE-----\n\n", subject, encoded); 453 1.1.1.2 christos os_free(encoded); 454 1.1.1.2 christos } 455 1.1.1.2 christos 456 1.1.1.2 christos 457 1.1.1.4 christos #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 458 1.1.1.4 christos static void eapol_test_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field, 459 1.1.1.4 christos const char *default_txt) 460 1.1.1.4 christos { 461 1.1.1.4 christos struct eapol_test_data *e = ctx; 462 1.1.1.4 christos struct wpa_supplicant *wpa_s = e->wpa_s; 463 1.1.1.4 christos struct wpa_ssid *ssid = wpa_s->current_ssid; 464 1.1.1.4 christos const char *field_name, *txt = NULL; 465 1.1.1.4 christos char *buf; 466 1.1.1.4 christos size_t buflen; 467 1.1.1.4 christos int len; 468 1.1.1.4 christos 469 1.1.1.4 christos if (ssid == NULL) 470 1.1.1.4 christos return; 471 1.1.1.4 christos 472 1.1.1.4 christos field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt, 473 1.1.1.4 christos &txt); 474 1.1.1.4 christos if (field_name == NULL) { 475 1.1.1.4 christos wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed", 476 1.1.1.4 christos field); 477 1.1.1.4 christos return; 478 1.1.1.4 christos } 479 1.1.1.4 christos 480 1.1.1.4 christos buflen = 100 + os_strlen(txt) + ssid->ssid_len; 481 1.1.1.4 christos buf = os_malloc(buflen); 482 1.1.1.4 christos if (buf == NULL) 483 1.1.1.4 christos return; 484 1.1.1.4 christos len = os_snprintf(buf, buflen, 485 1.1.1.4 christos WPA_CTRL_REQ "%s-%d:%s needed for SSID ", 486 1.1.1.4 christos field_name, ssid->id, txt); 487 1.1.1.5 christos if (os_snprintf_error(buflen, len)) { 488 1.1.1.4 christos os_free(buf); 489 1.1.1.4 christos return; 490 1.1.1.4 christos } 491 1.1.1.4 christos if (ssid->ssid && buflen > len + ssid->ssid_len) { 492 1.1.1.4 christos os_memcpy(buf + len, ssid->ssid, ssid->ssid_len); 493 1.1.1.4 christos len += ssid->ssid_len; 494 1.1.1.4 christos buf[len] = '\0'; 495 1.1.1.4 christos } 496 1.1.1.4 christos buf[buflen - 1] = '\0'; 497 1.1.1.4 christos wpa_msg(wpa_s, MSG_INFO, "%s", buf); 498 1.1.1.4 christos os_free(buf); 499 1.1.1.4 christos } 500 1.1.1.4 christos #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 501 1.1.1.4 christos #define eapol_test_eap_param_needed NULL 502 1.1.1.4 christos #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 503 1.1.1.4 christos 504 1.1.1.4 christos 505 1.1.1.7 christos static void eapol_test_cert_cb(void *ctx, struct tls_cert_data *cert, 506 1.1.1.7 christos const char *cert_hash) 507 1.1.1.2 christos { 508 1.1.1.2 christos struct eapol_test_data *e = ctx; 509 1.1.1.7 christos int i; 510 1.1.1.2 christos 511 1.1.1.2 christos wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT 512 1.1.1.2 christos "depth=%d subject='%s'%s%s", 513 1.1.1.7 christos cert->depth, cert->subject, 514 1.1.1.2 christos cert_hash ? " hash=" : "", 515 1.1.1.2 christos cert_hash ? cert_hash : ""); 516 1.1.1.2 christos 517 1.1.1.7 christos if (cert->cert) { 518 1.1.1.2 christos char *cert_hex; 519 1.1.1.7 christos size_t len = wpabuf_len(cert->cert) * 2 + 1; 520 1.1.1.2 christos cert_hex = os_malloc(len); 521 1.1.1.2 christos if (cert_hex) { 522 1.1.1.7 christos wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert->cert), 523 1.1.1.7 christos wpabuf_len(cert->cert)); 524 1.1.1.2 christos wpa_msg_ctrl(e->wpa_s, MSG_INFO, 525 1.1.1.2 christos WPA_EVENT_EAP_PEER_CERT 526 1.1.1.2 christos "depth=%d subject='%s' cert=%s", 527 1.1.1.7 christos cert->depth, cert->subject, cert_hex); 528 1.1.1.2 christos os_free(cert_hex); 529 1.1.1.2 christos } 530 1.1.1.2 christos 531 1.1.1.2 christos if (e->server_cert_file) 532 1.1.1.2 christos eapol_test_write_cert(e->server_cert_file, 533 1.1.1.7 christos cert->subject, cert->cert); 534 1.1.1.2 christos } 535 1.1.1.5 christos 536 1.1.1.7 christos for (i = 0; i < cert->num_altsubject; i++) 537 1.1.1.7 christos wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT 538 1.1.1.7 christos "depth=%d %s", cert->depth, cert->altsubject[i]); 539 1.1.1.2 christos } 540 1.1.1.2 christos 541 1.1.1.2 christos 542 1.1.1.3 christos static void eapol_test_set_anon_id(void *ctx, const u8 *id, size_t len) 543 1.1.1.3 christos { 544 1.1.1.3 christos struct eapol_test_data *e = ctx; 545 1.1.1.3 christos struct wpa_supplicant *wpa_s = e->wpa_s; 546 1.1.1.3 christos char *str; 547 1.1.1.3 christos int res; 548 1.1.1.3 christos 549 1.1.1.3 christos wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity", 550 1.1.1.3 christos id, len); 551 1.1.1.3 christos 552 1.1.1.3 christos if (wpa_s->current_ssid == NULL) 553 1.1.1.3 christos return; 554 1.1.1.3 christos 555 1.1.1.3 christos if (id == NULL) { 556 1.1.1.3 christos if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 557 1.1.1.3 christos "NULL", 0) < 0) 558 1.1.1.3 christos return; 559 1.1.1.3 christos } else { 560 1.1.1.3 christos str = os_malloc(len * 2 + 1); 561 1.1.1.3 christos if (str == NULL) 562 1.1.1.3 christos return; 563 1.1.1.3 christos wpa_snprintf_hex(str, len * 2 + 1, id, len); 564 1.1.1.3 christos res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 565 1.1.1.3 christos str, 0); 566 1.1.1.3 christos os_free(str); 567 1.1.1.3 christos if (res < 0) 568 1.1.1.3 christos return; 569 1.1.1.3 christos } 570 1.1.1.3 christos } 571 1.1.1.3 christos 572 1.1.1.3 christos 573 1.1.1.6 christos static enum wpa_states eapol_test_get_state(void *ctx) 574 1.1.1.6 christos { 575 1.1.1.6 christos struct eapol_test_data *e = ctx; 576 1.1.1.6 christos struct wpa_supplicant *wpa_s = e->wpa_s; 577 1.1.1.6 christos 578 1.1.1.6 christos return wpa_s->wpa_state; 579 1.1.1.6 christos } 580 1.1.1.6 christos 581 1.1.1.6 christos 582 1.1 christos static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, 583 1.1 christos struct wpa_ssid *ssid) 584 1.1 christos { 585 1.1 christos struct eapol_config eapol_conf; 586 1.1 christos struct eapol_ctx *ctx; 587 1.1.1.6 christos struct wpa_sm_ctx *wctx; 588 1.1 christos 589 1.1 christos ctx = os_zalloc(sizeof(*ctx)); 590 1.1 christos if (ctx == NULL) { 591 1.1 christos printf("Failed to allocate EAPOL context.\n"); 592 1.1 christos return -1; 593 1.1 christos } 594 1.1.1.2 christos ctx->ctx = e; 595 1.1 christos ctx->msg_ctx = wpa_s; 596 1.1 christos ctx->scard_ctx = wpa_s->scard; 597 1.1 christos ctx->cb = eapol_sm_cb; 598 1.1 christos ctx->cb_ctx = e; 599 1.1 christos ctx->eapol_send_ctx = wpa_s; 600 1.1 christos ctx->preauth = 0; 601 1.1 christos ctx->eapol_done_cb = eapol_test_eapol_done_cb; 602 1.1 christos ctx->eapol_send = eapol_test_eapol_send; 603 1.1 christos ctx->set_config_blob = eapol_test_set_config_blob; 604 1.1 christos ctx->get_config_blob = eapol_test_get_config_blob; 605 1.1 christos ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; 606 1.1 christos ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; 607 1.1 christos ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; 608 1.1.1.5 christos ctx->openssl_ciphers = wpa_s->conf->openssl_ciphers; 609 1.1.1.4 christos ctx->eap_param_needed = eapol_test_eap_param_needed; 610 1.1.1.2 christos ctx->cert_cb = eapol_test_cert_cb; 611 1.1.1.2 christos ctx->cert_in_cb = 1; 612 1.1.1.3 christos ctx->set_anon_id = eapol_test_set_anon_id; 613 1.1 christos 614 1.1 christos wpa_s->eapol = eapol_sm_init(ctx); 615 1.1 christos if (wpa_s->eapol == NULL) { 616 1.1 christos os_free(ctx); 617 1.1 christos printf("Failed to initialize EAPOL state machines.\n"); 618 1.1 christos return -1; 619 1.1 christos } 620 1.1 christos 621 1.1.1.6 christos wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA; 622 1.1.1.6 christos wctx = os_zalloc(sizeof(*wctx)); 623 1.1.1.6 christos if (wctx == NULL) { 624 1.1.1.6 christos os_free(ctx); 625 1.1.1.6 christos return -1; 626 1.1.1.6 christos } 627 1.1.1.6 christos wctx->ctx = e; 628 1.1.1.6 christos wctx->msg_ctx = wpa_s; 629 1.1.1.6 christos wctx->get_state = eapol_test_get_state; 630 1.1.1.6 christos wpa_s->wpa = wpa_sm_init(wctx); 631 1.1.1.6 christos if (!wpa_s->wpa) { 632 1.1.1.6 christos os_free(ctx); 633 1.1.1.6 christos os_free(wctx); 634 1.1.1.6 christos return -1; 635 1.1.1.6 christos } 636 1.1.1.6 christos 637 1.1.1.6 christos if (!ssid) 638 1.1.1.6 christos return 0; 639 1.1.1.6 christos 640 1.1 christos wpa_s->current_ssid = ssid; 641 1.1 christos os_memset(&eapol_conf, 0, sizeof(eapol_conf)); 642 1.1 christos eapol_conf.accept_802_1x_keys = 1; 643 1.1 christos eapol_conf.required_keys = 0; 644 1.1 christos eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; 645 1.1 christos eapol_conf.workaround = ssid->eap_workaround; 646 1.1.1.4 christos eapol_conf.external_sim = wpa_s->conf->external_sim; 647 1.1 christos eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf); 648 1.1 christos eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); 649 1.1 christos 650 1.1 christos 651 1.1.1.8 christos eapol_sm_notify_portValid(wpa_s->eapol, false); 652 1.1 christos /* 802.1X::portControl = Auto */ 653 1.1.1.8 christos eapol_sm_notify_portEnabled(wpa_s->eapol, true); 654 1.1 christos 655 1.1 christos return 0; 656 1.1 christos } 657 1.1 christos 658 1.1 christos 659 1.1 christos static void test_eapol_clean(struct eapol_test_data *e, 660 1.1 christos struct wpa_supplicant *wpa_s) 661 1.1 christos { 662 1.1 christos struct extra_radius_attr *p, *prev; 663 1.1 christos 664 1.1.1.6 christos wpa_sm_deinit(wpa_s->wpa); 665 1.1.1.6 christos wpa_s->wpa = NULL; 666 1.1 christos radius_client_deinit(e->radius); 667 1.1.1.3 christos wpabuf_free(e->last_eap_radius); 668 1.1 christos radius_msg_free(e->last_recv_radius); 669 1.1 christos e->last_recv_radius = NULL; 670 1.1 christos os_free(e->eap_identity); 671 1.1 christos e->eap_identity = NULL; 672 1.1 christos eapol_sm_deinit(wpa_s->eapol); 673 1.1 christos wpa_s->eapol = NULL; 674 1.1 christos if (e->radius_conf && e->radius_conf->auth_server) { 675 1.1 christos os_free(e->radius_conf->auth_server->shared_secret); 676 1.1.1.8 christos os_free(e->radius_conf->auth_server->ca_cert); 677 1.1.1.8 christos os_free(e->radius_conf->auth_server->client_cert); 678 1.1.1.8 christos os_free(e->radius_conf->auth_server->private_key); 679 1.1.1.8 christos os_free(e->radius_conf->auth_server->private_key_passwd); 680 1.1 christos os_free(e->radius_conf->auth_server); 681 1.1 christos } 682 1.1 christos os_free(e->radius_conf); 683 1.1 christos e->radius_conf = NULL; 684 1.1 christos scard_deinit(wpa_s->scard); 685 1.1.1.8 christos wpa_supplicant_ctrl_iface_deinit(wpa_s, wpa_s->ctrl_iface); 686 1.1.1.8 christos wpa_s->ctrl_iface = NULL; 687 1.1.1.3 christos 688 1.1.1.3 christos ext_password_deinit(wpa_s->ext_pw); 689 1.1.1.3 christos wpa_s->ext_pw = NULL; 690 1.1.1.3 christos 691 1.1 christos wpa_config_free(wpa_s->conf); 692 1.1 christos 693 1.1 christos p = e->extra_attrs; 694 1.1 christos while (p) { 695 1.1 christos prev = p; 696 1.1 christos p = p->next; 697 1.1 christos os_free(prev); 698 1.1 christos } 699 1.1 christos } 700 1.1 christos 701 1.1 christos 702 1.1 christos static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx) 703 1.1 christos { 704 1.1 christos struct wpa_supplicant *wpa_s = eloop_ctx; 705 1.1 christos u8 buf[100], *pos; 706 1.1 christos struct ieee802_1x_hdr *hdr; 707 1.1 christos struct eap_hdr *eap; 708 1.1 christos 709 1.1 christos hdr = (struct ieee802_1x_hdr *) buf; 710 1.1 christos hdr->version = EAPOL_VERSION; 711 1.1 christos hdr->type = IEEE802_1X_TYPE_EAP_PACKET; 712 1.1 christos hdr->length = htons(5); 713 1.1 christos 714 1.1 christos eap = (struct eap_hdr *) (hdr + 1); 715 1.1 christos eap->code = EAP_CODE_REQUEST; 716 1.1.1.7 christos if (os_get_random((u8 *) &eap->identifier, sizeof(eap->identifier)) < 0) 717 1.1.1.7 christos eap->identifier = os_random() & 0xff; 718 1.1 christos eap->length = htons(5); 719 1.1 christos pos = (u8 *) (eap + 1); 720 1.1 christos *pos = EAP_TYPE_IDENTITY; 721 1.1 christos 722 1.1 christos printf("Sending fake EAP-Request-Identity\n"); 723 1.1 christos eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf, 724 1.1.1.8 christos sizeof(*hdr) + 5, FRAME_ENCRYPTION_UNKNOWN); 725 1.1 christos } 726 1.1 christos 727 1.1 christos 728 1.1 christos static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx) 729 1.1 christos { 730 1.1 christos struct eapol_test_data *e = eloop_ctx; 731 1.1 christos printf("EAPOL test timed out\n"); 732 1.1 christos e->auth_timed_out = 1; 733 1.1 christos eloop_terminate(); 734 1.1 christos } 735 1.1 christos 736 1.1 christos 737 1.1 christos static char *eap_type_text(u8 type) 738 1.1 christos { 739 1.1 christos switch (type) { 740 1.1 christos case EAP_TYPE_IDENTITY: return "Identity"; 741 1.1 christos case EAP_TYPE_NOTIFICATION: return "Notification"; 742 1.1 christos case EAP_TYPE_NAK: return "Nak"; 743 1.1.1.8 christos 744 1.1.1.8 christos case EAP_TYPE_MD5: return "MD5"; 745 1.1.1.8 christos case EAP_TYPE_OTP: return "OTP"; 746 1.1.1.8 christos case EAP_TYPE_GTC: return "GTC"; 747 1.1 christos case EAP_TYPE_TLS: return "TLS"; 748 1.1.1.8 christos case EAP_TYPE_LEAP: return "LEAP"; 749 1.1.1.8 christos case EAP_TYPE_SIM: return "SIM"; 750 1.1 christos case EAP_TYPE_TTLS: return "TTLS"; 751 1.1.1.8 christos case EAP_TYPE_AKA: return "AKA"; 752 1.1 christos case EAP_TYPE_PEAP: return "PEAP"; 753 1.1.1.8 christos case EAP_TYPE_MSCHAPV2: return "MSCHAPv2"; 754 1.1 christos case EAP_TYPE_FAST: return "FAST"; 755 1.1.1.8 christos case EAP_TYPE_PAX: return "PAX"; 756 1.1 christos case EAP_TYPE_PSK: return "PSK"; 757 1.1.1.8 christos case EAP_TYPE_SAKE: return "SAKE"; 758 1.1.1.8 christos case EAP_TYPE_IKEV2: return "IKEv2"; 759 1.1.1.8 christos case EAP_TYPE_AKA_PRIME: return "AKA-PRIME"; 760 1.1.1.8 christos case EAP_TYPE_GPSK: return "GPSK"; 761 1.1.1.8 christos case EAP_TYPE_PWD: return "PWD"; 762 1.1.1.8 christos case EAP_TYPE_EKE: return "EKE"; 763 1.1.1.8 christos case EAP_TYPE_TEAP: return "TEAP"; 764 1.1 christos default: return "Unknown"; 765 1.1 christos } 766 1.1 christos } 767 1.1 christos 768 1.1 christos 769 1.1 christos static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) 770 1.1 christos { 771 1.1.1.3 christos struct wpabuf *eap; 772 1.1.1.3 christos const struct eap_hdr *hdr; 773 1.1 christos int eap_type = -1; 774 1.1 christos char buf[64]; 775 1.1 christos struct radius_msg *msg; 776 1.1 christos 777 1.1 christos if (e->last_recv_radius == NULL) 778 1.1 christos return; 779 1.1 christos 780 1.1 christos msg = e->last_recv_radius; 781 1.1 christos 782 1.1.1.3 christos eap = radius_msg_get_eap(msg); 783 1.1.1.8 christos if (!eap) { 784 1.1.1.8 christos /* RFC 3579, Chap. 2.6.3: 785 1.1 christos * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message 786 1.1 christos * attribute */ 787 1.1.1.8 christos wpa_printf(MSG_DEBUG, 788 1.1.1.8 christos "could not extract EAP-Message from RADIUS message"); 789 1.1.1.3 christos wpabuf_free(e->last_eap_radius); 790 1.1 christos e->last_eap_radius = NULL; 791 1.1 christos return; 792 1.1 christos } 793 1.1 christos 794 1.1.1.3 christos if (wpabuf_len(eap) < sizeof(*hdr)) { 795 1.1.1.8 christos wpa_printf(MSG_DEBUG, 796 1.1.1.8 christos "too short EAP packet received from authentication server"); 797 1.1.1.3 christos wpabuf_free(eap); 798 1.1 christos return; 799 1.1 christos } 800 1.1 christos 801 1.1.1.3 christos if (wpabuf_len(eap) > sizeof(*hdr)) 802 1.1.1.3 christos eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)]; 803 1.1 christos 804 1.1.1.3 christos hdr = wpabuf_head(eap); 805 1.1 christos switch (hdr->code) { 806 1.1 christos case EAP_CODE_REQUEST: 807 1.1 christos os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", 808 1.1 christos eap_type >= 0 ? eap_type_text(eap_type) : "??", 809 1.1 christos eap_type); 810 1.1 christos break; 811 1.1 christos case EAP_CODE_RESPONSE: 812 1.1 christos os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)", 813 1.1 christos eap_type >= 0 ? eap_type_text(eap_type) : "??", 814 1.1 christos eap_type); 815 1.1 christos break; 816 1.1 christos case EAP_CODE_SUCCESS: 817 1.1 christos os_strlcpy(buf, "EAP Success", sizeof(buf)); 818 1.1 christos /* LEAP uses EAP Success within an authentication, so must not 819 1.1 christos * stop here with eloop_terminate(); */ 820 1.1 christos break; 821 1.1 christos case EAP_CODE_FAILURE: 822 1.1 christos os_strlcpy(buf, "EAP Failure", sizeof(buf)); 823 1.1.1.6 christos if (e->ctrl_iface) 824 1.1.1.6 christos break; 825 1.1 christos eloop_terminate(); 826 1.1 christos break; 827 1.1 christos default: 828 1.1 christos os_strlcpy(buf, "unknown EAP code", sizeof(buf)); 829 1.1.1.3 christos wpa_hexdump_buf(MSG_DEBUG, "Decapsulated EAP packet", eap); 830 1.1 christos break; 831 1.1 christos } 832 1.1.1.8 christos buf[sizeof(buf) - 1] = '\0'; 833 1.1.1.8 christos wpa_printf(MSG_DEBUG, 834 1.1.1.8 christos "decapsulated EAP packet (code=%d id=%d len=%d) from RADIUS server: %s", 835 1.1.1.8 christos hdr->code, hdr->identifier, be_to_host16(hdr->length), 836 1.1.1.8 christos buf); 837 1.1 christos 838 1.1.1.3 christos wpabuf_free(e->last_eap_radius); 839 1.1 christos e->last_eap_radius = eap; 840 1.1 christos 841 1.1 christos { 842 1.1 christos struct ieee802_1x_hdr *dot1x; 843 1.1.1.3 christos dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap)); 844 1.1 christos assert(dot1x != NULL); 845 1.1 christos dot1x->version = EAPOL_VERSION; 846 1.1 christos dot1x->type = IEEE802_1X_TYPE_EAP_PACKET; 847 1.1.1.3 christos dot1x->length = htons(wpabuf_len(eap)); 848 1.1.1.3 christos os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap), 849 1.1.1.3 christos wpabuf_len(eap)); 850 1.1 christos eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid, 851 1.1.1.3 christos (u8 *) dot1x, 852 1.1.1.8 christos sizeof(*dot1x) + wpabuf_len(eap), 853 1.1.1.8 christos FRAME_ENCRYPTION_UNKNOWN); 854 1.1 christos os_free(dot1x); 855 1.1 christos } 856 1.1 christos } 857 1.1 christos 858 1.1 christos 859 1.1 christos static void ieee802_1x_get_keys(struct eapol_test_data *e, 860 1.1 christos struct radius_msg *msg, struct radius_msg *req, 861 1.1 christos const u8 *shared_secret, 862 1.1 christos size_t shared_secret_len) 863 1.1 christos { 864 1.1 christos struct radius_ms_mppe_keys *keys; 865 1.1.1.4 christos u8 *buf; 866 1.1.1.4 christos size_t len; 867 1.1 christos 868 1.1 christos keys = radius_msg_get_ms_keys(msg, req, shared_secret, 869 1.1 christos shared_secret_len); 870 1.1.1.8 christos if (keys && !keys->send && !keys->recv) { 871 1.1 christos os_free(keys); 872 1.1 christos keys = radius_msg_get_cisco_keys(msg, req, shared_secret, 873 1.1 christos shared_secret_len); 874 1.1 christos } 875 1.1 christos 876 1.1 christos if (keys) { 877 1.1 christos if (keys->send) { 878 1.1 christos wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)", 879 1.1 christos keys->send, keys->send_len); 880 1.1 christos } 881 1.1 christos if (keys->recv) { 882 1.1 christos wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)", 883 1.1 christos keys->recv, keys->recv_len); 884 1.1 christos e->authenticator_pmk_len = 885 1.1 christos keys->recv_len > PMK_LEN ? PMK_LEN : 886 1.1 christos keys->recv_len; 887 1.1 christos os_memcpy(e->authenticator_pmk, keys->recv, 888 1.1 christos e->authenticator_pmk_len); 889 1.1 christos if (e->authenticator_pmk_len == 16 && keys->send && 890 1.1 christos keys->send_len == 16) { 891 1.1 christos /* MS-CHAP-v2 derives 16 octet keys */ 892 1.1 christos wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key " 893 1.1 christos "to extend PMK to 32 octets"); 894 1.1 christos os_memcpy(e->authenticator_pmk + 895 1.1 christos e->authenticator_pmk_len, 896 1.1 christos keys->send, keys->send_len); 897 1.1 christos e->authenticator_pmk_len += keys->send_len; 898 1.1 christos } 899 1.1 christos } 900 1.1 christos 901 1.1 christos os_free(keys->send); 902 1.1 christos os_free(keys->recv); 903 1.1 christos os_free(keys); 904 1.1 christos } 905 1.1.1.4 christos 906 1.1.1.4 christos if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_EAP_KEY_NAME, &buf, &len, 907 1.1.1.4 christos NULL) == 0) { 908 1.1.1.4 christos os_memcpy(e->authenticator_eap_key_name, buf, len); 909 1.1.1.4 christos e->authenticator_eap_key_name_len = len; 910 1.1.1.4 christos } else { 911 1.1.1.4 christos e->authenticator_eap_key_name_len = 0; 912 1.1.1.4 christos } 913 1.1 christos } 914 1.1 christos 915 1.1 christos 916 1.1 christos /* Process the RADIUS frames from Authentication Server */ 917 1.1 christos static RadiusRxResult 918 1.1 christos ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, 919 1.1 christos const u8 *shared_secret, size_t shared_secret_len, 920 1.1 christos void *data) 921 1.1 christos { 922 1.1 christos struct eapol_test_data *e = data; 923 1.1 christos struct radius_hdr *hdr = radius_msg_get_hdr(msg); 924 1.1 christos 925 1.1 christos /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be 926 1.1 christos * present when packet contains an EAP-Message attribute */ 927 1.1 christos if (hdr->code == RADIUS_CODE_ACCESS_REJECT && 928 1.1 christos radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 929 1.1 christos 0) < 0 && 930 1.1 christos radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { 931 1.1.1.8 christos wpa_printf(MSG_DEBUG, 932 1.1.1.8 christos "Allowing RADIUS Access-Reject without Message-Authenticator since it does not include EAP-Message"); 933 1.1 christos } else if (radius_msg_verify(msg, shared_secret, shared_secret_len, 934 1.1 christos req, 1)) { 935 1.1.1.8 christos wpa_printf(MSG_INFO, 936 1.1.1.8 christos "Incoming RADIUS packet did not have correct Message-Authenticator - dropped"); 937 1.1.1.8 christos return RADIUS_RX_INVALID_AUTHENTICATOR; 938 1.1 christos } 939 1.1 christos 940 1.1 christos if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 941 1.1 christos hdr->code != RADIUS_CODE_ACCESS_REJECT && 942 1.1 christos hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { 943 1.1.1.8 christos wpa_printf(MSG_INFO, "Unknown RADIUS message code"); 944 1.1 christos return RADIUS_RX_UNKNOWN; 945 1.1 christos } 946 1.1 christos 947 1.1 christos e->radius_identifier = -1; 948 1.1 christos wpa_printf(MSG_DEBUG, "RADIUS packet matching with station"); 949 1.1 christos 950 1.1 christos radius_msg_free(e->last_recv_radius); 951 1.1 christos e->last_recv_radius = msg; 952 1.1 christos 953 1.1 christos switch (hdr->code) { 954 1.1 christos case RADIUS_CODE_ACCESS_ACCEPT: 955 1.1 christos e->radius_access_accept_received = 1; 956 1.1 christos ieee802_1x_get_keys(e, msg, req, shared_secret, 957 1.1 christos shared_secret_len); 958 1.1 christos break; 959 1.1 christos case RADIUS_CODE_ACCESS_REJECT: 960 1.1 christos e->radius_access_reject_received = 1; 961 1.1 christos break; 962 1.1 christos } 963 1.1 christos 964 1.1 christos ieee802_1x_decapsulate_radius(e); 965 1.1 christos 966 1.1 christos if ((hdr->code == RADIUS_CODE_ACCESS_ACCEPT && 967 1.1 christos e->eapol_test_num_reauths < 0) || 968 1.1 christos hdr->code == RADIUS_CODE_ACCESS_REJECT) { 969 1.1.1.6 christos if (!e->ctrl_iface) 970 1.1.1.6 christos eloop_terminate(); 971 1.1 christos } 972 1.1 christos 973 1.1 christos return RADIUS_RX_QUEUED; 974 1.1 christos } 975 1.1 christos 976 1.1 christos 977 1.1.1.6 christos static int driver_get_ssid(void *priv, u8 *ssid) 978 1.1.1.6 christos { 979 1.1.1.6 christos ssid[0] = 0; 980 1.1.1.6 christos return 0; 981 1.1.1.6 christos } 982 1.1.1.6 christos 983 1.1.1.6 christos 984 1.1.1.6 christos static int driver_get_bssid(void *priv, u8 *bssid) 985 1.1.1.6 christos { 986 1.1.1.6 christos struct eapol_test_data *e = priv; 987 1.1.1.6 christos 988 1.1.1.6 christos if (e->ctrl_iface && !e->id_req_sent) { 989 1.1.1.6 christos eloop_register_timeout(0, 0, send_eap_request_identity, 990 1.1.1.6 christos e->wpa_s, NULL); 991 1.1.1.6 christos e->id_req_sent = 1; 992 1.1.1.6 christos } 993 1.1.1.6 christos 994 1.1.1.6 christos os_memset(bssid, 0, ETH_ALEN); 995 1.1.1.6 christos bssid[5] = 1; 996 1.1.1.6 christos return 0; 997 1.1.1.6 christos } 998 1.1.1.6 christos 999 1.1.1.6 christos 1000 1.1.1.6 christos static int driver_get_capa(void *priv, struct wpa_driver_capa *capa) 1001 1.1.1.6 christos { 1002 1.1.1.6 christos os_memset(capa, 0, sizeof(*capa)); 1003 1.1.1.6 christos capa->flags = WPA_DRIVER_FLAGS_WIRED; 1004 1.1.1.6 christos return 0; 1005 1.1.1.6 christos } 1006 1.1.1.6 christos 1007 1.1.1.6 christos 1008 1.1.1.6 christos struct wpa_driver_ops eapol_test_drv_ops = { 1009 1.1.1.6 christos .name = "test", 1010 1.1.1.6 christos .get_ssid = driver_get_ssid, 1011 1.1.1.6 christos .get_bssid = driver_get_bssid, 1012 1.1.1.6 christos .get_capa = driver_get_capa, 1013 1.1.1.6 christos }; 1014 1.1.1.6 christos 1015 1.1 christos static void wpa_init_conf(struct eapol_test_data *e, 1016 1.1 christos struct wpa_supplicant *wpa_s, const char *authsrv, 1017 1.1.1.8 christos int port, bool tls, const char *secret, 1018 1.1.1.8 christos const char *ca_cert, const char *client_cert, 1019 1.1.1.8 christos const char *private_key, 1020 1.1.1.8 christos const char *private_key_passwd, 1021 1.1.1.6 christos const char *cli_addr, const char *ifname) 1022 1.1 christos { 1023 1.1 christos struct hostapd_radius_server *as; 1024 1.1 christos int res; 1025 1.1 christos 1026 1.1.1.6 christos wpa_s->driver = &eapol_test_drv_ops; 1027 1.1.1.6 christos wpa_s->drv_priv = e; 1028 1.1 christos wpa_s->bssid[5] = 1; 1029 1.1 christos os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN); 1030 1.1 christos e->own_ip_addr.s_addr = htonl((127 << 24) | 1); 1031 1.1.1.6 christos os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname)); 1032 1.1 christos 1033 1.1 christos e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers)); 1034 1.1 christos assert(e->radius_conf != NULL); 1035 1.1 christos e->radius_conf->num_auth_servers = 1; 1036 1.1 christos as = os_zalloc(sizeof(struct hostapd_radius_server)); 1037 1.1 christos assert(as != NULL); 1038 1.1 christos #if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) 1039 1.1 christos { 1040 1.1 christos int a[4]; 1041 1.1 christos u8 *pos; 1042 1.1 christos sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 1043 1.1 christos pos = (u8 *) &as->addr.u.v4; 1044 1.1 christos *pos++ = a[0]; 1045 1.1 christos *pos++ = a[1]; 1046 1.1 christos *pos++ = a[2]; 1047 1.1 christos *pos++ = a[3]; 1048 1.1.1.8 christos as->addr.af = AF_INET; 1049 1.1 christos } 1050 1.1 christos #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 1051 1.1.1.6 christos if (hostapd_parse_ip_addr(authsrv, &as->addr) < 0) { 1052 1.1.1.5 christos wpa_printf(MSG_ERROR, "Invalid IP address '%s'", 1053 1.1.1.5 christos authsrv); 1054 1.1.1.5 christos assert(0); 1055 1.1.1.5 christos } 1056 1.1 christos #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 1057 1.1 christos as->port = port; 1058 1.1.1.8 christos as->tls = tls; 1059 1.1 christos as->shared_secret = (u8 *) os_strdup(secret); 1060 1.1 christos as->shared_secret_len = os_strlen(secret); 1061 1.1.1.8 christos if (ca_cert) 1062 1.1.1.8 christos as->ca_cert = os_strdup(ca_cert); 1063 1.1.1.8 christos if (client_cert) 1064 1.1.1.8 christos as->client_cert = os_strdup(client_cert); 1065 1.1.1.8 christos if (private_key) 1066 1.1.1.8 christos as->private_key = os_strdup(private_key); 1067 1.1.1.8 christos if (private_key_passwd) 1068 1.1.1.8 christos as->private_key_passwd = os_strdup(private_key_passwd); 1069 1.1 christos e->radius_conf->auth_server = as; 1070 1.1 christos e->radius_conf->auth_servers = as; 1071 1.1 christos e->radius_conf->msg_dumps = 1; 1072 1.1 christos if (cli_addr) { 1073 1.1 christos if (hostapd_parse_ip_addr(cli_addr, 1074 1.1 christos &e->radius_conf->client_addr) == 0) 1075 1.1 christos e->radius_conf->force_client_addr = 1; 1076 1.1 christos else { 1077 1.1 christos wpa_printf(MSG_ERROR, "Invalid IP address '%s'", 1078 1.1 christos cli_addr); 1079 1.1 christos assert(0); 1080 1.1 christos } 1081 1.1 christos } 1082 1.1 christos 1083 1.1 christos e->radius = radius_client_init(wpa_s, e->radius_conf); 1084 1.1 christos assert(e->radius != NULL); 1085 1.1 christos 1086 1.1 christos res = radius_client_register(e->radius, RADIUS_AUTH, 1087 1.1 christos ieee802_1x_receive_auth, e); 1088 1.1 christos assert(res == 0); 1089 1.1 christos } 1090 1.1 christos 1091 1.1 christos 1092 1.1.1.4 christos static int scard_test(struct eapol_test_data *e) 1093 1.1 christos { 1094 1.1 christos struct scard_data *scard; 1095 1.1 christos size_t len; 1096 1.1 christos char imsi[20]; 1097 1.1 christos unsigned char _rand[16]; 1098 1.1 christos #ifdef PCSC_FUNCS 1099 1.1 christos unsigned char sres[4]; 1100 1.1 christos unsigned char kc[8]; 1101 1.1 christos #endif /* PCSC_FUNCS */ 1102 1.1 christos #define num_triplets 5 1103 1.1 christos unsigned char rand_[num_triplets][16]; 1104 1.1 christos unsigned char sres_[num_triplets][4]; 1105 1.1 christos unsigned char kc_[num_triplets][8]; 1106 1.1 christos int i, res; 1107 1.1 christos size_t j; 1108 1.1 christos 1109 1.1 christos #define AKA_RAND_LEN 16 1110 1.1 christos #define AKA_AUTN_LEN 16 1111 1.1 christos #define AKA_AUTS_LEN 14 1112 1.1 christos #define RES_MAX_LEN 16 1113 1.1 christos #define IK_LEN 16 1114 1.1 christos #define CK_LEN 16 1115 1.1 christos unsigned char aka_rand[AKA_RAND_LEN]; 1116 1.1 christos unsigned char aka_autn[AKA_AUTN_LEN]; 1117 1.1 christos unsigned char aka_auts[AKA_AUTS_LEN]; 1118 1.1 christos unsigned char aka_res[RES_MAX_LEN]; 1119 1.1 christos size_t aka_res_len; 1120 1.1 christos unsigned char aka_ik[IK_LEN]; 1121 1.1 christos unsigned char aka_ck[CK_LEN]; 1122 1.1 christos 1123 1.1.1.4 christos scard = scard_init(e->pcsc_reader); 1124 1.1 christos if (scard == NULL) 1125 1.1 christos return -1; 1126 1.1.1.4 christos if (scard_set_pin(scard, e->pcsc_pin)) { 1127 1.1 christos wpa_printf(MSG_WARNING, "PIN validation failed"); 1128 1.1 christos scard_deinit(scard); 1129 1.1 christos return -1; 1130 1.1 christos } 1131 1.1 christos 1132 1.1 christos len = sizeof(imsi); 1133 1.1 christos if (scard_get_imsi(scard, imsi, &len)) 1134 1.1 christos goto failed; 1135 1.1 christos wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len); 1136 1.1 christos /* NOTE: Permanent Username: 1 | IMSI */ 1137 1.1 christos 1138 1.1.1.3 christos wpa_printf(MSG_DEBUG, "SCARD: MNC length %d", 1139 1.1.1.3 christos scard_get_mnc_len(scard)); 1140 1.1.1.3 christos 1141 1.1 christos os_memset(_rand, 0, sizeof(_rand)); 1142 1.1 christos if (scard_gsm_auth(scard, _rand, sres, kc)) 1143 1.1 christos goto failed; 1144 1.1 christos 1145 1.1 christos os_memset(_rand, 0xff, sizeof(_rand)); 1146 1.1 christos if (scard_gsm_auth(scard, _rand, sres, kc)) 1147 1.1 christos goto failed; 1148 1.1 christos 1149 1.1 christos for (i = 0; i < num_triplets; i++) { 1150 1.1 christos os_memset(rand_[i], i, sizeof(rand_[i])); 1151 1.1 christos if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i])) 1152 1.1 christos goto failed; 1153 1.1 christos } 1154 1.1 christos 1155 1.1 christos for (i = 0; i < num_triplets; i++) { 1156 1.1 christos printf("1"); 1157 1.1 christos for (j = 0; j < len; j++) 1158 1.1 christos printf("%c", imsi[j]); 1159 1.1 christos printf(","); 1160 1.1 christos for (j = 0; j < 16; j++) 1161 1.1 christos printf("%02X", rand_[i][j]); 1162 1.1 christos printf(","); 1163 1.1 christos for (j = 0; j < 4; j++) 1164 1.1 christos printf("%02X", sres_[i][j]); 1165 1.1 christos printf(","); 1166 1.1 christos for (j = 0; j < 8; j++) 1167 1.1 christos printf("%02X", kc_[i][j]); 1168 1.1 christos printf("\n"); 1169 1.1 christos } 1170 1.1 christos 1171 1.1 christos wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication"); 1172 1.1 christos 1173 1.1 christos /* seq 39 (0x28) */ 1174 1.1 christos os_memset(aka_rand, 0xaa, 16); 1175 1.1 christos os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf" 1176 1.1 christos "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16); 1177 1.1 christos 1178 1.1 christos res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len, 1179 1.1 christos aka_ik, aka_ck, aka_auts); 1180 1.1 christos if (res == 0) { 1181 1.1 christos wpa_printf(MSG_DEBUG, "UMTS auth completed successfully"); 1182 1.1 christos wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len); 1183 1.1 christos wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN); 1184 1.1 christos wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN); 1185 1.1 christos } else if (res == -2) { 1186 1.1 christos wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization " 1187 1.1 christos "failure"); 1188 1.1 christos wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN); 1189 1.1 christos } else { 1190 1.1 christos wpa_printf(MSG_DEBUG, "UMTS auth failed"); 1191 1.1 christos } 1192 1.1 christos 1193 1.1 christos failed: 1194 1.1 christos scard_deinit(scard); 1195 1.1 christos 1196 1.1 christos return 0; 1197 1.1 christos #undef num_triplets 1198 1.1 christos } 1199 1.1 christos 1200 1.1 christos 1201 1.1.1.4 christos static int scard_get_triplets(struct eapol_test_data *e, int argc, char *argv[]) 1202 1.1 christos { 1203 1.1 christos struct scard_data *scard; 1204 1.1 christos size_t len; 1205 1.1 christos char imsi[20]; 1206 1.1 christos unsigned char _rand[16]; 1207 1.1 christos unsigned char sres[4]; 1208 1.1 christos unsigned char kc[8]; 1209 1.1 christos int num_triplets; 1210 1.1 christos int i; 1211 1.1 christos size_t j; 1212 1.1 christos 1213 1.1 christos if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) { 1214 1.1 christos printf("invalid parameters for sim command\n"); 1215 1.1 christos return -1; 1216 1.1 christos } 1217 1.1 christos 1218 1.1 christos if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) { 1219 1.1 christos /* disable debug output */ 1220 1.1 christos wpa_debug_level = 99; 1221 1.1 christos } 1222 1.1 christos 1223 1.1.1.4 christos scard = scard_init(e->pcsc_reader); 1224 1.1 christos if (scard == NULL) { 1225 1.1 christos printf("Failed to open smartcard connection\n"); 1226 1.1 christos return -1; 1227 1.1 christos } 1228 1.1 christos if (scard_set_pin(scard, argv[0])) { 1229 1.1 christos wpa_printf(MSG_WARNING, "PIN validation failed"); 1230 1.1 christos scard_deinit(scard); 1231 1.1 christos return -1; 1232 1.1 christos } 1233 1.1 christos 1234 1.1 christos len = sizeof(imsi); 1235 1.1 christos if (scard_get_imsi(scard, imsi, &len)) { 1236 1.1 christos scard_deinit(scard); 1237 1.1 christos return -1; 1238 1.1 christos } 1239 1.1 christos 1240 1.1 christos for (i = 0; i < num_triplets; i++) { 1241 1.1 christos os_memset(_rand, i, sizeof(_rand)); 1242 1.1 christos if (scard_gsm_auth(scard, _rand, sres, kc)) 1243 1.1 christos break; 1244 1.1 christos 1245 1.1 christos /* IMSI:Kc:SRES:RAND */ 1246 1.1 christos for (j = 0; j < len; j++) 1247 1.1 christos printf("%c", imsi[j]); 1248 1.1 christos printf(":"); 1249 1.1 christos for (j = 0; j < 8; j++) 1250 1.1 christos printf("%02X", kc[j]); 1251 1.1 christos printf(":"); 1252 1.1 christos for (j = 0; j < 4; j++) 1253 1.1 christos printf("%02X", sres[j]); 1254 1.1 christos printf(":"); 1255 1.1 christos for (j = 0; j < 16; j++) 1256 1.1 christos printf("%02X", _rand[j]); 1257 1.1 christos printf("\n"); 1258 1.1 christos } 1259 1.1 christos 1260 1.1 christos scard_deinit(scard); 1261 1.1 christos 1262 1.1 christos return 0; 1263 1.1 christos } 1264 1.1 christos 1265 1.1 christos 1266 1.1 christos static void eapol_test_terminate(int sig, void *signal_ctx) 1267 1.1 christos { 1268 1.1 christos struct wpa_supplicant *wpa_s = signal_ctx; 1269 1.1 christos wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); 1270 1.1 christos eloop_terminate(); 1271 1.1 christos } 1272 1.1 christos 1273 1.1 christos 1274 1.1 christos static void usage(void) 1275 1.1 christos { 1276 1.1 christos printf("usage:\n" 1277 1.1.1.6 christos "eapol_test [-enWSv] -c<conf> [-a<AS IP>] [-p<AS port>] " 1278 1.1.1.8 christos "[-s<AS secret>] \\\n" 1279 1.1.1.8 christos " [-X<RADIUS protocol> \\\n" 1280 1.1 christos " [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n" 1281 1.1.1.2 christos " [-M<client MAC address>] [-o<server cert file] \\\n" 1282 1.1.1.4 christos " [-N<attr spec>] [-R<PC/SC reader>] " 1283 1.1.1.4 christos "[-P<PC/SC PIN>] \\\n" 1284 1.1.1.8 christos #ifdef CONFIG_RADIUS_TLS 1285 1.1.1.8 christos " [-j<CA cert>] [-J<client cert>] \\\n" 1286 1.1.1.8 christos "[-k<private key] [-K<private key passwd>] \\\n" 1287 1.1.1.8 christos #endif /* CONFIG_RADIUS_TLS */ 1288 1.1.1.6 christos " [-A<client IP>] [-i<ifname>] [-T<ctrl_iface>]\n" 1289 1.1 christos "eapol_test scard\n" 1290 1.1 christos "eapol_test sim <PIN> <num triplets> [debug]\n" 1291 1.1 christos "\n"); 1292 1.1 christos printf("options:\n" 1293 1.1 christos " -c<conf> = configuration file\n" 1294 1.1 christos " -a<AS IP> = IP address of the authentication server, " 1295 1.1 christos "default 127.0.0.1\n" 1296 1.1.1.8 christos " -p<AS port> = Port of the authentication server,\n" 1297 1.1.1.8 christos " default 1812 for RADIUS/UDP and 2083 for RADIUS/TLS\n" 1298 1.1.1.8 christos " -s<AS secret> = shared secret with the authentication server,\n" 1299 1.1.1.8 christos " default 'radius' for RADIUS/UDP and 'radsec' for RADIUS/TLS\n" 1300 1.1.1.8 christos " -X<RADIUS protocol> = RADIUS protocol to use: UDP (default) or TLS\n" 1301 1.1 christos " -A<client IP> = IP address of the client, default: select " 1302 1.1 christos "automatically\n" 1303 1.1 christos " -r<count> = number of re-authentications\n" 1304 1.1.1.4 christos " -e = Request EAP-Key-Name\n" 1305 1.1 christos " -W = wait for a control interface monitor before starting\n" 1306 1.1 christos " -S = save configuration after authentication\n" 1307 1.1 christos " -n = no MPPE keys expected\n" 1308 1.1.1.6 christos " -v = show version\n" 1309 1.1 christos " -t<timeout> = sets timeout in seconds (default: 30 s)\n" 1310 1.1 christos " -C<Connect-Info> = RADIUS Connect-Info (default: " 1311 1.1 christos "CONNECT 11Mbps 802.11b)\n" 1312 1.1 christos " -M<client MAC address> = Set own MAC address " 1313 1.1 christos "(Calling-Station-Id,\n" 1314 1.1 christos " default: 02:00:00:00:00:01)\n" 1315 1.1.1.2 christos " -o<server cert file> = Write received server certificate\n" 1316 1.1.1.2 christos " chain to the specified file\n" 1317 1.1 christos " -N<attr spec> = send arbitrary attribute specified by:\n" 1318 1.1 christos " attr_id:syntax:value or attr_id\n" 1319 1.1 christos " attr_id - number id of the attribute\n" 1320 1.1 christos " syntax - one of: s, d, x\n" 1321 1.1 christos " s = string\n" 1322 1.1 christos " d = integer\n" 1323 1.1 christos " x = octet string\n" 1324 1.1 christos " value - attribute value.\n" 1325 1.1 christos " When only attr_id is specified, NULL will be used as " 1326 1.1 christos "value.\n" 1327 1.1 christos " Multiple attributes can be specified by using the " 1328 1.1 christos "option several times.\n"); 1329 1.1 christos } 1330 1.1 christos 1331 1.1 christos 1332 1.1 christos int main(int argc, char *argv[]) 1333 1.1 christos { 1334 1.1.1.4 christos struct wpa_global global; 1335 1.1 christos struct wpa_supplicant wpa_s; 1336 1.1 christos int c, ret = 1, wait_for_monitor = 0, save_config = 0; 1337 1.1 christos char *as_addr = "127.0.0.1"; 1338 1.1.1.8 christos int as_port = -1; 1339 1.1.1.8 christos char *as_secret = NULL; 1340 1.1.1.8 christos char *ca_cert = NULL, *client_cert = NULL; 1341 1.1.1.8 christos char *private_key = NULL, *private_key_passwd = NULL; 1342 1.1.1.8 christos bool tls = false; 1343 1.1 christos char *cli_addr = NULL; 1344 1.1 christos char *conf = NULL; 1345 1.1 christos int timeout = 30; 1346 1.1 christos char *pos; 1347 1.1 christos struct extra_radius_attr *p = NULL, *p1; 1348 1.1.1.6 christos const char *ifname = "test"; 1349 1.1.1.6 christos const char *ctrl_iface = NULL; 1350 1.1 christos 1351 1.1 christos if (os_program_init()) 1352 1.1 christos return -1; 1353 1.1 christos 1354 1.1 christos hostapd_logger_register_cb(hostapd_logger_cb); 1355 1.1 christos 1356 1.1 christos os_memset(&eapol_test, 0, sizeof(eapol_test)); 1357 1.1 christos eapol_test.connect_info = "CONNECT 11Mbps 802.11b"; 1358 1.1 christos os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN); 1359 1.1.1.4 christos eapol_test.pcsc_pin = "1234"; 1360 1.1 christos 1361 1.1 christos wpa_debug_level = 0; 1362 1.1 christos wpa_debug_show_keys = 1; 1363 1.1 christos 1364 1.1 christos for (;;) { 1365 1.1.1.8 christos c = getopt(argc, argv, 1366 1.1.1.8 christos "a:A:c:C:ei:j:J:k:K:M:nN:o:p:P:r:R:s:St:T:vWX:"); 1367 1.1 christos if (c < 0) 1368 1.1 christos break; 1369 1.1 christos switch (c) { 1370 1.1 christos case 'a': 1371 1.1 christos as_addr = optarg; 1372 1.1 christos break; 1373 1.1 christos case 'A': 1374 1.1 christos cli_addr = optarg; 1375 1.1 christos break; 1376 1.1 christos case 'c': 1377 1.1 christos conf = optarg; 1378 1.1 christos break; 1379 1.1 christos case 'C': 1380 1.1 christos eapol_test.connect_info = optarg; 1381 1.1 christos break; 1382 1.1.1.4 christos case 'e': 1383 1.1.1.4 christos eapol_test.req_eap_key_name = 1; 1384 1.1.1.4 christos break; 1385 1.1.1.6 christos case 'i': 1386 1.1.1.6 christos ifname = optarg; 1387 1.1.1.6 christos break; 1388 1.1.1.8 christos #ifdef CONFIG_RADIUS_TLS 1389 1.1.1.8 christos case 'j': 1390 1.1.1.8 christos ca_cert = optarg; 1391 1.1.1.8 christos break; 1392 1.1.1.8 christos case 'J': 1393 1.1.1.8 christos client_cert = optarg; 1394 1.1.1.8 christos break; 1395 1.1.1.8 christos case 'k': 1396 1.1.1.8 christos private_key = optarg; 1397 1.1.1.8 christos break; 1398 1.1.1.8 christos case 'K': 1399 1.1.1.8 christos private_key_passwd = optarg; 1400 1.1.1.8 christos break; 1401 1.1.1.8 christos #endif /* CONFIG_RADIUS_TLS */ 1402 1.1 christos case 'M': 1403 1.1 christos if (hwaddr_aton(optarg, eapol_test.own_addr)) { 1404 1.1 christos usage(); 1405 1.1 christos return -1; 1406 1.1 christos } 1407 1.1 christos break; 1408 1.1 christos case 'n': 1409 1.1 christos eapol_test.no_mppe_keys++; 1410 1.1 christos break; 1411 1.1.1.2 christos case 'o': 1412 1.1.1.2 christos if (eapol_test.server_cert_file) 1413 1.1.1.2 christos fclose(eapol_test.server_cert_file); 1414 1.1.1.2 christos eapol_test.server_cert_file = fopen(optarg, "w"); 1415 1.1.1.2 christos if (eapol_test.server_cert_file == NULL) { 1416 1.1.1.2 christos printf("Could not open '%s' for writing\n", 1417 1.1.1.2 christos optarg); 1418 1.1.1.2 christos return -1; 1419 1.1.1.2 christos } 1420 1.1.1.2 christos break; 1421 1.1 christos case 'p': 1422 1.1 christos as_port = atoi(optarg); 1423 1.1 christos break; 1424 1.1.1.4 christos case 'P': 1425 1.1.1.4 christos eapol_test.pcsc_pin = optarg; 1426 1.1.1.4 christos break; 1427 1.1 christos case 'r': 1428 1.1 christos eapol_test.eapol_test_num_reauths = atoi(optarg); 1429 1.1 christos break; 1430 1.1.1.4 christos case 'R': 1431 1.1.1.4 christos eapol_test.pcsc_reader = optarg; 1432 1.1.1.4 christos break; 1433 1.1 christos case 's': 1434 1.1 christos as_secret = optarg; 1435 1.1 christos break; 1436 1.1 christos case 'S': 1437 1.1 christos save_config++; 1438 1.1 christos break; 1439 1.1 christos case 't': 1440 1.1 christos timeout = atoi(optarg); 1441 1.1 christos break; 1442 1.1.1.6 christos case 'T': 1443 1.1.1.6 christos ctrl_iface = optarg; 1444 1.1.1.6 christos eapol_test.ctrl_iface = 1; 1445 1.1.1.6 christos break; 1446 1.1.1.6 christos case 'v': 1447 1.1.1.8 christos printf("eapol_test v%s\n", VERSION_STR); 1448 1.1.1.6 christos return 0; 1449 1.1 christos case 'W': 1450 1.1 christos wait_for_monitor++; 1451 1.1 christos break; 1452 1.1.1.8 christos case 'X': 1453 1.1.1.8 christos if (os_strcmp(optarg, "UDP") == 0) { 1454 1.1.1.8 christos tls = false; 1455 1.1.1.8 christos } else if (os_strcmp(optarg, "TLS") == 0) { 1456 1.1.1.8 christos tls = true; 1457 1.1.1.8 christos } else { 1458 1.1.1.8 christos usage(); 1459 1.1.1.8 christos return -1; 1460 1.1.1.8 christos } 1461 1.1.1.8 christos break; 1462 1.1 christos case 'N': 1463 1.1.1.3 christos p1 = os_zalloc(sizeof(*p1)); 1464 1.1 christos if (p1 == NULL) 1465 1.1 christos break; 1466 1.1 christos if (!p) 1467 1.1 christos eapol_test.extra_attrs = p1; 1468 1.1 christos else 1469 1.1 christos p->next = p1; 1470 1.1 christos p = p1; 1471 1.1 christos 1472 1.1 christos p->type = atoi(optarg); 1473 1.1 christos pos = os_strchr(optarg, ':'); 1474 1.1 christos if (pos == NULL) { 1475 1.1 christos p->syntax = 'n'; 1476 1.1 christos p->data = NULL; 1477 1.1 christos break; 1478 1.1 christos } 1479 1.1 christos 1480 1.1 christos pos++; 1481 1.1 christos if (pos[0] == '\0' || pos[1] != ':') { 1482 1.1 christos printf("Incorrect format of attribute " 1483 1.1 christos "specification\n"); 1484 1.1 christos break; 1485 1.1 christos } 1486 1.1 christos 1487 1.1 christos p->syntax = pos[0]; 1488 1.1 christos p->data = pos + 2; 1489 1.1 christos break; 1490 1.1 christos default: 1491 1.1 christos usage(); 1492 1.1 christos return -1; 1493 1.1 christos } 1494 1.1 christos } 1495 1.1 christos 1496 1.1.1.8 christos if (!as_secret) 1497 1.1.1.8 christos as_secret = tls ? "radsec" : "radius"; 1498 1.1.1.8 christos if (as_port < 0) 1499 1.1.1.8 christos as_port = tls ? 2083 : 1812; 1500 1.1.1.8 christos 1501 1.1 christos if (argc > optind && os_strcmp(argv[optind], "scard") == 0) { 1502 1.1.1.4 christos return scard_test(&eapol_test); 1503 1.1 christos } 1504 1.1 christos 1505 1.1 christos if (argc > optind && os_strcmp(argv[optind], "sim") == 0) { 1506 1.1.1.4 christos return scard_get_triplets(&eapol_test, argc - optind - 1, 1507 1.1 christos &argv[optind + 1]); 1508 1.1 christos } 1509 1.1 christos 1510 1.1.1.6 christos if (conf == NULL && !ctrl_iface) { 1511 1.1 christos usage(); 1512 1.1 christos printf("Configuration file is required.\n"); 1513 1.1 christos return -1; 1514 1.1 christos } 1515 1.1 christos 1516 1.1 christos if (eap_register_methods()) { 1517 1.1 christos wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 1518 1.1 christos return -1; 1519 1.1 christos } 1520 1.1 christos 1521 1.1 christos if (eloop_init()) { 1522 1.1 christos wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 1523 1.1 christos return -1; 1524 1.1 christos } 1525 1.1 christos 1526 1.1.1.4 christos os_memset(&global, 0, sizeof(global)); 1527 1.1 christos os_memset(&wpa_s, 0, sizeof(wpa_s)); 1528 1.1.1.4 christos wpa_s.global = &global; 1529 1.1 christos eapol_test.wpa_s = &wpa_s; 1530 1.1.1.4 christos dl_list_init(&wpa_s.bss); 1531 1.1.1.4 christos dl_list_init(&wpa_s.bss_id); 1532 1.1.1.6 christos if (conf) 1533 1.1.1.8 christos wpa_s.conf = wpa_config_read(conf, NULL, false); 1534 1.1.1.6 christos else 1535 1.1.1.6 christos wpa_s.conf = wpa_config_alloc_empty(ctrl_iface, NULL); 1536 1.1 christos if (wpa_s.conf == NULL) { 1537 1.1 christos printf("Failed to parse configuration file '%s'.\n", conf); 1538 1.1 christos return -1; 1539 1.1 christos } 1540 1.1.1.6 christos if (!ctrl_iface && wpa_s.conf->ssid == NULL) { 1541 1.1 christos printf("No networks defined.\n"); 1542 1.1 christos return -1; 1543 1.1 christos } 1544 1.1 christos 1545 1.1.1.4 christos if (eapol_test.pcsc_reader) { 1546 1.1.1.4 christos os_free(wpa_s.conf->pcsc_reader); 1547 1.1.1.4 christos wpa_s.conf->pcsc_reader = os_strdup(eapol_test.pcsc_reader); 1548 1.1.1.4 christos } 1549 1.1.1.4 christos 1550 1.1.1.8 christos wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, tls, as_secret, 1551 1.1.1.8 christos ca_cert, client_cert, private_key, private_key_passwd, 1552 1.1.1.6 christos cli_addr, ifname); 1553 1.1 christos wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s); 1554 1.1 christos if (wpa_s.ctrl_iface == NULL) { 1555 1.1 christos printf("Failed to initialize control interface '%s'.\n" 1556 1.1 christos "You may have another eapol_test process already " 1557 1.1 christos "running or the file was\n" 1558 1.1 christos "left by an unclean termination of eapol_test in " 1559 1.1 christos "which case you will need\n" 1560 1.1 christos "to manually remove this file before starting " 1561 1.1 christos "eapol_test again.\n", 1562 1.1 christos wpa_s.conf->ctrl_interface); 1563 1.1 christos return -1; 1564 1.1 christos } 1565 1.1.1.6 christos if (wpa_s.conf->ssid && 1566 1.1.1.6 christos wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) 1567 1.1 christos return -1; 1568 1.1 christos 1569 1.1 christos if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid)) 1570 1.1 christos return -1; 1571 1.1 christos 1572 1.1.1.3 christos if (wpas_init_ext_pw(&wpa_s) < 0) 1573 1.1.1.3 christos return -1; 1574 1.1.1.3 christos 1575 1.1 christos if (wait_for_monitor) 1576 1.1 christos wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface); 1577 1.1 christos 1578 1.1.1.6 christos if (!ctrl_iface) { 1579 1.1.1.6 christos eloop_register_timeout(timeout, 0, eapol_test_timeout, 1580 1.1.1.6 christos &eapol_test, NULL); 1581 1.1.1.6 christos eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, 1582 1.1.1.6 christos NULL); 1583 1.1.1.6 christos } 1584 1.1 christos eloop_register_signal_terminate(eapol_test_terminate, &wpa_s); 1585 1.1 christos eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s); 1586 1.1 christos eloop_run(); 1587 1.1 christos 1588 1.1 christos eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL); 1589 1.1 christos eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL); 1590 1.1 christos 1591 1.1 christos if (eapol_test_compare_pmk(&eapol_test) == 0 || 1592 1.1 christos eapol_test.no_mppe_keys) 1593 1.1 christos ret = 0; 1594 1.1 christos if (eapol_test.auth_timed_out) 1595 1.1 christos ret = -2; 1596 1.1 christos if (eapol_test.radius_access_reject_received) 1597 1.1 christos ret = -3; 1598 1.1 christos 1599 1.1 christos if (save_config) 1600 1.1 christos wpa_config_write(conf, wpa_s.conf); 1601 1.1 christos 1602 1.1 christos test_eapol_clean(&eapol_test, &wpa_s); 1603 1.1 christos 1604 1.1 christos eap_peer_unregister_methods(); 1605 1.1.1.2 christos #ifdef CONFIG_AP 1606 1.1.1.2 christos eap_server_unregister_methods(); 1607 1.1.1.2 christos #endif /* CONFIG_AP */ 1608 1.1 christos 1609 1.1 christos eloop_destroy(); 1610 1.1 christos 1611 1.1.1.2 christos if (eapol_test.server_cert_file) 1612 1.1.1.2 christos fclose(eapol_test.server_cert_file); 1613 1.1.1.2 christos 1614 1.1 christos printf("MPPE keys OK: %d mismatch: %d\n", 1615 1.1 christos eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch); 1616 1.1 christos if (eapol_test.num_mppe_mismatch) 1617 1.1 christos ret = -4; 1618 1.1 christos if (ret) 1619 1.1 christos printf("FAILURE\n"); 1620 1.1 christos else 1621 1.1 christos printf("SUCCESS\n"); 1622 1.1 christos 1623 1.1.1.8 christos crypto_unload(); 1624 1.1 christos os_program_deinit(); 1625 1.1 christos 1626 1.1 christos return ret; 1627 1.1 christos } 1628