From owner-svn-src-all@FreeBSD.ORG Wed Nov 3 10:44:25 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DEE8B1065695; Wed, 3 Nov 2010 10:44:25 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CBA678FC24; Wed, 3 Nov 2010 10:44:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oA3AiPE4018219; Wed, 3 Nov 2010 10:44:25 GMT (envelope-from rpaulo@svn.freebsd.org) Received: (from rpaulo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oA3AiPwS018213; Wed, 3 Nov 2010 10:44:25 GMT (envelope-from rpaulo@svn.freebsd.org) Message-Id: <201011031044.oA3AiPwS018213@svn.freebsd.org> From: Rui Paulo Date: Wed, 3 Nov 2010 10:44:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r214735 - in head/usr.sbin/wpa: hostapd wpa_passphrase wpa_supplicant X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Nov 2010 10:44:26 -0000 Author: rpaulo Date: Wed Nov 3 10:44:25 2010 New Revision: 214735 URL: http://svn.freebsd.org/changeset/base/214735 Log: Adapt for wpa_supplicant / hostapd 0.7.3. Modified: head/usr.sbin/wpa/hostapd/Makefile head/usr.sbin/wpa/hostapd/driver_freebsd.c head/usr.sbin/wpa/wpa_passphrase/Makefile head/usr.sbin/wpa/wpa_supplicant/Makefile head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c Modified: head/usr.sbin/wpa/hostapd/Makefile ============================================================================== --- head/usr.sbin/wpa/hostapd/Makefile Wed Nov 3 10:43:38 2010 (r214734) +++ head/usr.sbin/wpa/hostapd/Makefile Wed Nov 3 10:44:25 2010 (r214735) @@ -3,17 +3,31 @@ .include "${.CURDIR}/../Makefile.inc" .PATH.c:${HOSTAPD_DISTDIR} \ + ${WPA_DISTDIR}/src/ap \ ${WPA_DISTDIR}/src/eap_server \ + ${WPA_DISTDIR}/src/eap_common \ + ${WPA_DISTDIR}/src/eapol_auth \ + ${WPA_DISTDIR}/src/drivers \ ${WPA_DISTDIR}/src/radius \ + ${WPA_DISTDIR} PROG= hostapd -SRCS= accounting.c aes.c aes_wrap.c ap_list.c beacon.c common.c \ - config.c ctrl_iface.c drivers.c eapol_sm.c eap.c eap_common.c \ - eap_identity.c eap_methods.c eloop.c hostapd.c \ - hw_features.c ieee802_11.c ieee802_11_common.c ieee802_11_auth.c \ - ieee802_1x.c ip_addr.c md5.c mlme.c pmksa_cache.c radius.c \ - radius_client.c rc4.c sha1.c sta_info.c vlan_init.c wme.c \ - wpa.c wpa_auth_ie.c wpa_common.c wpa_debug.c wpabuf.c +SRCS= accounting.c aes-wrap.c ap_config.c \ + ap_drv_ops.c ap_mlme.c authsrv.c \ + chap.c common.c config_file.c ctrl_iface.c crypto_openssl.c \ + ctrl_iface_ap.c drivers.c drv_callbacks.c dump_state.c \ + eap_common.c eap_peap_common.c eap_register.c eap_server.c \ + eap_server_gtc.c eap_server_identity.c eap_server_md5.c \ + eap_server_methods.c eap_server_mschapv2.c eap_server_peap.c \ + eap_server_tls.c eap_server_tls_common.c eap_server_ttls.c \ + eapol_auth_dump.c eapol_auth_sm.c eloop.c hostapd.c ieee802_11_auth.c \ + ieee802_11_common.c ieee802_11_ht.c ieee802_1x.c ip_addr.c \ + md5.c main.c ms_funcs.c peerkey_auth.c pmksa_cache_auth.c \ + preauth_auth.c radius.c radius_client.c sta_info.c \ + sha1-pbkdf2.c sha1-tlsprf.c sha1-tprf.c sha1.c \ + tkip_countermeasures.c utils.c \ + vlan_init.c wpa_auth.c wpa_auth_glue.c wpa_auth_ie.c wpa_common.c \ + wpa_debug.c wpabuf.c SRCS+= l2_packet_freebsd.c driver_freebsd.c os_unix.c MAN= hostapd.8 hostapd.conf.5 @@ -24,16 +38,16 @@ FILESDIR= ${SHAREDIR}/examples/hostapd FILES= hostapd.conf hostapd.eap_user hostapd.wpa_psk .endif -CFLAGS+= -I${HOSTAPD_DISTDIR} +CFLAGS+= -I${HOSTAPD_DISTDIR} -I${WPA_DISTDIR}/src/drivers -CFLAGS+= -DCONFIG_DRIVER_BSD +CFLAGS+= -DCONFIG_DRIVER_BSD -DHOSTAPD CFLAGS+= -DCONFIG_DRIVER_RADIUS_ACL .if ${MK_INET6} != "no" CFLAGS+= -DCONFIG_IPV6 .endif -CFLAGS+= -g -DPADD+= ${LIBPCAP} -LDADD+= -lpcap +#CFLAGS+= -g +DPADD+= ${LIBPCAP} ${LIBSSL} +LDADD+= -lpcap -lssl # User customizations for wpa_supplicant/hostapd build environment CFLAGS+=${HOSTAPD_CFLAGS} Modified: head/usr.sbin/wpa/hostapd/driver_freebsd.c ============================================================================== --- head/usr.sbin/wpa/hostapd/driver_freebsd.c Wed Nov 3 10:43:38 2010 (r214734) +++ head/usr.sbin/wpa/hostapd/driver_freebsd.c Wed Nov 3 10:44:25 2010 (r214735) @@ -14,12 +14,13 @@ * * $FreeBSD$ */ -#include -#include -#include -#include +#include "includes.h" #include -#include + +#include "common.h" +#include "driver.h" +#include "eloop.h" +#include "common/ieee802_11_defs.h" #include #include @@ -32,34 +33,29 @@ #undef WPA_OUI_TYPE #undef WME_OUI_TYPE -#include "hostapd.h" -#include "driver.h" -#include "ieee802_1x.h" -#include "ieee802_11_auth.h" -#include "eloop.h" -#include "sta_info.h" #include "l2_packet/l2_packet.h" -#include "eapol_sm.h" -#include "wpa.h" -#include "radius/radius.h" -#include "ieee802_11.h" -#include "common.h" -#include "hostap_common.h" - struct bsd_driver_data { - struct hostapd_data *hapd; /* back pointer */ + struct hostapd_data *hapd; /* back pointer */ - char iface[IFNAMSIZ + 1]; - unsigned int ifindex; /* interface index */ - struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ - int ioctl_sock; /* socket for ioctl() use */ - int wext_sock; /* socket for wireless events */ + int ioctl_sock; /* open socket for 802.11 ioctls */ + int wext_sock; + struct l2_packet_data *sock_xmit;/* raw packet xmit socket */ + int route; /* routing socket for events */ + char iface[IFNAMSIZ+1]; /* interface name */ + unsigned int ifindex; /* interface index */ + void *ctx; + struct wpa_driver_capa capa; /* driver capability */ + int is_ap; /* Access point mode */ + int prev_roaming; /* roaming state to restore on deinit */ + int prev_privacy; /* privacy state to restore on deinit */ + int prev_wpa; /* wpa state to restore on deinit */ }; static const struct wpa_driver_ops bsd_driver_ops; -static int bsd_sta_deauth(void *priv, const u8 *addr, int reason_code); +static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, + int reason_code); static int set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len) @@ -171,44 +167,37 @@ bsd_commit(void *priv) } static int -bsd_set_ieee8021x(const char *ifname, void *priv, int enabled) +bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params) { - struct bsd_driver_data *drv = priv; - struct hostapd_data *hapd = drv->hapd; - struct hostapd_bss_config *conf = hapd->conf; - - wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled); + wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, params->enabled); - if (!enabled) { + if (!params->enabled) { /* XXX restore state */ return set80211param(priv, IEEE80211_IOC_AUTHMODE, IEEE80211_AUTH_AUTO); } - if (!conf->wpa && !conf->ieee802_1x) { - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); + if (!params->wpa && !params->ieee802_1x) { + wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled", + __func__); return -1; } - if (conf->wpa && set80211param(drv, IEEE80211_IOC_WPA, conf->wpa)) { - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); + if (params->wpa && set80211param(priv,IEEE80211_IOC_WPA, params->wpa)) { + wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state", + __func__); return -1; } if (set80211param(priv, IEEE80211_IOC_AUTHMODE, - (conf->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { - hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER, - HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); + (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { + wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X", + __func__); return -1; } return 0; } static int -bsd_set_privacy(const char *ifname, void *priv, int enabled) +bsd_set_privacy(void *priv, int enabled) { - struct bsd_driver_data *drv = priv; - struct hostapd_data *hapd = drv->hapd; - wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled); return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled); @@ -238,9 +227,9 @@ bsd_sta_set_flags(void *priv, const u8 * int flags_or, int flags_and) { /* For now, only support setting Authorized flag */ - if (flags_or & WLAN_STA_AUTHORIZED) + if (flags_or & WPA_STA_AUTHORIZED) return bsd_set_sta_authorized(priv, addr, 1); - if (!(flags_and & WLAN_STA_AUTHORIZED)) + if (!(flags_and & WPA_STA_AUTHORIZED)) return bsd_set_sta_authorized(priv, addr, 0); return 0; } @@ -267,53 +256,64 @@ bsd_del_key(void *priv, const unsigned c } static int -bsd_set_key(const char *ifname, void *priv, const char *alg, - const u8 *addr, int key_idx, - const u8 *key, size_t key_len, int txkey) +bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, + const unsigned char *addr, int key_idx, int set_tx, const u8 *seq, + size_t seq_len, const u8 *key, size_t key_len) { - struct bsd_driver_data *drv = priv; - struct hostapd_data *hapd = drv->hapd; struct ieee80211req_key wk; - u_int8_t cipher; - if (strcmp(alg, "none") == 0) - return bsd_del_key(priv, addr, key_idx); + wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d " + "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx, + set_tx, seq_len, key_len); - wpa_printf(MSG_DEBUG, "%s: alg=%s addr=%s key_idx=%d\n", - __func__, alg, ether_sprintf(addr), key_idx); + if (alg == WPA_ALG_NONE) { + return bsd_del_key(priv, addr, key_idx); + } - if (strcmp(alg, "WEP") == 0) - cipher = IEEE80211_CIPHER_WEP; - else if (strcmp(alg, "TKIP") == 0) - cipher = IEEE80211_CIPHER_TKIP; - else if (strcmp(alg, "CCMP") == 0) - cipher = IEEE80211_CIPHER_AES_CCM; - else { - printf("%s: unknown/unsupported algorithm %s\n", - __func__, alg); + os_memset(&wk, 0, sizeof(wk)); + switch (alg) { + case WPA_ALG_WEP: + wk.ik_type = IEEE80211_CIPHER_WEP; + break; + case WPA_ALG_TKIP: + wk.ik_type = IEEE80211_CIPHER_TKIP; + break; + case WPA_ALG_CCMP: + wk.ik_type = IEEE80211_CIPHER_AES_CCM; + break; + default: + wpa_printf(MSG_ERROR, "%s: unknown alg=%d", __func__, alg); return -1; } - if (key_len > sizeof(wk.ik_keydata)) { - printf("%s: key length %d too big\n", __func__, key_len); - return -3; - } + wk.ik_flags = IEEE80211_KEY_RECV; + if (set_tx) + wk.ik_flags |= IEEE80211_KEY_XMIT; - memset(&wk, 0, sizeof(wk)); - wk.ik_type = cipher; if (addr == NULL) { - memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); + os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); wk.ik_keyix = key_idx; - wk.ik_flags = IEEE80211_KEY_XMIT - | IEEE80211_KEY_GROUP - | IEEE80211_KEY_DEFAULT; } else { - memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); - wk.ik_keyix = IEEE80211_KEYIX_NONE; - wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; + os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); + /* + * Deduce whether group/global or unicast key by checking + * the address (yech). Note also that we can only mark global + * keys default; doing this for a unicast key is an error. + */ + if (os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", + IEEE80211_ADDR_LEN) == 0) { + wk.ik_flags |= IEEE80211_KEY_GROUP; + wk.ik_keyix = key_idx; + } else { + wk.ik_keyix = key_idx == 0 ? IEEE80211_KEYIX_NONE : + key_idx; + } } + if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) + wk.ik_flags |= IEEE80211_KEY_DEFAULT; wk.ik_keylen = key_len; - memcpy(wk.ik_keydata, key, key_len); + os_memcpy(&wk.ik_keyrsc, seq, seq_len); + os_memcpy(wk.ik_keydata, key, key_len); return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); } @@ -355,7 +355,7 @@ bsd_flush(void *priv) u8 allsta[IEEE80211_ADDR_LEN]; memset(allsta, 0xff, IEEE80211_ADDR_LEN); - return bsd_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE); + return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE); } @@ -393,7 +393,7 @@ bsd_sta_clear_stats(void *priv, const u8 } static int -bsd_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len) +bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) { struct bsd_driver_data *drv = priv; struct hostapd_data *hapd = drv->hapd; @@ -416,7 +416,7 @@ bsd_set_opt_ie(const char *ifname, void } static int -bsd_sta_deauth(void *priv, const u8 *addr, int reason_code) +bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code) { struct bsd_driver_data *drv = priv; struct hostapd_data *hapd = drv->hapd; @@ -432,7 +432,7 @@ bsd_sta_deauth(void *priv, const u8 *add } static int -bsd_sta_disassoc(void *priv, const u8 *addr, int reason_code) +bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, int reason_code) { struct bsd_driver_data *drv = priv; struct hostapd_data *hapd = drv->hapd; @@ -446,85 +446,32 @@ bsd_sta_disassoc(void *priv, const u8 *a return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); } -static int -bsd_del_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) -{ - struct hostapd_data *hapd = drv->hapd; - struct hostapd_bss_config *conf = hapd->conf; - struct sta_info *sta; - - hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_INFO, "deassociated"); - - sta = ap_get_sta(hapd, addr); - if (sta != NULL) { - sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); - if (conf->wpa) - wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); - sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; - ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); - ap_free_sta(hapd, sta); - } - return 0; -} - -static int -bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) +static void +bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN]) { - struct hostapd_data *hapd = drv->hapd; - struct hostapd_bss_config *conf = hapd->conf; - struct sta_info *sta; struct ieee80211req_wpaie ie; - int new_assoc, ielen, res; - - hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211, - HOSTAPD_LEVEL_INFO, "associated"); + int ielen = 0; + u8 *iebuf = NULL; - sta = ap_sta_add(hapd, addr); - if (sta == NULL) - return -1; /* * Fetch and validate any negotiated WPA/RSN parameters. */ - if (conf->wpa) { - memset(&ie, 0, sizeof(ie)); - memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); - if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) { - printf("Failed to get WPA/RSN information element.\n"); - return -1; /* XXX not right */ - } - if (ie.wpa_ie[1] == 0) { - printf("No WPA/RSN information element for station!\n"); - return -1; /* XXX not right */ - } - if (sta->wpa_sm == NULL) - sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, - sta->addr); - if (sta->wpa_sm == NULL) { - printf("Failed to initialize WPA state machine\n"); - return -1; - } - ielen = 2 + ie.wpa_ie[1]; - res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, - ie.wpa_ie, ielen, NULL, 0); - if (res != WPA_IE_OK) { - printf("WPA/RSN information element rejected? " - "(res %u)\n", res); - return -1; - } - } + memset(&ie, 0, sizeof(ie)); + memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); + if (get80211var(priv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) { + printf("Failed to get WPA/RSN information element.\n"); + goto no_ie; + } + iebuf = ie.wpa_ie; + ielen = ie.wpa_ie[1]; + if (ielen == 0) + iebuf = NULL; + else + ielen += 2; - /* - * Now that the internal station state is setup - * kick the authenticator into action. - */ - new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; - sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; - wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); - hostapd_new_assoc_sta(hapd, sta, !new_assoc); - ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); +no_ie: + drv_event_assoc(ctx, addr, iebuf, ielen); - return 0; } #include @@ -545,6 +492,7 @@ bsd_wireless_event_receive(int sock, voi struct ieee80211_auth_event *auth; #endif int n; + union wpa_event_data data; n = read(sock, buf, sizeof(buf)); if (n < 0) { @@ -576,14 +524,14 @@ bsd_wireless_event_receive(int sock, voi break; case RTM_IEEE80211_LEAVE: leave = (struct ieee80211_leave_event *) &ifan[1]; - bsd_del_sta(drv, leave->iev_addr); + drv_event_disassoc(drv->hapd, leave->iev_addr); break; case RTM_IEEE80211_JOIN: #ifdef RTM_IEEE80211_REJOIN case RTM_IEEE80211_REJOIN: #endif join = (struct ieee80211_join_event *) &ifan[1]; - bsd_new_sta(drv, join->iev_addr); + bsd_new_sta(drv, drv->hapd, join->iev_addr); break; case RTM_IEEE80211_REPLAY: /* ignore */ @@ -594,9 +542,13 @@ bsd_wireless_event_receive(int sock, voi "Michael MIC failure wireless event: " "keyix=%u src_addr=" MACSTR, mic->iev_keyix, MAC2STR(mic->iev_src)); - ieee80211_michael_mic_failure(hapd, mic->iev_src, 1); + os_memset(&data, 0, sizeof(data)); + data.michael_mic_failure.unicast = 1; + data.michael_mic_failure.src = mic->iev_src; + wpa_supplicant_event(drv->hapd, + EVENT_MICHAEL_MIC_FAILURE, &data); break; -#ifdef CONFIG_DRIVER_RADIUS_ACL +#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET case RTM_IEEE80211_AUTH: auth = (struct ieee80211_auth_event *) &ifan[1]; wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR, @@ -628,41 +580,9 @@ bsd_wireless_event_receive(int sock, voi } static int -bsd_wireless_event_init(void *priv) -{ - struct bsd_driver_data *drv = priv; - int s; - - drv->wext_sock = -1; - - s = socket(PF_ROUTE, SOCK_RAW, 0); - if (s < 0) { - perror("socket(PF_ROUTE,SOCK_RAW)"); - return -1; - } - eloop_register_read_sock(s, bsd_wireless_event_receive, drv, NULL); - drv->wext_sock = s; - - return 0; -} - -static void -bsd_wireless_event_deinit(void *priv) -{ - struct bsd_driver_data *drv = priv; - - if (drv != NULL) { - if (drv->wext_sock < 0) - return; - eloop_unregister_read_sock(drv->wext_sock); - close(drv->wext_sock); - } -} - - -static int bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, int encrypt, const u8 *own_addr) + { struct bsd_driver_data *drv = priv; struct hostapd_data *hapd = drv->hapd; @@ -706,25 +626,14 @@ static void handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) { struct bsd_driver_data *drv = ctx; - struct hostapd_data *hapd = drv->hapd; - struct sta_info *sta; - - sta = ap_get_sta(hapd, src_addr); - if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { - printf("Data frame from not associated STA %s\n", - ether_sprintf(src_addr)); - /* XXX cannot happen */ - return; - } - ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr), - len - sizeof(struct l2_ethhdr)); + drv_event_eapol_rx(drv->hapd, src_addr, buf, len); } static int -bsd_get_ssid(const char *ifname, void *priv, u8 *buf, int len) +bsd_get_ssid(void *priv, u8 *buf, int len) { struct bsd_driver_data *drv = priv; - struct hostapd_data *hapd = drv->hapd; + int ssid_len = get80211var(priv, IEEE80211_IOC_SSID, buf, len); wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"\n", __func__, ssid_len, buf); @@ -733,7 +642,7 @@ bsd_get_ssid(const char *ifname, void *p } static int -bsd_set_ssid(const char *ifname, void *priv, const u8 *buf, int len) +bsd_set_ssid(void *priv, const u8 *buf, int len) { struct bsd_driver_data *drv = priv; struct hostapd_data *hapd = drv->hapd; @@ -752,7 +661,7 @@ bsd_set_countermeasures(void *priv, int return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled); } -#ifdef CONFIG_DRIVER_RADIUS_ACL +#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET static int bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted, u32 session_timeout) @@ -814,24 +723,23 @@ bsd_set_radius_acl_expire(void *priv, co #endif /* CONFIG_DRIVER_RADIUS_ACL */ static void * -bsd_init(struct hostapd_data *hapd) +bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) { struct bsd_driver_data *drv; - drv = malloc(sizeof(struct bsd_driver_data)); + drv = os_zalloc(sizeof(struct bsd_driver_data)); if (drv == NULL) { printf("Could not allocate memory for bsd driver data\n"); goto bad; } - memset(drv, 0, sizeof(*drv)); drv->hapd = hapd; drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->ioctl_sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } - memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface)); + memcpy(drv->iface, params->ifname, sizeof(drv->iface)); /* * NB: We require the interface name be mappable to an index. * This implies we do not support having wpa_supplicant @@ -849,10 +757,20 @@ bsd_init(struct hostapd_data *hapd) handle_read, drv, 1); if (drv->sock_xmit == NULL) goto bad; - if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr)) + if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) goto bad; - bsd_set_iface_flags(drv, -IFF_UP); /* mark down during setup */ + /* mark down during setup */ + if (bsd_set_iface_flags(drv, -IFF_UP) < 0) + goto bad; + + drv->route = socket(PF_ROUTE, SOCK_RAW, 0); + if (drv->route < 0) { + perror("socket(PF_ROUTE,SOCK_RAW)"); + goto bad; + } + eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv, + NULL); return drv; bad: @@ -872,6 +790,10 @@ bsd_deinit(void *priv) { struct bsd_driver_data *drv = priv; + if (drv->route >= 0) { + eloop_unregister_read_sock(drv->route); + close(drv->route); + } (void) bsd_set_iface_flags(drv, -IFF_UP); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); @@ -882,27 +804,25 @@ bsd_deinit(void *priv) const struct wpa_driver_ops wpa_driver_bsd_ops = { .name = "bsd", - .init = bsd_init, - .deinit = bsd_deinit, + .hapd_init = bsd_init, + .hapd_deinit = bsd_deinit, .set_ieee8021x = bsd_set_ieee8021x, .set_privacy = bsd_set_privacy, - .set_encryption = bsd_set_key, + .set_key = bsd_set_key, .get_seqnum = bsd_get_seqnum, .flush = bsd_flush, .set_generic_elem = bsd_set_opt_ie, - .wireless_event_init = bsd_wireless_event_init, - .wireless_event_deinit = bsd_wireless_event_deinit, .sta_set_flags = bsd_sta_set_flags, .read_sta_data = bsd_read_sta_driver_data, - .send_eapol = bsd_send_eapol, + .hapd_send_eapol = bsd_send_eapol, .sta_disassoc = bsd_sta_disassoc, .sta_deauth = bsd_sta_deauth, - .set_ssid = bsd_set_ssid, - .get_ssid = bsd_get_ssid, + .hapd_set_ssid = bsd_set_ssid, + .hapd_get_ssid = bsd_get_ssid, .set_countermeasures = bsd_set_countermeasures, .sta_clear_stats = bsd_sta_clear_stats, .commit = bsd_commit, -#ifdef CONFIG_DRIVER_RADIUS_ACL +#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET .set_radius_acl_auth = bsd_set_radius_acl_auth, .set_radius_acl_expire = bsd_set_radius_acl_expire, #endif Modified: head/usr.sbin/wpa/wpa_passphrase/Makefile ============================================================================== --- head/usr.sbin/wpa/wpa_passphrase/Makefile Wed Nov 3 10:43:38 2010 (r214734) +++ head/usr.sbin/wpa/wpa_passphrase/Makefile Wed Nov 3 10:44:25 2010 (r214735) @@ -5,7 +5,8 @@ .PATH.c:${WPA_SUPPLICANT_DISTDIR} PROG= wpa_passphrase -SRCS= wpa_passphrase.c sha1.c md5.c +SRCS= wpa_passphrase.c sha1.c sha1-internal.c sha1-pbkdf2.c \ + md5.c md5-internal.c CFLAGS+= -DINTERNAL_SHA1 CFLAGS+= -DINTERNAL_MD5 Modified: head/usr.sbin/wpa/wpa_supplicant/Makefile ============================================================================== --- head/usr.sbin/wpa/wpa_supplicant/Makefile Wed Nov 3 10:43:38 2010 (r214734) +++ head/usr.sbin/wpa/wpa_supplicant/Makefile Wed Nov 3 10:44:25 2010 (r214735) @@ -6,11 +6,15 @@ ${WPA_DISTDIR}/src/drivers \ ${WPA_DISTDIR}/src/eap_peer \ ${WPA_DISTDIR}/src/rsn_supp + ${WPA_DISTDIR}/src/crypto PROG= wpa_supplicant -SRCS= aes.c aes_wrap.c blacklist.c common.c config.c ctrl_iface.c \ +SRCS= aes-cbc.c aes-ctr.c aes-eax.c aes-encblock.c \ + aes-internal.c aes-omac1.c aes-unwrap.c \ + aes-wrap.c bss.c blacklist.c common.c config.c ctrl_iface.c \ ctrl_iface_unix.c drivers.c eloop.c events.c l2_packet_freebsd.c main.c\ - md5.c preauth.c pmksa_cache.c rc4.c scan.c scan_helpers.c sha1.c \ + md5.c notify.c preauth.c pmksa_cache.c scan.c \ + sha1-pbkdf2.c sha1-tlsprf.c sha1-tprf.c sha1.c \ wpa.c wpa_common.c wpa_debug.c wpa_ie.c wpa_supplicant.c \ wpabuf.c wpas_glue.c \ driver_ndis.c Packet32.c \ @@ -34,7 +38,7 @@ CFLAGS+= -DCONFIG_DRIVER_NDIS CFLAGS+= -DCONFIG_DRIVER_WIRED CFLAGS+= -DCONFIG_TERMINATE_ONLASTIF CFLAGS+= -DCONFIG_DEBUG_SYSLOG -CFLAGS+= -g +#CFLAGS+= -g DPADD+= ${LIBPCAP} LDADD+= -lpcap @@ -49,7 +53,7 @@ LDADD+=${WPA_SUPPLICANT_LDADD} #LDFLAGS+=${WPA_SUPPLICANT_LDFLAGS} .if ${MK_WPA_SUPPLICANT_EAPOL} != "no" -SRCS+= eapol_supp_sm.c eap.c eap_common.c eap_methods.c +SRCS+= eapol_supp_sm.c eap.c eap_common.c eap_methods.c eap_register.c CFLAGS+= -DIEEE8021X_EAPOL .if ${MK_OPENSSL} != "no" && !defined(RELEASE_CRUNCH) Modified: head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c ============================================================================== --- head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c Wed Nov 3 10:43:38 2010 (r214734) +++ head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c Wed Nov 3 10:44:25 2010 (r214735) @@ -220,7 +220,7 @@ wpa_driver_bsd_set_ssid(void *priv, cons static int wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv, - const char *wpa_ie, size_t wpa_ie_len) + const u8 *wpa_ie, size_t wpa_ie_len) { struct ieee80211req ireq; @@ -259,14 +259,6 @@ wpa_driver_bsd_set_wpa_internal(void *pr } static int -wpa_driver_bsd_set_wpa(void *priv, int enabled) -{ - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - - return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled); -} - -static int wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx, const unsigned char *addr) { @@ -290,7 +282,7 @@ wpa_driver_bsd_del_key(struct wpa_driver } static int -wpa_driver_bsd_set_key(void *priv, wpa_alg alg, +wpa_driver_bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, const unsigned char *addr, int key_idx, int set_tx, const u8 *seq, size_t seq_len, const u8 *key, size_t key_len) @@ -393,6 +385,26 @@ wpa_driver_bsd_set_drop_unencrypted(void } static int +wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg) +{ + struct wpa_driver_bsd_data *drv = priv; + int authmode; + + if ((auth_alg & WPA_AUTH_ALG_OPEN) && + (auth_alg & WPA_AUTH_ALG_SHARED)) + authmode = IEEE80211_AUTH_AUTO; + else if (auth_alg & WPA_AUTH_ALG_SHARED) + authmode = IEEE80211_AUTH_SHARED; + else + authmode = IEEE80211_AUTH_OPEN; + + wpa_printf(MSG_DEBUG, "%s alg 0x%x authmode %u", + __func__, auth_alg, authmode); + + return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode); +} + +static int wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code) { struct wpa_driver_bsd_data *drv = priv; @@ -452,6 +464,11 @@ wpa_driver_bsd_associate(void *priv, str return -1; } + if (wpa_driver_bsd_set_drop_unencrypted(drv, params->drop_unencrypted) + < 0) + return -1; + if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0) + return -1; /* XXX error handling is wrong but unclear what to do... */ if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) return -1; @@ -485,30 +502,11 @@ wpa_driver_bsd_associate(void *priv, str } static int -wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg) -{ - struct wpa_driver_bsd_data *drv = priv; - int authmode; - - if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) && - (auth_alg & AUTH_ALG_SHARED_KEY)) - authmode = IEEE80211_AUTH_AUTO; - else if (auth_alg & AUTH_ALG_SHARED_KEY) - authmode = IEEE80211_AUTH_SHARED; - else - authmode = IEEE80211_AUTH_OPEN; - - wpa_printf(MSG_DEBUG, "%s alg 0x%x authmode %u", - __func__, auth_alg, authmode); - - return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode); -} - -static int -wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len) +wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params) { struct wpa_driver_bsd_data *drv = priv; struct ieee80211_scan_req sr; + int i; int flags; /* XXX not true but easiest to perpetuate the myth */ @@ -529,30 +527,21 @@ wpa_driver_bsd_scan(void *priv, const u8 | IEEE80211_IOC_SCAN_NOJOIN ; sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER; - if (ssid_len != 0) { - /* XXX ssid_len must be <= IEEE80211_NWID_LEN */ - memcpy(sr.sr_ssid[sr.sr_nssid].ssid, ssid, ssid_len); - sr.sr_ssid[sr.sr_nssid].len = ssid_len; - sr.sr_nssid++; - } - if (drv->lastssid_len != 0 && - (drv->lastssid_len != ssid_len || - memcmp(drv->lastssid, ssid, ssid_len) != 0)) { - /* - * If we are scanning because we received a deauth - * and the scan cache is warm then we'll find the - * ap there and short circuit a full-blown scan. - */ - memcpy(sr.sr_ssid[sr.sr_nssid].ssid, drv->lastssid, - drv->lastssid_len); - sr.sr_ssid[sr.sr_nssid].len = drv->lastssid_len; - sr.sr_nssid++; - /* NB: clear so we don't retry w/o associating first */ - drv->lastssid_len = 0; - } - if (sr.sr_nssid != 0) /* NB: check scan cache first */ + if (params->num_ssids > 0) { + sr.sr_nssid = params->num_ssids; +#if 0 + /* Boundary check is done by upper layer */ + if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID) + sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID; +#endif + /* NB: check scan cache first */ sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK; - +} + for (i = 0; i < sr.sr_nssid; i++) { + sr.sr_ssid[i].len = params->ssids[i].ssid_len; + os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid, + sr.sr_ssid[i].len); + } /* NB: net80211 delivers a scan complete event so no need to poll */ return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr)); } @@ -654,40 +643,6 @@ wpa_driver_bsd_event_receive(int sock, v } } -/* Compare function for sorting scan results. Return >0 if @b is consider - * better. */ -static int -wpa_scan_result_compar(const void *a, const void *b) -{ - const struct wpa_scan_result *wa = a; - const struct wpa_scan_result *wb = b; - - /* WPA/WPA2 support preferred */ - if ((wb->wpa_ie_len || wb->rsn_ie_len) && - !(wa->wpa_ie_len || wa->rsn_ie_len)) - return 1; - if (!(wb->wpa_ie_len || wb->rsn_ie_len) && - (wa->wpa_ie_len || wa->rsn_ie_len)) - return -1; - - /* privacy support preferred */ - if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) && - (wb->caps & IEEE80211_CAPINFO_PRIVACY) == 0) - return 1; - if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) == 0 && - (wb->caps & IEEE80211_CAPINFO_PRIVACY)) - return -1; - - /* best/max rate preferred if signal level close enough XXX */ - if (wa->maxrate != wb->maxrate && abs(wb->level - wa->level) < 5) - return wb->maxrate - wa->maxrate; - - /* use freq for channel preference */ - - /* all things being equal, use signal level */ - return wb->level - wa->level; -} - static int getmaxrate(const uint8_t rates[15], uint8_t nrates) { @@ -715,74 +670,97 @@ iswpaoui(const u_int8_t *frm) return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); } -static int -wpa_driver_bsd_get_scan_results(void *priv, - struct wpa_scan_result *results, - size_t max_size) -{ -#define min(a,b) ((a)>(b)?(b):(a)) - struct wpa_driver_bsd_data *drv = priv; - uint8_t buf[24*1024]; - const uint8_t *cp, *vp; - const struct ieee80211req_scan_result *sr; - struct wpa_scan_result *wsr; - int len, ielen; - memset(results, 0, max_size * sizeof(struct wpa_scan_result)); +static void +wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res, + struct ieee80211req_scan_result *sr) +{ + struct wpa_scan_res *result, **tmp; + size_t extra_len; + u8 *pos; + + extra_len = 2 + sr->isr_ssid_len; + extra_len += 2 + sr->isr_nrates; + extra_len += 3; /* ERP IE */ + extra_len += sr->isr_ie_len; + + result = os_zalloc(sizeof(*result) + extra_len); + if (result == NULL) + return; + os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN); + result->freq = sr->isr_freq; + result->beacon_int = sr->isr_intval; + result->caps = sr->isr_capinfo; + result->qual = sr->isr_rssi; + result->noise = sr->isr_noise; + + pos = (u8 *)(result + 1); + + *pos++ = WLAN_EID_SSID; + *pos++ = sr->isr_ssid_len; + os_memcpy(pos, sr + 1, sr->isr_ssid_len); + pos += sr->isr_ssid_len; + + /* + * Deal all rates as supported rate. + * Because net80211 doesn't report extended supported rate or not. + */ + *pos++ = WLAN_EID_SUPP_RATES; + *pos++ = sr->isr_nrates; + os_memcpy(pos, sr->isr_rates, sr->isr_nrates); + pos += sr->isr_nrates; + + *pos++ = WLAN_EID_ERP_INFO; + *pos++ = 1; + *pos++ = sr->isr_erp; + + os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len); + pos += sr->isr_ie_len; + + result->ie_len = pos - (u8 *)(result + 1); + + tmp = os_realloc(res->res, + (res->num + 1) * sizeof(struct wpa_scan_res *)); + if (tmp == NULL) { + os_free(result); + return; + } + tmp[res->num++] = result; + res->res = tmp; +} + +static struct wpa_scan_results * +wpa_driver_bsd_get_scan_results2(void *priv) +{ + struct ieee80211req_scan_result *sr; + struct wpa_scan_results *res; + int len, rest; + uint8_t buf[24*1024], *pos; - len = get80211var(drv, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf)); + len = get80211var(priv, IEEE80211_IOC_SCAN_RESULTS, buf, 24*1024); if (len < 0) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***