$search
00001 /* 00002 * WPA Supplicant - test code for pre-authentication 00003 * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 * 00014 * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c. 00015 * Not used in production version. 00016 */ 00017 00018 #include "includes.h" 00019 #include <assert.h> 00020 00021 #include "common.h" 00022 #include "config.h" 00023 #include "eapol_supp/eapol_supp_sm.h" 00024 #include "eloop.h" 00025 #include "rsn_supp/wpa.h" 00026 #include "eap_peer/eap.h" 00027 #include "wpa_supplicant_i.h" 00028 #include "l2_packet/l2_packet.h" 00029 #include "ctrl_iface.h" 00030 #include "pcsc_funcs.h" 00031 #include "rsn_supp/preauth.h" 00032 #include "rsn_supp/pmksa_cache.h" 00033 #include "drivers/driver.h" 00034 00035 00036 extern int wpa_debug_level; 00037 extern int wpa_debug_show_keys; 00038 00039 struct wpa_driver_ops *wpa_drivers[] = { NULL }; 00040 00041 00042 struct preauth_test_data { 00043 int auth_timed_out; 00044 }; 00045 00046 00047 static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code) 00048 { 00049 wpa_supplicant_disassociate(wpa_s, reason_code); 00050 } 00051 00052 00053 static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code) 00054 { 00055 wpa_supplicant_deauthenticate(wpa_s, reason_code); 00056 } 00057 00058 00059 static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type, 00060 const void *data, u16 data_len, 00061 size_t *msg_len, void **data_pos) 00062 { 00063 struct ieee802_1x_hdr *hdr; 00064 00065 *msg_len = sizeof(*hdr) + data_len; 00066 hdr = os_malloc(*msg_len); 00067 if (hdr == NULL) 00068 return NULL; 00069 00070 hdr->version = wpa_s->conf->eapol_version; 00071 hdr->type = type; 00072 hdr->length = htons(data_len); 00073 00074 if (data) 00075 os_memcpy(hdr + 1, data, data_len); 00076 else 00077 os_memset(hdr + 1, 0, data_len); 00078 00079 if (data_pos) 00080 *data_pos = hdr + 1; 00081 00082 return (u8 *) hdr; 00083 } 00084 00085 00086 static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type, 00087 const void *data, u16 data_len, 00088 size_t *msg_len, void **data_pos) 00089 { 00090 return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos); 00091 } 00092 00093 00094 static void _wpa_supplicant_set_state(void *ctx, enum wpa_states state) 00095 { 00096 struct wpa_supplicant *wpa_s = ctx; 00097 wpa_s->wpa_state = state; 00098 } 00099 00100 00101 static enum wpa_states _wpa_supplicant_get_state(void *ctx) 00102 { 00103 struct wpa_supplicant *wpa_s = ctx; 00104 return wpa_s->wpa_state; 00105 } 00106 00107 00108 static int wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto, 00109 const u8 *buf, size_t len) 00110 { 00111 printf("%s - not implemented\n", __func__); 00112 return -1; 00113 } 00114 00115 00116 static void * wpa_supplicant_get_network_ctx(void *wpa_s) 00117 { 00118 return wpa_supplicant_get_ssid(wpa_s); 00119 } 00120 00121 00122 static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s) 00123 { 00124 wpa_supplicant_cancel_auth_timeout(wpa_s); 00125 } 00126 00127 00128 static int wpa_supplicant_get_beacon_ie(void *wpa_s) 00129 { 00130 printf("%s - not implemented\n", __func__); 00131 return -1; 00132 } 00133 00134 00135 static int wpa_supplicant_get_bssid(void *wpa_s, u8 *bssid) 00136 { 00137 printf("%s - not implemented\n", __func__); 00138 return -1; 00139 } 00140 00141 00142 static int wpa_supplicant_set_key(void *wpa_s, enum wpa_alg alg, 00143 const u8 *addr, int key_idx, int set_tx, 00144 const u8 *seq, size_t seq_len, 00145 const u8 *key, size_t key_len) 00146 { 00147 printf("%s - not implemented\n", __func__); 00148 return -1; 00149 } 00150 00151 00152 static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr, 00153 int protection_type, 00154 int key_type) 00155 { 00156 printf("%s - not implemented\n", __func__); 00157 return -1; 00158 } 00159 00160 00161 static int wpa_supplicant_add_pmkid(void *wpa_s, 00162 const u8 *bssid, const u8 *pmkid) 00163 { 00164 printf("%s - not implemented\n", __func__); 00165 return -1; 00166 } 00167 00168 00169 static int wpa_supplicant_remove_pmkid(void *wpa_s, 00170 const u8 *bssid, const u8 *pmkid) 00171 { 00172 printf("%s - not implemented\n", __func__); 00173 return -1; 00174 } 00175 00176 00177 static void wpa_supplicant_set_config_blob(void *ctx, 00178 struct wpa_config_blob *blob) 00179 { 00180 struct wpa_supplicant *wpa_s = ctx; 00181 wpa_config_set_blob(wpa_s->conf, blob); 00182 } 00183 00184 00185 static const struct wpa_config_blob * 00186 wpa_supplicant_get_config_blob(void *ctx, const char *name) 00187 { 00188 struct wpa_supplicant *wpa_s = ctx; 00189 return wpa_config_get_blob(wpa_s->conf, name); 00190 } 00191 00192 00193 static void test_eapol_clean(struct wpa_supplicant *wpa_s) 00194 { 00195 rsn_preauth_deinit(wpa_s->wpa); 00196 pmksa_candidate_free(wpa_s->wpa); 00197 wpa_sm_deinit(wpa_s->wpa); 00198 scard_deinit(wpa_s->scard); 00199 if (wpa_s->ctrl_iface) { 00200 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); 00201 wpa_s->ctrl_iface = NULL; 00202 } 00203 wpa_config_free(wpa_s->conf); 00204 } 00205 00206 00207 static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx) 00208 { 00209 struct preauth_test_data *p = eloop_ctx; 00210 printf("EAPOL test timed out\n"); 00211 p->auth_timed_out = 1; 00212 eloop_terminate(); 00213 } 00214 00215 00216 static void eapol_test_poll(void *eloop_ctx, void *timeout_ctx) 00217 { 00218 struct wpa_supplicant *wpa_s = eloop_ctx; 00219 if (!rsn_preauth_in_progress(wpa_s->wpa)) 00220 eloop_terminate(); 00221 else { 00222 eloop_register_timeout(0, 100000, eapol_test_poll, eloop_ctx, 00223 timeout_ctx); 00224 } 00225 } 00226 00227 00228 static struct wpa_driver_ops dummy_driver; 00229 00230 00231 static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname) 00232 { 00233 struct l2_packet_data *l2; 00234 struct wpa_sm_ctx *ctx; 00235 00236 os_memset(&dummy_driver, 0, sizeof(dummy_driver)); 00237 wpa_s->driver = &dummy_driver; 00238 00239 ctx = os_zalloc(sizeof(*ctx)); 00240 assert(ctx != NULL); 00241 00242 ctx->ctx = wpa_s; 00243 ctx->msg_ctx = wpa_s; 00244 ctx->set_state = _wpa_supplicant_set_state; 00245 ctx->get_state = _wpa_supplicant_get_state; 00246 ctx->deauthenticate = _wpa_supplicant_deauthenticate; 00247 ctx->disassociate = _wpa_supplicant_disassociate; 00248 ctx->set_key = wpa_supplicant_set_key; 00249 ctx->get_network_ctx = wpa_supplicant_get_network_ctx; 00250 ctx->get_bssid = wpa_supplicant_get_bssid; 00251 ctx->ether_send = wpa_ether_send; 00252 ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie; 00253 ctx->alloc_eapol = _wpa_alloc_eapol; 00254 ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout; 00255 ctx->add_pmkid = wpa_supplicant_add_pmkid; 00256 ctx->remove_pmkid = wpa_supplicant_remove_pmkid; 00257 ctx->set_config_blob = wpa_supplicant_set_config_blob; 00258 ctx->get_config_blob = wpa_supplicant_get_config_blob; 00259 ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection; 00260 00261 wpa_s->wpa = wpa_sm_init(ctx); 00262 assert(wpa_s->wpa != NULL); 00263 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, WPA_PROTO_RSN); 00264 00265 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname)); 00266 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname, NULL); 00267 00268 l2 = l2_packet_init(wpa_s->ifname, NULL, ETH_P_RSN_PREAUTH, NULL, 00269 NULL, 0); 00270 assert(l2 != NULL); 00271 if (l2_packet_get_own_addr(l2, wpa_s->own_addr)) { 00272 wpa_printf(MSG_WARNING, "Failed to get own L2 address\n"); 00273 exit(-1); 00274 } 00275 l2_packet_deinit(l2); 00276 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr); 00277 } 00278 00279 00280 static void eapol_test_terminate(int sig, void *signal_ctx) 00281 { 00282 struct wpa_supplicant *wpa_s = signal_ctx; 00283 wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); 00284 eloop_terminate(); 00285 } 00286 00287 00288 int main(int argc, char *argv[]) 00289 { 00290 struct wpa_supplicant wpa_s; 00291 int ret = 1; 00292 u8 bssid[ETH_ALEN]; 00293 struct preauth_test_data preauth_test; 00294 00295 if (os_program_init()) 00296 return -1; 00297 00298 os_memset(&preauth_test, 0, sizeof(preauth_test)); 00299 00300 wpa_debug_level = 0; 00301 wpa_debug_show_keys = 1; 00302 00303 if (argc != 4) { 00304 printf("usage: preauth_test <conf> <target MAC address> " 00305 "<ifname>\n"); 00306 return -1; 00307 } 00308 00309 if (hwaddr_aton(argv[2], bssid)) { 00310 printf("Failed to parse target address '%s'.\n", argv[2]); 00311 return -1; 00312 } 00313 00314 if (eap_register_methods()) { 00315 wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 00316 return -1; 00317 } 00318 00319 if (eloop_init()) { 00320 wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 00321 return -1; 00322 } 00323 00324 os_memset(&wpa_s, 0, sizeof(wpa_s)); 00325 wpa_s.conf = wpa_config_read(argv[1]); 00326 if (wpa_s.conf == NULL) { 00327 printf("Failed to parse configuration file '%s'.\n", argv[1]); 00328 return -1; 00329 } 00330 if (wpa_s.conf->ssid == NULL) { 00331 printf("No networks defined.\n"); 00332 return -1; 00333 } 00334 00335 wpa_init_conf(&wpa_s, argv[3]); 00336 wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s); 00337 if (wpa_s.ctrl_iface == NULL) { 00338 printf("Failed to initialize control interface '%s'.\n" 00339 "You may have another preauth_test process already " 00340 "running or the file was\n" 00341 "left by an unclean termination of preauth_test in " 00342 "which case you will need\n" 00343 "to manually remove this file before starting " 00344 "preauth_test again.\n", 00345 wpa_s.conf->ctrl_interface); 00346 return -1; 00347 } 00348 if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) 00349 return -1; 00350 00351 if (rsn_preauth_init(wpa_s.wpa, bssid, &wpa_s.conf->ssid->eap)) 00352 return -1; 00353 00354 eloop_register_timeout(30, 0, eapol_test_timeout, &preauth_test, NULL); 00355 eloop_register_timeout(0, 100000, eapol_test_poll, &wpa_s, NULL); 00356 eloop_register_signal_terminate(eapol_test_terminate, &wpa_s); 00357 eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s); 00358 eloop_run(); 00359 00360 if (preauth_test.auth_timed_out) 00361 ret = -2; 00362 else { 00363 ret = pmksa_cache_set_current(wpa_s.wpa, NULL, bssid, NULL, 0) 00364 ? 0 : -3; 00365 } 00366 00367 test_eapol_clean(&wpa_s); 00368 00369 eap_peer_unregister_methods(); 00370 00371 eloop_destroy(); 00372 00373 os_program_deinit(); 00374 00375 return ret; 00376 }