WPA is on and RX protection for TA is on.
Keep track of the TX/RX protection for each node when WPA is on.
tested by djm@ (ral+wpa), ckuethe@ (ath-noenc) and krw@ (wpi<->ral+wpa).
hints from bluhm@
has been in snaps for a few days.
pointed out by bluhm@ something like 1 year ago but we did not have
the right infrastructure to fix it properly at that time.
ok deraadt@
-/* $OpenBSD: ieee80211_input.c,v 1.87 2008/07/28 19:42:13 damien Exp $ */
+/* $OpenBSD: ieee80211_input.c,v 1.88 2008/08/02 08:20:16 damien Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
goto out;
}
- if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
- if (ic->ic_flags &
- (IEEE80211_F_WEPON | IEEE80211_F_RSNON)) {
+ if ((ic->ic_flags & IEEE80211_F_WEPON) ||
+ ((ic->ic_flags & IEEE80211_F_RSNON) &&
+ (ni->ni_flags & IEEE80211_NODE_RXPROT))) {
+ /* protection is on for Rx */
+ if (!(rxi->rxi_flags & IEEE80211_RXI_HWDEC)) {
+ if (!(wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
+ /* drop unencrypted */
+ ic->ic_stats.is_rx_unencrypted++;
+ goto err;
+ }
+ /* do software decryption */
m = ieee80211_decrypt(ic, m, ni);
if (m == NULL) {
ic->ic_stats.is_rx_wepfail++;
goto err;
}
wh = mtod(m, struct ieee80211_frame *);
- } else {
- ic->ic_stats.is_rx_nowep++;
- goto out;
}
- } else if (!(rxi->rxi_flags & IEEE80211_RXI_HWDEC)) {
- /* XXX */
+ } else if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) ||
+ (rxi->rxi_flags & IEEE80211_RXI_HWDEC)) {
+ /* frame encrypted but protection off for Rx */
+ ic->ic_stats.is_rx_nowep++;
+ goto out;
}
+
#if NBPFILTER > 0
/* copy to listener after decrypt */
if (ic->ic_rawbpf)
}
eh = mtod(m, struct ether_header *);
- if ((ic->ic_flags & IEEE80211_F_RSNON) && !ni->ni_port_valid &&
+ if ((ic->ic_flags & IEEE80211_F_RSNON) &&
+ !ni->ni_port_valid &&
eh->ether_type != htons(ETHERTYPE_PAE)) {
DPRINTF(("port not valid: %s\n",
ether_sprintf(wh->i_addr2)));
-/* $OpenBSD: ieee80211_node.c,v 1.37 2008/07/28 19:42:13 damien Exp $ */
+/* $OpenBSD: ieee80211_node.c,v 1.38 2008/08/02 08:20:16 damien Exp $ */
/* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */
/*-
* multicast frames using the group key we've just configured.
*/
ni->ni_port_valid = 1;
+ ni->ni_flags |= IEEE80211_NODE_TXPROT;
/* schedule a GTK rekeying after 3600s */
timeout_add(&ic->ic_rsn_timeout, 3600 * hz);
ni->ni_key_count = 0;
ni->ni_port_valid = 0;
+ ni->ni_flags &= ~IEEE80211_NODE_TXRXPROT;
ni->ni_replaycnt = -1; /* XXX */
ni->ni_rsn_retries = 0;
ni->ni_rsncipher = ni->ni_rsnciphers;
timeout_del(&ni->ni_rsn_timeout);
ni->ni_rsn_retries = 0;
+ ni->ni_flags &= ~IEEE80211_NODE_TXRXPROT;
ni->ni_port_valid = 0;
(*ic->ic_delete_key)(ic, ni, &ni->ni_pairwise_key);
}
-/* $OpenBSD: ieee80211_node.h,v 1.28 2008/07/27 18:24:01 damien Exp $ */
+/* $OpenBSD: ieee80211_node.h,v 1.29 2008/08/02 08:20:16 damien Exp $ */
/* $NetBSD: ieee80211_node.h,v 1.9 2004/04/30 22:57:32 dyoung Exp $ */
/*-
u_int8_t ni_flags; /* special-purpose state */
#define IEEE80211_NODE_ERP 0x01
#define IEEE80211_NODE_QOS 0x02
-#define IEEE80211_NODE_REKEY 0x04
+#define IEEE80211_NODE_REKEY 0x04 /* GTK rekying in progress */
+#define IEEE80211_NODE_RXPROT 0x08 /* RX protection ON */
+#define IEEE80211_NODE_TXPROT 0x10 /* TX protection ON */
+#define IEEE80211_NODE_TXRXPROT \
+ (IEEE80211_NODE_TXPROT | IEEE80211_NODE_RXPROT)
};
RB_HEAD(ieee80211_tree, ieee80211_node);
-/* $OpenBSD: ieee80211_output.c,v 1.63 2008/07/27 14:21:15 damien Exp $ */
+/* $OpenBSD: ieee80211_output.c,v 1.64 2008/08/02 08:20:16 damien Exp $ */
/* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */
/*-
goto bad;
}
- if ((ic->ic_flags & IEEE80211_F_RSNON) && !ni->ni_port_valid &&
+ if ((ic->ic_flags & IEEE80211_F_RSNON) &&
+ !ni->ni_port_valid &&
eh.ether_type != htons(ETHERTYPE_PAE)) {
DPRINTF(("port not valid: %s\n",
ether_sprintf(eh.ether_dhost)));
}
if ((ic->ic_flags & IEEE80211_F_WEPON) ||
- ((ic->ic_flags & IEEE80211_F_RSNON) && ni->ni_port_valid))
+ ((ic->ic_flags & IEEE80211_F_RSNON) &&
+ (ni->ni_flags & IEEE80211_NODE_TXPROT)))
wh->i_fc[1] |= IEEE80211_FC1_PROTECTED;
*pni = ni;
-/* $OpenBSD: ieee80211_pae_input.c,v 1.3 2008/07/27 14:21:15 damien Exp $ */
+/* $OpenBSD: ieee80211_pae_input.c,v 1.4 2008/08/02 08:20:16 damien Exp $ */
/*-
* Copyright (c) 2007,2008 Damien Bergamini <damien.bergamini@free.fr>
reason = IEEE80211_REASON_AUTH_LEAVE;
goto deauth;
}
+ ni->ni_flags |= IEEE80211_NODE_RXPROT;
}
if (gtk != NULL) {
u_int64_t rsc;
goto deauth;
}
}
+ if (info & EAPOL_KEY_INSTALL)
+ ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
+
if (info & EAPOL_KEY_SECURE) {
+ ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
if (ic->ic_opmode != IEEE80211_M_IBSS ||
++ni->ni_key_count == 2) {
DPRINTF(("marking port %s valid\n",
ieee80211_node_leave(ic, ni);
return;
}
+ ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
}
if (ic->ic_opmode != IEEE80211_M_IBSS || ++ni->ni_key_count == 2) {
DPRINTF(("marking port %s valid\n",
--ic->ic_rsn_keydonesta == 0)
ieee80211_setkeysdone(ic);
ni->ni_flags &= ~IEEE80211_NODE_REKEY;
+ ni->ni_flags |= IEEE80211_NODE_TXRXPROT;
ni->ni_rsn_gstate = RSNA_IDLE;
ni->ni_rsn_retries = 0;