diff options
Diffstat (limited to 'contrib/wpa_supplicant/preauth_test.c')
-rw-r--r-- | contrib/wpa_supplicant/preauth_test.c | 387 |
1 files changed, 180 insertions, 207 deletions
diff --git a/contrib/wpa_supplicant/preauth_test.c b/contrib/wpa_supplicant/preauth_test.c index 13741bb..d89058d 100644 --- a/contrib/wpa_supplicant/preauth_test.c +++ b/contrib/wpa_supplicant/preauth_test.c @@ -1,6 +1,15 @@ /* * WPA Supplicant - test code for pre-authentication - * Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi> + * Copyright (c) 2003-2006, Jouni Malinen <jkmaline@cc.hut.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. * * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c. * Not used in production version. @@ -27,181 +36,175 @@ #include "l2_packet.h" #include "ctrl_iface.h" #include "pcsc_funcs.h" +#include "preauth.h" extern int wpa_debug_level; extern int wpa_debug_show_keys; -void wpa_msg(struct wpa_supplicant *wpa_s, int level, char *fmt, ...) -{ - va_list ap; - char *buf; - const int buflen = 2048; - int len; - - buf = malloc(buflen); - if (buf == NULL) { - printf("Failed to allocate message buffer for:\n"); - va_start(ap, fmt); - vprintf(fmt, ap); - printf("\n"); - va_end(ap); - return; - } - va_start(ap, fmt); - len = vsnprintf(buf, buflen, fmt, ap); - va_end(ap); - wpa_printf(level, "%s", buf); - wpa_supplicant_ctrl_iface_send(wpa_s, level, buf, len); - free(buf); -} +struct wpa_driver_ops *wpa_supplicant_drivers[] = { }; -void wpa_supplicant_event(struct wpa_supplicant *wpa_s, wpa_event_type event, - union wpa_event_data *data) +struct preauth_test_data { + int auth_timed_out; +}; + + +static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec) { + wpa_supplicant_req_scan(wpa_s, sec, usec); } -int rsn_preauth_init(struct wpa_supplicant *wpa_s, u8 *dst) +static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code) { - return -1; + wpa_supplicant_disassociate(wpa_s, reason_code); } -void rsn_preauth_deinit(struct wpa_supplicant *wpa_s) +static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code) { + wpa_supplicant_deauthenticate(wpa_s, reason_code); } -int pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf, size_t len) +static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type, + const void *data, u16 data_len, + size_t *msg_len, void **data_pos) { - return 0; + struct ieee802_1x_hdr *hdr; + + *msg_len = sizeof(*hdr) + data_len; + hdr = malloc(*msg_len); + if (hdr == NULL) + return NULL; + + hdr->version = wpa_s->conf->eapol_version; + hdr->type = type; + hdr->length = htons(data_len); + + if (data) + memcpy(hdr + 1, data, data_len); + else + memset(hdr + 1, 0, data_len); + + if (data_pos) + *data_pos = hdr + 1; + + return (u8 *) hdr; } -int wpa_get_mib(struct wpa_supplicant *wpa_s, char *buf, size_t buflen) +static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type, + const void *data, u16 data_len, + size_t *msg_len, void **data_pos) { - return 0; + return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos); } -void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec) +static void _wpa_supplicant_set_state(void *ctx, wpa_states state) { + struct wpa_supplicant *wpa_s = ctx; + wpa_s->wpa_state = state; } -const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len) +static wpa_states _wpa_supplicant_get_state(void *ctx) { - return NULL; + struct wpa_supplicant *wpa_s = ctx; + return wpa_s->wpa_state; } -int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) +static int wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto, + const u8 *buf, size_t len) { + printf("%s - not implemented\n", __func__); return -1; } -static int eapol_test_eapol_send(void *ctx, int type, u8 *buf, size_t len) +static struct wpa_ssid * _wpa_supplicant_get_ssid(void *wpa_s) { - struct wpa_supplicant *wpa_s = ctx; - u8 *msg; - size_t msglen; - struct l2_ethhdr *ethhdr; - struct ieee802_1x_hdr *hdr; - int res; - - printf("WPA: wpa_eapol_send(type=%d len=%d)\n", type, len); + return wpa_supplicant_get_ssid(wpa_s); +} - if (wpa_s->l2_preauth == NULL) - return -1; - msglen = sizeof(*ethhdr) + sizeof(*hdr) + len; - msg = malloc(msglen); - if (msg == NULL) - return -1; +static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s) +{ + wpa_supplicant_cancel_auth_timeout(wpa_s); +} - ethhdr = (struct l2_ethhdr *) msg; - memcpy(ethhdr->h_dest, wpa_s->preauth_bssid, ETH_ALEN); - memcpy(ethhdr->h_source, wpa_s->own_addr, ETH_ALEN); - ethhdr->h_proto = htons(ETH_P_RSN_PREAUTH); - hdr = (struct ieee802_1x_hdr *) (ethhdr + 1); - hdr->version = wpa_s->conf->eapol_version; - hdr->type = type; - hdr->length = htons(len); +static int wpa_supplicant_get_beacon_ie(void *wpa_s) +{ + printf("%s - not implemented\n", __func__); + return -1; +} - memcpy((u8 *) (hdr + 1), buf, len); - wpa_hexdump(MSG_MSGDUMP, "TX EAPOL (preauth)", msg, msglen); - res = l2_packet_send(wpa_s->l2_preauth, msg, msglen); - free(msg); - return res; +void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) +{ + printf("%s - not implemented\n", __func__); } -static void eapol_test_eapol_done_cb(void *ctx) +static int wpa_supplicant_get_bssid(void *wpa_s, u8 *bssid) { - printf("WPA: EAPOL processing complete\n"); + printf("%s - not implemented\n", __func__); + return -1; } -static void eapol_sm_cb(struct eapol_sm *eapol, int success, void *ctx) +static int wpa_supplicant_set_key(void *wpa_s, wpa_alg alg, + const u8 *addr, int key_idx, int set_tx, + const u8 *seq, size_t seq_len, + const u8 *key, size_t key_len) { - printf("eapol_sm_cb: success=%d\n", success); - eloop_terminate(); + printf("%s - not implemented\n", __func__); + return -1; } -static int test_eapol(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) +static int wpa_supplicant_add_pmkid(void *wpa_s, + const u8 *bssid, const u8 *pmkid) { - struct eapol_config eapol_conf; - struct eapol_ctx *ctx; + printf("%s - not implemented\n", __func__); + return -1; +} - ctx = malloc(sizeof(*ctx)); - if (ctx == NULL) { - printf("Failed to allocate EAPOL context.\n"); - return -1; - } - memset(ctx, 0, sizeof(*ctx)); - ctx->ctx = wpa_s; - ctx->msg_ctx = wpa_s; - ctx->scard_ctx = wpa_s->scard; - ctx->cb = eapol_sm_cb; - ctx->cb_ctx = wpa_s; - ctx->preauth = 0; - ctx->eapol_done_cb = eapol_test_eapol_done_cb; - ctx->eapol_send = eapol_test_eapol_send; - - wpa_s->preauth_eapol = eapol_sm_init(ctx); - if (wpa_s->preauth_eapol == NULL) { - free(ctx); - printf("Failed to initialize EAPOL state machines.\n"); - return -1; - } - wpa_s->current_ssid = ssid; - memset(&eapol_conf, 0, sizeof(eapol_conf)); - eapol_conf.accept_802_1x_keys = 1; - eapol_conf.required_keys = 0; - eapol_conf.workaround = ssid->eap_workaround; - eapol_sm_notify_config(wpa_s->preauth_eapol, ssid, &eapol_conf); +static int wpa_supplicant_remove_pmkid(void *wpa_s, + const u8 *bssid, const u8 *pmkid) +{ + printf("%s - not implemented\n", __func__); + return -1; +} - eapol_sm_notify_portValid(wpa_s->preauth_eapol, FALSE); - /* 802.1X::portControl = Auto */ - eapol_sm_notify_portEnabled(wpa_s->preauth_eapol, TRUE); +static void wpa_supplicant_set_config_blob(void *ctx, + struct wpa_config_blob *blob) +{ + struct wpa_supplicant *wpa_s = ctx; + wpa_config_set_blob(wpa_s->conf, blob); +} - return 0; + +static const struct wpa_config_blob * +wpa_supplicant_get_config_blob(void *ctx, const char *name) +{ + struct wpa_supplicant *wpa_s = ctx; + return wpa_config_get_blob(wpa_s->conf, name); } static void test_eapol_clean(struct wpa_supplicant *wpa_s) { - l2_packet_deinit(wpa_s->l2_preauth); - eapol_sm_deinit(wpa_s->preauth_eapol); - wpa_s->preauth_eapol = NULL; + rsn_preauth_deinit(wpa_s->wpa); + pmksa_candidate_free(wpa_s->wpa); + pmksa_cache_free(wpa_s->wpa); + wpa_sm_deinit(wpa_s->wpa); scard_deinit(wpa_s->scard); wpa_supplicant_ctrl_iface_deinit(wpa_s); wpa_config_free(wpa_s->conf); @@ -210,117 +213,75 @@ static void test_eapol_clean(struct wpa_supplicant *wpa_s) static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx) { - struct wpa_supplicant *wpa_s = eloop_ctx; + struct preauth_test_data *p = eloop_ctx; printf("EAPOL test timed out\n"); - wpa_s->auth_timed_out = 1; + p->auth_timed_out = 1; eloop_terminate(); } -static void wpa_supplicant_imsi_identity(struct wpa_supplicant *wpa_s, - struct wpa_ssid *ssid) +static void eapol_test_poll(void *eloop_ctx, void *timeout_ctx) { - if (ssid->identity == NULL && wpa_s->imsi) { - ssid->identity = malloc(1 + wpa_s->imsi_len); - if (ssid->identity) { - ssid->identity[0] = '1'; - memcpy(ssid->identity + 1, wpa_s->imsi, - wpa_s->imsi_len); - ssid->identity_len = 1 + wpa_s->imsi_len; - wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from " - "IMSI", ssid->identity, - ssid->identity_len); - } + struct wpa_supplicant *wpa_s = eloop_ctx; + if (!rsn_preauth_in_progress(wpa_s->wpa)) + eloop_terminate(); + else { + eloop_register_timeout(0, 100000, eapol_test_poll, eloop_ctx, + timeout_ctx); } } -static void wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s, - struct wpa_ssid *ssid) -{ - char buf[100]; - size_t len; - - if (ssid->pcsc == NULL) - return; - if (wpa_s->scard != NULL) { - wpa_supplicant_imsi_identity(wpa_s, ssid); - return; - } - wpa_printf(MSG_DEBUG, "Selected network is configured to use SIM - " - "initialize PCSC"); - wpa_s->scard = scard_init(SCARD_TRY_BOTH, ssid->pin); - if (wpa_s->scard == NULL) { - wpa_printf(MSG_WARNING, "Failed to initialize SIM " - "(pcsc-lite)"); - /* TODO: what to do here? */ - return; - } - eapol_sm_register_scard_ctx(wpa_s->preauth_eapol, wpa_s->scard); - - len = sizeof(buf); - if (scard_get_imsi(wpa_s->scard, buf, &len)) { - wpa_printf(MSG_WARNING, "Failed to get IMSI from SIM"); - /* TODO: what to do here? */ - return; - } - - wpa_hexdump(MSG_DEBUG, "IMSI", (u8 *) buf, len); - free(wpa_s->imsi); - wpa_s->imsi = malloc(len); - if (wpa_s->imsi) { - memcpy(wpa_s->imsi, buf, len); - wpa_s->imsi_len = len; - wpa_supplicant_imsi_identity(wpa_s, ssid); - } -} +static struct wpa_driver_ops dummy_driver; -static void rsn_preauth_receive(void *ctx, unsigned char *src_addr, - unsigned char *buf, size_t len) +static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname) { - struct wpa_supplicant *wpa_s = ctx; + struct l2_packet_data *l2; + struct wpa_sm_ctx *ctx; - wpa_printf(MSG_DEBUG, "RX pre-auth from " MACSTR, MAC2STR(src_addr)); - wpa_hexdump(MSG_MSGDUMP, "RX pre-auth", buf, len); - - if (wpa_s->preauth_eapol == NULL || - memcmp(wpa_s->preauth_bssid, "\x00\x00\x00\x00\x00\x00", - ETH_ALEN) == 0 || - memcmp(wpa_s->preauth_bssid, src_addr, ETH_ALEN) != 0) { - wpa_printf(MSG_WARNING, "RSN pre-auth frame received from " - "unexpected source " MACSTR " - dropped", - MAC2STR(src_addr)); - return; - } + memset(&dummy_driver, 0, sizeof(dummy_driver)); + wpa_s->driver = &dummy_driver; - eapol_sm_rx_eapol(wpa_s->preauth_eapol, src_addr, buf, len); -} + ctx = malloc(sizeof(*ctx)); + assert(ctx != NULL); + memset(ctx, 0, sizeof(*ctx)); + ctx->ctx = wpa_s; + ctx->set_state = _wpa_supplicant_set_state; + ctx->get_state = _wpa_supplicant_get_state; + ctx->req_scan = _wpa_supplicant_req_scan; + ctx->deauthenticate = _wpa_supplicant_deauthenticate; + ctx->disassociate = _wpa_supplicant_disassociate; + ctx->set_key = wpa_supplicant_set_key; + ctx->scan = wpa_supplicant_scan; + ctx->get_ssid = _wpa_supplicant_get_ssid; + ctx->get_bssid = wpa_supplicant_get_bssid; + ctx->ether_send = wpa_ether_send; + ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie; + ctx->alloc_eapol = _wpa_alloc_eapol; + ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout; + ctx->add_pmkid = wpa_supplicant_add_pmkid; + ctx->remove_pmkid = wpa_supplicant_remove_pmkid; + ctx->set_config_blob = wpa_supplicant_set_config_blob; + ctx->get_config_blob = wpa_supplicant_get_config_blob; + + wpa_s->wpa = wpa_sm_init(ctx); + assert(wpa_s->wpa != NULL); + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, WPA_PROTO_RSN); -static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *target, - const char *ifname) -{ strncpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname)); + wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname); - if (hwaddr_aton(target, wpa_s->preauth_bssid)) { - printf("Failed to parse target address '%s'.\n", target); - exit(-1); - } - - wpa_s->l2_preauth = l2_packet_init(wpa_s->ifname, NULL, - ETH_P_RSN_PREAUTH, - rsn_preauth_receive, wpa_s); - if (wpa_s->l2_preauth == NULL) { - wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 packet " - "processing for pre-authentication"); - exit(-1); - } - - if (l2_packet_get_own_addr(wpa_s->l2_preauth, wpa_s->own_addr)) { + l2 = l2_packet_init(wpa_s->ifname, NULL, ETH_P_RSN_PREAUTH, NULL, + NULL, 0); + assert(l2 != NULL); + if (l2_packet_get_own_addr(l2, wpa_s->own_addr)) { wpa_printf(MSG_WARNING, "Failed to get own L2 address\n"); exit(-1); } + l2_packet_deinit(l2); + wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr); } @@ -337,16 +298,25 @@ int main(int argc, char *argv[]) { struct wpa_supplicant wpa_s; int ret = 1; + u8 bssid[ETH_ALEN]; + struct preauth_test_data preauth_test; + + memset(&preauth_test, 0, sizeof(preauth_test)); wpa_debug_level = 0; wpa_debug_show_keys = 1; if (argc != 4) { - printf("usage: eapol_test <conf> <target MAC address> " + printf("usage: preauth_test <conf> <target MAC address> " "<ifname>\n"); return -1; } + if (hwaddr_aton(argv[2], bssid)) { + printf("Failed to parse target address '%s'.\n", argv[2]); + return -1; + } + eloop_init(&wpa_s); memset(&wpa_s, 0, sizeof(wpa_s)); @@ -360,33 +330,36 @@ int main(int argc, char *argv[]) return -1; } - wpa_init_conf(&wpa_s, argv[2], argv[3]); + wpa_init_conf(&wpa_s, argv[3]); if (wpa_supplicant_ctrl_iface_init(&wpa_s)) { printf("Failed to initialize control interface '%s'.\n" - "You may have another eapol_test process already " + "You may have another preauth_test process already " "running or the file was\n" - "left by an unclean termination of eapol_test in " + "left by an unclean termination of preauth_test in " "which case you will need\n" "to manually remove this file before starting " - "eapol_test again.\n", + "preauth_test again.\n", wpa_s.conf->ctrl_interface); return -1; } - wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid); + if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) + return -1; - if (test_eapol(&wpa_s, wpa_s.conf->ssid)) + if (rsn_preauth_init(wpa_s.wpa, bssid, wpa_s.conf->ssid)) return -1; - eloop_register_timeout(30, 0, eapol_test_timeout, &wpa_s, NULL); + eloop_register_timeout(30, 0, eapol_test_timeout, &preauth_test, NULL); + eloop_register_timeout(0, 100000, eapol_test_poll, &wpa_s, NULL); eloop_register_signal(SIGINT, eapol_test_terminate, NULL); eloop_register_signal(SIGTERM, eapol_test_terminate, NULL); eloop_register_signal(SIGHUP, eapol_test_terminate, NULL); eloop_run(); - if (wpa_s.auth_timed_out) + if (preauth_test.auth_timed_out) ret = -2; - else - ret = 0; + else { + ret = pmksa_cache_get(wpa_s.wpa, bssid, NULL) ? 0 : -3; + } test_eapol_clean(&wpa_s); |