From 8e61a47dc66cd7ecd4fe3488997bfb72fbb1c971 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Thu, 25 Feb 2010 18:30:20 +0000 Subject: [PATCH] First try at porting wpa_supplicant. --- usr.sbin/802_11/wpa_supplicant/Makefile | 106 ++++++++-- usr.sbin/802_11/wpa_supplicant/Packet32.c | 60 +++++- usr.sbin/802_11/wpa_supplicant/Packet32.h | 5 +- .../802_11/wpa_supplicant/driver_dragonfly.c | 185 ++++++++++++++---- usr.sbin/802_11/wpa_supplicant/driver_wired.c | 185 ++++++++++++++++++ .../wpa_supplicant/driver_wired.c.patch | 34 ---- usr.sbin/802_11/wpa_supplicant/events.c.patch | 35 ---- usr.sbin/802_11/wpa_supplicant/ntddndis.h | 5 +- .../802_11/wpa_supplicant/wpa_supplicant.8 | 34 ++-- .../wpa_supplicant/wpa_supplicant.conf.5 | 25 ++- 10 files changed, 519 insertions(+), 155 deletions(-) create mode 100644 usr.sbin/802_11/wpa_supplicant/driver_wired.c delete mode 100644 usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch delete mode 100644 usr.sbin/802_11/wpa_supplicant/events.c.patch diff --git a/usr.sbin/802_11/wpa_supplicant/Makefile b/usr.sbin/802_11/wpa_supplicant/Makefile index 30534f321e..8d0a296f8e 100644 --- a/usr.sbin/802_11/wpa_supplicant/Makefile +++ b/usr.sbin/802_11/wpa_supplicant/Makefile @@ -1,12 +1,12 @@ -# $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/Makefile,v 1.9 2007/07/11 16:04:08 sam Exp $ -# $DragonFly: src/usr.sbin/802_11/wpa_supplicant/Makefile,v 1.2 2007/08/07 11:25:36 sephe Exp $ +# $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/Makefile 189263 2009-03-02 02:28:22Z sam $ +# $DragonFly$ .include "${.CURDIR}/../Makefile.inc" -.PATH.c: ${WPA_DISTDIR}/wpa_supplicant \ - ${WPA_DISTDIR}/src/drivers \ - ${WPA_DISTDIR}/src/eap_peer \ - ${WPA_DISTDIR}/src/rsn_supp +.PATH.c:${WPA_DISTDIR}/wpa_supplicant \ + ${WPA_DISTDIR}/src/drivers \ + ${WPA_DISTDIR}/src/eap_peer \ + ${WPA_DISTDIR}/src/rsn_supp PROG= wpa_supplicant SRCS= aes.c aes_wrap.c blacklist.c common.c config.c ctrl_iface.c \ @@ -20,13 +20,21 @@ SRCS= aes.c aes_wrap.c blacklist.c common.c config.c ctrl_iface.c \ MAN= wpa_supplicant.8 wpa_supplicant.conf.5 -CFLAGS+= -I${.CURDIR} -I${WPA_DISTDIR} -CFLAGS+= -I${WPA_DISTDIR}/src/drivers -CFLAGS+= -I${WPA_DISTDIR}/src/rsn_supp +#.if ${MK_EXAMPLES} != "no" +#FILESDIR= ${SHAREDIR}/examples/etc +#.PATH: ${WPA_SUPPLICANT_DISTDIR} +#FILES= wpa_supplicant.conf +#.endif + +CFLAGS+=-I${WPA_SUPPLICANT_DISTDIR} +CFLAGS+=-I${WPA_DISTDIR}/src/drivers +CFLAGS+=-I${WPA_DISTDIR}/src/rsn_supp + CFLAGS+= -DCONFIG_DRIVER_BSD CFLAGS+= -DCONFIG_DRIVER_NDIS CFLAGS+= -DCONFIG_DRIVER_WIRED CFLAGS+= -DCONFIG_TERMINATE_ONLASTIF +CFLAGS+= -DCONFIG_DEBUG_SYSLOG CFLAGS+= -g DPADD+= ${LIBPCAP} LDADD+= -lpcap @@ -35,17 +43,18 @@ LDADD+= -lpcap SRCS+= config_file.c base64.c CFLAGS+=-DCONFIG_BACKEND_FILE -.if !defined(NO_WPA_SUPPLICANT_EAPOL) -.PATH: ${.CURDIR}/.. ${WPA_DISTDIR}/src/eapol_supp -.PATH: ${.CURDIR}/.. ${WPA_DISTDIR}/src/eap_peer +# User customizations to the wpa_supplicant build environment +CFLAGS+=${WPA_SUPPLICANT_CFLAGS} +#DPADD+=${WPA_SUPPLICANT_DPADD} +LDADD+=${WPA_SUPPLICANT_LDADD} +#LDFLAGS+=${WPA_SUPPLICANT_LDFLAGS} + SRCS+= eapol_supp_sm.c eap.c eap_common.c eap_methods.c CFLAGS+= -DIEEE8021X_EAPOL .if !defined(NO_CRYPT) && !defined(NO_OPENSSL) -.PATH: ${.CURDIR}/.. ${WPA_DISTDIR}/src/eap_common -.PATH: ${.CURDIR}/.. ${WPA_DISTDIR}/eap_peer/ CFLAGS+=-DEAP_TLS -DEAP_PEAP -DEAP_MSCHAPv2 -DEAP_LEAP -DEAP_PSK \ - -DEAP_TLV -DEAP_TLS_FUNCS + -DEAP_TLV -DEAP_TLS_FUNCS -DEAP_TLS_OPENSSL SRCS+= chap.c crypto_openssl.c \ eap_leap.c \ eap_mschapv2.c \ @@ -61,16 +70,79 @@ SRCS+= eap_ttls.c eap_md5.c SRCS+= eap_gtc.c .endif +.if !empty(CFLAGS:M*-DEAP_OTP) +SRCS+= eap_otp.c +.endif + +.if !empty(CFLAGS:M*-DEAP_AKA) +NEED_SIM_COMMON= true +SRCS+= eap_aka.c +.endif + +.if !empty(CFLAGS:M*-DEAP_SIM) +NEED_SIM_COMMON= true +SRCS+= eap_sim.c +.endif + +.if defined(NEED_SIM_COMMON) +SRCS+= eap_sim_common.c + +# PC/SC interface for smartcards (USIM, GSM SIM) +# GSM/UMTS authentication algorithm (for EAP-SIM/EAP-AKA) +# NB: requires devel/pcsc-lite +# +# WPA_SUPPLICANT_CFLAGS=-DEAP_AKA -DPCSC_FUNCS -I/usr/local/include/PCSC +# WPA_SUPPLICANT_LDADD=-L/usr/local/lib +# +.if !empty(CFLAGS:M*-DPCSC_FUNCS) +SRCS+= pcsc_funcs.c +DPADD+=${LIBPTHREAD} +LDADD+=-lpcsclite -lpthread +.endif +.endif + +.if !empty(CFLAGS:M*-DEAP_GPSK) +CFLAGS+=-DEAP_GPSK_SHA256 +SRCS+= eap_gpsk.c eap_gpsk_common.c +NEED_SHA256= true +.endif + +.if !empty(CFLAGS:M*-DEAP_PAX) +SRCS+= eap_pax.c eap_pax_common.c +.endif + +.if !empty(CFLAGS:M*-DEAP_SAKE) +SRCS+= eap_sake.c eap_sake_common.c +.endif + # NB: requires patch to openssl #CFLAGS+= -DEAP_FAST #SRCS+= eap_fast.c -DPADD+= ${LIBSSL} ${LIBCRYPTO} -LDADD+= -lssl -lcrypto +NEED_LIBSSL= true .else +CFLAGS+= -DEAP_TLS_NONE SRCS+= tls_none.c .endif +# +# Configure crypto/cipher support. +# +# EAPOL support requires openssl in which case we use their +# cipher code. Otherwise we use our internal versions. +# +.if !defined(NEED_LIBSSL) +CFLAGS+= -DINTERNAL_AES +CFLAGS+= -DINTERNAL_SHA1 +CFLAGS+= -DINTERNAL_MD5 +.else +DPADD+= ${LIBSSL} ${LIBCRYPTO} +LDADD+= -lssl -lcrypto +.endif + +.if defined(NEED_SHA256) +CFLAGS+=-DINTERNAL_SHA256 +SRCS+= sha256.c .endif .include diff --git a/usr.sbin/802_11/wpa_supplicant/Packet32.c b/usr.sbin/802_11/wpa_supplicant/Packet32.c index 820b9147a9..1bda801e1a 100644 --- a/usr.sbin/802_11/wpa_supplicant/Packet32.c +++ b/usr.sbin/802_11/wpa_supplicant/Packet32.c @@ -29,10 +29,11 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/Packet32.c,v 1.4 2007/07/11 16:04:08 sam Exp $ - * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/Packet32.c,v 1.4 2008/11/12 21:44:59 swildner Exp $ + * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/Packet32.c 189220 2009-03-01 08:01:38Z sam $ + * $DragonFly$ */ + /* * This file implements a small portion of the Winpcap API for the * Windows NDIS interface in wpa_supplicant. It provides just enough @@ -48,7 +49,6 @@ #include #include #include - #include #include #include @@ -281,7 +281,7 @@ PacketGetAdapterNames(CHAR *namelist, ULONG *len) ifm = (struct if_msghdr *)next; if (ifm->ifm_type == RTM_IFINFO) { sdl = (struct sockaddr_dl *)(ifm + 1); - if (strnstr(sdl->sdl_data, "ndis", sdl->sdl_nlen)) { + if (strnstr(sdl->sdl_data, "wlan", sdl->sdl_nlen)) { if ((spc + sdl->sdl_nlen) > *len) { free(buf); return(FALSE); @@ -314,7 +314,7 @@ PacketGetAdapterNames(CHAR *namelist, ULONG *len) ifm = (struct if_msghdr *)next; if (ifm->ifm_type == RTM_IFINFO) { sdl = (struct sockaddr_dl *)(ifm + 1); - if (strnstr(sdl->sdl_data, "ndis", sdl->sdl_nlen)) { + if (strnstr(sdl->sdl_data, "wlan", sdl->sdl_nlen)) { if ((spc + sdl->sdl_nlen) > *len) { free(buf); return(FALSE); @@ -364,3 +364,53 @@ PacketCloseAdapter(void *iface) return; } + +#if __FreeBSD_version < 600000 + +/* + * The version of libpcap in FreeBSD 5.2.1 doesn't have these routines. + * Call me insane if you will, but I still run 5.2.1 on my laptop, and + * I'd like to use WPA there. + */ + +int +pcap_get_selectable_fd(pcap_t *p) +{ + return(pcap_fileno(p)); +} + +/* + * The old version of libpcap opens its BPF descriptor in read-only + * mode. We need to temporarily create a new one we can write to. + */ + +int +pcap_inject(pcap_t *p, const void *buf, size_t len) +{ + int fd; + int res, n = 0; + char device[sizeof "/dev/bpf0000000000"]; + struct ifreq ifr; + + /* + * Go through all the minors and find one that isn't in use. + */ + do { + (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); + fd = open(device, O_RDWR); + } while (fd < 0 && errno == EBUSY); + + if (fd == -1) + return(-1); + + bzero((char *)&ifr, sizeof(ifr)); + ioctl(pcap_fileno(p), BIOCGETIF, (caddr_t)&ifr); + ioctl(fd, BIOCSETIF, (caddr_t)&ifr); + + res = write(fd, buf, len); + + close(fd); + + return(res); +} +#endif diff --git a/usr.sbin/802_11/wpa_supplicant/Packet32.h b/usr.sbin/802_11/wpa_supplicant/Packet32.h index 17e2535691..3415c18ddc 100644 --- a/usr.sbin/802_11/wpa_supplicant/Packet32.h +++ b/usr.sbin/802_11/wpa_supplicant/Packet32.h @@ -29,15 +29,14 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/Packet32.h,v 1.2.2.1 2005/10/27 17:06:47 wpaul Exp $ - * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/Packet32.h,v 1.1 2006/06/24 07:29:44 sephe Exp $ + * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/Packet32.h 151517 2005-10-20 16:49:31Z wpaul $ + * $DragonFly$ */ #ifndef _PACKET32_H_ #define _PACKET32_H_ #include -#include #include struct PACKET_OID_DATA { diff --git a/usr.sbin/802_11/wpa_supplicant/driver_dragonfly.c b/usr.sbin/802_11/wpa_supplicant/driver_dragonfly.c index 736fc4ac61..5c19a34b88 100644 --- a/usr.sbin/802_11/wpa_supplicant/driver_dragonfly.c +++ b/usr.sbin/802_11/wpa_supplicant/driver_dragonfly.c @@ -11,8 +11,8 @@ * * See README and COPYING for more details. * - * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c,v 1.14 2007/06/11 03:57:46 sam Exp $ - * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/driver_dragonfly.c,v 1.3 2008/01/19 07:03:55 sephe Exp $ + * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c 189263 2009-03-02 02:28:22Z sam $ + * $DragonFly$ */ #include @@ -23,7 +23,7 @@ #include #include "common.h" -#include "driver.h" +#include "drivers/driver.h" #include "eloop.h" #include "l2_packet.h" #include "ieee802_11_defs.h" @@ -32,8 +32,6 @@ #include #include -#include -#include #include struct wpa_driver_bsd_data { @@ -45,6 +43,11 @@ struct wpa_driver_bsd_data { 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 */ + int prev_scanvalid; /* scan valid to restore on deinit */ + uint8_t lastssid[IEEE80211_NWID_LEN]; + int lastssid_len; + uint32_t drivercaps; /* general driver capabilities */ + uint32_t cryptocaps; /* hardware crypto support */ }; static int @@ -131,7 +134,7 @@ getifflags(struct wpa_driver_bsd_data *drv, int *flags) perror("SIOCGIFFLAGS"); return errno; } - *flags = ifr.ifr_flags & 0xffff; + *flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); return 0; } @@ -143,6 +146,7 @@ setifflags(struct wpa_driver_bsd_data *drv, int flags) memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name)); ifr.ifr_flags = flags & 0xffff; + ifr.ifr_flagshigh = flags >> 16; if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) { perror("SIOCSIFFLAGS"); return errno; @@ -192,7 +196,21 @@ static int wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv, const char *wpa_ie, size_t wpa_ie_len) { - return set80211var(drv, IEEE80211_IOC_OPTIE, wpa_ie, wpa_ie_len); + struct ieee80211req ireq; + + memset(&ireq, 0, sizeof(ireq)); + strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); + ireq.i_type = IEEE80211_IOC_APPIE; + ireq.i_val = IEEE80211_APPIE_WPA; + ireq.i_len = wpa_ie_len; + ireq.i_data = (void *) wpa_ie; + if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { + fprintf(stderr, + "ioctl[IEEE80211_IOC_APPIE:IEEE80211_APPIE_WPA]: %s\n", + strerror(errno)); + return -1; + } + return 0; } static int @@ -255,7 +273,7 @@ wpa_driver_bsd_set_key(void *priv, wpa_alg alg, struct ieee80211req_key wk; struct ether_addr ea; char *alg_name; - uint8_t cipher; + u_int8_t cipher; if (alg == WPA_ALG_NONE) return wpa_driver_bsd_del_key(drv, key_idx, addr); @@ -281,11 +299,11 @@ wpa_driver_bsd_set_key(void *priv, wpa_alg alg, memcpy(&ea, addr, IEEE80211_ADDR_LEN); wpa_printf(MSG_DEBUG, - "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu", - __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx, - seq_len, key_len); + "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu", + __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx, + seq_len, key_len); - if (seq_len > sizeof(uint64_t)) { + if (seq_len > sizeof(u_int64_t)) { wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big", __func__, seq_len); return -2; @@ -348,6 +366,8 @@ wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code) struct wpa_driver_bsd_data *drv = priv; struct ieee80211req_mlme mlme; + drv->lastssid_len = 0; + wpa_printf(MSG_DEBUG, "%s", __func__); memset(&mlme, 0, sizeof(mlme)); mlme.im_op = IEEE80211_MLME_DEAUTH; @@ -362,6 +382,8 @@ wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code) struct wpa_driver_bsd_data *drv = priv; struct ieee80211req_mlme mlme; + drv->lastssid_len = 0; + wpa_printf(MSG_DEBUG, "%s", __func__); memset(&mlme, 0, sizeof(mlme)); mlme.im_op = IEEE80211_MLME_DISASSOC; @@ -414,6 +436,8 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) return -1; + memcpy(drv->lastssid, params->ssid, params->ssid_len); + drv->lastssid_len = params->ssid_len; return 0; } @@ -441,18 +465,53 @@ static int wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len) { struct wpa_driver_bsd_data *drv = priv; + struct ieee80211_scan_req sr; int flags; + /* XXX not true but easiest to perpetuate the myth */ /* NB: interface must be marked UP to do a scan */ - if (getifflags(drv, &flags) != 0 || setifflags(drv, flags | IFF_UP) != 0) + if (getifflags(drv, &flags) != 0) { + wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__); return -1; - - /* set desired ssid before scan */ - if (wpa_driver_bsd_set_ssid(drv, ssid, ssid_len) < 0) + } + if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) { + wpa_printf(MSG_DEBUG, "%s unable to mark interface UP", + __func__); return -1; + } + + memset(&sr, 0, sizeof(sr)); + sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE + | IEEE80211_IOC_SCAN_ONCE + | 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 */ + sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK; /* NB: net80211 delivers a scan complete event so no need to poll */ - return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0); + return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr)); } #include @@ -601,14 +660,14 @@ getmaxrate(const uint8_t rates[15], uint8_t nrates) /* unalligned little endian access */ #define LE_READ_4(p) \ - ((uint32_t) \ - ((((const uint8_t *)(p))[0] ) | \ - (((const uint8_t *)(p))[1] << 8) | \ - (((const uint8_t *)(p))[2] << 16) | \ - (((const uint8_t *)(p))[3] << 24))) + ((u_int32_t) \ + ((((const u_int8_t *)(p))[0] ) | \ + (((const u_int8_t *)(p))[1] << 8) | \ + (((const u_int8_t *)(p))[2] << 16) | \ + (((const u_int8_t *)(p))[3] << 24))) static int __inline -iswpaoui(const uint8_t *frm) +iswpaoui(const u_int8_t *frm) { return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); } @@ -641,9 +700,9 @@ wpa_driver_bsd_get_scan_results(void *priv, wsr->noise = sr->isr_noise; wsr->qual = sr->isr_rssi; wsr->level = 0; /* XXX? */ - wsr->caps = sr->isr_capinfo2; + wsr->caps = sr->isr_capinfo; wsr->maxrate = getmaxrate(sr->isr_rates, sr->isr_nrates); - vp = (uint8_t *)(sr+1); + 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; @@ -681,12 +740,34 @@ wpa_driver_bsd_get_scan_results(void *priv, #undef min } +#define GETPARAM(drv, param, v) \ + (((v) = get80211param(drv, param)) != -1) +#define IEEE80211_C_BGSCAN 0x20000000 + +/* + * Set the scan cache valid threshold to 1.5 x bg scan interval + * to force all scan requests to consult the cache unless they + * explicitly bypass it. + */ +static int +setscanvalid(struct wpa_driver_bsd_data *drv) +{ + int bgscan, scanvalid; + + if (!GETPARAM(drv, IEEE80211_IOC_SCANVALID, drv->prev_scanvalid) || + !GETPARAM(drv, IEEE80211_IOC_BGSCAN_INTERVAL, bgscan)) + return -1; + scanvalid = 3*bgscan/2; + return (drv->prev_scanvalid < scanvalid) ? + set80211param(drv, IEEE80211_IOC_SCANVALID, scanvalid) : 0; +} + static void * wpa_driver_bsd_init(void *ctx, const char *ifname) { -#define GETPARAM(drv, param, v) \ - (((v) = get80211param(drv, param)) != -1) struct wpa_driver_bsd_data *drv; + struct ieee80211_devcaps_req devcaps; + int flags; drv = malloc(sizeof(*drv)); if (drv == NULL) @@ -707,14 +788,31 @@ wpa_driver_bsd_init(void *ctx, const char *ifname) drv->sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->sock < 0) goto fail1; + drv->ctx = ctx; + strncpy(drv->ifname, ifname, sizeof(drv->ifname)); + + /* + * Mark the interface as down to ensure wpa_supplicant has exclusive + * access to the net80211 state machine, do this before opening the + * route socket to avoid a false event that the interface disappeared. + */ + if (getifflags(drv, &flags) == 0) + (void) setifflags(drv, flags &~ IFF_UP); + drv->route = socket(PF_ROUTE, SOCK_RAW, 0); if (drv->route < 0) goto fail; eloop_register_read_sock(drv->route, wpa_driver_bsd_event_receive, ctx, drv); - drv->ctx = ctx; - strncpy(drv->ifname, ifname, sizeof(drv->ifname)); + if (get80211var(drv, IEEE80211_IOC_DEVCAPS, &devcaps, sizeof(devcaps)) < 0) { + wpa_printf(MSG_DEBUG, + "%s: failed to get device capabilities: %s", + __func__, strerror(errno)); + goto fail; + } + drv->drivercaps = devcaps.dc_drivercaps; + drv->cryptocaps = devcaps.dc_cryptocaps; if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) { wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s", @@ -736,7 +834,18 @@ wpa_driver_bsd_init(void *ctx, const char *ifname) "roaming: %s", __func__, strerror(errno)); goto fail; } - + if (drv->drivercaps & IEEE80211_C_BGSCAN) { + /* + * Driver does background scanning; force the scan valid + * setting to 1.5 x bg scan interval so the scan cache is + * always consulted before we force a foreground scan. + */ + if (setscanvalid(drv) < 0) { + wpa_printf(MSG_DEBUG, + "%s: warning, failed to set scanvalid, scanning " + "may be suboptimal: %s", __func__, strerror(errno)); + } + } if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) { wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s", __func__, strerror(errno)); @@ -749,8 +858,8 @@ fail: fail1: free(drv); return NULL; -#undef GETPARAM } +#undef GETPARAM static void wpa_driver_bsd_deinit(void *priv) @@ -763,9 +872,17 @@ wpa_driver_bsd_deinit(void *priv) (void) setifflags(drv, flags &~ IFF_UP); wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); - if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) - wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state", - __func__); + if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) { + /* NB: don't whinge if device ejected or equivalent */ + if (errno != ENXIO) + wpa_printf(MSG_DEBUG, "%s: failed to restore roaming " + "state", __func__); + } + if (drv->drivercaps & IEEE80211_C_BGSCAN) { + /* XXX check return value */ + (void) set80211param(drv, IEEE80211_IOC_SCANVALID, + drv->prev_scanvalid); + } (void) close(drv->route); /* ioctl socket */ (void) close(drv->sock); /* event socket */ diff --git a/usr.sbin/802_11/wpa_supplicant/driver_wired.c b/usr.sbin/802_11/wpa_supplicant/driver_wired.c new file mode 100644 index 0000000000..ed9efb90f9 --- /dev/null +++ b/usr.sbin/802_11/wpa_supplicant/driver_wired.c @@ -0,0 +1,185 @@ +/* + * WPA Supplicant - wired Ethernet driver interface + * Copyright (c) 2005-2007, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/driver_wired.c 189263 2009-03-02 02:28:22Z sam $ + */ + +#include "includes.h" +#include +#include +#include + +#include "common.h" +#include "drivers/driver.h" +#include "wpa.h" + +static const u8 pae_group_addr[ETH_ALEN] = +{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; + +struct wpa_driver_wired_data { + int sock; + char ifname[IFNAMSIZ + 1]; + int multi; + int flags; + void *ctx; +}; + +static int +getifflags(struct wpa_driver_wired_data *drv, int *flags) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name)); + if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { + perror("SIOCGIFFLAGS"); + return errno; + } + *flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); + return 0; +} + +static int +setifflags(struct wpa_driver_wired_data *drv, int flags) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name)); + ifr.ifr_flags = flags & 0xffff; + ifr.ifr_flagshigh = flags >> 16; + if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) { + perror("SIOCSIFFLAGS"); + return errno; + } + return 0; +} + +static int +wpa_driver_wired_get_ssid(void *priv, u8 *ssid) +{ + ssid[0] = 0; + return 0; +} + +static int +wpa_driver_wired_get_bssid(void *priv, u8 *bssid) +{ + /* Report PAE group address as the "BSSID" for wired connection. */ + os_memcpy(bssid, pae_group_addr, ETH_ALEN); + return 0; +} + +static int +siocmulti(struct wpa_driver_wired_data *drv, int op, const u8 *addr) +{ + struct ifreq ifr; + struct sockaddr_dl *dlp; + + os_memset(&ifr, 0, sizeof(ifr)); + os_strncpy(ifr.ifr_name, drv->ifname, IFNAMSIZ); + dlp = (struct sockaddr_dl *) &ifr.ifr_addr; + dlp->sdl_len = sizeof(struct sockaddr_dl); + dlp->sdl_family = AF_LINK; + dlp->sdl_index = 0; + dlp->sdl_nlen = 0; + dlp->sdl_alen = ETH_ALEN; + dlp->sdl_slen = 0; + os_memcpy(LLADDR(dlp), addr, ETH_ALEN); + if (ioctl(drv->sock, op, (caddr_t) &ifr) < 0) { + wpa_printf(MSG_INFO, "ioctl[%s]: %s", op == SIOCADDMULTI ? + "SIOCADDMULTI" : "SIOCDELMULTI", strerror(errno)); + return -1; + } + return 0; +} + +static void * +wpa_driver_wired_init(void *ctx, const char *ifname) +{ + struct wpa_driver_wired_data *drv; + int flags; + + drv = os_zalloc(sizeof(*drv)); + if (drv == NULL) + return NULL; + os_strncpy(drv->ifname, ifname, sizeof(drv->ifname)); + drv->sock = socket(PF_INET, SOCK_DGRAM, 0); + if (drv->sock < 0) + goto fail1; + drv->ctx = ctx; + + if (getifflags(drv, &drv->flags) < 0) { + wpa_printf(MSG_INFO, "%s: Unable to get interface flags", + __func__); + goto fail; + } + flags = drv->flags | IFF_UP; /* NB: force interface up */ + + /* + * Arrange to receive PAE mcast frames. Try to add an + * explicit mcast address. If that fails, fallback to + * the all multicast mechanism. + */ + if (siocmulti(drv, SIOCADDMULTI, pae_group_addr) == 0) { + wpa_printf(MSG_DEBUG, "%s: Added PAE multicast address", + __func__); + drv->multi = 1; + } else if ((drv->flags & IFF_ALLMULTI) == 0) + flags |= IFF_ALLMULTI; + + if (flags != drv->flags) { + if (setifflags(drv, flags) < 0) { + wpa_printf(MSG_INFO, "%s: Failed to set interface flags", + __func__); + goto fail; + } + if ((flags ^ drv->flags) & IFF_ALLMULTI) + wpa_printf(MSG_DEBUG, "%s: Enabled all-multi mode", + __func__); + } + return drv; +fail: + close(drv->sock); +fail1: + free(drv); + return NULL; +} + +static void +wpa_driver_wired_deinit(void *priv) +{ + struct wpa_driver_wired_data *drv = priv; + + if (drv->multi) { + if (siocmulti(drv, SIOCDELMULTI, pae_group_addr) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE " + "multicast " "group (SIOCDELMULTI)", __func__); + } + } + if (setifflags(drv, drv->flags) < 0) { + wpa_printf(MSG_INFO, "%s: Failed to restore interface flags", + __func__); + } + (void) close(drv->sock); + os_free(drv); +} + +const struct wpa_driver_ops wpa_driver_wired_ops = { + .name = "wired", + .desc = "BSD wired Ethernet driver", + .get_ssid = wpa_driver_wired_get_ssid, + .get_bssid = wpa_driver_wired_get_bssid, + .init = wpa_driver_wired_init, + .deinit = wpa_driver_wired_deinit, +}; diff --git a/usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch b/usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch deleted file mode 100644 index b816b827e8..0000000000 --- a/usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch +++ /dev/null @@ -1,34 +0,0 @@ -$DragonFly: src/usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch,v 1.1 2007/08/07 11:25:37 sephe Exp $ -diff -urp wpa_supplicant-0.5.8/driver_wired.c /usr/src/contrib/wpa_supplicant-0.5.8/driver_wired.c ---- driver_wired.c 2007-05-29 08:41:52.000000000 +0800 -+++ driver_wired.c 2007-07-22 11:35:36.000000000 +0800 -@@ -18,9 +18,9 @@ - #ifdef __linux__ - #include - #endif /* __linux__ */ --#ifdef __FreeBSD__ -+#if defined(__FreeBSD__) || defined(__DragonFly__) - #include --#endif /* __FreeBSD__ */ -+#endif /* __FreeBSD__ || __DragonFly__ */ - - #include "common.h" - #include "driver.h" -@@ -119,7 +119,7 @@ static int wpa_driver_wired_multi(const - ifr.ifr_hwaddr.sa_family = AF_UNSPEC; - os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN); - #endif /* __linux__ */ --#ifdef __FreeBSD__ -+#if defined(__FreeBSD__) || defined(__DragonFly__) - { - struct sockaddr_dl *dlp; - dlp = (struct sockaddr_dl *) &ifr.ifr_addr; -@@ -131,7 +131,7 @@ static int wpa_driver_wired_multi(const - dlp->sdl_slen = 0; - os_memcpy(LLADDR(dlp), addr, ETH_ALEN); - } --#endif /* __FreeBSD__ */ -+#endif /* __FreeBSD__ || __DragonFly__ */ - - if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) { - perror("ioctl[SIOC{ADD/DEL}MULTI]"); diff --git a/usr.sbin/802_11/wpa_supplicant/events.c.patch b/usr.sbin/802_11/wpa_supplicant/events.c.patch deleted file mode 100644 index 2eb4914059..0000000000 --- a/usr.sbin/802_11/wpa_supplicant/events.c.patch +++ /dev/null @@ -1,35 +0,0 @@ -$DragonFly: src/usr.sbin/802_11/wpa_supplicant/events.c.patch,v 1.1 2007/08/07 11:25:37 sephe Exp $ -diff -urp wpa_supplicant-0.5.8/events.c /usr/src/contrib/wpa_supplicant-0.5.8/events.c ---- events.c 2007-05-29 08:39:51.000000000 +0800 -+++ events.c 2007-07-22 12:50:20.000000000 +0800 -@@ -802,6 +802,18 @@ wpa_supplicant_event_michael_mic_failure - } - - -+#ifdef CONFIG_TERMINATE_ONLASTIF -+static int any_interfaces(struct wpa_supplicant *head) -+{ -+ struct wpa_supplicant *wpa_s; -+ -+ for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next) -+ if (!wpa_s->interface_removed) -+ return 1; -+ return 0; -+} -+#endif /* CONFIG_TERMINATE_ONLASTIF */ -+ - static void - wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s, - union wpa_event_data *data) -@@ -826,6 +838,11 @@ wpa_supplicant_event_interface_status(st - wpa_supplicant_mark_disassoc(wpa_s); - l2_packet_deinit(wpa_s->l2); - wpa_s->l2 = NULL; -+#ifdef CONFIG_TERMINATE_ONLASTIF -+ /* check if last interface */ -+ if (!any_interfaces(wpa_s->global->ifaces)) -+ eloop_terminate(); -+#endif /* CONFIG_TERMINATE_ONLASTIF */ - break; - } - } diff --git a/usr.sbin/802_11/wpa_supplicant/ntddndis.h b/usr.sbin/802_11/wpa_supplicant/ntddndis.h index e6336b1973..905abb17eb 100644 --- a/usr.sbin/802_11/wpa_supplicant/ntddndis.h +++ b/usr.sbin/802_11/wpa_supplicant/ntddndis.h @@ -2,8 +2,7 @@ #define _NTDDNDIS_H_ /* - * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/ntddndis.h,v 1.2.2.1 2005/10/27 17:06:47 wpaul Exp $ - * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/ntddndis.h,v 1.1 2006/06/24 07:29:44 sephe Exp $ + * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/ntddndis.h 151517 2005-10-20 16:49:31Z wpaul $ */ /* @@ -28,7 +27,5 @@ typedef char * PCHAR; #define FALSE 0 #define OID_802_3_CURRENT_ADDRESS 0x01010102 -#define OID_802_3_MULTICAST_LIST 0x01010103 - #endif /* _NTDDNDIS_H_ */ diff --git a/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.8 b/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.8 index 37aab2a7e0..fb89507184 100644 --- a/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.8 +++ b/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.8 @@ -22,10 +22,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.8,v 1.2 2005/06/27 06:40:43 ru Exp $ -.\" $DragonFly: src/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.8,v 1.7 2008/03/09 11:04:35 swildner Exp $ +.\" $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.8 195644 2009-07-12 19:58:52Z sam $ +.\" $DragonFly$ .\" -.Dd July 22, 2007 +.Dd March 24, 2008 .Dt WPA_SUPPLICANT 8 .Os .Sh NAME @@ -33,10 +33,9 @@ .Nd "WPA/802.11i Supplicant for wireless network devices" .Sh SYNOPSIS .Nm -.Op Fl BdehLqvw +.Op Fl BdehLqsvw .Fl i Ar ifname .Fl c Ar config-file -.Op Fl N i Ar ifname Fl c Ar config-file ... .Sh DESCRIPTION The .Nm @@ -102,12 +101,20 @@ Show help text. Decrease debugging verbosity (i.e., counteract the use of the .Fl d flag). +.It Fl s +Send log messages through +.Xr syslog 3 +instead of to the terminal. .It Fl v Display version information on the terminal and exit. .It Fl w If the specified interface is not present, wait for it to be added; e.g.\& a cardbus device to be inserted. -This option is not normally used. +This option is not normally used; instead, +.Xr devd 8 +should be configured to launch +.Nm +when a device is created. .It Fl B Detach from the controlling terminal and run as a daemon process in the background. @@ -115,24 +122,21 @@ in the background. Include key information in debugging output. .It Fl L Display the license for this program on the terminal and exit. -.It Fl N i Ar ifname Fl c Ar config-file ... -Specify an additional interface and configuration file. -If multiple interfaces are specified then -.Nm -will manage them all with a single process. .El .Sh SEE ALSO -.Xr acx 4 , +.Xr an 4 , .Xr ath 4 , -.Xr bwi 4 , +.Xr ipw 4 , .Xr iwi 4 , -.Xr iwl 4 , .Xr ral 4 , .Xr rum 4 , .Xr ural 4 , .Xr wi 4 , .Xr wlan 4 , +.Xr wpi 4 , +.Xr zyd 4 , .Xr wpa_supplicant.conf 5 , +.Xr devd 8 , .Xr ifconfig 8 , .Xr wpa_cli 8 .Sh HISTORY @@ -144,7 +148,7 @@ utility first appeared in The .Nm utility was written by -.An Jouni Malinen Aq jkmaline@cc.hut.fi . +.An Jouni Malinen Aq j@w1.fi . This manual page is derived from the .Pa README file included in the diff --git a/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.conf.5 b/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.conf.5 index 7e6fadb356..62c792ae09 100644 --- a/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.conf.5 +++ b/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.conf.5 @@ -22,10 +22,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5,v 1.9 2007/07/11 16:04:08 sam Exp $ -.\" $DragonFly: src/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.conf.5,v 1.4 2007/08/07 11:25:37 sephe Exp $ +.\" $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5 195644 2009-07-12 19:58:52Z sam $ .\" -.Dd July 22, 2007 +.Dd July 8, 2007 .Dt WPA_SUPPLICANT.CONF 5 .Os .Sh NAME @@ -220,7 +219,11 @@ an 8-63 character passphrase. .Tn ASCII passphrases are dynamically converted to a 256-bit key at runtime -using the network SSID. +using the network SSID, or they can be statically converted at +configuration time using +the +.Xr wpa_passphrase 8 +utility. .It Va eapol_flags Dynamic WEP key usage for non-WPA mode, specified as a bit field. Bit 0 (1) forces dynamically generated unicast WEP keys to be used. @@ -236,10 +239,10 @@ used only as a Phase 2 method with EAP-PEAP or EAP-TTLS), used only as a Phase 2 method with EAP-PEAP or EAP-TTLS), .Li OTP (EAP-OTP, cannot be used with WPA; -used only as a Phase 2 method with EAP-PEAP or EAP-TTLS), +used only as a Phase 2 metod with EAP-PEAP or EAP-TTLS), .Li GTC (EAP-GTC, cannot be used with WPA; -used only as a Phase 2 method with EAP-PEAP or EAP-TTLS), +used only as a Phase 2 metod with EAP-PEAP or EAP-TTLS), .Li TLS (EAP-TLS, client and server certificate), .Li PEAP @@ -400,7 +403,7 @@ PAC is being provisioned or refreshed. Enable/disable EAP workarounds for various interoperability issues with misbehaving authentication servers. By default these workarounds are enabled. -String EAP conformance can be configured by setting this to 0. +Strict EAP conformance can be configured by setting this to 0. .El .Sh CERTIFICATES Some EAP authentication methods require use of certificates. @@ -515,8 +518,14 @@ network={ wep_key0=42FEEDDEAFBABEDEAFBEEFAA55 } .Ed +.Sh FILES +.Bl -tag -width ".Pa /usr/share/examples/etc/wpa_supplicant.conf" -compact +.It Pa /etc/wpa_supplicant.conf +.It Pa /usr/share/examples/etc/wpa_supplicant.conf +.El .Sh SEE ALSO .Xr wpa_cli 8 , +.Xr wpa_passphrase 8 , .Xr wpa_supplicant 8 .Sh HISTORY The @@ -533,4 +542,4 @@ and files in the .Nm wpa_supplicant distribution provided by -.An Jouni Malinen Aq jkmaline@cc.hut.fi . +.An Jouni Malinen Aq j@w1.fi . -- 2.41.0