Search Linux Wireless

[PATCH] mac80211: dynamic wep

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch fixes my problems with "dynamic wep" (widely used in
universities), and I can successfully associate and transfer data. The
corresponding wpa_supplicant.conf is:

network={
    ssid="airsas"
    key_mgmt=IEEE8021X
    eap=TTLS
    anonymous_identity="anon@xxxxxx"
    phase2="auth=PAP"
    identity="username"
    password="password"
}

The patch contains basically two changes:
1) Allow privacy mismatch until associated
2) Decrypt unicast frames with the per-STA key, not making any
   assumptions about it being key index 0.



diff -ru linux+mac80211-9.0.3/include/linux/ieee80211.h linux-2.6.22.1/include/linux/ieee80211.h
--- linux+mac80211-9.0.3/include/linux/ieee80211.h	2007-08-06 16:28:48.000000000 -0400
+++ linux-2.6.22.1/include/linux/ieee80211.h	2007-08-07 13:35:18.000000000 -0400
@@ -357,7 +357,7 @@
 #define WLAN_CAPABILITY_IBSS		(1<<1)
 #define WLAN_CAPABILITY_CF_POLLABLE	(1<<2)
 #define WLAN_CAPABILITY_CF_POLL_REQUEST	(1<<3)
-#define WLAN_CAPABILITY_PRIVACY		(1<<4)
+#define WLAN_CAPABILITY_PRIVACY		(1<<4) /* Force WEP on data packets */
 #define WLAN_CAPABILITY_SHORT_PREAMBLE	(1<<5)
 #define WLAN_CAPABILITY_PBCC		(1<<6)
 #define WLAN_CAPABILITY_CHANNEL_AGILITY	(1<<7)
diff -ru linux+mac80211-9.0.3/net/mac80211/ieee80211.c linux-2.6.22.1/net/mac80211/ieee80211.c
--- linux+mac80211-9.0.3/net/mac80211/ieee80211.c	2007-08-06 16:28:48.000000000 -0400
+++ linux-2.6.22.1/net/mac80211/ieee80211.c	2007-08-09 20:03:07.000000000 -0400
@@ -3488,7 +3488,6 @@
 ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
 {
 	struct ieee80211_hdr *hdr;
-	int always_sta_key;
 	hdr = (struct ieee80211_hdr *) rx->skb->data;
 
 	/* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
@@ -3556,29 +3555,23 @@
 		return TXRX_QUEUED;
 	}
 
-	if (rx->sdata->type == IEEE80211_IF_TYPE_STA)
-		always_sta_key = 0;
-	else
-		always_sta_key = 1;
+	if (rx->fc & IEEE80211_FCTL_PROTECTED && /* WEP */
+	    (rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV)) {
+
+		if (rx->skb->pkt_type == PACKET_HOST && 
+		    rx->sta && rx->sta->key) {
 
-	if (rx->sta && rx->sta->key && always_sta_key) {
-		rx->key = rx->sta->key;
-	} else {
-		if (rx->sta && rx->sta->key)
 			rx->key = rx->sta->key;
-		else
-			rx->key = rx->sdata->default_key;
 
-		if ((rx->local->hw.flags & IEEE80211_HW_WEP_INCLUDE_IV) &&
-		    rx->fc & IEEE80211_FCTL_PROTECTED) {
+		} else { 
 			int keyidx = ieee80211_wep_get_keyidx(rx->skb);
+			if (keyidx < 0 || keyidx >= NUM_DEFAULT_KEYS)
+				return TXRX_DROP;
+		
+			rx->key = rx->sdata->keys[keyidx];
 
-			if (keyidx >= 0 && keyidx < NUM_DEFAULT_KEYS &&
-			    (!rx->sta || !rx->sta->key || keyidx > 0))
-				rx->key = rx->sdata->keys[keyidx];
-
-			if (!rx->key) {
-				if (!rx->u.rx.ra_match)
+			if (unlikely(!rx->key)) {
+				if (!rx->u.rx.ra_match) 
 					return TXRX_DROP;
 				printk(KERN_DEBUG "%s: RX WEP frame with "
 				       "unknown keyidx %d (A1=" MAC_FMT " A2="
@@ -3587,14 +3580,21 @@
 				       MAC_ARG(hdr->addr1),
 				       MAC_ARG(hdr->addr2),
 				       MAC_ARG(hdr->addr3));
-				if (!rx->local->apdev)
+				if (!rx->local->apdev) {
+					rx->local->dot11WEPUndecryptableCount++;
 					return TXRX_DROP;
+				}
 				ieee80211_rx_mgmt(
 					rx->local, rx->skb, rx->u.rx.status,
 					ieee80211_msg_wep_frame_unknown_key);
 				return TXRX_QUEUED;
 			}
 		}
+	} else { /* No WEP */
+		if (rx->sta && rx->sta->key)
+			rx->key = rx->sta->key;
+		else
+			rx->key = rx->sdata->default_key;
 	}
 
 	if (rx->fc & IEEE80211_FCTL_PROTECTED && rx->key && rx->u.rx.ra_match) {
diff -ru linux+mac80211-9.0.3/net/mac80211/ieee80211_ioctl.c linux-2.6.22.1/net/mac80211/ieee80211_ioctl.c
--- linux+mac80211-9.0.3/net/mac80211/ieee80211_ioctl.c	2007-08-06 16:28:48.000000000 -0400
+++ linux-2.6.22.1/net/mac80211/ieee80211_ioctl.c	2007-08-09 19:01:56.000000000 -0400
@@ -479,13 +479,14 @@
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-	if (is_broadcast_ether_addr(sta_addr)) {
+	if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
+		printk(KERN_DEBUG "%s: set_encrypt - invalid idx = %d\n",
+		       dev->name, idx);
+		return -EINVAL;
+	}
+
+	if (is_multicast_ether_addr(sta_addr)) {
 		sta = NULL;
-		if (idx >= NUM_DEFAULT_KEYS) {
-			printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
-			       dev->name, idx);
-			return -EINVAL;
-		}
 		key = sdata->keys[idx];
 
 		/* TODO: consider adding hwaccel support for these; at least
@@ -499,7 +500,7 @@
 		 * being, this can be only set at compile time. */
 	} else {
 		set_tx_key = 0;
-		if (idx != 0) {
+		if (idx != 0 && alg != ALG_WEP) {
 			printk(KERN_DEBUG "%s: set_encrypt - non-zero idx for "
 			       "individual key\n", dev->name);
 			return -EINVAL;
diff -ru linux+mac80211-9.0.3/net/mac80211/ieee80211_sta.c linux-2.6.22.1/net/mac80211/ieee80211_sta.c
--- linux+mac80211-9.0.3/net/mac80211/ieee80211_sta.c	2007-08-06 16:28:48.000000000 -0400
+++ linux-2.6.22.1/net/mac80211/ieee80211_sta.c	2007-08-07 15:01:31.000000000 -0400
@@ -1131,10 +1131,11 @@
 	bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
 	if (!bss)
 		return 0;
-
-	if (ieee80211_sta_wep_configured(dev) !=
-	    !!(bss->capability & WLAN_CAPABILITY_PRIVACY))
-		res = 1;
+	
+	if (ifsta->associated && ieee80211_sta_wep_configured(dev) != 
+	    !!(bss->capability & WLAN_CAPABILITY_PRIVACY)) {
+		res = 1;  /* associated and WEP encryption mismatch */
+	}
 
 	ieee80211_rx_bss_put(dev, bss);

-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux