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 #define WLANCOND_AUTH_WPA_VERSION_DISABLED 0x00000001
00049 #define WLANCOND_AUTH_WPA_VERSION_WPA 0x00000002
00050 #define WLANCOND_AUTH_WPA_VERSION_WPA2 0x00000004
00051 #define WLANCOND_AUTH_KEY_MGMT_802_1X 1
00052 #define WLANCOND_AUTH_KEY_MGMT_PSK 2
00053
00054
00055 static guint mic_failure_timer_id = 0;
00056
00057
00058 static guint mic_failure_running_timer_id = 0;
00059
00060
00061 static GSList *ap_black_list = NULL;
00062
00063
00064 static const guint8 WPA_CIPHER_SUITE_NONE[] = {0x00, 0x50, 0xf2, 0};
00065 static const guint8 WPA_CIPHER_SUITE_WEP40[] = {0x00, 0x50, 0xf2, 1};
00066 static const guint8 WPA_CIPHER_SUITE_TKIP[] = {0x00, 0x50, 0xf2, 2};
00067
00068 static const guint8 WPA_CIPHER_SUITE_CCMP[] = {0x00, 0x50, 0xf2, 4};
00069 static const guint8 WPA_CIPHER_SUITE_WEP104[] = {0x00, 0x50, 0xf2, 5};
00070
00071 static const guint8 RSN_CIPHER_SUITE_NONE[] = {0x00, 0x0f, 0xac, 0};
00072 static const guint8 RSN_CIPHER_SUITE_WEP40[] = {0x00, 0x0f, 0xac, 1};
00073 static const guint8 RSN_CIPHER_SUITE_TKIP[] = {0x00, 0x0f, 0xac, 2};
00074
00075 static const guint8 RSN_CIPHER_SUITE_CCMP[] = {0x00, 0x0f, 0xac, 4};
00076 static const guint8 RSN_CIPHER_SUITE_WEP104[] = {0x00, 0x0f, 0xac, 5};
00077
00078
00079 static const guint8 RSN_KEY_MGMT_802_1X[] = {0x00, 0x0f, 0xac, 1};
00080 static const guint8 RSN_KEY_MGMT_PSK[] = {0x00, 0x0f, 0xac, 2};
00081 static const guint8 WPA_KEY_MGMT_802_1X[] = {0x00, 0x50, 0xf2, 1};
00082 static const guint8 WPA_KEY_MGMT_PSK[] = {0x00, 0x50, 0xf2, 2};
00083
00084 static const guint8 WPA_OUI[] = { 0x00, 0x50, 0xf2 };
00085
00086 static guint parse_rsn_cipher_suite(guint8 *suite)
00087 {
00088 if (memcmp(suite, RSN_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN) == 0)
00089 return CIPHER_SUITE_TKIP;
00090 if (memcmp(suite, RSN_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN) == 0)
00091 return CIPHER_SUITE_CCMP;
00092 if (memcmp(suite, RSN_CIPHER_SUITE_NONE, CIPHER_SUITE_LEN) == 0)
00093 return CIPHER_SUITE_NONE;
00094 if (memcmp(suite, RSN_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN) == 0)
00095 return CIPHER_SUITE_WEP40;
00096 if (memcmp(suite, RSN_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN) == 0)
00097 return CIPHER_SUITE_WEP104;
00098 return 0;
00099 }
00100
00101 static guint parse_rsn_key_mgmt_suite(guint8 *suite)
00102 {
00103 if (memcmp(suite, RSN_KEY_MGMT_802_1X, CIPHER_SUITE_LEN) == 0)
00104 return WLANCOND_WPA_EAP;
00105 if (memcmp(suite, RSN_KEY_MGMT_PSK, CIPHER_SUITE_LEN) == 0)
00106 return WLANCOND_WPA_PSK;
00107 return 0;
00108 }
00109
00110 static guint parse_wpa_cipher_suite(guint8* suite)
00111 {
00112 if (memcmp(suite, WPA_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN) == 0)
00113 return CIPHER_SUITE_TKIP;
00114 if (memcmp(suite, WPA_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN) == 0)
00115 return CIPHER_SUITE_CCMP;
00116 if (memcmp(suite, WPA_CIPHER_SUITE_NONE, CIPHER_SUITE_LEN) == 0)
00117 return CIPHER_SUITE_NONE;
00118 if (memcmp(suite, WPA_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN) == 0)
00119 return CIPHER_SUITE_WEP40;
00120 if (memcmp(suite, WPA_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN) == 0)
00121 return CIPHER_SUITE_WEP104;
00122 return 0;
00123 }
00124
00125 static guint parse_wpa_key_mgmt_suite(guint8 *suite)
00126 {
00127 if (memcmp(suite, WPA_KEY_MGMT_802_1X, CIPHER_SUITE_LEN) == 0)
00128 return WLANCOND_WPA_EAP;
00129 if (memcmp(suite, WPA_KEY_MGMT_PSK, CIPHER_SUITE_LEN) == 0)
00130 return WLANCOND_WPA_PSK;
00131 return 0;
00132 }
00139 static int generate_wpa_ie(guint32 encryption,
00140 struct wlan_status_t *wlan_status)
00141 {
00142 guint8 *wpa_ie;
00143 struct wpa_ie_t *wpa_hdr;
00144 guint8* hdr_p;
00145
00146
00147 wpa_ie = g_malloc(sizeof(struct wpa_ie_t)+4+CIPHER_SUITE_LEN*3);
00148
00149 wpa_hdr = (struct wpa_ie_t*) wpa_ie;
00150 wpa_hdr->element_id = WPA_ELEMENT;
00151 memcpy(&wpa_hdr->oui, WPA_OUI, sizeof(WPA_OUI));
00152 wpa_hdr->oui_type = 1;
00153
00154 wpa_hdr->version = WPA_VERSION;
00155 hdr_p = (guint8*)(wpa_hdr + 1);
00156
00157
00158 switch (wlan_status->group_cipher) {
00159 case CIPHER_SUITE_TKIP:
00160 memcpy(hdr_p, WPA_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN);
00161 break;
00162 case CIPHER_SUITE_CCMP:
00163 memcpy(hdr_p, WPA_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN);
00164 break;
00165 case CIPHER_SUITE_WEP104:
00166 memcpy(hdr_p, WPA_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN);
00167 break;
00168 case CIPHER_SUITE_WEP40:
00169 memcpy(hdr_p, WPA_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN);
00170 break;
00171 default:
00172 DLOG_ERR("Unsupported group cipher suite");
00173 g_free(wpa_ie);
00174 return -1;
00175 }
00176
00177 hdr_p += CIPHER_SUITE_LEN;
00178
00179
00180 *hdr_p++ = 1;
00181 *hdr_p++ = 0;
00182
00183 switch (wlan_status->pairwise_cipher) {
00184 case CIPHER_SUITE_TKIP:
00185 memcpy(hdr_p, WPA_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN);
00186 break;
00187 case CIPHER_SUITE_CCMP:
00188 memcpy(hdr_p, WPA_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN);
00189 break;
00190 case CIPHER_SUITE_WEP104:
00191 memcpy(hdr_p, WPA_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN);
00192 break;
00193 case CIPHER_SUITE_WEP40:
00194 memcpy(hdr_p, WPA_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN);
00195 break;
00196 default:
00197 DLOG_ERR("Unsupported pairwise cipher suite");
00198 g_free(wpa_ie);
00199 return -1;
00200 }
00201
00202 hdr_p += CIPHER_SUITE_LEN;
00203
00204
00205 *hdr_p++ = 1;
00206 *hdr_p++ = 0;
00207
00208 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WPA_PSK) {
00209 DLOG_DEBUG("WPA PSK selected");
00210 memcpy(hdr_p, WPA_KEY_MGMT_PSK, CIPHER_SUITE_LEN);
00211 } else if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) ==
00212 WLANCOND_WPA_EAP) {
00213 DLOG_DEBUG("WPA EAP selected");
00214 memcpy(hdr_p, WPA_KEY_MGMT_802_1X, CIPHER_SUITE_LEN);
00215 } else {
00216 DLOG_ERR("Unknown key management suite");
00217 g_free(wpa_ie);
00218 return 1;
00219 }
00220
00221 hdr_p += CIPHER_SUITE_LEN;
00222
00223
00224
00225 wpa_hdr->length = (hdr_p - wpa_ie) - 2;
00226
00227 #ifdef DEBUG_IE
00228 int i;
00229 printf("Own WPA IE:\n");
00230 for (i=0;i<wpa_hdr->length;i++) {
00231 printf("0x%02x ", wpa_ie[i]);
00232 }
00233 printf("\n");
00234 #endif
00235
00236 update_own_ie(wpa_ie, wpa_hdr->length + 2);
00237
00238 return 0;
00239 }
00246 static int generate_wpa2_ie(guint32 encryption,
00247 struct wlan_status_t *wlan_status)
00248 {
00249
00250 guint8 *wpa_ie;
00251 struct rsn_ie_t *wpa_hdr;
00252 guint8* hdr_p;
00253
00254
00255 wpa_ie = g_malloc(sizeof(struct rsn_ie_t)+8+CIPHER_SUITE_LEN*3+
00256 WLANCOND_PMKID_LEN);
00257
00258 wpa_hdr = (struct rsn_ie_t*) wpa_ie;
00259 wpa_hdr->element_id = RSN_ELEMENT;
00260
00261 wpa_hdr->version = RSN_VERSION;
00262 hdr_p = (guint8*)(wpa_hdr + 1);
00263
00264
00265 switch (wlan_status->group_cipher) {
00266 case CIPHER_SUITE_TKIP:
00267 memcpy(hdr_p, RSN_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN);
00268 break;
00269 case CIPHER_SUITE_CCMP:
00270 memcpy(hdr_p, RSN_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN);
00271 break;
00272 case CIPHER_SUITE_WEP104:
00273 memcpy(hdr_p, RSN_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN);
00274 break;
00275 case CIPHER_SUITE_WEP40:
00276 memcpy(hdr_p, RSN_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN);
00277 break;
00278 default:
00279 DLOG_ERR("Unsupported group cipher suite");
00280 g_free(wpa_ie);
00281 return -1;
00282 }
00283
00284 hdr_p += CIPHER_SUITE_LEN;
00285
00286
00287 *hdr_p++ = 1;
00288 *hdr_p++ = 0;
00289
00290 switch (wlan_status->pairwise_cipher) {
00291 case CIPHER_SUITE_TKIP:
00292 memcpy(hdr_p, RSN_CIPHER_SUITE_TKIP, CIPHER_SUITE_LEN);
00293 break;
00294 case CIPHER_SUITE_CCMP:
00295 memcpy(hdr_p, RSN_CIPHER_SUITE_CCMP, CIPHER_SUITE_LEN);
00296 break;
00297 case CIPHER_SUITE_WEP104:
00298 memcpy(hdr_p, RSN_CIPHER_SUITE_WEP104, CIPHER_SUITE_LEN);
00299 break;
00300 case CIPHER_SUITE_WEP40:
00301 memcpy(hdr_p, RSN_CIPHER_SUITE_WEP40, CIPHER_SUITE_LEN);
00302 break;
00303 default:
00304 DLOG_ERR("Unsupported pairwise cipher suite");
00305 g_free(wpa_ie);
00306 return -1;
00307 }
00308
00309 hdr_p += CIPHER_SUITE_LEN;
00310
00311
00312 *hdr_p++ = 1;
00313 *hdr_p++ = 0;
00314
00315 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WPA_PSK) {
00316 memcpy(hdr_p, RSN_KEY_MGMT_PSK, CIPHER_SUITE_LEN);
00317 } else if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) ==
00318 WLANCOND_WPA_EAP){
00319 memcpy(hdr_p, RSN_KEY_MGMT_802_1X, CIPHER_SUITE_LEN);
00320 } else {
00321 DLOG_ERR("Unknown key management suite");
00322 g_free(wpa_ie);
00323 return -1;
00324 }
00325
00326 hdr_p += CIPHER_SUITE_LEN;
00327
00328
00329 *hdr_p++ = 0;
00330 *hdr_p++ = 0;
00331
00332
00333 unsigned char *pmkid;
00334
00335 if (find_pmkid_from_pmk_cache(wlan_status->conn.bssid, &pmkid)) {
00336 DLOG_ERR("Error trying to retrieve the pmkid.");
00337 g_free(wpa_ie);
00338 return ESUPPLICANT;
00339 }
00340
00341 if (pmkid != NULL) {
00342 *hdr_p++ = 1;
00343 *hdr_p++ = 0;
00344 memcpy(hdr_p, pmkid, WLANCOND_PMKID_LEN);
00345 hdr_p += WLANCOND_PMKID_LEN;
00346 }
00347
00348 wpa_hdr->length = (hdr_p - wpa_ie) - 2;
00349
00350 #ifdef DEBUG_IE
00351 int i;
00352 printf("Own WPA IE:\n");
00353 for (i=0;i<wpa_hdr->length;i++) {
00354 printf("0x%02x ", wpa_ie[i]);
00355 }
00356 printf("\n");
00357 #endif
00358
00359 update_own_ie(wpa_ie, wpa_hdr->length + 2);
00360
00361 return 0;
00362 }
00363
00364 static gint compare_bssid(gconstpointer a, gconstpointer b)
00365 {
00366 return memcmp(a, b, ETH_ALEN);
00367 }
00368
00373 static void remove_ap_from_black_list(unsigned char* bssid)
00374 {
00375 GSList *list;
00376
00377 list = g_slist_find_custom(ap_black_list, bssid, &compare_bssid);
00378
00379 if (list != NULL) {
00380 unsigned char* bssid_entry = list->data;
00381 print_mac(WLANCOND_PRIO_MEDIUM,
00382 "Found black list entry to be removed:",
00383 bssid);
00384
00385
00386 ap_black_list = g_slist_remove(ap_black_list,
00387 bssid_entry);
00388 g_free(bssid_entry);
00389 }
00390 }
00391
00397 static gboolean mic_failure_timer_cb(void* data)
00398 {
00399
00400
00401
00402 mic_failure_timer_id = 0;
00403
00404 print_mac(WLANCOND_PRIO_MEDIUM,
00405 "No MIC failures within the last 60 seconds for:",
00406 data);
00407
00408 remove_ap_from_black_list(data);
00409
00410 return FALSE;
00411 }
00412
00418 gboolean is_ap_in_black_list(unsigned char* bssid)
00419 {
00420 GSList *list;
00421
00422 list = g_slist_find_custom(ap_black_list, bssid, &compare_bssid);
00423
00424 if (list != NULL) {
00425 print_mac(WLANCOND_PRIO_HIGH,
00426 "Found AP from black list:", bssid);
00427 return TRUE;
00428 }
00429 return FALSE;
00430 }
00431
00437 static gboolean mic_failure_running_cb(void* data)
00438 {
00439 mic_failure_running_timer_id = 0;
00440
00441 print_mac(WLANCOND_PRIO_HIGH, "MIC failures off for:", data);
00442
00443 remove_ap_from_black_list(data);
00444
00445 return FALSE;
00446 }
00447
00448 static void add_ap_to_black_list(unsigned char* bssid)
00449 {
00450 ap_black_list = g_slist_prepend(ap_black_list,
00451 g_memdup(bssid, ETH_ALEN));
00452 }
00453
00454 static void mic_destroy_cb(gpointer data)
00455 {
00456
00457 g_free(data);
00458 }
00459
00465 int handle_mic_failure(gboolean key_type, unsigned char* bssid)
00466 {
00467
00468 if (mic_failure_timer_id != 0) {
00469
00470 g_source_remove(mic_failure_timer_id);
00471 mic_failure_timer_id = 0;
00472
00473
00474 wpa_mic_failure_event(key_type, TRUE);
00475
00476 print_mac(WLANCOND_PRIO_HIGH,
00477 "Second MIC failure, disconnecting AP:", bssid);
00478
00479 mlme_command(bssid, WLANCOND_MLME_DEAUTH,
00480 WLANCOND_REASON_MIC_FAILURE);
00481
00482 set_wlan_state(WLAN_NOT_INITIALIZED,
00483 DISCONNECTED_SIGNAL,
00484 FALSE);
00485
00486
00487 mic_failure_running_timer_id = g_timeout_add_seconds_full(
00488 G_PRIORITY_DEFAULT,
00489 MIC_FAILURE_TIMEOUT,
00490 mic_failure_running_cb,
00491 g_memdup(bssid, ETH_ALEN),
00492 mic_destroy_cb);
00493
00494 add_ap_to_black_list(bssid);
00495
00496 return 0;
00497 }
00498
00499 wpa_mic_failure_event(key_type, FALSE);
00500
00501 mic_failure_timer_id = g_timeout_add_seconds_full(
00502 G_PRIORITY_DEFAULT,
00503 MIC_FAILURE_TIMEOUT,
00504 mic_failure_timer_cb,
00505 g_memdup(bssid, ETH_ALEN),
00506 mic_destroy_cb);
00507
00508 return 0;
00509 }
00510
00518 int parse_rsn_ie(unsigned char* wpa_ie, unsigned int wpa_ie_len,
00519 struct ap_info_t* ap_info)
00520 {
00521 struct rsn_ie_t *wpa_hdr;
00522 guint8 *hdr_p;
00523 guint ind;
00524 guint i;
00525 guint cipher_count = 0;
00526
00527
00528
00529
00530
00531
00532 wpa_hdr = (struct rsn_ie_t*) wpa_ie;
00533
00534 if (wpa_ie_len < sizeof(struct rsn_ie_t)) {
00535 DLOG_ERR("WPA IE too short");
00536 return -1;
00537 }
00538
00539 if (wpa_hdr->element_id != RSN_ELEMENT) {
00540 DLOG_ERR("Unknown WPA IE received");
00541 return -1;
00542 }
00543
00544 ind = wpa_ie_len - sizeof(*wpa_hdr);
00545 hdr_p = (guint8*)(wpa_hdr + 1);
00546
00547 if (ind >= CIPHER_SUITE_LEN) {
00548 ap_info->group_cipher = parse_rsn_cipher_suite(hdr_p);
00549 hdr_p += CIPHER_SUITE_LEN;
00550 ind -= CIPHER_SUITE_LEN;
00551 } else {
00552 DLOG_ERR("Strange length in WPA IE");
00553 return -1;
00554 }
00555
00556 if (ind >= 2) {
00557 ap_info->pairwise_cipher = 0;
00558 cipher_count = *(guint16*)hdr_p;
00559
00560 ind -= 2;
00561
00562 if (cipher_count == 0) {
00563 DLOG_ERR("No pairwise ciphers");
00564
00565 return 0;
00566 }
00567
00568 if (ind < cipher_count * CIPHER_SUITE_LEN) {
00569 DLOG_ERR("Invalid pairwise cipher length");
00570 return -1;
00571 }
00572
00573 hdr_p += 2;
00574
00575 for (i = 0; i < cipher_count; i++) {
00576 ap_info->pairwise_cipher |= parse_rsn_cipher_suite(hdr_p);
00577 ind -= CIPHER_SUITE_LEN;
00578 hdr_p += CIPHER_SUITE_LEN;
00579 }
00580 } else if (ind == 1) {
00581 DLOG_ERR("Remaining data too short");
00582 return -1;
00583 }
00584
00585 if (ind >= 2) {
00586 ap_info->key_mgmt = 0;
00587 cipher_count = *(guint16*)hdr_p;
00588 hdr_p += 2;
00589 ind -= 2;
00590
00591 if (cipher_count == 0 || ind < cipher_count *
00592 CIPHER_SUITE_LEN) {
00593 DLOG_ERR("Invalid key mgmt cipher count or length");
00594 return -1;
00595 }
00596
00597 for (i = 0; i < cipher_count; i++) {
00598 ap_info->key_mgmt |= parse_rsn_key_mgmt_suite(hdr_p);
00599 ind -= CIPHER_SUITE_LEN;
00600 hdr_p += CIPHER_SUITE_LEN;
00601 }
00602 } else if (ind == 1) {
00603 DLOG_ERR("Remaining data too short");
00604 return -1;
00605 }
00606
00607 if (ind >= 2) {
00608
00609 hdr_p += 2;
00610 ind -= 2;
00611 }
00612
00613 if (ind > 0) {
00614 DLOG_DEBUG("IE includes PMKID data");
00615 }
00616 return 0;
00617 }
00618
00619
00627 int parse_wpa_ie(unsigned char* wpa_ie, unsigned int wpa_ie_len,
00628 struct ap_info_t* ap_info)
00629 {
00630 struct wpa_ie_t *wpa_hdr;
00631 guint8 *hdr_p;
00632 guint ind, i;
00633 guint cipher_count = 0;
00634 const guint8 WPA1_OUI[] = { 0x00, 0x50, 0xf2, 1 };
00635
00636
00637
00638
00639
00640
00641 wpa_hdr = (struct wpa_ie_t*) wpa_ie;
00642
00643 if (wpa_ie_len < sizeof(struct wpa_ie_t)) {
00644 DLOG_ERR("WPA IE too short");
00645 return -1;
00646 }
00647
00648 if (wpa_hdr->element_id != WPA_ELEMENT) {
00649 DLOG_ERR("Unknown WPA IE received");
00650 return -1;
00651 }
00652
00653 if (memcmp(&wpa_hdr->oui, WPA1_OUI, CIPHER_SUITE_LEN) != 0) {
00654 DLOG_ERR("Invalid WPA header");
00655 return -1;
00656 }
00657
00658 ind = wpa_ie_len - sizeof(*wpa_hdr);
00659 hdr_p = (guint8*)(wpa_hdr + 1);
00660
00661 if (ind >= CIPHER_SUITE_LEN) {
00662 ap_info->group_cipher = parse_wpa_cipher_suite(hdr_p);
00663 ind -= CIPHER_SUITE_LEN;
00664 hdr_p += CIPHER_SUITE_LEN;
00665 } else {
00666 DLOG_ERR("Strange length in WPA IE");
00667 return -1;
00668 }
00669
00670 if (ind >= 2) {
00671 ap_info->pairwise_cipher = 0;
00672 cipher_count = *(guint16*)hdr_p;
00673 ind -= 2;
00674
00675 if (cipher_count == 0) {
00676 DLOG_ERR("No pairwise ciphers");
00677
00678 return 0;
00679 }
00680
00681 if (ind < cipher_count * CIPHER_SUITE_LEN) {
00682 DLOG_ERR("Invalid pairwise cipher length");
00683 return -1;
00684 }
00685
00686 hdr_p += 2;
00687
00688 for (i = 0; i < cipher_count; i++) {
00689 ap_info->pairwise_cipher |=
00690 parse_wpa_cipher_suite(hdr_p);
00691 ind -= CIPHER_SUITE_LEN;
00692 hdr_p += CIPHER_SUITE_LEN;
00693 }
00694 } else if (ind == 1) {
00695 DLOG_ERR("Remaining data too short");
00696 return -1;
00697 }
00698
00699 if (ind >= 2) {
00700 ap_info->key_mgmt = 0;
00701 cipher_count = *(guint16*)hdr_p;
00702 hdr_p += 2;
00703 ind -= 2;
00704
00705 if (cipher_count == 0 || ind < cipher_count *
00706 CIPHER_SUITE_LEN) {
00707 DLOG_ERR("Invalid key mgmt cipher count (%d) or length",
00708 cipher_count);
00709 return -1;
00710 }
00711
00712 for (i = 0; i < cipher_count; i++) {
00713 ap_info->key_mgmt |= parse_wpa_key_mgmt_suite(hdr_p);
00714 ind -= CIPHER_SUITE_LEN;
00715 hdr_p += CIPHER_SUITE_LEN;
00716 }
00717 } else if (ind == 1) {
00718 DLOG_ERR("Remaining data too short");
00719 return -1;
00720 }
00721
00722 if (ind >= 2) {
00723
00724 hdr_p += 2;
00725 ind -= 2;
00726 }
00727
00728 if (ind > 0) {
00729 DLOG_ERR("IE too long?");
00730 return -1;
00731 }
00732 return 0;
00733 }
00734
00735 gint nl80211_encryption_method(guint32 encryption,
00736 struct wlan_status_t *wlan_status)
00737 {
00738 gint32 value = 0;
00739 guint32 key_mgmt = 0;
00740 gboolean wpa2 = FALSE;
00741 guint32 authentication = wlan_status->conn.authentication_type;
00742
00743 if (encryption & WLANCOND_ENCRYPT_WPA2_MASK)
00744 wpa2 = TRUE;
00745
00746 if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) == WLANCOND_WPA_PSK) {
00747 if (wpa2 == TRUE)
00748 value = WLANCOND_AUTH_WPA_VERSION_WPA2;
00749 else
00750 value = WLANCOND_AUTH_WPA_VERSION_WPA;
00751 key_mgmt = WLANCOND_AUTH_KEY_MGMT_PSK;
00752
00753 } else if ((encryption & WLANCOND_ENCRYPT_METHOD_MASK) ==
00754 WLANCOND_WPA_EAP) {
00755 if (wpa2 == TRUE)
00756 value = WLANCOND_AUTH_WPA_VERSION_WPA2;
00757 else
00758 value = WLANCOND_AUTH_WPA_VERSION_WPA;
00759 key_mgmt = WLANCOND_AUTH_KEY_MGMT_802_1X;
00760 } else {
00761 value = WLANCOND_AUTH_WPA_VERSION_DISABLED;
00762 }
00763
00764 if (key_mgmt != 0) {
00765
00766 if (authentication != EAP_AUTH_TYPE_WFA_SC) {
00767 if (wpa2 == TRUE)
00768 value = generate_wpa2_ie(encryption,
00769 wlan_status);
00770 else
00771 value = generate_wpa_ie(encryption,
00772 wlan_status);
00773 }
00774 }
00775
00776 if (value < 0)
00777 return value;
00778
00779 return 0;
00780 }
00781