aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/wpa/hostapd/Makefile38
-rw-r--r--usr.sbin/wpa/hostapd/driver_freebsd.c368
-rw-r--r--usr.sbin/wpa/wpa_passphrase/Makefile3
-rw-r--r--usr.sbin/wpa/wpa_supplicant/Makefile12
-rw-r--r--usr.sbin/wpa/wpa_supplicant/driver_freebsd.c277
5 files changed, 306 insertions, 392 deletions
diff --git a/usr.sbin/wpa/hostapd/Makefile b/usr.sbin/wpa/hostapd/Makefile
index db9b1d35360d..55a1e061185e 100644
--- a/usr.sbin/wpa/hostapd/Makefile
+++ b/usr.sbin/wpa/hostapd/Makefile
@@ -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}
diff --git a/usr.sbin/wpa/hostapd/driver_freebsd.c b/usr.sbin/wpa/hostapd/driver_freebsd.c
index 89d00513f439..81af8c084380 100644
--- a/usr.sbin/wpa/hostapd/driver_freebsd.c
+++ b/usr.sbin/wpa/hostapd/driver_freebsd.c
@@ -14,12 +14,13 @@
*
* $FreeBSD$
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
+#include "includes.h"
#include <sys/ioctl.h>
-#include <errno.h>
+
+#include "common.h"
+#include "driver.h"
+#include "eloop.h"
+#include "common/ieee802_11_defs.h"
#include <sys/socket.h>
#include <net/if.h>
@@ -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 */
-
- 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 */
+ struct hostapd_data *hapd; /* back pointer */
+
+ 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__, params->enabled);
- wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, 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 *addr, int total_flags,
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 char *addr, int key_idx)
}
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)
+ 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);
+
+ if (alg == WPA_ALG_NONE) {
return bsd_del_key(priv, addr, key_idx);
+ }
- wpa_printf(MSG_DEBUG, "%s: alg=%s addr=%s key_idx=%d\n",
- __func__, alg, ether_sprintf(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 *addr)
}
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 *priv, const u8 *ie, size_t ie_len)
}
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 *addr, int reason_code)
}
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 *addr, int reason_code)
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;
+ int ielen = 0;
+ u8 *iebuf = NULL;
- hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_INFO, "associated");
-
- 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 <net/route.h>
@@ -545,6 +492,7 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
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, void *ctx, void *sock_ctx)
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, void *ctx, void *sock_ctx)
"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, void *ctx, void *sock_ctx)
}
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 *priv, u8 *buf, int len)
}
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 enabled)
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, const u8 *mac)
#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
diff --git a/usr.sbin/wpa/wpa_passphrase/Makefile b/usr.sbin/wpa/wpa_passphrase/Makefile
index 027f1a1e4462..385e23ca2d44 100644
--- a/usr.sbin/wpa/wpa_passphrase/Makefile
+++ b/usr.sbin/wpa/wpa_passphrase/Makefile
@@ -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
diff --git a/usr.sbin/wpa/wpa_supplicant/Makefile b/usr.sbin/wpa/wpa_supplicant/Makefile
index 2eb57e147706..52c23ebd85a7 100644
--- a/usr.sbin/wpa/wpa_supplicant/Makefile
+++ b/usr.sbin/wpa/wpa_supplicant/Makefile
@@ -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)
diff --git a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
index a9c86a6a16f3..0ac3c506d10c 100644
--- a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
+++ b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
@@ -220,7 +220,7 @@ wpa_driver_bsd_set_ssid(void *priv, const char *ssid,
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 *priv, int wpa, int privacy)
}
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_bsd_data *drv, int key_idx,
}
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 *priv, int enabled)
}
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, struct wpa_driver_associate_params *params)
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, struct wpa_driver_associate_params *params)
}
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 *ssid, size_t ssid_len)
| 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, void *ctx, void *sock_ctx)
}
}
-/* 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)
+
+static void
+wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
+ struct ieee80211req_scan_result *sr)
{
-#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;
+ 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;
+}
- memset(results, 0, max_size * sizeof(struct wpa_scan_result));
+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)
- return -1;
- cp = buf;
- wsr = results;
- while (len >= sizeof(struct ieee80211req_scan_result)) {
- sr = (const struct ieee80211req_scan_result *) cp;
- memcpy(wsr->bssid, sr->isr_bssid, IEEE80211_ADDR_LEN);
- wsr->ssid_len = sr->isr_ssid_len;
- wsr->freq = sr->isr_freq;
- wsr->noise = sr->isr_noise;
- wsr->qual = sr->isr_rssi;
- wsr->level = 0; /* XXX? */
- wsr->caps = sr->isr_capinfo;
- wsr->maxrate = getmaxrate(sr->isr_rates, sr->isr_nrates);
- vp = ((u_int8_t *)sr) + sr->isr_ie_off;
- memcpy(wsr->ssid, vp, sr->isr_ssid_len);
- if (sr->isr_ie_len > 0) {
- vp += sr->isr_ssid_len;
- ielen = sr->isr_ie_len;
- while (ielen > 0) {
- switch (vp[0]) {
- case IEEE80211_ELEMID_VENDOR:
- if (!iswpaoui(vp))
- break;
- wsr->wpa_ie_len =
- min(2+vp[1], SSID_MAX_WPA_IE_LEN);
- memcpy(wsr->wpa_ie, vp, wsr->wpa_ie_len);
- break;
- case IEEE80211_ELEMID_RSN:
- wsr->rsn_ie_len =
- min(2+vp[1], SSID_MAX_WPA_IE_LEN);
- memcpy(wsr->rsn_ie, vp, wsr->rsn_ie_len);
- break;
- }
- ielen -= 2+vp[1];
- vp += 2+vp[1];
- }
- }
+ return NULL;
+
+ res = os_zalloc(sizeof(*res));
+ if (res == NULL)
+ return NULL;
- cp += sr->isr_len, len -= sr->isr_len;
- wsr++;
+ pos = buf;
+ rest = len;
+ while (rest >= sizeof(struct ieee80211req_scan_result)) {
+ sr = (struct ieee80211req_scan_result *)pos;
+ wpa_driver_bsd_add_scan_entry(res, sr);
+ pos += sr->isr_len;
+ rest -= sr->isr_len;
}
- qsort(results, wsr - results, sizeof(struct wpa_scan_result),
- wpa_scan_result_compar);
- wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%d BSSes)",
- len, wsr - results);
+ wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%lu BSSes)",
+ len, (unsigned long)res->num);
- return wsr - results;
-#undef min
+ return (res);
}
+
#define GETPARAM(drv, param, v) \
(((v) = get80211param(drv, param)) != -1)
#define IEEE80211_C_BGSCAN 0x20000000
@@ -941,14 +919,11 @@ struct wpa_driver_ops wpa_driver_bsd_ops = {
.deinit = wpa_driver_bsd_deinit,
.get_bssid = wpa_driver_bsd_get_bssid,
.get_ssid = wpa_driver_bsd_get_ssid,
- .set_wpa = wpa_driver_bsd_set_wpa,
.set_key = wpa_driver_bsd_set_key,
.set_countermeasures = wpa_driver_bsd_set_countermeasures,
- .set_drop_unencrypted = wpa_driver_bsd_set_drop_unencrypted,
- .scan = wpa_driver_bsd_scan,
- .get_scan_results = wpa_driver_bsd_get_scan_results,
+ .scan2 = wpa_driver_bsd_scan,
+ .get_scan_results2 = wpa_driver_bsd_get_scan_results2,
.deauthenticate = wpa_driver_bsd_deauthenticate,
.disassociate = wpa_driver_bsd_disassociate,
.associate = wpa_driver_bsd_associate,
- .set_auth_alg = wpa_driver_bsd_set_auth_alg,
};