From owner-p4-projects@FreeBSD.ORG Wed Jan 28 17:39:03 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 94DB216A4D0; Wed, 28 Jan 2004 17:39:03 -0800 (PST) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6FD4216A4CE for ; Wed, 28 Jan 2004 17:39:03 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5A0A343D46 for ; Wed, 28 Jan 2004 17:38:45 -0800 (PST) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.10/8.12.10) with ESMTP id i0T1cj0B044141 for ; Wed, 28 Jan 2004 17:38:45 -0800 (PST) (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.10/8.12.10/Submit) id i0T1ciXo044138 for perforce@freebsd.org; Wed, 28 Jan 2004 17:38:44 -0800 (PST) (envelope-from sam@freebsd.org) Date: Wed, 28 Jan 2004 17:38:44 -0800 (PST) Message-Id: <200401290138.i0T1ciXo044138@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Subject: PERFORCE change 46108 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Jan 2004 01:39:04 -0000 http://perforce.freebsd.org/chv.cgi?CH=46108 Change 46108 by sam@sam_ebb on 2004/01/28 17:38:15 o add error status reponses for error conditions encountered in shared key authentication o hack the ieee80211_send_mgmt so the arg parameter for AUTH frames is interpreted to have the status code in the upper 16 bits; this allows error status codes to be returned w/o modifying any existing code Affected files ... .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_input.c#9 edit .. //depot/projects/netperf+sockets/sys/net80211/ieee80211_output.c#9 edit Differences ... ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_input.c#9 (text+ko) ==== @@ -752,19 +752,27 @@ } } -/* TBD send appropriate responses on error? */ static void ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh, u_int8_t *frm, u_int8_t *efrm, struct ieee80211_node *ni, int rssi, u_int32_t rstamp, u_int16_t seq, u_int16_t status) { u_int8_t *challenge = NULL; - int allocbs, i; + int allocbs, i, estatus; if ((ic->ic_flags & IEEE80211_F_WEPON) == 0) { IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, ("%s: WEP is off\n", __func__)); - return; + estatus = IEEE80211_STATUS_ALG; + goto bad; + } + if (ic->ic_authmode != IEEE80211_AUTH_AUTO && + ic->ic_authmode != IEEE80211_AUTH_SHARED) { + IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, + ("%s: operating in %u mode, reject\n", + __func__, ic->ic_authmode)); + estatus = IEEE80211_STATUS_ALG; + goto bad; } if (frm + 1 < efrm) { @@ -773,7 +781,8 @@ ("%s: elt %d %d bytes too long\n", __func__, frm[0], (frm[1] + 2) - (efrm - frm))); ic->ic_stats.is_rx_bad_auth++; - return; + estatus = IEEE80211_STATUS_CHALLENGE; + goto bad; } if (*frm == IEEE80211_ELEMID_CHALLENGE) challenge = frm; @@ -786,14 +795,16 @@ IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, ("%s: no challenge sent\n", __func__)); ic->ic_stats.is_rx_bad_auth++; - return; + estatus = IEEE80211_STATUS_CHALLENGE; + goto bad; } if (challenge[1] != IEEE80211_CHALLENGE_LEN) { IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, ("%s: bad challenge len %d\n", __func__, challenge[1])); ic->ic_stats.is_rx_bad_auth++; - return; + estatus = IEEE80211_STATUS_CHALLENGE; + goto bad; } default: break; @@ -809,7 +820,8 @@ if (ic->ic_state != IEEE80211_S_RUN) { IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, ("%s: not running\n", __func__)); - return; + estatus = IEEE80211_STATUS_ALG; /* XXX */ + goto bad; } switch (seq) { case IEEE80211_AUTH_SHARED_REQUEST: @@ -817,6 +829,7 @@ ni = ieee80211_alloc_node(ic, wh->i_addr2); if (ni == NULL) { ic->ic_stats.is_rx_nodealloc++; + /* NB: no way to return an error */ return; } IEEE80211_ADDR_COPY(ni->ni_bssid, @@ -836,6 +849,7 @@ ("%s: challenge alloc failed\n", __func__)); /* XXX statistic */ + /* NB: don't return error so they rexmit */ return; } for (i = IEEE80211_CHALLENGE_LEN / sizeof(u_int32_t); @@ -851,6 +865,7 @@ if (ni == ic->ic_bss) { IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, ("%s: unknown STA\n", __func__)); + /* NB: don't send a response */ return; } allocbs = 1; @@ -858,14 +873,16 @@ IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, ("%s: no challenge recorded\n", __func__)); ic->ic_stats.is_rx_bad_auth++; - return; + estatus = IEEE80211_STATUS_CHALLENGE; + goto bad; } if (memcmp(ni->ni_challenge, &challenge[2], challenge[1]) != 0) { IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, ("%s: challenge mismatch\n", __func__)); ic->ic_stats.is_rx_auth_fail++; - return; + estatus = IEEE80211_STATUS_CHALLENGE; + goto bad; } IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, @@ -877,7 +894,8 @@ ("%s: bad shared key auth seq %d from %s\n", __func__, seq, ether_sprintf(wh->i_addr2))); ic->ic_stats.is_rx_bad_auth++; - return; + estatus = IEEE80211_STATUS_SEQUENCE; + goto bad; } IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, seq + 1); @@ -930,6 +948,17 @@ } break; } + return; +bad: + /* + * Send an error response; but only when operating as an AP. + */ + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + /* XXX hack to workaround calling convention */ + IEEE80211_SEND_MGMT(ic, ni, + IEEE80211_FC0_SUBTYPE_AUTH, + (seq + 1) | (estatus<<16)); + } } /* Verify the existence and length of __elem or get out. */ @@ -1283,6 +1312,12 @@ ("%s: unsupported auth algorithm %d from %s\n", __func__, algo, ether_sprintf(wh->i_addr2))); ic->ic_stats.is_rx_auth_unsupported++; + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + /* XXX not right */ + IEEE80211_SEND_MGMT(ic, ni, + IEEE80211_FC0_SUBTYPE_AUTH, + (seq+1) | (IEEE80211_STATUS_ALG<<16)); + } return; } break; ==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_output.c#9 (text+ko) ==== @@ -317,7 +317,7 @@ u_int8_t *frm; enum ieee80211_phymode mode; u_int16_t capinfo; - int has_challenge, is_shared_key, ret, timer; + int has_challenge, is_shared_key, ret, timer, status; KASSERT(ni != NULL, ("null node")); @@ -428,6 +428,8 @@ break; case IEEE80211_FC0_SUBTYPE_AUTH: + status = arg >> 16; + arg &= 0xffff; has_challenge = ((arg == IEEE80211_AUTH_SHARED_CHALLENGE || arg == IEEE80211_AUTH_SHARED_RESPONSE) && ni->ni_challenge != NULL); @@ -446,7 +448,7 @@ m = ieee80211_getmgtframe(&frm, 3 * sizeof(u_int16_t) - + (has_challenge ? + + (has_challenge && status == IEEE80211_STATUS_SUCCESS ? sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0)); if (m == NULL) senderr(ENOMEM, is_tx_nobuf); @@ -455,9 +457,9 @@ (is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED) : htole16(IEEE80211_AUTH_ALG_OPEN); ((u_int16_t *)frm)[1] = htole16(arg); /* sequence number */ - ((u_int16_t *)frm)[2] = 0; /* status */ + ((u_int16_t *)frm)[2] = htole16(status);/* status */ - if (has_challenge) { + if (has_challenge && status == IEEE80211_STATUS_SUCCESS) { ((u_int16_t *)frm)[3] = htole16((IEEE80211_CHALLENGE_LEN << 8) | IEEE80211_ELEMID_CHALLENGE);