00001
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <stdint.h>
00027 #include <string.h>
00028 #include <sys/ioctl.h>
00029 #include <glib.h>
00030 #include <glib-object.h>
00031 #include <unistd.h>
00032 #include <sys/types.h>
00033 #include <sys/socket.h>
00034 #include <linux/types.h>
00035 #include <linux/netlink.h>
00036 #include <linux/rtnetlink.h>
00037 #include <linux/if_ether.h>
00038
00039 #define DBUS_API_SUBJECT_TO_CHANGE
00040 #include <dbus/dbus.h>
00041 #include <eap-dbus.h>
00042
00043 #include "wpa.h"
00044 #include "common.h"
00045 #include "dbus-handler.h"
00046 #include "log.h"
00047
00048
00049 static guint mic_failure_timer_id = 0;
00050
00051
00052 static guint mic_failure_running_timer_id = 0;
00053
00054
00055 static GSList *ap_black_list = NULL;
00056
00057
00058 static const guint8 WPA_CIPHER_SUITE_NONE[] = {0x00, 0x50, 0xf2, 0};
00059 static const guint8 WPA_CIPHER_SUITE_WEP40[] = {0x00, 0x50, 0xf2, 1};
00060 static const guint8 WPA_CIPHER_SUITE_TKIP[] = {0x00, 0x50, 0xf2, 2};
00061
00062 static const guint8 WPA_CIPHER_SUITE_CCMP[] = {0x00, 0x50, 0xf2, 4};
00063 static const guint8 WPA_CIPHER_SUITE_WEP104[] = {0x00, 0x50, 0xf2, 5};
00064
00065 static const guint8 RSN_CIPHER_SUITE_NONE[] = {0x00, 0x0f, 0xac, 0};
00066 static const guint8 RSN_CIPHER_SUITE_WEP40[] = {0x00, 0x0f, 0xac, 1};
00067 static const guint8 RSN_CIPHER_SUITE_TKIP[] = {0x00, 0x0f, 0xac, 2};
00068
00069 static const guint8 RSN_CIPHER_SUITE_CCMP[] = {0x00, 0x0f, 0xac, 4};
00070 static const guint8 RSN_CIPHER_SUITE_WEP104[] = {0x00, 0x0f, 0xac, 5};
00071
00072
00073 static const guint8 RSN_KEY_MGMT_802_1X[] = {0x00, 0x0f, 0xac, 1};
00074 static const guint8 RSN_KEY_MGMT_PSK[] = {0x00, 0x0f, 0xac, 2};
00075 static const guint8 WPA_KEY_MGMT_802_1X[] = {0x00, 0x50, 0xf2, 1};
00076 static const guint8 WPA_KEY_MGMT_PSK[] = {0x00, 0x50, 0xf2, 2};
00077
00078 static const guint8 WPA_OUI[] = { 0x00, 0x50, 0xf2 };
00079
00080 static guint parse_rsn_cipher_suite(guint8 *suite)
00081 {
00082 if (memcmp(suite, RSN_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN) == 0)
00083 return CIPHER_SUITE_TKIP;
00084 if (memcmp(suite, RSN_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN) == 0)
00085 return CIPHER_SUITE_CCMP;
00086 if (memcmp(suite, RSN_CIPHER_SUITE_NONE, CIPHER_SUITE_LEN) == 0)
00087 return CIPHER_SUITE_NONE;
00088 if (memcmp(suite, RSN_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN) == 0)
00089 return CIPHER_SUITE_WEP40;
00090 if (memcmp(suite, RSN_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN) == 0)
00091 return CIPHER_SUITE_WEP104;
00092 return 0;
00093 }
00094
00095 static guint parse_rsn_key_mgmt_suite(guint8 *suite)
00096 {
00097 if (memcmp(suite, RSN_KEY_MGMT_802_1X, CIPHER_SUITE_LEN) == 0)
00098 return WPA_802_1X;
00099 if (memcmp(suite, RSN_KEY_MGMT_PSK, CIPHER_SUITE_LEN) == 0)
00100 return WPA_PSK;
00101 return 0;
00102 }
00103
00104 static guint parse_wpa_cipher_suite(guint8* suite)
00105 {
00106 if (memcmp(suite, WPA_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN) == 0)
00107 return CIPHER_SUITE_TKIP;
00108 if (memcmp(suite, WPA_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN) == 0)
00109 return CIPHER_SUITE_CCMP;
00110 if (memcmp(suite, WPA_CIPHER_SUITE_NONE, CIPHER_SUITE_LEN) == 0)
00111 return CIPHER_SUITE_NONE;
00112 if (memcmp(suite, WPA_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN) == 0)
00113 return CIPHER_SUITE_WEP40;
00114 if (memcmp(suite, WPA_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN) == 0)
00115 return CIPHER_SUITE_WEP104;
00116 return 0;
00117 }
00118
00119 static guint parse_wpa_key_mgmt_suite(guint8 *suite)
00120 {
00121 if (memcmp(suite, WPA_KEY_MGMT_802_1X, CIPHER_SUITE_LEN) == 0)
00122 return WPA_802_1X;
00123 if (memcmp(suite, WPA_KEY_MGMT_PSK, CIPHER_SUITE_LEN) == 0)
00124 return WPA_PSK;
00125 return 0;
00126 }
00133 static int generate_wpa_ie(guint32 encryption,
00134 struct wlan_status_t *wlan_status)
00135 {
00136 guint8 *wpa_ie;
00137 struct wpa_ie_t *wpa_hdr;
00138 guint8* hdr_p;
00139
00140
00141 wpa_ie = g_malloc(sizeof(struct wpa_ie_t)+4+CIPHER_SUITE_LEN*3);
00142
00143 wpa_hdr = (struct wpa_ie_t*) wpa_ie;
00144 wpa_hdr->element_id = WPA_ELEMENT;
00145 memcpy(&wpa_hdr->oui, WPA_OUI, sizeof(WPA_OUI));
00146 wpa_hdr->oui_type = 1;
00147
00148 wpa_hdr->version = WPA_VERSION;
00149 hdr_p = (guint8*)(wpa_hdr + 1);
00150
00151
00152 switch (wlan_status->group_cipher) {
00153 case CIPHER_SUITE_TKIP:
00154 memcpy(hdr_p, WPA_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN);
00155 break;
00156 case CIPHER_SUITE_CCMP:
00157 memcpy(hdr_p, WPA_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN);
00158 break;
00159 case CIPHER_SUITE_WEP104:
00160 memcpy(hdr_p, WPA_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN);
00161 break;
00162 case CIPHER_SUITE_WEP40:
00163 memcpy(hdr_p, WPA_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN);
00164 break;
00165 default:
00166 DLOG_ERR("Unsupported group cipher suite");
00167 g_free(wpa_ie);
00168 return -1;
00169 }
00170
00171 hdr_p += CIPHER_SUITE_LEN;
00172
00173
00174 *hdr_p++ = 1;
00175 *hdr_p++ = 0;
00176
00177 switch (wlan_status->pairwise_cipher) {
00178 case CIPHER_SUITE_TKIP:
00179 memcpy(hdr_p, WPA_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN);
00180 break;
00181 case CIPHER_SUITE_CCMP:
00182 memcpy(hdr_p, WPA_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN);
00183 break;
00184 case CIPHER_SUITE_WEP104:
00185 memcpy(hdr_p, WPA_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN);
00186 break;
00187 case CIPHER_SUITE_WEP40:
00188 memcpy(hdr_p, WPA_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN);
00189 break;
00190 default:
00191 DLOG_ERR("Unsupported pairwise cipher suite: %08x",
00192 wlan_status->pairwise_cipher);
00193 g_free(wpa_ie);
00194 return -1;
00195 }
00196
00197 hdr_p += CIPHER_SUITE_LEN;
00198
00199
00200 *hdr_p++ = 1;
00201 *hdr_p++ = 0;
00202
00203 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WPA_PSK) {
00204 DLOG_DEBUG("WPA PSK selected");
00205 memcpy(hdr_p, WPA_KEY_MGMT_PSK, CIPHER_SUITE_LEN);
00206 } else if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) ==
00207 WLANCOND_WPA_EAP) {
00208 DLOG_DEBUG("WPA EAP selected");
00209 memcpy(hdr_p, WPA_KEY_MGMT_802_1X, CIPHER_SUITE_LEN);
00210 } else {
00211 DLOG_ERR("Unknown key management suite");
00212 g_free(wpa_ie);
00213 return 1;
00214 }
00215
00216 hdr_p += CIPHER_SUITE_LEN;
00217
00218
00219
00220 wpa_hdr->length = (hdr_p - wpa_ie) - 2;
00221
00222 #ifdef DEBUG_IE
00223 int i;
00224 printf("Own WPA IE:\n");
00225 for (i=0;i<wpa_hdr->length;i++) {
00226 printf("0x%02x ", wpa_ie[i]);
00227 }
00228 printf("\n");
00229 #endif
00230
00231 update_own_ie(wpa_ie, wpa_hdr->length + 2);
00232
00233 return 0;
00234 }
00241 static int generate_wpa2_ie(guint32 encryption,
00242 struct wlan_status_t *wlan_status)
00243 {
00244
00245 guint8 *wpa_ie;
00246 struct rsn_ie_t *wpa_hdr;
00247 guint8* hdr_p;
00248
00249
00250 wpa_ie = g_malloc(sizeof(struct rsn_ie_t)+8+CIPHER_SUITE_LEN*3+
00251 IW_PMKID_LEN);
00252
00253 wpa_hdr = (struct rsn_ie_t*) wpa_ie;
00254 wpa_hdr->element_id = RSN_ELEMENT;
00255
00256 wpa_hdr->version = RSN_VERSION;
00257 hdr_p = (guint8*)(wpa_hdr + 1);
00258
00259
00260 switch (wlan_status->group_cipher) {
00261 case CIPHER_SUITE_TKIP:
00262 memcpy(hdr_p, RSN_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN);
00263 break;
00264 case CIPHER_SUITE_CCMP:
00265 memcpy(hdr_p, RSN_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN);
00266 break;
00267 case CIPHER_SUITE_WEP104:
00268 memcpy(hdr_p, RSN_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN);
00269 break;
00270 case CIPHER_SUITE_WEP40:
00271 memcpy(hdr_p, RSN_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN);
00272 break;
00273 default:
00274 DLOG_ERR("Unsupported group cipher suite");
00275 g_free(wpa_ie);
00276 return -1;
00277 }
00278
00279 hdr_p += CIPHER_SUITE_LEN;
00280
00281
00282 *hdr_p++ = 1;
00283 *hdr_p++ = 0;
00284
00285 switch (wlan_status->pairwise_cipher) {
00286 case CIPHER_SUITE_TKIP:
00287 memcpy(hdr_p, RSN_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN);
00288 break;
00289 case CIPHER_SUITE_CCMP:
00290 memcpy(hdr_p, RSN_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN);
00291 break;
00292 case CIPHER_SUITE_WEP104:
00293 memcpy(hdr_p, RSN_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN);
00294 break;
00295 case CIPHER_SUITE_WEP40:
00296 memcpy(hdr_p, RSN_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN);
00297 break;
00298 default:
00299 DLOG_ERR("Unsupported pairwise cipher suite");
00300 g_free(wpa_ie);
00301 return -1;
00302 }
00303
00304 hdr_p += CIPHER_SUITE_LEN;
00305
00306
00307 *hdr_p++ = 1;
00308 *hdr_p++ = 0;
00309
00310 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WPA_PSK) {
00311 memcpy(hdr_p, RSN_KEY_MGMT_PSK, CIPHER_SUITE_LEN);
00312 } else if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) ==
00313 WLANCOND_WPA_EAP){
00314 memcpy(hdr_p, RSN_KEY_MGMT_802_1X, CIPHER_SUITE_LEN);
00315 } else {
00316 DLOG_ERR("Unknown key management suite");
00317 g_free(wpa_ie);
00318 return -1;
00319 }
00320
00321 hdr_p += CIPHER_SUITE_LEN;
00322
00323
00324 *hdr_p++ = 0;
00325 *hdr_p++ = 0;
00326
00327
00328 unsigned char *pmkid;
00329
00330 if (find_pmkid_from_pmk_cache(wlan_status->conn.bssid, &pmkid)) {
00331 DLOG_ERR("Error trying to retrieve the pmkid.");
00332 return ESUPPLICANT;
00333 }
00334
00335 if (pmkid != NULL) {
00336 *hdr_p++ = 1;
00337 *hdr_p++ = 0;
00338 memcpy(hdr_p, pmkid, IW_PMKID_LEN);
00339 hdr_p += IW_PMKID_LEN;
00340 }
00341
00342 wpa_hdr->length = (hdr_p - wpa_ie) - 2;
00343
00344 #ifdef DEBUG_IE
00345 int i;
00346 printf("Own WPA IE:\n");
00347 for (i=0;i<wpa_hdr->length;i++) {
00348 printf("0x%02x ", wpa_ie[i]);
00349 }
00350 printf("\n");
00351 #endif
00352
00353 update_own_ie(wpa_ie, wpa_hdr->length + 2);
00354
00355 return 0;
00356 }
00363 int set_wpa_ie(struct wlan_status_t *wlan_status)
00364 {
00365 struct iwreq req;
00366
00367 DLOG_DEBUG("Setting IE, len:%d", wlan_status->wpa_ie.ie_len);
00368
00369 init_iwreq(&req);
00370
00371 req.u.data.pointer = (caddr_t) wlan_status->wpa_ie.ie;
00372 req.u.data.length = wlan_status->wpa_ie.ie_len;
00373
00374 if (ioctl(socket_open(), SIOCSIWGENIE, &req) < 0) {
00375 DLOG_ERR("Set WPA IE failed\n");
00376 return -1;
00377 }
00378
00379 return 0;
00380 }
00381
00382 static guint32 pairwise_encryption_to_cipher(guint32 encryption,
00383 struct scan_results_t *scan_results)
00384 {
00385 if ((encryption & WLANCOND_ENCRYPT_ALG_MASK) == WLANCOND_WPA_TKIP)
00386 return IW_AUTH_CIPHER_TKIP;
00387 if ((encryption & WLANCOND_ENCRYPT_ALG_MASK) == WLANCOND_WPA_AES)
00388 return IW_AUTH_CIPHER_CCMP;
00389 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WPA_PSK ||
00390 (encryption & WLANCOND_ENCRYPT_METHOD_MASK)
00391 == WLANCOND_WPA_EAP) {
00392 if (scan_results->extra_cap_bits & WLANCOND_WEP40)
00393 return IW_AUTH_CIPHER_WEP40;
00394 else if (scan_results->extra_cap_bits & WLANCOND_WEP104)
00395 return IW_AUTH_CIPHER_WEP104;
00396 }
00397 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WEP)
00398 return IW_AUTH_CIPHER_WEP104;
00399 return IW_AUTH_CIPHER_NONE;
00400 }
00401
00402 static guint32 group_encryption_to_cipher(guint32 encryption,
00403 struct scan_results_t *scan_results)
00404 {
00405 if ((encryption & WLANCOND_ENCRYPT_GROUP_ALG_MASK) ==
00406 WLANCOND_WPA_TKIP_GROUP)
00407 return IW_AUTH_CIPHER_TKIP;
00408 if ((encryption & WLANCOND_ENCRYPT_GROUP_ALG_MASK) ==
00409 (guint32)WLANCOND_WPA_AES_GROUP)
00410 return IW_AUTH_CIPHER_CCMP;
00411 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WPA_PSK ||
00412 (encryption & WLANCOND_ENCRYPT_METHOD_MASK)
00413 == WLANCOND_WPA_EAP) {
00414 if (scan_results->extra_cap_bits & WLANCOND_WEP40_GROUP)
00415 return IW_AUTH_CIPHER_WEP40;
00416 else if (scan_results->extra_cap_bits & WLANCOND_WEP104_GROUP)
00417 return IW_AUTH_CIPHER_WEP104;
00418 }
00419 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WEP)
00420 return IW_AUTH_CIPHER_WEP104;
00421 return IW_AUTH_CIPHER_NONE;
00422 }
00429 static int set_encryption_method_helper(gint index, guint32 value)
00430 {
00431 struct iwreq req;
00432
00433 init_iwreq(&req);
00434
00435
00436
00437 req.u.param.flags = index & IW_AUTH_INDEX;
00438 req.u.param.value = value;
00439
00440 if (ioctl(socket_open(), SIOCSIWAUTH, &req) < 0) {
00441 DLOG_ERR("Could not set auth mode %d, %X", index, value);
00442 return -1;
00443 }
00444
00445 return 0;
00446 }
00452 int set_countermeasures(guint on_off)
00453 {
00454 return set_encryption_method_helper(IW_AUTH_TKIP_COUNTERMEASURES,
00455 on_off);
00456 }
00457
00465 gint set_encryption_method(guint32 encryption,
00466 struct wlan_status_t *wlan_status,
00467 struct scan_results_t *scan_results)
00468 {
00469 gint32 value = 0;
00470 guint32 key_mgmt = 0;
00471 gboolean wpa2 = FALSE;
00472 guint32 authentication = wlan_status->conn.authentication_type;
00473
00474 if (encryption & WLANCOND_ENCRYPT_WPA2_MASK)
00475 wpa2 = TRUE;
00476
00477 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WPA_PSK) {
00478 if (wpa2 == TRUE)
00479 value = IW_AUTH_WPA_VERSION_WPA2;
00480 else
00481 value = IW_AUTH_WPA_VERSION_WPA;
00482 key_mgmt = IW_AUTH_KEY_MGMT_PSK;
00483
00484 } else if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) ==
00485 WLANCOND_WPA_EAP) {
00486 if (wpa2 == TRUE)
00487 value = IW_AUTH_WPA_VERSION_WPA2;
00488 else
00489 value = IW_AUTH_WPA_VERSION_WPA;
00490 key_mgmt = IW_AUTH_KEY_MGMT_802_1X;
00491 } else {
00492 value = IW_AUTH_WPA_VERSION_DISABLED;
00493 }
00494
00495 if (key_mgmt != 0) {
00496 if (set_encryption_method_helper(IW_AUTH_WPA_ENABLED, 1) < 0)
00497 return -1;
00498
00499 set_encryption_method_helper(IW_AUTH_DROP_UNENCRYPTED,
00500 1);
00501
00502 set_encryption_method_helper(IW_AUTH_80211_AUTH_ALG,
00503 IW_AUTH_ALG_OPEN_SYSTEM);
00504
00505 }
00506
00507 if (set_encryption_method_helper(IW_AUTH_WPA_VERSION, value) < 0)
00508 return -1;
00509
00510 if (key_mgmt != 0) {
00511
00512 if (authentication != EAP_AUTH_TYPE_WFA_SC) {
00513 if (wpa2 == TRUE)
00514 value = generate_wpa2_ie(encryption,
00515 wlan_status);
00516 else
00517 value = generate_wpa_ie(encryption,
00518 wlan_status);
00519 }
00520 } else {
00521 if (set_encryption_method_helper(IW_AUTH_WPA_ENABLED, 0) < 0)
00522 return -1;
00523
00524
00525 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) != WLANCOND_WEP){
00526 set_encryption_method_helper(IW_AUTH_DROP_UNENCRYPTED,
00527 0);
00528 } else {
00529
00530 set_encryption_method_helper(IW_AUTH_80211_AUTH_ALG,
00531 IW_AUTH_ALG_OPEN_SYSTEM|IW_AUTH_ALG_SHARED_KEY);
00532 }
00533
00534 }
00535 if (value < 0)
00536 return value;
00537
00538
00539 if (set_wpa_ie(wlan_status) <0)
00540 return -1;
00541
00542 value = pairwise_encryption_to_cipher(encryption, scan_results);
00543
00544 if (set_encryption_method_helper(IW_AUTH_CIPHER_PAIRWISE, value) < 0)
00545 return -1;
00546
00547 value = group_encryption_to_cipher(encryption, scan_results);
00548
00549 if (set_encryption_method_helper(IW_AUTH_CIPHER_GROUP, value) < 0)
00550 return -1;
00551
00552 if (set_encryption_method_helper(IW_AUTH_KEY_MGMT, key_mgmt) < 0)
00553 return -1;
00554
00555 value = key_mgmt != 0 ||
00556 (encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WEP;
00557
00558 if (set_encryption_method_helper(IW_AUTH_PRIVACY_INVOKED, value) < 0) {
00559
00560 if (wlan_status->conn.mode != WLANCOND_ADHOC)
00561 return -1;
00562 }
00563
00564 if (key_mgmt != 0) {
00565 value = 0;
00566 } else {
00567 value = 1;
00568 }
00569
00570 if (set_encryption_method_helper(IW_AUTH_RX_UNENCRYPTED_EAPOL,
00571 value) < 0)
00572 return -1;
00573
00574 return 0;
00575 }
00576
00577 static gint compare_bssid(gconstpointer a, gconstpointer b)
00578 {
00579 return memcmp(a, b, ETH_ALEN);
00580 }
00581
00586 static void remove_ap_from_black_list(unsigned char* bssid)
00587 {
00588 GSList *list;
00589
00590 list = g_slist_find_custom(ap_black_list, bssid, &compare_bssid);
00591
00592 if (list != NULL) {
00593 unsigned char* bssid_entry = list->data;
00594 print_mac(WLANCOND_PRIO_MEDIUM,
00595 "Found black list entry to be removed:",
00596 bssid);
00597
00598
00599 ap_black_list = g_slist_remove(ap_black_list,
00600 bssid_entry);
00601 g_free(bssid_entry);
00602 }
00603 }
00604
00610 static gboolean mic_failure_timer_cb(void* data)
00611 {
00612
00613
00614
00615 mic_failure_timer_id = 0;
00616
00617 print_mac(WLANCOND_PRIO_MEDIUM,
00618 "No MIC failures within the last 60 seconds for:",
00619 data);
00620
00621 remove_ap_from_black_list(data);
00622
00623 return FALSE;
00624 }
00625
00631 gboolean is_ap_in_black_list(unsigned char* bssid)
00632 {
00633 GSList *list;
00634
00635 list = g_slist_find_custom(ap_black_list, bssid, &compare_bssid);
00636
00637 if (list != NULL) {
00638 print_mac(WLANCOND_PRIO_HIGH,
00639 "Found AP from black list:", bssid);
00640 return TRUE;
00641 }
00642 return FALSE;
00643 }
00644
00650 static gboolean mic_failure_running_cb(void* data)
00651 {
00652 mic_failure_running_timer_id = 0;
00653
00654 print_mac(WLANCOND_PRIO_HIGH, "MIC failures off for:", data);
00655
00656 remove_ap_from_black_list(data);
00657
00658 return FALSE;
00659 }
00660
00661 static void add_ap_to_black_list(unsigned char* bssid)
00662 {
00663 ap_black_list = g_slist_prepend(ap_black_list,
00664 g_memdup(bssid, ETH_ALEN));
00665 }
00666
00667 static void mic_destroy_cb(gpointer data)
00668 {
00669
00670 g_free(data);
00671 }
00672
00678 int handle_mic_failure(gboolean key_type, unsigned char* bssid)
00679 {
00680
00681 if (mic_failure_timer_id != 0) {
00682
00683 g_source_remove(mic_failure_timer_id);
00684 mic_failure_timer_id = 0;
00685
00686
00687 wpa_mic_failure_event(key_type, TRUE);
00688
00689 print_mac(WLANCOND_PRIO_HIGH,
00690 "Second MIC failure, disconnecting AP:", bssid);
00691
00692 sleep(1);
00693
00694 mlme_command(bssid, IW_MLME_DEAUTH,
00695 WLANCOND_REASON_MIC_FAILURE);
00696
00697 set_wlan_state(WLAN_NOT_INITIALIZED,
00698 DISCONNECTED_SIGNAL,
00699 FORCE_NO);
00700
00701
00702 mic_failure_running_timer_id = g_timeout_add_seconds_full(
00703 G_PRIORITY_DEFAULT,
00704 MIC_FAILURE_TIMEOUT,
00705 mic_failure_running_cb,
00706 g_memdup(bssid, ETH_ALEN),
00707 mic_destroy_cb);
00708
00709 add_ap_to_black_list(bssid);
00710
00711 return 0;
00712 }
00713
00714 wpa_mic_failure_event(key_type, FALSE);
00715
00716 mic_failure_timer_id = g_timeout_add_seconds_full(
00717 G_PRIORITY_DEFAULT,
00718 MIC_FAILURE_TIMEOUT,
00719 mic_failure_timer_cb,
00720 g_memdup(bssid, ETH_ALEN),
00721 mic_destroy_cb);
00722
00723 return 0;
00724 }
00725
00733 int parse_rsn_ie(unsigned char* wpa_ie, unsigned int wpa_ie_len,
00734 struct ap_info_t* ap_info)
00735 {
00736 struct rsn_ie_t *wpa_hdr;
00737 guint8 *hdr_p;
00738 guint ind;
00739 guint i;
00740 guint cipher_count = 0;
00741
00742
00743
00744
00745
00746
00747 wpa_hdr = (struct rsn_ie_t*) wpa_ie;
00748
00749 if (wpa_ie_len < sizeof(struct rsn_ie_t)) {
00750 DLOG_ERR("WPA IE too short");
00751 return -1;
00752 }
00753
00754 if (wpa_hdr->element_id != RSN_ELEMENT) {
00755 DLOG_ERR("Unknown WPA IE received");
00756 return -1;
00757 }
00758
00759 ind = wpa_ie_len - sizeof(*wpa_hdr);
00760 hdr_p = (guint8*)(wpa_hdr + 1);
00761
00762 if (ind >= CIPHER_SUITE_LEN) {
00763 ap_info->group_cipher = parse_rsn_cipher_suite(hdr_p);
00764 hdr_p += CIPHER_SUITE_LEN;
00765 ind -= CIPHER_SUITE_LEN;
00766 } else {
00767 DLOG_ERR("Strange length in WPA IE");
00768 return -1;
00769 }
00770
00771 if (ind >= 2) {
00772 ap_info->pairwise_cipher = 0;
00773 cipher_count = *(guint16*)hdr_p;
00774
00775 ind -= 2;
00776
00777 if (cipher_count == 0) {
00778 DLOG_ERR("No pairwise ciphers");
00779
00780 return 0;
00781 }
00782
00783 if (ind < cipher_count * CIPHER_SUITE_LEN) {
00784 DLOG_ERR("Invalid pairwise cipher length");
00785 return -1;
00786 }
00787
00788 hdr_p += 2;
00789
00790 for (i = 0; i < cipher_count; i++) {
00791 ap_info->pairwise_cipher |= parse_rsn_cipher_suite(hdr_p);
00792 ind -= CIPHER_SUITE_LEN;
00793 hdr_p += CIPHER_SUITE_LEN;
00794 }
00795 } else if (ind == 1) {
00796 DLOG_ERR("Remaining data too short");
00797 return -1;
00798 }
00799
00800 if (ind >= 2) {
00801 ap_info->key_mgmt = 0;
00802 cipher_count = *(guint16*)hdr_p;
00803 hdr_p += 2;
00804 ind -= 2;
00805
00806 if (cipher_count == 0 || ind < cipher_count *
00807 CIPHER_SUITE_LEN) {
00808 DLOG_ERR("Invalid key mgmt cipher count or length");
00809 return -1;
00810 }
00811
00812 for (i = 0; i < cipher_count; i++) {
00813 ap_info->key_mgmt |= parse_rsn_key_mgmt_suite(hdr_p);
00814 ind -= CIPHER_SUITE_LEN;
00815 hdr_p += CIPHER_SUITE_LEN;
00816 }
00817 } else if (ind == 1) {
00818 DLOG_ERR("Remaining data too short");
00819 return -1;
00820 }
00821
00822 if (ind >= 2) {
00823
00824 hdr_p += 2;
00825 ind -= 2;
00826 }
00827
00828 if (ind > 0) {
00829 DLOG_DEBUG("IE includes PMKID data");
00830 }
00831 return 0;
00832 }
00833
00834
00842 int parse_wpa_ie(unsigned char* wpa_ie, unsigned int wpa_ie_len,
00843 struct ap_info_t* ap_info)
00844 {
00845 struct wpa_ie_t *wpa_hdr;
00846 guint8 *hdr_p;
00847 guint ind, i;
00848 guint cipher_count = 0;
00849 const guint8 WPA1_OUI[] = { 0x00, 0x50, 0xf2, 1 };
00850
00851
00852
00853
00854
00855
00856 wpa_hdr = (struct wpa_ie_t*) wpa_ie;
00857
00858 if (wpa_ie_len < sizeof(struct wpa_ie_t)) {
00859 DLOG_ERR("WPA IE too short");
00860 return -1;
00861 }
00862
00863 if (wpa_hdr->element_id != WPA_ELEMENT) {
00864 DLOG_ERR("Unknown WPA IE received");
00865 return -1;
00866 }
00867
00868 if (memcmp(&wpa_hdr->oui, WPA1_OUI, CIPHER_SUITE_LEN) != 0) {
00869 DLOG_ERR("Invalid WPA header");
00870 return -1;
00871 }
00872
00873 ind = wpa_ie_len - sizeof(*wpa_hdr);
00874 hdr_p = (guint8*)(wpa_hdr + 1);
00875
00876 if (ind >= CIPHER_SUITE_LEN) {
00877 ap_info->group_cipher = parse_wpa_cipher_suite(hdr_p);
00878 ind -= CIPHER_SUITE_LEN;
00879 hdr_p += CIPHER_SUITE_LEN;
00880 } else {
00881 DLOG_ERR("Strange length in WPA IE");
00882 return -1;
00883 }
00884
00885 if (ind >= 2) {
00886 ap_info->pairwise_cipher = 0;
00887 cipher_count = *(guint16*)hdr_p;
00888 ind -= 2;
00889
00890 if (cipher_count == 0) {
00891 DLOG_ERR("No pairwise ciphers");
00892
00893 return 0;
00894 }
00895
00896 if (ind < cipher_count * CIPHER_SUITE_LEN) {
00897 DLOG_ERR("Invalid pairwise cipher length");
00898 return -1;
00899 }
00900
00901 hdr_p += 2;
00902
00903 for (i = 0; i < cipher_count; i++) {
00904 ap_info->pairwise_cipher |=
00905 parse_wpa_cipher_suite(hdr_p);
00906 ind -= CIPHER_SUITE_LEN;
00907 hdr_p += CIPHER_SUITE_LEN;
00908 }
00909 } else if (ind == 1) {
00910 DLOG_ERR("Remaining data too short");
00911 return -1;
00912 }
00913
00914 if (ind >= 2) {
00915 ap_info->key_mgmt = 0;
00916 cipher_count = *(guint16*)hdr_p;
00917 hdr_p += 2;
00918 ind -= 2;
00919
00920 if (cipher_count == 0 || ind < cipher_count *
00921 CIPHER_SUITE_LEN) {
00922 DLOG_ERR("Invalid key mgmt cipher count (%d) or length",
00923 cipher_count);
00924 return -1;
00925 }
00926
00927 for (i = 0; i < cipher_count; i++) {
00928 ap_info->key_mgmt |= parse_wpa_key_mgmt_suite(hdr_p);
00929 ind -= CIPHER_SUITE_LEN;
00930 hdr_p += CIPHER_SUITE_LEN;
00931 }
00932 } else if (ind == 1) {
00933 DLOG_ERR("Remaining data too short");
00934 return -1;
00935 }
00936
00937 if (ind >= 2) {
00938
00939 hdr_p += 2;
00940 ind -= 2;
00941 }
00942
00943 if (ind > 0) {
00944 DLOG_ERR("IE too long?");
00945 return -1;
00946 }
00947 return 0;
00948 }