-hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
- Authenticator and RADIUS authentication server
-================================================================
+wpa_supplicant and hostapd v0.6.x
+---------------------------------
Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved.
-This program is dual-licensed under both the GPL version 2 and BSD
+These program is dual-licensed under both the GPL version 2 and BSD
license. Either license may be used at your option.
+This package may include either wpa_supplicant, hostapd, or both. See
+README file respective subdirectories (wpa_supplicant/README or
+hostapd/README) for more details.
-License
--------
-
-GPL v2:
-
-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.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-(this copy of the license is in COPYING file)
-
-
-Alternatively, this software may be distributed, used, and modified
-under the terms of BSD license:
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-3. Neither the name(s) of the above-listed copyright holder(s) nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-
-Introduction
-============
-
-Originally, hostapd was an optional user space component for Host AP
-driver. It adds more features to the basic IEEE 802.11 management
-included in the kernel driver: using external RADIUS authentication
-server for MAC address based access control, IEEE 802.1X Authenticator
-and dynamic WEP keying, RADIUS accounting, WPA/WPA2 (IEEE 802.11i/RSN)
-Authenticator and dynamic TKIP/CCMP keying.
-
-The current version includes support for other drivers, an integrated
-EAP server (i.e., allow full authentication without requiring
-an external RADIUS authentication server), and RADIUS authentication
-server for EAP authentication.
-
-
-Requirements
-------------
-
-Current hardware/software requirements:
-- drivers:
- Host AP driver for Prism2/2.5/3.
- (http://hostap.epitest.fi/)
- Please note that station firmware version needs to be 1.7.0 or newer
- to work in WPA mode.
-
- madwifi driver for cards based on Atheros chip set (ar521x)
- (http://sourceforge.net/projects/madwifi/)
- Please note that you will need to add the correct path for
- madwifi driver root directory in .config (see defconfig file for
- an example: CFLAGS += -I<path>)
-
- Prism54 driver for Intersil/Conexant Prism GT/Duette/Indigo
- (http://www.prism54.org/)
-
- Any wired Ethernet driver for wired IEEE 802.1X authentication
- (experimental code)
-
- FreeBSD -current (with some kernel mods that have not yet been
- committed when hostapd v0.3.0 was released)
- BSD net80211 layer (e.g., Atheros driver)
-
-
-Build configuration
--------------------
-
-In order to be able to build hostapd, you will need to create a build
-time configuration file, .config that selects which optional
-components are included. See defconfig file for example configuration
-and list of available options.
-
-
-
-IEEE 802.1X
-===========
-
-IEEE Std 802.1X-2001 is a standard for port-based network access
-control. In case of IEEE 802.11 networks, a "virtual port" is used
-between each associated station and the AP. IEEE 802.11 specifies
-minimal authentication mechanism for stations, whereas IEEE 802.1X
-introduces a extensible mechanism for authenticating and authorizing
-users.
-
-IEEE 802.1X uses elements called Supplicant, Authenticator, Port
-Access Entity, and Authentication Server. Supplicant is a component in
-a station and it performs the authentication with the Authentication
-Server. An access point includes an Authenticator that relays the packets
-between a Supplicant and an Authentication Server. In addition, it has a
-Port Access Entity (PAE) with Authenticator functionality for
-controlling the virtual port authorization, i.e., whether to accept
-packets from or to the station.
-
-IEEE 802.1X uses Extensible Authentication Protocol (EAP). The frames
-between a Supplicant and an Authenticator are sent using EAP over LAN
-(EAPOL) and the Authenticator relays these frames to the Authentication
-Server (and similarly, relays the messages from the Authentication
-Server to the Supplicant). The Authentication Server can be colocated with the
-Authenticator, in which case there is no need for additional protocol
-for EAP frame transmission. However, a more common configuration is to
-use an external Authentication Server and encapsulate EAP frame in the
-frames used by that server. RADIUS is suitable for this, but IEEE
-802.1X would also allow other mechanisms.
-
-Host AP driver includes PAE functionality in the kernel driver. It
-is a relatively simple mechanism for denying normal frames going to
-or coming from an unauthorized port. PAE allows IEEE 802.1X related
-frames to be passed between the Supplicant and the Authenticator even
-on an unauthorized port.
-
-User space daemon, hostapd, includes Authenticator functionality. It
-receives 802.1X (EAPOL) frames from the Supplicant using the wlan#ap
-device that is also used with IEEE 802.11 management frames. The
-frames to the Supplicant are sent using the same device.
-
-The normal configuration of the Authenticator would use an external
-Authentication Server. hostapd supports RADIUS encapsulation of EAP
-packets, so the Authentication Server should be a RADIUS server, like
-FreeRADIUS (http://www.freeradius.org/). The Authenticator in hostapd
-relays the frames between the Supplicant and the Authentication
-Server. It also controls the PAE functionality in the kernel driver by
-controlling virtual port authorization, i.e., station-AP
-connection, based on the IEEE 802.1X state.
-
-When a station would like to use the services of an access point, it
-will first perform IEEE 802.11 authentication. This is normally done
-with open systems authentication, so there is no security. After
-this, IEEE 802.11 association is performed. If IEEE 802.1X is
-configured to be used, the virtual port for the station is set in
-Unauthorized state and only IEEE 802.1X frames are accepted at this
-point. The Authenticator will then ask the Supplicant to authenticate
-with the Authentication Server. After this is completed successfully,
-the virtual port is set to Authorized state and frames from and to the
-station are accepted.
-
-Host AP configuration for IEEE 802.1X
--------------------------------------
-
-The user space daemon has its own configuration file that can be used to
-define AP options. Distribution package contains an example
-configuration file (hostapd/hostapd.conf) that can be used as a basis
-for configuration. It includes examples of all supported configuration
-options and short description of each option. hostapd should be started
-with full path to the configuration file as the command line argument,
-e.g., './hostapd /etc/hostapd.conf'. If you have more that one wireless
-LAN card, you can use one hostapd process for multiple interfaces by
-giving a list of configuration files (one per interface) in the command
-line.
-
-hostapd includes a minimal co-located IEEE 802.1X server which can be
-used to test IEEE 802.1X authentication. However, it should not be
-used in normal use since it does not provide any security. This can be
-configured by setting ieee8021x and minimal_eap options in the
-configuration file.
-
-An external Authentication Server (RADIUS) is configured with
-auth_server_{addr,port,shared_secret} options. In addition,
-ieee8021x and own_ip_addr must be set for this mode. With such
-configuration, the co-located Authentication Server is not used and EAP
-frames will be relayed using EAPOL between the Supplicant and the
-Authenticator and RADIUS encapsulation between the Authenticator and
-the Authentication Server. Other than this, the functionality is similar
-to the case with the co-located Authentication Server.
-
-Authentication Server and Supplicant
-------------------------------------
-
-Any RADIUS server supporting EAP should be usable as an IEEE 802.1X
-Authentication Server with hostapd Authenticator. FreeRADIUS
-(http://www.freeradius.org/) has been successfully tested with hostapd
-Authenticator and both Xsupplicant (http://www.open1x.org) and Windows
-XP Supplicants. EAP/TLS was used with Xsupplicant and
-EAP/MD5-Challenge with Windows XP.
-
-http://www.missl.cs.umd.edu/wireless/eaptls/ has useful information
-about using EAP/TLS with FreeRADIUS and Xsupplicant (just replace
-Cisco access point with Host AP driver, hostapd daemon, and a Prism2
-card ;-). http://www.freeradius.org/doc/EAP-MD5.html has information
-about using EAP/MD5 with FreeRADIUS, including instructions for WinXP
-configuration. http://www.denobula.com/EAPTLS.pdf has a HOWTO on
-EAP/TLS use with WinXP Supplicant.
-
-Automatic WEP key configuration
--------------------------------
-
-EAP/TLS generates a session key that can be used to send WEP keys from
-an AP to authenticated stations. The Authenticator in hostapd can be
-configured to automatically select a random default/broadcast key
-(shared by all authenticated stations) with wep_key_len_broadcast
-option (5 for 40-bit WEP or 13 for 104-bit WEP). In addition,
-wep_key_len_unicast option can be used to configure individual unicast
-keys for stations. This requires support for individual keys in the
-station driver.
-
-WEP keys can be automatically updated by configuring rekeying. This
-will improve security of the network since same WEP key will only be
-used for a limited period of time. wep_rekey_period option sets the
-interval for rekeying in seconds.
-
-
-WPA/WPA2
-========
-
-Features
---------
-
-Supported WPA/IEEE 802.11i features:
-- WPA-PSK ("WPA-Personal")
-- WPA with EAP (e.g., with RADIUS authentication server) ("WPA-Enterprise")
-- key management for CCMP, TKIP, WEP104, WEP40
-- RSN/WPA2 (IEEE 802.11i), including PMKSA caching and pre-authentication
-
-WPA
----
-
-The original security mechanism of IEEE 802.11 standard was not
-designed to be strong and has proved to be insufficient for most
-networks that require some kind of security. Task group I (Security)
-of IEEE 802.11 working group (http://www.ieee802.org/11/) has worked
-to address the flaws of the base standard and has in practice
-completed its work in May 2004. The IEEE 802.11i amendment to the IEEE
-802.11 standard was approved in June 2004 and this amendment is likely
-to be published in July 2004.
-
-Wi-Fi Alliance (http://www.wi-fi.org/) used a draft version of the
-IEEE 802.11i work (draft 3.0) to define a subset of the security
-enhancements that can be implemented with existing wlan hardware. This
-is called Wi-Fi Protected Access<TM> (WPA). This has now become a
-mandatory component of interoperability testing and certification done
-by Wi-Fi Alliance. Wi-Fi provides information about WPA at its web
-site (http://www.wi-fi.org/OpenSection/protected_access.asp).
-
-IEEE 802.11 standard defined wired equivalent privacy (WEP) algorithm
-for protecting wireless networks. WEP uses RC4 with 40-bit keys,
-24-bit initialization vector (IV), and CRC32 to protect against packet
-forgery. All these choices have proven to be insufficient: key space is
-too small against current attacks, RC4 key scheduling is insufficient
-(beginning of the pseudorandom stream should be skipped), IV space is
-too small and IV reuse makes attacks easier, there is no replay
-protection, and non-keyed authentication does not protect against bit
-flipping packet data.
-
-WPA is an intermediate solution for the security issues. It uses
-Temporal Key Integrity Protocol (TKIP) to replace WEP. TKIP is a
-compromise on strong security and possibility to use existing
-hardware. It still uses RC4 for the encryption like WEP, but with
-per-packet RC4 keys. In addition, it implements replay protection,
-keyed packet authentication mechanism (Michael MIC).
-
-Keys can be managed using two different mechanisms. WPA can either use
-an external authentication server (e.g., RADIUS) and EAP just like
-IEEE 802.1X is using or pre-shared keys without need for additional
-servers. Wi-Fi calls these "WPA-Enterprise" and "WPA-Personal",
-respectively. Both mechanisms will generate a master session key for
-the Authenticator (AP) and Supplicant (client station).
-
-WPA implements a new key handshake (4-Way Handshake and Group Key
-Handshake) for generating and exchanging data encryption keys between
-the Authenticator and Supplicant. This handshake is also used to
-verify that both Authenticator and Supplicant know the master session
-key. These handshakes are identical regardless of the selected key
-management mechanism (only the method for generating master session
-key changes).
-
-
-IEEE 802.11i / WPA2
--------------------
-
-The design for parts of IEEE 802.11i that were not included in WPA has
-finished (May 2004) and this amendment to IEEE 802.11 was approved in
-June 2004. Wi-Fi Alliance is using the final IEEE 802.11i as a new
-version of WPA called WPA2. This includes, e.g., support for more
-robust encryption algorithm (CCMP: AES in Counter mode with CBC-MAC)
-to replace TKIP and optimizations for handoff (reduced number of
-messages in initial key handshake, pre-authentication, and PMKSA caching).
-
-Some wireless LAN vendors are already providing support for CCMP in
-their WPA products. There is no "official" interoperability
-certification for CCMP and/or mixed modes using both TKIP and CCMP, so
-some interoperability issues can be expected even though many
-combinations seem to be working with equipment from different vendors.
-Testing for WPA2 is likely to start during the second half of 2004.
-
-hostapd configuration for WPA/WPA2
-----------------------------------
-
-TODO
-
-# Enable WPA. Setting this variable configures the AP to require WPA (either
-# WPA-PSK or WPA-RADIUS/EAP based on other configuration). For WPA-PSK, either
-# wpa_psk or wpa_passphrase must be set and wpa_key_mgmt must include WPA-PSK.
-# For WPA-RADIUS/EAP, ieee8021x must be set (but without dynamic WEP keys),
-# RADIUS authentication server must be configured, and WPA-EAP must be included
-# in wpa_key_mgmt.
-# This field is a bit field that can be used to enable WPA (IEEE 802.11i/D3.0)
-# and/or WPA2 (full IEEE 802.11i/RSN):
-# bit0 = WPA
-# bit1 = IEEE 802.11i/RSN (WPA2)
-#wpa=1
-
-# WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit
-# secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase
-# (8..63 characters) that will be converted to PSK. This conversion uses SSID
-# so the PSK changes when ASCII passphrase is used and the SSID is changed.
-#wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
-#wpa_passphrase=secret passphrase
-
-# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
-# entries are separated with a space.
-#wpa_key_mgmt=WPA-PSK WPA-EAP
-
-# Set of accepted cipher suites (encryption algorithms) for pairwise keys
-# (unicast packets). This is a space separated list of algorithms:
-# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i]
-# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i]
-# Group cipher suite (encryption algorithm for broadcast and multicast frames)
-# is automatically selected based on this configuration. If only CCMP is
-# allowed as the pairwise cipher, group cipher will also be CCMP. Otherwise,
-# TKIP will be used as the group cipher.
-#wpa_pairwise=TKIP CCMP
-
-# Time interval for rekeying GTK (broadcast/multicast encryption keys) in
-# seconds.
-#wpa_group_rekey=600
-
-# Time interval for rekeying GMK (master key used internally to generate GTKs
-# (in seconds).
-#wpa_gmk_rekey=86400
-
-# Enable IEEE 802.11i/RSN/WPA2 pre-authentication. This is used to speed up
-# roaming be pre-authenticating IEEE 802.1X/EAP part of the full RSN
-# authentication and key handshake before actually associating with a new AP.
-#rsn_preauth=1
-#
-# Space separated list of interfaces from which pre-authentication frames are
-# accepted (e.g., 'eth0' or 'eth0 wlan0wds0'. This list should include all
-# interface that are used for connections to other APs. This could include
-# wired interfaces and WDS links. The normal wireless data interface towards
-# associated stations (e.g., wlan0) should not be added, since
-# pre-authentication is only used with APs other than the currently associated
-# one.
-#rsn_preauth_interfaces=eth0
+Source code files have been moved around in v0.6.x releases and
+compared to earlier releases, the programs are now build by first
+going to a subdirectory (wpa_supplicant or hostapd) and creating
+build configuration (.config) and running 'make' there (for
+Linux/BSD/cygwin builds).
+++ /dev/null
-.cvsignore
-ChangeLog
-Makefile
-defconfig
-developer.txt
-doc/.cvsignore
-doc/code_structure.doxygen
-doc/ctrl_iface.doxygen
-doc/doxygen.fast
-doc/doxygen.full
-doc/driver_wrapper.doxygen
-doc/eap.doxygen
-doc/hostapd.fig
-doc/kerneldoc2doxygen.pl
-doc/mainpage.doxygen
-doc/porting.doxygen
-driver_bsd.c
-driver_devicescape.c
-driver_madwifi.c
-driver_prism54.c
-driver_test.c
-eap_vendor_test.c
-hostapd.8
-hostapd_cli.1
-l2_packet_freebsd.c
-l2_packet_linux.c
-l2_packet_ndis.c
-l2_packet_none.c
-l2_packet_pcap.c
-l2_packet_winpcap.c
-logwatch/README
-logwatch/hostapd
-logwatch/hostapd.conf
-madwifi.conf
-nt_password_hash.c
-os_win32.c
--- /dev/null
+hostapd/.gitignore
+hostapd/Makefile
+hostapd/defconfig
+hostapd/doc/
+hostapd/eap_testing.txt
+hostapd/hostapd.8
+hostapd/hostapd.accept
+hostapd/hostapd.conf
+hostapd/hostapd.deny
+hostapd/hostapd.eap_user
+hostapd/hostapd.radius_clients
+hostapd/hostapd.sim_db
+hostapd/hostapd.vlan
+hostapd/hostapd.wpa_psk
+hostapd/hostapd_cli.1
+hostapd/logwatch/hostapd
+hostapd/logwatch/hostapd.conf
+hostapd/wired.conf
+src/Makefile
+src/common/Makefile
+src/crypto/Makefile
+src/drivers/Makefile
+src/drivers/driver_iphone.m
+src/drivers/driver_osx.m
+src/eap_common/Makefile
+src/eap_peer/Makefile
+src/eap_server/Makefile
+src/eapol_supp/Makefile
+src/hlr_auc_gw/Makefile
+src/hlr_auc_gw/hlr_auc_gw.milenage_db
+src/l2_packet/Makefile
+src/radius/Makefile
+src/rsn_supp/Makefile
+src/tls/Makefile
+src/utils/Makefile
+src/wps/Makefile
-Original source can be downloaded at:
-<http://hostap.epitest.fi/releases/hostapd-0.5.8.tar.gz>
+ HOSTAPD-0.6.10 AS USED BY DRAGONFLY
-A list of deleted files is in README.DELETED.
+ This directory contains a selected set of files from the
+ hostapd-6.10.tar.gz distribution. No files have been moved
+ or modified from their extracted position.
+
+ This distribution was downloaded from the following site:
+
+ http://hostap.epitest.fi/hostapd/
+
+ MD5 (hostapd-0.6.10.tar.gz) = 1ac442d1f984273f108b3de579c1b70d
+ SHA1 (hostapd-0.6.10.tar.gz) = 2cacf994abd3cebad36679d32f64c9e9906ccff8
+
+
+ DO NOT CREATE OR EDIT ANY FILES IN THIS DIRECTORY HIERARCHY! THIS
+ HIERARCHY REPRESENTS AN EXACT COPY, MINUS UNNEEDED FILES, OF THE
+ ORIGINAL ARCHIVE. All modifications are made on the master branch or in
+ src/usr.sbin/802_11.
+
+ The only additional files added to this directory are README.DRAGONFLY
+ and README.DELETED.
+
+ For mor information, check development(7).
+++ /dev/null
-/*
- * AES-based functions
- *
- * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
- * - One-Key CBC MAC (OMAC1) hash with AES-128
- * - AES-128 CTR mode encryption
- * - AES-128 EAX mode encryption/decryption
- * - AES-128 CBC
- *
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
- *
- * 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.
- */
-
-#ifndef AES_WRAP_H
-#define AES_WRAP_H
-
-int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher);
-int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain);
-int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac);
-int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
-int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
- u8 *data, size_t data_len);
-int aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
- const u8 *hdr, size_t hdr_len,
- u8 *data, size_t data_len, u8 *tag);
-int aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
- const u8 *hdr, size_t hdr_len,
- u8 *data, size_t data_len, const u8 *tag);
-int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data,
- size_t data_len);
-int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
- size_t data_len);
-
-#endif /* AES_WRAP_H */
+++ /dev/null
-/*
- * hostapd / Configuration file
- * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
- *
- * 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.
- */
-
-#include "includes.h"
-#ifndef CONFIG_NATIVE_WINDOWS
-#include <grp.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-#include "hostapd.h"
-#include "driver.h"
-#include "sha1.h"
-#include "eap.h"
-#include "radius_client.h"
-#include "wpa_common.h"
-
-
-#define MAX_STA_COUNT 2007
-
-
-static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
- const char *fname)
-{
- FILE *f;
- char buf[128], *pos, *pos2;
- int line = 0, vlan_id;
- struct hostapd_vlan *vlan;
-
- f = fopen(fname, "r");
- if (!f) {
- printf("VLAN file '%s' not readable.\n", fname);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- if (buf[0] == '*') {
- vlan_id = VLAN_ID_WILDCARD;
- pos = buf + 1;
- } else {
- vlan_id = strtol(buf, &pos, 10);
- if (buf == pos || vlan_id < 1 ||
- vlan_id > MAX_VLAN_ID) {
- printf("Invalid VLAN ID at line %d in '%s'\n",
- line, fname);
- fclose(f);
- return -1;
- }
- }
-
- while (*pos == ' ' || *pos == '\t')
- pos++;
- pos2 = pos;
- while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0')
- pos2++;
- *pos2 = '\0';
- if (*pos == '\0' || strlen(pos) > IFNAMSIZ) {
- printf("Invalid VLAN ifname at line %d in '%s'\n",
- line, fname);
- fclose(f);
- return -1;
- }
-
- vlan = malloc(sizeof(*vlan));
- if (vlan == NULL) {
- printf("Out of memory while reading VLAN interfaces "
- "from '%s'\n", fname);
- fclose(f);
- return -1;
- }
-
- memset(vlan, 0, sizeof(*vlan));
- vlan->vlan_id = vlan_id;
- strncpy(vlan->ifname, pos, sizeof(vlan->ifname));
- if (bss->vlan_tail)
- bss->vlan_tail->next = vlan;
- else
- bss->vlan = vlan;
- bss->vlan_tail = vlan;
- }
-
- fclose(f);
-
- return 0;
-}
-
-
-static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
-{
- struct hostapd_vlan *vlan, *prev;
-
- vlan = bss->vlan;
- prev = NULL;
- while (vlan) {
- prev = vlan;
- vlan = vlan->next;
- free(prev);
- }
-
- bss->vlan = NULL;
-}
-
-
-/* convert floats with one decimal place to value*10 int, i.e.,
- * "1.5" will return 15 */
-static int hostapd_config_read_int10(const char *value)
-{
- int i, d;
- char *pos;
-
- i = atoi(value);
- pos = strchr(value, '.');
- d = 0;
- if (pos) {
- pos++;
- if (*pos >= '0' && *pos <= '9')
- d = *pos - '0';
- }
-
- return i * 10 + d;
-}
-
-
-static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
-{
- bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
- bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
- bss->logger_syslog = (unsigned int) -1;
- bss->logger_stdout = (unsigned int) -1;
-
- bss->auth_algs = HOSTAPD_AUTH_OPEN | HOSTAPD_AUTH_SHARED_KEY;
-
- bss->wep_rekeying_period = 300;
- /* use key0 in individual key and key1 in broadcast key */
- bss->broadcast_key_idx_min = 1;
- bss->broadcast_key_idx_max = 2;
- bss->eap_reauth_period = 3600;
-
- bss->wpa_group_rekey = 600;
- bss->wpa_gmk_rekey = 86400;
- bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
- bss->wpa_pairwise = WPA_CIPHER_TKIP;
- bss->wpa_group = WPA_CIPHER_TKIP;
-
- bss->max_num_sta = MAX_STA_COUNT;
-
- bss->dtim_period = 2;
-
- bss->radius_server_auth_port = 1812;
- bss->ap_max_inactivity = AP_MAX_INACTIVITY;
- bss->eapol_version = EAPOL_VERSION;
-}
-
-
-static struct hostapd_config * hostapd_config_defaults(void)
-{
- struct hostapd_config *conf;
- struct hostapd_bss_config *bss;
- int i;
- const int aCWmin = 15, aCWmax = 1024;
- const struct hostapd_wme_ac_params ac_bk =
- { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
- const struct hostapd_wme_ac_params ac_be =
- { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
- const struct hostapd_wme_ac_params ac_vi = /* video traffic */
- { aCWmin >> 1, aCWmin, 2, 3000 / 32, 1 };
- const struct hostapd_wme_ac_params ac_vo = /* voice traffic */
- { aCWmin >> 2, aCWmin >> 1, 2, 1500 / 32, 1 };
-
- conf = wpa_zalloc(sizeof(*conf));
- bss = wpa_zalloc(sizeof(*bss));
- if (conf == NULL || bss == NULL) {
- printf("Failed to allocate memory for configuration data.\n");
- free(conf);
- free(bss);
- return NULL;
- }
-
- /* set default driver based on configuration */
- conf->driver = driver_lookup("default");
- if (conf->driver == NULL) {
- printf("No default driver registered!\n");
- free(conf);
- free(bss);
- return NULL;
- }
-
- bss->radius = wpa_zalloc(sizeof(*bss->radius));
- if (bss->radius == NULL) {
- free(conf);
- free(bss);
- return NULL;
- }
-
- hostapd_config_defaults_bss(bss);
-
- conf->num_bss = 1;
- conf->bss = bss;
-
- conf->beacon_int = 100;
- conf->rts_threshold = -1; /* use driver default: 2347 */
- conf->fragm_threshold = -1; /* user driver default: 2346 */
- conf->send_probe_response = 1;
- conf->bridge_packets = INTERNAL_BRIDGE_DO_NOT_CONTROL;
-
- memcpy(conf->country, "US ", 3);
-
- for (i = 0; i < NUM_TX_QUEUES; i++)
- conf->tx_queue[i].aifs = -1; /* use hw default */
-
- conf->wme_ac_params[0] = ac_be;
- conf->wme_ac_params[1] = ac_bk;
- conf->wme_ac_params[2] = ac_vi;
- conf->wme_ac_params[3] = ac_vo;
-
- return conf;
-}
-
-
-static int hostapd_parse_ip_addr(const char *txt, struct hostapd_ip_addr *addr)
-{
- if (inet_aton(txt, &addr->u.v4)) {
- addr->af = AF_INET;
- return 0;
- }
-
-#ifdef CONFIG_IPV6
- if (inet_pton(AF_INET6, txt, &addr->u.v6) > 0) {
- addr->af = AF_INET6;
- return 0;
- }
-#endif /* CONFIG_IPV6 */
-
- return -1;
-}
-
-
-int hostapd_mac_comp(const void *a, const void *b)
-{
- return memcmp(a, b, sizeof(macaddr));
-}
-
-
-int hostapd_mac_comp_empty(const void *a)
-{
- macaddr empty = { 0 };
- return memcmp(a, empty, sizeof(macaddr));
-}
-
-
-static int hostapd_config_read_maclist(const char *fname, macaddr **acl,
- int *num)
-{
- FILE *f;
- char buf[128], *pos;
- int line = 0;
- u8 addr[ETH_ALEN];
- macaddr *newacl;
-
- if (!fname)
- return 0;
-
- f = fopen(fname, "r");
- if (!f) {
- printf("MAC list file '%s' not found.\n", fname);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- if (hwaddr_aton(buf, addr)) {
- printf("Invalid MAC address '%s' at line %d in '%s'\n",
- buf, line, fname);
- fclose(f);
- return -1;
- }
-
- newacl = (macaddr *) realloc(*acl, (*num + 1) * ETH_ALEN);
- if (newacl == NULL) {
- printf("MAC list reallocation failed\n");
- fclose(f);
- return -1;
- }
-
- *acl = newacl;
- memcpy((*acl)[*num], addr, ETH_ALEN);
- (*num)++;
- }
-
- fclose(f);
-
- qsort(*acl, *num, sizeof(macaddr), hostapd_mac_comp);
-
- return 0;
-}
-
-
-static int hostapd_config_read_wpa_psk(const char *fname,
- struct hostapd_ssid *ssid)
-{
- FILE *f;
- char buf[128], *pos;
- int line = 0, ret = 0, len, ok;
- u8 addr[ETH_ALEN];
- struct hostapd_wpa_psk *psk;
-
- if (!fname)
- return 0;
-
- f = fopen(fname, "r");
- if (!f) {
- printf("WPA PSK file '%s' not found.\n", fname);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- if (hwaddr_aton(buf, addr)) {
- printf("Invalid MAC address '%s' on line %d in '%s'\n",
- buf, line, fname);
- ret = -1;
- break;
- }
-
- psk = wpa_zalloc(sizeof(*psk));
- if (psk == NULL) {
- printf("WPA PSK allocation failed\n");
- ret = -1;
- break;
- }
- if (memcmp(addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
- psk->group = 1;
- else
- memcpy(psk->addr, addr, ETH_ALEN);
-
- pos = buf + 17;
- if (pos == '\0') {
- printf("No PSK on line %d in '%s'\n", line, fname);
- free(psk);
- ret = -1;
- break;
- }
- pos++;
-
- ok = 0;
- len = strlen(pos);
- if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
- ok = 1;
- else if (len >= 8 && len < 64) {
- pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
- 4096, psk->psk, PMK_LEN);
- ok = 1;
- }
- if (!ok) {
- printf("Invalid PSK '%s' on line %d in '%s'\n",
- pos, line, fname);
- free(psk);
- ret = -1;
- break;
- }
-
- psk->next = ssid->wpa_psk;
- ssid->wpa_psk = psk;
- }
-
- fclose(f);
-
- return ret;
-}
-
-
-int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
-{
- struct hostapd_ssid *ssid = &conf->ssid;
-
- if (ssid->wpa_passphrase != NULL) {
- if (ssid->wpa_psk != NULL) {
- printf("Warning: both WPA PSK and passphrase set. "
- "Using passphrase.\n");
- free(ssid->wpa_psk);
- }
- ssid->wpa_psk = wpa_zalloc(sizeof(struct hostapd_wpa_psk));
- if (ssid->wpa_psk == NULL) {
- printf("Unable to alloc space for PSK\n");
- return -1;
- }
- wpa_hexdump_ascii(MSG_DEBUG, "SSID",
- (u8 *) ssid->ssid, ssid->ssid_len);
- wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",
- (u8 *) ssid->wpa_passphrase,
- strlen(ssid->wpa_passphrase));
- pbkdf2_sha1(ssid->wpa_passphrase,
- ssid->ssid, ssid->ssid_len,
- 4096, ssid->wpa_psk->psk, PMK_LEN);
- wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",
- ssid->wpa_psk->psk, PMK_LEN);
- ssid->wpa_psk->group = 1;
-
- memset(ssid->wpa_passphrase, 0,
- strlen(ssid->wpa_passphrase));
- free(ssid->wpa_passphrase);
- ssid->wpa_passphrase = NULL;
- }
-
- if (ssid->wpa_psk_file) {
- if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file,
- &conf->ssid))
- return -1;
- free(ssid->wpa_psk_file);
- ssid->wpa_psk_file = NULL;
- }
-
- return 0;
-}
-
-
-#ifdef EAP_SERVER
-static int hostapd_config_read_eap_user(const char *fname,
- struct hostapd_bss_config *conf)
-{
- FILE *f;
- char buf[512], *pos, *start, *pos2;
- int line = 0, ret = 0, num_methods;
- struct hostapd_eap_user *user, *tail = NULL;
-
- if (!fname)
- return 0;
-
- f = fopen(fname, "r");
- if (!f) {
- printf("EAP user file '%s' not found.\n", fname);
- return -1;
- }
-
- /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
- while (fgets(buf, sizeof(buf), f)) {
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- user = NULL;
-
- if (buf[0] != '"' && buf[0] != '*') {
- printf("Invalid EAP identity (no \" in start) on "
- "line %d in '%s'\n", line, fname);
- goto failed;
- }
-
- user = wpa_zalloc(sizeof(*user));
- if (user == NULL) {
- printf("EAP user allocation failed\n");
- goto failed;
- }
- user->force_version = -1;
-
- if (buf[0] == '*') {
- pos = buf;
- } else {
- pos = buf + 1;
- start = pos;
- while (*pos != '"' && *pos != '\0')
- pos++;
- if (*pos == '\0') {
- printf("Invalid EAP identity (no \" in end) on"
- " line %d in '%s'\n", line, fname);
- goto failed;
- }
-
- user->identity = malloc(pos - start);
- if (user->identity == NULL) {
- printf("Failed to allocate memory for EAP "
- "identity\n");
- goto failed;
- }
- memcpy(user->identity, start, pos - start);
- user->identity_len = pos - start;
-
- if (pos[0] == '"' && pos[1] == '*') {
- user->wildcard_prefix = 1;
- pos++;
- }
- }
- pos++;
- while (*pos == ' ' || *pos == '\t')
- pos++;
-
- if (*pos == '\0') {
- printf("No EAP method on line %d in '%s'\n",
- line, fname);
- goto failed;
- }
-
- start = pos;
- while (*pos != ' ' && *pos != '\t' && *pos != '\0')
- pos++;
- if (*pos == '\0') {
- pos = NULL;
- } else {
- *pos = '\0';
- pos++;
- }
- num_methods = 0;
- while (*start) {
- char *pos3 = strchr(start, ',');
- if (pos3) {
- *pos3++ = '\0';
- }
- user->methods[num_methods].method =
- eap_get_type(start, &user->methods[num_methods]
- .vendor);
- if (user->methods[num_methods].vendor ==
- EAP_VENDOR_IETF &&
- user->methods[num_methods].method == EAP_TYPE_NONE)
- {
- printf("Unsupported EAP type '%s' on line %d "
- "in '%s'\n", start, line, fname);
- goto failed;
- }
-
- num_methods++;
- if (num_methods >= EAP_USER_MAX_METHODS)
- break;
- if (pos3 == NULL)
- break;
- start = pos3;
- }
- if (num_methods == 0) {
- printf("No EAP types configured on line %d in '%s'\n",
- line, fname);
- goto failed;
- }
-
- if (pos == NULL)
- goto done;
-
- while (*pos == ' ' || *pos == '\t')
- pos++;
- if (*pos == '\0')
- goto done;
-
- if (strncmp(pos, "[ver=0]", 7) == 0) {
- user->force_version = 0;
- goto done;
- }
-
- if (strncmp(pos, "[ver=1]", 7) == 0) {
- user->force_version = 1;
- goto done;
- }
-
- if (strncmp(pos, "[2]", 3) == 0) {
- user->phase2 = 1;
- goto done;
- }
-
- if (*pos == '"') {
- pos++;
- start = pos;
- while (*pos != '"' && *pos != '\0')
- pos++;
- if (*pos == '\0') {
- printf("Invalid EAP password (no \" in end) "
- "on line %d in '%s'\n", line, fname);
- goto failed;
- }
-
- user->password = malloc(pos - start);
- if (user->password == NULL) {
- printf("Failed to allocate memory for EAP "
- "password\n");
- goto failed;
- }
- memcpy(user->password, start, pos - start);
- user->password_len = pos - start;
-
- pos++;
- } else if (strncmp(pos, "hash:", 5) == 0) {
- pos += 5;
- pos2 = pos;
- while (*pos2 != '\0' && *pos2 != ' ' &&
- *pos2 != '\t' && *pos2 != '#')
- pos2++;
- if (pos2 - pos != 32) {
- printf("Invalid password hash on line %d in "
- "'%s'\n", line, fname);
- goto failed;
- }
- user->password = malloc(16);
- if (user->password == NULL) {
- printf("Failed to allocate memory for EAP "
- "password hash\n");
- goto failed;
- }
- if (hexstr2bin(pos, user->password, 16) < 0) {
- printf("Invalid hash password on line %d in "
- "'%s'\n", line, fname);
- goto failed;
- }
- user->password_len = 16;
- user->password_hash = 1;
- pos = pos2;
- } else {
- pos2 = pos;
- while (*pos2 != '\0' && *pos2 != ' ' &&
- *pos2 != '\t' && *pos2 != '#')
- pos2++;
- if ((pos2 - pos) & 1) {
- printf("Invalid hex password on line %d in "
- "'%s'\n", line, fname);
- goto failed;
- }
- user->password = malloc((pos2 - pos) / 2);
- if (user->password == NULL) {
- printf("Failed to allocate memory for EAP "
- "password\n");
- goto failed;
- }
- if (hexstr2bin(pos, user->password,
- (pos2 - pos) / 2) < 0) {
- printf("Invalid hex password on line %d in "
- "'%s'\n", line, fname);
- goto failed;
- }
- user->password_len = (pos2 - pos) / 2;
- pos = pos2;
- }
-
- while (*pos == ' ' || *pos == '\t')
- pos++;
- if (strncmp(pos, "[2]", 3) == 0) {
- user->phase2 = 1;
- }
-
- done:
- if (tail == NULL) {
- tail = conf->eap_user = user;
- } else {
- tail->next = user;
- tail = user;
- }
- continue;
-
- failed:
- if (user) {
- free(user->password);
- free(user->identity);
- free(user);
- }
- ret = -1;
- break;
- }
-
- fclose(f);
-
- return ret;
-}
-#endif /* EAP_SERVER */
-
-
-static int
-hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
- int *num_server, const char *val, int def_port,
- struct hostapd_radius_server **curr_serv)
-{
- struct hostapd_radius_server *nserv;
- int ret;
- static int server_index = 1;
-
- nserv = realloc(*server, (*num_server + 1) * sizeof(*nserv));
- if (nserv == NULL)
- return -1;
-
- *server = nserv;
- nserv = &nserv[*num_server];
- (*num_server)++;
- (*curr_serv) = nserv;
-
- memset(nserv, 0, sizeof(*nserv));
- nserv->port = def_port;
- ret = hostapd_parse_ip_addr(val, &nserv->addr);
- nserv->index = server_index++;
-
- return ret;
-}
-
-
-static int hostapd_config_parse_key_mgmt(int line, const char *value)
-{
- int val = 0, last;
- char *start, *end, *buf;
-
- buf = strdup(value);
- if (buf == NULL)
- return -1;
- start = buf;
-
- while (start != '\0') {
- while (*start == ' ' || *start == '\t')
- start++;
- if (*start == '\0')
- break;
- end = start;
- while (*end != ' ' && *end != '\t' && *end != '\0')
- end++;
- last = *end == '\0';
- *end = '\0';
- if (strcmp(start, "WPA-PSK") == 0)
- val |= WPA_KEY_MGMT_PSK;
- else if (strcmp(start, "WPA-EAP") == 0)
- val |= WPA_KEY_MGMT_IEEE8021X;
- else {
- printf("Line %d: invalid key_mgmt '%s'\n",
- line, start);
- free(buf);
- return -1;
- }
-
- if (last)
- break;
- start = end + 1;
- }
-
- free(buf);
- if (val == 0) {
- printf("Line %d: no key_mgmt values configured.\n", line);
- return -1;
- }
-
- return val;
-}
-
-
-static int hostapd_config_parse_cipher(int line, const char *value)
-{
- int val = 0, last;
- char *start, *end, *buf;
-
- buf = strdup(value);
- if (buf == NULL)
- return -1;
- start = buf;
-
- while (start != '\0') {
- while (*start == ' ' || *start == '\t')
- start++;
- if (*start == '\0')
- break;
- end = start;
- while (*end != ' ' && *end != '\t' && *end != '\0')
- end++;
- last = *end == '\0';
- *end = '\0';
- if (strcmp(start, "CCMP") == 0)
- val |= WPA_CIPHER_CCMP;
- else if (strcmp(start, "TKIP") == 0)
- val |= WPA_CIPHER_TKIP;
- else if (strcmp(start, "WEP104") == 0)
- val |= WPA_CIPHER_WEP104;
- else if (strcmp(start, "WEP40") == 0)
- val |= WPA_CIPHER_WEP40;
- else if (strcmp(start, "NONE") == 0)
- val |= WPA_CIPHER_NONE;
- else {
- printf("Line %d: invalid cipher '%s'.", line, start);
- free(buf);
- return -1;
- }
-
- if (last)
- break;
- start = end + 1;
- }
- free(buf);
-
- if (val == 0) {
- printf("Line %d: no cipher values configured.", line);
- return -1;
- }
- return val;
-}
-
-
-static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
- struct hostapd_config *conf)
-{
- if (bss->ieee802_1x && !bss->eap_server &&
- !bss->radius->auth_servers) {
- printf("Invalid IEEE 802.1X configuration (no EAP "
- "authenticator configured).\n");
- return -1;
- }
-
- if (bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
- bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
- bss->ssid.wpa_psk_file == NULL) {
- printf("WPA-PSK enabled, but PSK or passphrase is not "
- "configured.\n");
- return -1;
- }
-
- if (hostapd_mac_comp_empty(bss->bssid) != 0) {
- size_t i;
-
- for (i = 0; i < conf->num_bss; i++) {
- if ((&conf->bss[i] != bss) &&
- (hostapd_mac_comp(conf->bss[i].bssid,
- bss->bssid) == 0)) {
- printf("Duplicate BSSID " MACSTR
- " on interface '%s' and '%s'.\n",
- MAC2STR(bss->bssid),
- conf->bss[i].iface, bss->iface);
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-
-static int hostapd_config_check(struct hostapd_config *conf)
-{
- size_t i;
-
- for (i = 0; i < conf->num_bss; i++) {
- if (hostapd_config_check_bss(&conf->bss[i], conf))
- return -1;
- }
-
- return 0;
-}
-
-
-static int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
- char *val)
-{
- size_t len = strlen(val);
-
- if (keyidx < 0 || keyidx > 3 || wep->key[keyidx] != NULL)
- return -1;
-
- if (val[0] == '"') {
- if (len < 2 || val[len - 1] != '"')
- return -1;
- len -= 2;
- wep->key[keyidx] = malloc(len);
- if (wep->key[keyidx] == NULL)
- return -1;
- memcpy(wep->key[keyidx], val + 1, len);
- wep->len[keyidx] = len;
- } else {
- if (len & 1)
- return -1;
- len /= 2;
- wep->key[keyidx] = malloc(len);
- if (wep->key[keyidx] == NULL)
- return -1;
- wep->len[keyidx] = len;
- if (hexstr2bin(val, wep->key[keyidx], len) < 0)
- return -1;
- }
-
- wep->keys_set++;
-
- return 0;
-}
-
-
-static int hostapd_parse_rates(int **rate_list, char *val)
-{
- int *list;
- int count;
- char *pos, *end;
-
- free(*rate_list);
- *rate_list = NULL;
-
- pos = val;
- count = 0;
- while (*pos != '\0') {
- if (*pos == ' ')
- count++;
- pos++;
- }
-
- list = malloc(sizeof(int) * (count + 2));
- if (list == NULL)
- return -1;
- pos = val;
- count = 0;
- while (*pos != '\0') {
- end = strchr(pos, ' ');
- if (end)
- *end = '\0';
-
- list[count++] = atoi(pos);
- if (!end)
- break;
- pos = end + 1;
- }
- list[count] = -1;
-
- *rate_list = list;
- return 0;
-}
-
-
-static int hostapd_config_bss(struct hostapd_config *conf, const char *ifname)
-{
- struct hostapd_bss_config *bss;
-
- if (*ifname == '\0')
- return -1;
-
- bss = realloc(conf->bss, (conf->num_bss + 1) *
- sizeof(struct hostapd_bss_config));
- if (bss == NULL) {
- printf("Failed to allocate memory for multi-BSS entry\n");
- return -1;
- }
- conf->bss = bss;
-
- bss = &(conf->bss[conf->num_bss]);
- memset(bss, 0, sizeof(*bss));
- bss->radius = wpa_zalloc(sizeof(*bss->radius));
- if (bss->radius == NULL) {
- printf("Failed to allocate memory for multi-BSS RADIUS "
- "data\n");
- return -1;
- }
-
- conf->num_bss++;
- conf->last_bss = bss;
-
- hostapd_config_defaults_bss(bss);
- snprintf(bss->iface, sizeof(bss->iface), "%s", ifname);
- memcpy(bss->ssid.vlan, bss->iface, IFNAMSIZ + 1);
-
- return 0;
-}
-
-
-static int valid_cw(int cw)
-{
- return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
- cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023);
-}
-
-
-enum {
- IEEE80211_TX_QUEUE_DATA0 = 0, /* used for EDCA AC_VO data */
- IEEE80211_TX_QUEUE_DATA1 = 1, /* used for EDCA AC_VI data */
- IEEE80211_TX_QUEUE_DATA2 = 2, /* used for EDCA AC_BE data */
- IEEE80211_TX_QUEUE_DATA3 = 3, /* used for EDCA AC_BK data */
- IEEE80211_TX_QUEUE_DATA4 = 4,
- IEEE80211_TX_QUEUE_AFTER_BEACON = 6,
- IEEE80211_TX_QUEUE_BEACON = 7
-};
-
-static int hostapd_config_tx_queue(struct hostapd_config *conf, char *name,
- char *val)
-{
- int num;
- char *pos;
- struct hostapd_tx_queue_params *queue;
-
- /* skip 'tx_queue_' prefix */
- pos = name + 9;
- if (strncmp(pos, "data", 4) == 0 &&
- pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
- num = pos[4] - '0';
- pos += 6;
- } else if (strncmp(pos, "after_beacon_", 13) == 0) {
- num = IEEE80211_TX_QUEUE_AFTER_BEACON;
- pos += 13;
- } else if (strncmp(pos, "beacon_", 7) == 0) {
- num = IEEE80211_TX_QUEUE_BEACON;
- pos += 7;
- } else {
- printf("Unknown tx_queue name '%s'\n", pos);
- return -1;
- }
-
- queue = &conf->tx_queue[num];
-
- if (strcmp(pos, "aifs") == 0) {
- queue->aifs = atoi(val);
- if (queue->aifs < 0 || queue->aifs > 255) {
- printf("Invalid AIFS value %d\n", queue->aifs);
- return -1;
- }
- } else if (strcmp(pos, "cwmin") == 0) {
- queue->cwmin = atoi(val);
- if (!valid_cw(queue->cwmin)) {
- printf("Invalid cwMin value %d\n", queue->cwmin);
- return -1;
- }
- } else if (strcmp(pos, "cwmax") == 0) {
- queue->cwmax = atoi(val);
- if (!valid_cw(queue->cwmax)) {
- printf("Invalid cwMax value %d\n", queue->cwmax);
- return -1;
- }
- } else if (strcmp(pos, "burst") == 0) {
- queue->burst = hostapd_config_read_int10(val);
- } else {
- printf("Unknown tx_queue field '%s'\n", pos);
- return -1;
- }
-
- queue->configured = 1;
-
- return 0;
-}
-
-
-static int hostapd_config_wme_ac(struct hostapd_config *conf, char *name,
- char *val)
-{
- int num, v;
- char *pos;
- struct hostapd_wme_ac_params *ac;
-
- /* skip 'wme_ac_' prefix */
- pos = name + 7;
- if (strncmp(pos, "be_", 3) == 0) {
- num = 0;
- pos += 3;
- } else if (strncmp(pos, "bk_", 3) == 0) {
- num = 1;
- pos += 3;
- } else if (strncmp(pos, "vi_", 3) == 0) {
- num = 2;
- pos += 3;
- } else if (strncmp(pos, "vo_", 3) == 0) {
- num = 3;
- pos += 3;
- } else {
- printf("Unknown wme name '%s'\n", pos);
- return -1;
- }
-
- ac = &conf->wme_ac_params[num];
-
- if (strcmp(pos, "aifs") == 0) {
- v = atoi(val);
- if (v < 1 || v > 255) {
- printf("Invalid AIFS value %d\n", v);
- return -1;
- }
- ac->aifs = v;
- } else if (strcmp(pos, "cwmin") == 0) {
- v = atoi(val);
- if (v < 0 || v > 12) {
- printf("Invalid cwMin value %d\n", v);
- return -1;
- }
- ac->cwmin = v;
- } else if (strcmp(pos, "cwmax") == 0) {
- v = atoi(val);
- if (v < 0 || v > 12) {
- printf("Invalid cwMax value %d\n", v);
- return -1;
- }
- ac->cwmax = v;
- } else if (strcmp(pos, "txop_limit") == 0) {
- v = atoi(val);
- if (v < 0 || v > 0xffff) {
- printf("Invalid txop value %d\n", v);
- return -1;
- }
- ac->txopLimit = v;
- } else if (strcmp(pos, "acm") == 0) {
- v = atoi(val);
- if (v < 0 || v > 1) {
- printf("Invalid acm value %d\n", v);
- return -1;
- }
- ac->admission_control_mandatory = v;
- } else {
- printf("Unknown wme_ac_ field '%s'\n", pos);
- return -1;
- }
-
- return 0;
-}
-
-
-struct hostapd_config * hostapd_config_read(const char *fname)
-{
- struct hostapd_config *conf;
- struct hostapd_bss_config *bss;
- FILE *f;
- char buf[256], *pos;
- int line = 0;
- int errors = 0;
- size_t i;
-
- f = fopen(fname, "r");
- if (f == NULL) {
- printf("Could not open configuration file '%s' for reading.\n",
- fname);
- return NULL;
- }
-
- conf = hostapd_config_defaults();
- if (conf == NULL) {
- fclose(f);
- return NULL;
- }
- bss = conf->last_bss = conf->bss;
-
- while (fgets(buf, sizeof(buf), f)) {
- bss = conf->last_bss;
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- pos = strchr(buf, '=');
- if (pos == NULL) {
- printf("Line %d: invalid line '%s'\n", line, buf);
- errors++;
- continue;
- }
- *pos = '\0';
- pos++;
-
- if (strcmp(buf, "interface") == 0) {
- snprintf(conf->bss[0].iface,
- sizeof(conf->bss[0].iface), "%s", pos);
- } else if (strcmp(buf, "bridge") == 0) {
- snprintf(bss->bridge, sizeof(bss->bridge), "%s", pos);
- } else if (strcmp(buf, "driver") == 0) {
- conf->driver = driver_lookup(pos);
- if (conf->driver == NULL) {
- printf("Line %d: invalid/unknown driver "
- "'%s'\n", line, pos);
- errors++;
- }
- } else if (strcmp(buf, "debug") == 0) {
- bss->debug = atoi(pos);
- } else if (strcmp(buf, "logger_syslog_level") == 0) {
- bss->logger_syslog_level = atoi(pos);
- } else if (strcmp(buf, "logger_stdout_level") == 0) {
- bss->logger_stdout_level = atoi(pos);
- } else if (strcmp(buf, "logger_syslog") == 0) {
- bss->logger_syslog = atoi(pos);
- } else if (strcmp(buf, "logger_stdout") == 0) {
- bss->logger_stdout = atoi(pos);
- } else if (strcmp(buf, "dump_file") == 0) {
- bss->dump_log_name = strdup(pos);
- } else if (strcmp(buf, "ssid") == 0) {
- bss->ssid.ssid_len = strlen(pos);
- if (bss->ssid.ssid_len > HOSTAPD_MAX_SSID_LEN ||
- bss->ssid.ssid_len < 1) {
- printf("Line %d: invalid SSID '%s'\n", line,
- pos);
- errors++;
- } else {
- memcpy(bss->ssid.ssid, pos,
- bss->ssid.ssid_len);
- bss->ssid.ssid[bss->ssid.ssid_len] = '\0';
- bss->ssid.ssid_set = 1;
- }
- } else if (strcmp(buf, "macaddr_acl") == 0) {
- bss->macaddr_acl = atoi(pos);
- if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
- bss->macaddr_acl != DENY_UNLESS_ACCEPTED &&
- bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
- printf("Line %d: unknown macaddr_acl %d\n",
- line, bss->macaddr_acl);
- }
- } else if (strcmp(buf, "accept_mac_file") == 0) {
- if (hostapd_config_read_maclist(pos, &bss->accept_mac,
- &bss->num_accept_mac))
- {
- printf("Line %d: Failed to read "
- "accept_mac_file '%s'\n",
- line, pos);
- errors++;
- }
- } else if (strcmp(buf, "deny_mac_file") == 0) {
- if (hostapd_config_read_maclist(pos, &bss->deny_mac,
- &bss->num_deny_mac))
- {
- printf("Line %d: Failed to read "
- "deny_mac_file '%s'\n",
- line, pos);
- errors++;
- }
- } else if (strcmp(buf, "ap_max_inactivity") == 0) {
- bss->ap_max_inactivity = atoi(pos);
- } else if (strcmp(buf, "country_code") == 0) {
- memcpy(conf->country, pos, 2);
- /* FIX: make this configurable */
- conf->country[2] = ' ';
- } else if (strcmp(buf, "ieee80211d") == 0) {
- conf->ieee80211d = atoi(pos);
- } else if (strcmp(buf, "ieee80211h") == 0) {
- conf->ieee80211h = atoi(pos);
- } else if (strcmp(buf, "assoc_ap_addr") == 0) {
- if (hwaddr_aton(pos, bss->assoc_ap_addr)) {
- printf("Line %d: invalid MAC address '%s'\n",
- line, pos);
- errors++;
- }
- bss->assoc_ap = 1;
- } else if (strcmp(buf, "ieee8021x") == 0) {
- bss->ieee802_1x = atoi(pos);
- } else if (strcmp(buf, "eapol_version") == 0) {
- bss->eapol_version = atoi(pos);
- if (bss->eapol_version < 1 ||
- bss->eapol_version > 2) {
- printf("Line %d: invalid EAPOL "
- "version (%d): '%s'.\n",
- line, bss->eapol_version, pos);
- errors++;
- } else
- wpa_printf(MSG_DEBUG, "eapol_version=%d",
- bss->eapol_version);
-#ifdef EAP_SERVER
- } else if (strcmp(buf, "eap_authenticator") == 0) {
- bss->eap_server = atoi(pos);
- printf("Line %d: obsolete eap_authenticator used; "
- "this has been renamed to eap_server\n", line);
- } else if (strcmp(buf, "eap_server") == 0) {
- bss->eap_server = atoi(pos);
- } else if (strcmp(buf, "eap_user_file") == 0) {
- if (hostapd_config_read_eap_user(pos, bss))
- errors++;
- } else if (strcmp(buf, "ca_cert") == 0) {
- free(bss->ca_cert);
- bss->ca_cert = strdup(pos);
- } else if (strcmp(buf, "server_cert") == 0) {
- free(bss->server_cert);
- bss->server_cert = strdup(pos);
- } else if (strcmp(buf, "private_key") == 0) {
- free(bss->private_key);
- bss->private_key = strdup(pos);
- } else if (strcmp(buf, "private_key_passwd") == 0) {
- free(bss->private_key_passwd);
- bss->private_key_passwd = strdup(pos);
- } else if (strcmp(buf, "check_crl") == 0) {
- bss->check_crl = atoi(pos);
-#ifdef EAP_SIM
- } else if (strcmp(buf, "eap_sim_db") == 0) {
- free(bss->eap_sim_db);
- bss->eap_sim_db = strdup(pos);
-#endif /* EAP_SIM */
-#endif /* EAP_SERVER */
- } else if (strcmp(buf, "eap_message") == 0) {
- char *term;
- bss->eap_req_id_text = strdup(pos);
- if (bss->eap_req_id_text == NULL) {
- printf("Line %d: Failed to allocate memory "
- "for eap_req_id_text\n", line);
- errors++;
- continue;
- }
- bss->eap_req_id_text_len =
- strlen(bss->eap_req_id_text);
- term = strstr(bss->eap_req_id_text, "\\0");
- if (term) {
- *term++ = '\0';
- memmove(term, term + 1,
- bss->eap_req_id_text_len -
- (term - bss->eap_req_id_text) - 1);
- bss->eap_req_id_text_len--;
- }
- } else if (strcmp(buf, "wep_key_len_broadcast") == 0) {
- bss->default_wep_key_len = atoi(pos);
- if (bss->default_wep_key_len > 13) {
- printf("Line %d: invalid WEP key len %lu "
- "(= %lu bits)\n", line,
- (unsigned long)
- bss->default_wep_key_len,
- (unsigned long)
- bss->default_wep_key_len * 8);
- errors++;
- }
- } else if (strcmp(buf, "wep_key_len_unicast") == 0) {
- bss->individual_wep_key_len = atoi(pos);
- if (bss->individual_wep_key_len < 0 ||
- bss->individual_wep_key_len > 13) {
- printf("Line %d: invalid WEP key len %d "
- "(= %d bits)\n", line,
- bss->individual_wep_key_len,
- bss->individual_wep_key_len * 8);
- errors++;
- }
- } else if (strcmp(buf, "wep_rekey_period") == 0) {
- bss->wep_rekeying_period = atoi(pos);
- if (bss->wep_rekeying_period < 0) {
- printf("Line %d: invalid period %d\n",
- line, bss->wep_rekeying_period);
- errors++;
- }
- } else if (strcmp(buf, "eap_reauth_period") == 0) {
- bss->eap_reauth_period = atoi(pos);
- if (bss->eap_reauth_period < 0) {
- printf("Line %d: invalid period %d\n",
- line, bss->eap_reauth_period);
- errors++;
- }
- } else if (strcmp(buf, "eapol_key_index_workaround") == 0) {
- bss->eapol_key_index_workaround = atoi(pos);
-#ifdef CONFIG_IAPP
- } else if (strcmp(buf, "iapp_interface") == 0) {
- bss->ieee802_11f = 1;
- snprintf(bss->iapp_iface, sizeof(bss->iapp_iface),
- "%s", pos);
-#endif /* CONFIG_IAPP */
- } else if (strcmp(buf, "own_ip_addr") == 0) {
- if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
- printf("Line %d: invalid IP address '%s'\n",
- line, pos);
- errors++;
- }
- } else if (strcmp(buf, "nas_identifier") == 0) {
- bss->nas_identifier = strdup(pos);
- } else if (strcmp(buf, "auth_server_addr") == 0) {
- if (hostapd_config_read_radius_addr(
- &bss->radius->auth_servers,
- &bss->radius->num_auth_servers, pos, 1812,
- &bss->radius->auth_server)) {
- printf("Line %d: invalid IP address '%s'\n",
- line, pos);
- errors++;
- }
- } else if (bss->radius->auth_server &&
- strcmp(buf, "auth_server_port") == 0) {
- bss->radius->auth_server->port = atoi(pos);
- } else if (bss->radius->auth_server &&
- strcmp(buf, "auth_server_shared_secret") == 0) {
- int len = strlen(pos);
- if (len == 0) {
- /* RFC 2865, Ch. 3 */
- printf("Line %d: empty shared secret is not "
- "allowed.\n", line);
- errors++;
- }
- bss->radius->auth_server->shared_secret =
- (u8 *) strdup(pos);
- bss->radius->auth_server->shared_secret_len = len;
- } else if (strcmp(buf, "acct_server_addr") == 0) {
- if (hostapd_config_read_radius_addr(
- &bss->radius->acct_servers,
- &bss->radius->num_acct_servers, pos, 1813,
- &bss->radius->acct_server)) {
- printf("Line %d: invalid IP address '%s'\n",
- line, pos);
- errors++;
- }
- } else if (bss->radius->acct_server &&
- strcmp(buf, "acct_server_port") == 0) {
- bss->radius->acct_server->port = atoi(pos);
- } else if (bss->radius->acct_server &&
- strcmp(buf, "acct_server_shared_secret") == 0) {
- int len = strlen(pos);
- if (len == 0) {
- /* RFC 2865, Ch. 3 */
- printf("Line %d: empty shared secret is not "
- "allowed.\n", line);
- errors++;
- }
- bss->radius->acct_server->shared_secret =
- (u8 *) strdup(pos);
- bss->radius->acct_server->shared_secret_len = len;
- } else if (strcmp(buf, "radius_retry_primary_interval") == 0) {
- bss->radius->retry_primary_interval = atoi(pos);
- } else if (strcmp(buf, "radius_acct_interim_interval") == 0) {
- bss->radius->acct_interim_interval = atoi(pos);
- } else if (strcmp(buf, "auth_algs") == 0) {
- bss->auth_algs = atoi(pos);
- if (bss->auth_algs == 0) {
- printf("Line %d: no authentication algorithms "
- "allowed\n",
- line);
- errors++;
- }
- } else if (strcmp(buf, "max_num_sta") == 0) {
- bss->max_num_sta = atoi(pos);
- if (bss->max_num_sta < 0 ||
- bss->max_num_sta > MAX_STA_COUNT) {
- printf("Line %d: Invalid max_num_sta=%d; "
- "allowed range 0..%d\n", line,
- bss->max_num_sta, MAX_STA_COUNT);
- errors++;
- }
- } else if (strcmp(buf, "wpa") == 0) {
- bss->wpa = atoi(pos);
- } else if (strcmp(buf, "wpa_group_rekey") == 0) {
- bss->wpa_group_rekey = atoi(pos);
- } else if (strcmp(buf, "wpa_strict_rekey") == 0) {
- bss->wpa_strict_rekey = atoi(pos);
- } else if (strcmp(buf, "wpa_gmk_rekey") == 0) {
- bss->wpa_gmk_rekey = atoi(pos);
- } else if (strcmp(buf, "wpa_passphrase") == 0) {
- int len = strlen(pos);
- if (len < 8 || len > 63) {
- printf("Line %d: invalid WPA passphrase length"
- " %d (expected 8..63)\n", line, len);
- errors++;
- } else {
- free(bss->ssid.wpa_passphrase);
- bss->ssid.wpa_passphrase = strdup(pos);
- }
- } else if (strcmp(buf, "wpa_psk") == 0) {
- free(bss->ssid.wpa_psk);
- bss->ssid.wpa_psk =
- wpa_zalloc(sizeof(struct hostapd_wpa_psk));
- if (bss->ssid.wpa_psk == NULL)
- errors++;
- else if (hexstr2bin(pos, bss->ssid.wpa_psk->psk,
- PMK_LEN) ||
- pos[PMK_LEN * 2] != '\0') {
- printf("Line %d: Invalid PSK '%s'.\n", line,
- pos);
- errors++;
- } else {
- bss->ssid.wpa_psk->group = 1;
- }
- } else if (strcmp(buf, "wpa_psk_file") == 0) {
- free(bss->ssid.wpa_psk_file);
- bss->ssid.wpa_psk_file = strdup(pos);
- if (!bss->ssid.wpa_psk_file) {
- printf("Line %d: allocation failed\n", line);
- errors++;
- }
- } else if (strcmp(buf, "wpa_key_mgmt") == 0) {
- bss->wpa_key_mgmt =
- hostapd_config_parse_key_mgmt(line, pos);
- if (bss->wpa_key_mgmt == -1)
- errors++;
- } else if (strcmp(buf, "wpa_pairwise") == 0) {
- bss->wpa_pairwise =
- hostapd_config_parse_cipher(line, pos);
- if (bss->wpa_pairwise == -1 ||
- bss->wpa_pairwise == 0)
- errors++;
- else if (bss->wpa_pairwise &
- (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
- WPA_CIPHER_WEP104)) {
- printf("Line %d: unsupported pairwise "
- "cipher suite '%s'\n",
- bss->wpa_pairwise, pos);
- errors++;
- } else {
- if (bss->wpa_pairwise & WPA_CIPHER_TKIP)
- bss->wpa_group = WPA_CIPHER_TKIP;
- else
- bss->wpa_group = WPA_CIPHER_CCMP;
- }
-#ifdef CONFIG_RSN_PREAUTH
- } else if (strcmp(buf, "rsn_preauth") == 0) {
- bss->rsn_preauth = atoi(pos);
- } else if (strcmp(buf, "rsn_preauth_interfaces") == 0) {
- bss->rsn_preauth_interfaces = strdup(pos);
-#endif /* CONFIG_RSN_PREAUTH */
-#ifdef CONFIG_PEERKEY
- } else if (strcmp(buf, "peerkey") == 0) {
- bss->peerkey = atoi(pos);
-#endif /* CONFIG_PEERKEY */
- } else if (strcmp(buf, "ctrl_interface") == 0) {
- free(bss->ctrl_interface);
- bss->ctrl_interface = strdup(pos);
- } else if (strcmp(buf, "ctrl_interface_group") == 0) {
-#ifndef CONFIG_NATIVE_WINDOWS
- struct group *grp;
- char *endp;
- const char *group = pos;
-
- grp = getgrnam(group);
- if (grp) {
- bss->ctrl_interface_gid = grp->gr_gid;
- bss->ctrl_interface_gid_set = 1;
- wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
- " (from group name '%s')",
- bss->ctrl_interface_gid, group);
- continue;
- }
-
- /* Group name not found - try to parse this as gid */
- bss->ctrl_interface_gid = strtol(group, &endp, 10);
- if (*group == '\0' || *endp != '\0') {
- wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
- "'%s'", line, group);
- errors++;
- continue;
- }
- bss->ctrl_interface_gid_set = 1;
- wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
- bss->ctrl_interface_gid);
-#endif /* CONFIG_NATIVE_WINDOWS */
-#ifdef RADIUS_SERVER
- } else if (strcmp(buf, "radius_server_clients") == 0) {
- free(bss->radius_server_clients);
- bss->radius_server_clients = strdup(pos);
- } else if (strcmp(buf, "radius_server_auth_port") == 0) {
- bss->radius_server_auth_port = atoi(pos);
- } else if (strcmp(buf, "radius_server_ipv6") == 0) {
- bss->radius_server_ipv6 = atoi(pos);
-#endif /* RADIUS_SERVER */
- } else if (strcmp(buf, "test_socket") == 0) {
- free(bss->test_socket);
- bss->test_socket = strdup(pos);
- } else if (strcmp(buf, "use_pae_group_addr") == 0) {
- bss->use_pae_group_addr = atoi(pos);
- } else if (strcmp(buf, "hw_mode") == 0) {
- if (strcmp(pos, "a") == 0)
- conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
- else if (strcmp(pos, "b") == 0)
- conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
- else if (strcmp(pos, "g") == 0)
- conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
- else {
- printf("Line %d: unknown hw_mode '%s'\n",
- line, pos);
- errors++;
- }
- } else if (strcmp(buf, "channel") == 0) {
- conf->channel = atoi(pos);
- } else if (strcmp(buf, "beacon_int") == 0) {
- int val = atoi(pos);
- /* MIB defines range as 1..65535, but very small values
- * cause problems with the current implementation.
- * Since it is unlikely that this small numbers are
- * useful in real life scenarios, do not allow beacon
- * period to be set below 15 TU. */
- if (val < 15 || val > 65535) {
- printf("Line %d: invalid beacon_int %d "
- "(expected 15..65535)\n",
- line, val);
- errors++;
- } else
- conf->beacon_int = val;
- } else if (strcmp(buf, "dtim_period") == 0) {
- bss->dtim_period = atoi(pos);
- if (bss->dtim_period < 1 || bss->dtim_period > 255) {
- printf("Line %d: invalid dtim_period %d\n",
- line, bss->dtim_period);
- errors++;
- }
- } else if (strcmp(buf, "rts_threshold") == 0) {
- conf->rts_threshold = atoi(pos);
- if (conf->rts_threshold < 0 ||
- conf->rts_threshold > 2347) {
- printf("Line %d: invalid rts_threshold %d\n",
- line, conf->rts_threshold);
- errors++;
- }
- } else if (strcmp(buf, "fragm_threshold") == 0) {
- conf->fragm_threshold = atoi(pos);
- if (conf->fragm_threshold < 256 ||
- conf->fragm_threshold > 2346) {
- printf("Line %d: invalid fragm_threshold %d\n",
- line, conf->fragm_threshold);
- errors++;
- }
- } else if (strcmp(buf, "send_probe_response") == 0) {
- int val = atoi(pos);
- if (val != 0 && val != 1) {
- printf("Line %d: invalid send_probe_response "
- "%d (expected 0 or 1)\n", line, val);
- } else
- conf->send_probe_response = val;
- } else if (strcmp(buf, "supported_rates") == 0) {
- if (hostapd_parse_rates(&conf->supported_rates, pos)) {
- printf("Line %d: invalid rate list\n", line);
- errors++;
- }
- } else if (strcmp(buf, "basic_rates") == 0) {
- if (hostapd_parse_rates(&conf->basic_rates, pos)) {
- printf("Line %d: invalid rate list\n", line);
- errors++;
- }
- } else if (strcmp(buf, "ignore_broadcast_ssid") == 0) {
- bss->ignore_broadcast_ssid = atoi(pos);
- } else if (strcmp(buf, "bridge_packets") == 0) {
- conf->bridge_packets = atoi(pos);
- } else if (strcmp(buf, "wep_default_key") == 0) {
- bss->ssid.wep.idx = atoi(pos);
- if (bss->ssid.wep.idx > 3) {
- printf("Invalid wep_default_key index %d\n",
- bss->ssid.wep.idx);
- errors++;
- }
- } else if (strcmp(buf, "wep_key0") == 0 ||
- strcmp(buf, "wep_key1") == 0 ||
- strcmp(buf, "wep_key2") == 0 ||
- strcmp(buf, "wep_key3") == 0) {
- if (hostapd_config_read_wep(&bss->ssid.wep,
- buf[7] - '0', pos)) {
- printf("Line %d: invalid WEP key '%s'\n",
- line, buf);
- errors++;
- }
- } else if (strcmp(buf, "dynamic_vlan") == 0) {
- bss->ssid.dynamic_vlan = atoi(pos);
- } else if (strcmp(buf, "vlan_file") == 0) {
- if (hostapd_config_read_vlan_file(bss, pos)) {
- printf("Line %d: failed to read VLAN file "
- "'%s'\n", line, pos);
- errors++;
- }
-#ifdef CONFIG_FULL_DYNAMIC_VLAN
- } else if (strcmp(buf, "vlan_tagged_interface") == 0) {
- bss->ssid.vlan_tagged_interface = strdup(pos);
-#endif /* CONFIG_FULL_DYNAMIC_VLAN */
- } else if (strcmp(buf, "passive_scan_interval") == 0) {
- conf->passive_scan_interval = atoi(pos);
- } else if (strcmp(buf, "passive_scan_listen") == 0) {
- conf->passive_scan_listen = atoi(pos);
- } else if (strcmp(buf, "passive_scan_mode") == 0) {
- conf->passive_scan_mode = atoi(pos);
- } else if (strcmp(buf, "ap_table_max_size") == 0) {
- conf->ap_table_max_size = atoi(pos);
- } else if (strcmp(buf, "ap_table_expiration_time") == 0) {
- conf->ap_table_expiration_time = atoi(pos);
- } else if (strncmp(buf, "tx_queue_", 9) == 0) {
- if (hostapd_config_tx_queue(conf, buf, pos)) {
- printf("Line %d: invalid TX queue item\n",
- line);
- errors++;
- }
- } else if (strcmp(buf, "wme_enabled") == 0) {
- bss->wme_enabled = atoi(pos);
- } else if (strncmp(buf, "wme_ac_", 7) == 0) {
- if (hostapd_config_wme_ac(conf, buf, pos)) {
- printf("Line %d: invalid wme ac item\n",
- line);
- errors++;
- }
- } else if (strcmp(buf, "bss") == 0) {
- if (hostapd_config_bss(conf, pos)) {
- printf("Line %d: invalid bss item\n", line);
- errors++;
- }
- } else if (strcmp(buf, "bssid") == 0) {
- if (bss == conf->bss) {
- printf("Line %d: bssid item not allowed "
- "for the default interface\n", line);
- errors++;
- } else if (hwaddr_aton(pos, bss->bssid)) {
- printf("Line %d: invalid bssid item\n", line);
- errors++;
- }
-#ifdef CONFIG_IEEE80211W
- } else if (strcmp(buf, "ieee80211w") == 0) {
- bss->ieee80211w = atoi(pos);
-#endif /* CONFIG_IEEE80211W */
- } else {
- printf("Line %d: unknown configuration item '%s'\n",
- line, buf);
- errors++;
- }
- }
-
- fclose(f);
-
- if (bss->individual_wep_key_len == 0) {
- /* individual keys are not use; can use key idx0 for broadcast
- * keys */
- bss->broadcast_key_idx_min = 0;
- }
-
- for (i = 0; i < conf->num_bss; i++) {
- bss = &conf->bss[i];
-
- bss->radius->auth_server = bss->radius->auth_servers;
- bss->radius->acct_server = bss->radius->acct_servers;
-
- if (bss->wpa && bss->ieee802_1x) {
- bss->ssid.security_policy = SECURITY_WPA;
- } else if (bss->wpa) {
- bss->ssid.security_policy = SECURITY_WPA_PSK;
- } else if (bss->ieee802_1x) {
- bss->ssid.security_policy = SECURITY_IEEE_802_1X;
- bss->ssid.wep.default_len = bss->default_wep_key_len;
- } else if (bss->ssid.wep.keys_set)
- bss->ssid.security_policy = SECURITY_STATIC_WEP;
- else
- bss->ssid.security_policy = SECURITY_PLAINTEXT;
- }
-
- if (hostapd_config_check(conf))
- errors++;
-
- if (errors) {
- printf("%d errors found in configuration file '%s'\n",
- errors, fname);
- hostapd_config_free(conf);
- conf = NULL;
- }
-
- return conf;
-}
-
-
-int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b)
-{
- int i;
-
- if (a->idx != b->idx || a->default_len != b->default_len)
- return 1;
- for (i = 0; i < NUM_WEP_KEYS; i++)
- if (a->len[i] != b->len[i] ||
- memcmp(a->key[i], b->key[i], a->len[i]) != 0)
- return 1;
- return 0;
-}
-
-
-static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
- int num_servers)
-{
- int i;
-
- for (i = 0; i < num_servers; i++) {
- free(servers[i].shared_secret);
- }
- free(servers);
-}
-
-
-static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
-{
- free(user->identity);
- free(user->password);
- free(user);
-}
-
-
-static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
-{
- int i;
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- free(keys->key[i]);
- keys->key[i] = NULL;
- }
-}
-
-
-static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
-{
- struct hostapd_wpa_psk *psk, *prev;
- struct hostapd_eap_user *user, *prev_user;
-
- if (conf == NULL)
- return;
-
- psk = conf->ssid.wpa_psk;
- while (psk) {
- prev = psk;
- psk = psk->next;
- free(prev);
- }
-
- free(conf->ssid.wpa_passphrase);
- free(conf->ssid.wpa_psk_file);
-#ifdef CONFIG_FULL_DYNAMIC_VLAN
- free(conf->ssid.vlan_tagged_interface);
-#endif /* CONFIG_FULL_DYNAMIC_VLAN */
-
- user = conf->eap_user;
- while (user) {
- prev_user = user;
- user = user->next;
- hostapd_config_free_eap_user(prev_user);
- }
-
- free(conf->dump_log_name);
- free(conf->eap_req_id_text);
- free(conf->accept_mac);
- free(conf->deny_mac);
- free(conf->nas_identifier);
- hostapd_config_free_radius(conf->radius->auth_servers,
- conf->radius->num_auth_servers);
- hostapd_config_free_radius(conf->radius->acct_servers,
- conf->radius->num_acct_servers);
- free(conf->rsn_preauth_interfaces);
- free(conf->ctrl_interface);
- free(conf->ca_cert);
- free(conf->server_cert);
- free(conf->private_key);
- free(conf->private_key_passwd);
- free(conf->eap_sim_db);
- free(conf->radius_server_clients);
- free(conf->test_socket);
- free(conf->radius);
- hostapd_config_free_vlan(conf);
- if (conf->ssid.dyn_vlan_keys) {
- struct hostapd_ssid *ssid = &conf->ssid;
- size_t i;
- for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
- if (ssid->dyn_vlan_keys[i] == NULL)
- continue;
- hostapd_config_free_wep(ssid->dyn_vlan_keys[i]);
- free(ssid->dyn_vlan_keys[i]);
- }
- free(ssid->dyn_vlan_keys);
- ssid->dyn_vlan_keys = NULL;
- }
-}
-
-
-void hostapd_config_free(struct hostapd_config *conf)
-{
- size_t i;
-
- if (conf == NULL)
- return;
-
- for (i = 0; i < conf->num_bss; i++)
- hostapd_config_free_bss(&conf->bss[i]);
- free(conf->bss);
-
- free(conf);
-}
-
-
-/* Perform a binary search for given MAC address from a pre-sorted list.
- * Returns 1 if address is in the list or 0 if not. */
-int hostapd_maclist_found(macaddr *list, int num_entries, const u8 *addr)
-{
- int start, end, middle, res;
-
- start = 0;
- end = num_entries - 1;
-
- while (start <= end) {
- middle = (start + end) / 2;
- res = memcmp(list[middle], addr, ETH_ALEN);
- if (res == 0)
- return 1;
- if (res < 0)
- start = middle + 1;
- else
- end = middle - 1;
- }
-
- return 0;
-}
-
-
-int hostapd_rate_found(int *list, int rate)
-{
- int i;
-
- if (list == NULL)
- return 0;
-
- for (i = 0; list[i] >= 0; i++)
- if (list[i] == rate)
- return 1;
-
- return 0;
-}
-
-
-const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
-{
- struct hostapd_vlan *v = vlan;
- while (v) {
- if (v->vlan_id == vlan_id || v->vlan_id == VLAN_ID_WILDCARD)
- return v->ifname;
- v = v->next;
- }
- return NULL;
-}
-
-
-const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
- const u8 *addr, const u8 *prev_psk)
-{
- struct hostapd_wpa_psk *psk;
- int next_ok = prev_psk == NULL;
-
- for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
- if (next_ok &&
- (psk->group || memcmp(psk->addr, addr, ETH_ALEN) == 0))
- return psk->psk;
-
- if (psk->psk == prev_psk)
- next_ok = 1;
- }
-
- return NULL;
-}
-
-
-const struct hostapd_eap_user *
-hostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
- size_t identity_len, int phase2)
-{
- struct hostapd_eap_user *user = conf->eap_user;
-
- while (user) {
- if (!phase2 && user->identity == NULL) {
- /* Wildcard match */
- break;
- }
-
- if (!phase2 && user->wildcard_prefix &&
- identity_len >= user->identity_len &&
- memcmp(user->identity, identity, user->identity_len) == 0)
- {
- /* Wildcard prefix match */
- break;
- }
-
- if (user->phase2 == !!phase2 &&
- user->identity_len == identity_len &&
- memcmp(user->identity, identity, identity_len) == 0)
- break;
- user = user->next;
- }
-
- return user;
-}
+++ /dev/null
-/*
- * hostapd / EAP Standalone Authenticator state machine (RFC 4137)
- * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
- *
- * 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.
- */
-
-#ifndef EAP_H
-#define EAP_H
-
-#include "defs.h"
-#include "eap_defs.h"
-#include "eap_methods.h"
-
-struct eap_sm;
-
-#define EAP_MAX_METHODS 8
-struct eap_user {
- struct {
- int vendor;
- u32 method;
- } methods[EAP_MAX_METHODS];
- u8 *password;
- size_t password_len;
- int password_hash; /* whether password is hashed with
- * nt_password_hash() */
- int phase2;
- int force_version;
-};
-
-enum eapol_bool_var {
- EAPOL_eapSuccess, EAPOL_eapRestart, EAPOL_eapFail, EAPOL_eapResp,
- EAPOL_eapReq, EAPOL_eapNoReq, EAPOL_portEnabled, EAPOL_eapTimeout
-};
-
-struct eapol_callbacks {
- Boolean (*get_bool)(void *ctx, enum eapol_bool_var variable);
- void (*set_bool)(void *ctx, enum eapol_bool_var variable,
- Boolean value);
- void (*set_eapReqData)(void *ctx, const u8 *eapReqData,
- size_t eapReqDataLen);
- void (*set_eapKeyData)(void *ctx, const u8 *eapKeyData,
- size_t eapKeyDataLen);
- int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
- int phase2, struct eap_user *user);
- const char * (*get_eap_req_id_text)(void *ctx, size_t *len);
-};
-
-struct eap_config {
- void *ssl_ctx;
- void *eap_sim_db_priv;
- Boolean backend_auth;
-};
-
-
-#ifdef EAP_SERVER
-
-struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
- struct eap_config *eap_conf);
-void eap_sm_deinit(struct eap_sm *sm);
-int eap_sm_step(struct eap_sm *sm);
-void eap_set_eapRespData(struct eap_sm *sm, const u8 *eapRespData,
- size_t eapRespDataLen);
-void eap_sm_notify_cached(struct eap_sm *sm);
-void eap_sm_pending_cb(struct eap_sm *sm);
-int eap_sm_method_pending(struct eap_sm *sm);
-
-#else /* EAP_SERVER */
-
-static inline struct eap_sm * eap_sm_init(void *eapol_ctx,
- struct eapol_callbacks *eapol_cb,
- struct eap_config *eap_conf)
-{
- return NULL;
-}
-
-static inline void eap_sm_deinit(struct eap_sm *sm)
-{
-}
-
-static inline int eap_sm_step(struct eap_sm *sm)
-{
- return 0;
-}
-
-
-static inline void eap_set_eapRespData(struct eap_sm *sm,
- const u8 *eapRespData,
- size_t eapRespDataLen)
-{
-}
-
-static inline void eap_sm_notify_cached(struct eap_sm *sm)
-{
-}
-
-static inline void eap_sm_pending_cb(struct eap_sm *sm)
-{
-}
-
-static inline int eap_sm_method_pending(struct eap_sm *sm)
-{
- return 0;
-}
-
-#endif /* EAP_SERVER */
-
-#endif /* EAP_H */
+++ /dev/null
-/*
- * hostapd / EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-07.txt)
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
- *
- * 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.
- */
-
-#include "includes.h"
-
-#include "hostapd.h"
-#include "common.h"
-#include "eap_i.h"
-#include "eap_tls_common.h"
-#include "tls.h"
-
-
-/* Maximum supported PEAP version
- * 0 = Microsoft's PEAP version 0; draft-kamath-pppext-peapv0-00.txt
- * 1 = draft-josefsson-ppext-eap-tls-eap-05.txt
- * 2 = draft-josefsson-ppext-eap-tls-eap-07.txt
- */
-#define EAP_PEAP_VERSION 1
-
-
-static void eap_peap_reset(struct eap_sm *sm, void *priv);
-
-
-struct eap_peap_data {
- struct eap_ssl_data ssl;
- enum {
- START, PHASE1, PHASE2_START, PHASE2_ID, PHASE2_METHOD,
- PHASE2_TLV, SUCCESS_REQ, FAILURE_REQ, SUCCESS, FAILURE
- } state;
-
- int peap_version;
- const struct eap_method *phase2_method;
- void *phase2_priv;
- int force_version;
-};
-
-
-static const char * eap_peap_state_txt(int state)
-{
- switch (state) {
- case START:
- return "START";
- case PHASE1:
- return "PHASE1";
- case PHASE2_START:
- return "PHASE2_START";
- case PHASE2_ID:
- return "PHASE2_ID";
- case PHASE2_METHOD:
- return "PHASE2_METHOD";
- case PHASE2_TLV:
- return "PHASE2_TLV";
- case SUCCESS_REQ:
- return "SUCCESS_REQ";
- case FAILURE_REQ:
- return "FAILURE_REQ";
- case SUCCESS:
- return "SUCCESS";
- case FAILURE:
- return "FAILURE";
- default:
- return "Unknown?!";
- }
-}
-
-
-static void eap_peap_state(struct eap_peap_data *data, int state)
-{
- wpa_printf(MSG_DEBUG, "EAP-PEAP: %s -> %s",
- eap_peap_state_txt(data->state),
- eap_peap_state_txt(state));
- data->state = state;
-}
-
-
-static EapType eap_peap_req_success(struct eap_sm *sm,
- struct eap_peap_data *data)
-{
- if (data->state == FAILURE || data->state == FAILURE_REQ) {
- eap_peap_state(data, FAILURE);
- return EAP_TYPE_NONE;
- }
-
- if (data->peap_version == 0) {
- sm->tlv_request = TLV_REQ_SUCCESS;
- eap_peap_state(data, PHASE2_TLV);
- return EAP_TYPE_TLV;
- } else {
- eap_peap_state(data, SUCCESS_REQ);
- return EAP_TYPE_NONE;
- }
-}
-
-
-static EapType eap_peap_req_failure(struct eap_sm *sm,
- struct eap_peap_data *data)
-{
- if (data->state == FAILURE || data->state == FAILURE_REQ ||
- data->state == SUCCESS_REQ ||
- (data->phase2_method &&
- data->phase2_method->method == EAP_TYPE_TLV)) {
- eap_peap_state(data, FAILURE);
- return EAP_TYPE_NONE;
- }
-
- if (data->peap_version == 0) {
- sm->tlv_request = TLV_REQ_FAILURE;
- eap_peap_state(data, PHASE2_TLV);
- return EAP_TYPE_TLV;
- } else {
- eap_peap_state(data, FAILURE_REQ);
- return EAP_TYPE_NONE;
- }
-}
-
-
-static void * eap_peap_init(struct eap_sm *sm)
-{
- struct eap_peap_data *data;
-
- data = wpa_zalloc(sizeof(*data));
- if (data == NULL)
- return NULL;
- data->peap_version = EAP_PEAP_VERSION;
- data->force_version = -1;
- if (sm->user && sm->user->force_version >= 0) {
- data->force_version = sm->user->force_version;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: forcing version %d",
- data->force_version);
- data->peap_version = data->force_version;
- }
- data->state = START;
-
- if (eap_tls_ssl_init(sm, &data->ssl, 0)) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Failed to initialize SSL.");
- eap_peap_reset(sm, data);
- return NULL;
- }
-
- return data;
-}
-
-
-static void eap_peap_reset(struct eap_sm *sm, void *priv)
-{
- struct eap_peap_data *data = priv;
- if (data == NULL)
- return;
- if (data->phase2_priv && data->phase2_method)
- data->phase2_method->reset(sm, data->phase2_priv);
- eap_tls_ssl_deinit(sm, &data->ssl);
- free(data);
-}
-
-
-static u8 * eap_peap_build_start(struct eap_sm *sm, struct eap_peap_data *data,
- int id, size_t *reqDataLen)
-{
- struct eap_hdr *req;
- u8 *pos;
-
- *reqDataLen = sizeof(*req) + 2;
- req = malloc(*reqDataLen);
- if (req == NULL) {
- wpa_printf(MSG_ERROR, "EAP-PEAP: Failed to allocate memory for"
- " request");
- eap_peap_state(data, FAILURE);
- return NULL;
- }
-
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
- req->length = htons(*reqDataLen);
- pos = (u8 *) (req + 1);
- *pos++ = EAP_TYPE_PEAP;
- *pos = EAP_TLS_FLAGS_START | data->peap_version;
-
- eap_peap_state(data, PHASE1);
-
- return (u8 *) req;
-}
-
-
-static u8 * eap_peap_build_req(struct eap_sm *sm, struct eap_peap_data *data,
- int id, size_t *reqDataLen)
-{
- int res;
- u8 *req;
-
- res = eap_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_PEAP,
- data->peap_version, id, &req,
- reqDataLen);
-
- if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase1 done, starting "
- "Phase2");
- eap_peap_state(data, PHASE2_START);
- }
-
- if (res == 1)
- return eap_tls_build_ack(reqDataLen, id, EAP_TYPE_PEAP,
- data->peap_version);
- return req;
-}
-
-
-static u8 * eap_peap_encrypt(struct eap_sm *sm, struct eap_peap_data *data,
- int id, u8 *plain, size_t plain_len,
- size_t *out_len)
-{
- int res;
- u8 *pos;
- struct eap_hdr *req;
-
- /* TODO: add support for fragmentation, if needed. This will need to
- * add TLS Message Length field, if the frame is fragmented. */
- req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
- if (req == NULL)
- return NULL;
-
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
-
- pos = (u8 *) (req + 1);
- *pos++ = EAP_TYPE_PEAP;
- *pos++ = data->peap_version;
-
- res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
- plain, plain_len,
- pos, data->ssl.tls_out_limit);
- if (res < 0) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Failed to encrypt Phase 2 "
- "data");
- free(req);
- return NULL;
- }
-
- *out_len = sizeof(struct eap_hdr) + 2 + res;
- req->length = host_to_be16(*out_len);
- return (u8 *) req;
-}
-
-
-static u8 * eap_peap_build_phase2_req(struct eap_sm *sm,
- struct eap_peap_data *data,
- int id, size_t *reqDataLen)
-{
- u8 *req, *buf, *encr_req;
- size_t req_len;
-
- buf = req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
- &req_len);
- if (req == NULL)
- return NULL;
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
- req, req_len);
-
- if (data->peap_version == 0 &&
- data->phase2_method->method != EAP_TYPE_TLV) {
- req += sizeof(struct eap_hdr);
- req_len -= sizeof(struct eap_hdr);
- }
-
- encr_req = eap_peap_encrypt(sm, data, id, req, req_len, reqDataLen);
- free(buf);
-
- return encr_req;
-}
-
-
-static u8 * eap_peap_build_phase2_term(struct eap_sm *sm,
- struct eap_peap_data *data,
- int id, size_t *reqDataLen, int success)
-{
- u8 *encr_req;
- size_t req_len;
- struct eap_hdr *hdr;
-
- req_len = sizeof(*hdr);
- hdr = wpa_zalloc(req_len);
- if (hdr == NULL)
- return NULL;
-
- hdr->code = success ? EAP_CODE_SUCCESS : EAP_CODE_FAILURE;
- hdr->identifier = id;
- hdr->length = htons(req_len);
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
- (u8 *) hdr, req_len);
-
- encr_req = eap_peap_encrypt(sm, data, id, (u8 *) hdr, req_len,
- reqDataLen);
- free(hdr);
-
- return encr_req;
-}
-
-
-static u8 * eap_peap_buildReq(struct eap_sm *sm, void *priv, int id,
- size_t *reqDataLen)
-{
- struct eap_peap_data *data = priv;
-
- switch (data->state) {
- case START:
- return eap_peap_build_start(sm, data, id, reqDataLen);
- case PHASE1:
- return eap_peap_build_req(sm, data, id, reqDataLen);
- case PHASE2_ID:
- case PHASE2_METHOD:
- case PHASE2_TLV:
- return eap_peap_build_phase2_req(sm, data, id, reqDataLen);
- case SUCCESS_REQ:
- return eap_peap_build_phase2_term(sm, data, id, reqDataLen, 1);
- case FAILURE_REQ:
- return eap_peap_build_phase2_term(sm, data, id, reqDataLen, 0);
- default:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d",
- __func__, data->state);
- return NULL;
- }
-}
-
-
-static Boolean eap_peap_check(struct eap_sm *sm, void *priv,
- u8 *respData, size_t respDataLen)
-{
- struct eap_hdr *resp;
- u8 *pos;
-
- resp = (struct eap_hdr *) respData;
- pos = (u8 *) (resp + 1);
- if (respDataLen < sizeof(*resp) + 2 || *pos != EAP_TYPE_PEAP ||
- (ntohs(resp->length)) > respDataLen) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Invalid frame");
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static int eap_peap_phase2_init(struct eap_sm *sm, struct eap_peap_data *data,
- EapType eap_type)
-{
- if (data->phase2_priv && data->phase2_method) {
- data->phase2_method->reset(sm, data->phase2_priv);
- data->phase2_method = NULL;
- data->phase2_priv = NULL;
- }
- data->phase2_method = eap_sm_get_eap_methods(EAP_VENDOR_IETF,
- eap_type);
- if (!data->phase2_method)
- return -1;
-
- sm->init_phase2 = 1;
- data->phase2_priv = data->phase2_method->init(sm);
- sm->init_phase2 = 0;
- return 0;
-}
-
-
-static void eap_peap_process_phase2_response(struct eap_sm *sm,
- struct eap_peap_data *data,
- u8 *in_data, size_t in_len)
-{
- u8 next_type = EAP_TYPE_NONE;
- struct eap_hdr *hdr;
- u8 *pos;
- size_t left;
-
- if (data->phase2_priv == NULL) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - Phase2 not "
- "initialized?!", __func__);
- return;
- }
-
- hdr = (struct eap_hdr *) in_data;
- pos = (u8 *) (hdr + 1);
-
- if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
- left = in_len - sizeof(*hdr);
- wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Phase2 type Nak'ed; "
- "allowed types", pos + 1, left - 1);
- eap_sm_process_nak(sm, pos + 1, left - 1);
- if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
- sm->user->methods[sm->user_eap_method_index].method !=
- EAP_TYPE_NONE) {
- next_type = sm->user->methods[
- sm->user_eap_method_index++].method;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d",
- next_type);
- } else {
- next_type = eap_peap_req_failure(sm, data);
- }
- eap_peap_phase2_init(sm, data, next_type);
- return;
- }
-
- if (data->phase2_method->check(sm, data->phase2_priv, in_data,
- in_len)) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 check() asked to "
- "ignore the packet");
- return;
- }
-
- data->phase2_method->process(sm, data->phase2_priv, in_data, in_len);
-
- if (!data->phase2_method->isDone(sm, data->phase2_priv))
- return;
-
-
- if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method failed");
- next_type = eap_peap_req_failure(sm, data);
- eap_peap_phase2_init(sm, data, next_type);
- return;
- }
-
- switch (data->state) {
- case PHASE2_ID:
- if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
- wpa_hexdump_ascii(MSG_DEBUG, "EAP_PEAP: Phase2 "
- "Identity not found in the user "
- "database",
- sm->identity, sm->identity_len);
- next_type = eap_peap_req_failure(sm, data);
- break;
- }
-
- eap_peap_state(data, PHASE2_METHOD);
- next_type = sm->user->methods[0].method;
- sm->user_eap_method_index = 1;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type);
- break;
- case PHASE2_METHOD:
- next_type = eap_peap_req_success(sm, data);
- break;
- case PHASE2_TLV:
- if (sm->tlv_request == TLV_REQ_SUCCESS ||
- data->state == SUCCESS_REQ) {
- eap_peap_state(data, SUCCESS);
- } else {
- eap_peap_state(data, FAILURE);
- }
- break;
- case FAILURE:
- break;
- default:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d",
- __func__, data->state);
- break;
- }
-
- eap_peap_phase2_init(sm, data, next_type);
-}
-
-
-static void eap_peap_process_phase2(struct eap_sm *sm,
- struct eap_peap_data *data,
- struct eap_hdr *resp,
- u8 *in_data, size_t in_len)
-{
- u8 *in_decrypted;
- int len_decrypted, len, res;
- struct eap_hdr *hdr;
- size_t buf_len;
-
- wpa_printf(MSG_DEBUG, "EAP-PEAP: received %lu bytes encrypted data for"
- " Phase 2", (unsigned long) in_len);
-
- res = eap_tls_data_reassemble(sm, &data->ssl, &in_data, &in_len);
- if (res < 0 || res == 1)
- return;
-
- buf_len = in_len;
- if (data->ssl.tls_in_total > buf_len)
- buf_len = data->ssl.tls_in_total;
- in_decrypted = malloc(buf_len);
- if (in_decrypted == NULL) {
- free(data->ssl.tls_in);
- data->ssl.tls_in = NULL;
- data->ssl.tls_in_len = 0;
- wpa_printf(MSG_WARNING, "EAP-PEAP: failed to allocate memory "
- "for decryption");
- return;
- }
-
- len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
- in_data, in_len,
- in_decrypted, buf_len);
- free(data->ssl.tls_in);
- data->ssl.tls_in = NULL;
- data->ssl.tls_in_len = 0;
- if (len_decrypted < 0) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Failed to decrypt Phase 2 "
- "data");
- free(in_decrypted);
- eap_peap_state(data, FAILURE);
- return;
- }
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP",
- in_decrypted, len_decrypted);
-
- hdr = (struct eap_hdr *) in_decrypted;
-
- if (data->peap_version == 0 && data->state != PHASE2_TLV) {
- struct eap_hdr *nhdr = malloc(sizeof(struct eap_hdr) +
- len_decrypted);
- if (nhdr == NULL) {
- free(in_decrypted);
- return;
- }
- memcpy((u8 *) (nhdr + 1), in_decrypted, len_decrypted);
- free(in_decrypted);
- nhdr->code = resp->code;
- nhdr->identifier = resp->identifier;
- nhdr->length = host_to_be16(sizeof(struct eap_hdr) +
- len_decrypted);
-
- len_decrypted += sizeof(struct eap_hdr);
- in_decrypted = (u8 *) nhdr;
- }
- hdr = (struct eap_hdr *) in_decrypted;
- if (len_decrypted < (int) sizeof(*hdr)) {
- free(in_decrypted);
- wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
- "EAP frame (len=%d)", len_decrypted);
- eap_peap_req_failure(sm, data);
- return;
- }
- len = be_to_host16(hdr->length);
- if (len > len_decrypted) {
- free(in_decrypted);
- wpa_printf(MSG_INFO, "EAP-PEAP: Length mismatch in "
- "Phase 2 EAP frame (len=%d hdr->length=%d)",
- len_decrypted, len);
- eap_peap_req_failure(sm, data);
- return;
- }
- wpa_printf(MSG_DEBUG, "EAP-PEAP: received Phase 2: code=%d "
- "identifier=%d length=%d", hdr->code, hdr->identifier, len);
- switch (hdr->code) {
- case EAP_CODE_RESPONSE:
- eap_peap_process_phase2_response(sm, data, (u8 *) hdr, len);
- break;
- case EAP_CODE_SUCCESS:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Success");
- if (data->state == SUCCESS_REQ) {
- eap_peap_state(data, SUCCESS);
- }
- break;
- case EAP_CODE_FAILURE:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Failure");
- eap_peap_state(data, FAILURE);
- break;
- default:
- wpa_printf(MSG_INFO, "EAP-PEAP: Unexpected code=%d in "
- "Phase 2 EAP header", hdr->code);
- break;
- }
-
- free(in_decrypted);
- }
-
-
-static void eap_peap_process(struct eap_sm *sm, void *priv,
- u8 *respData, size_t respDataLen)
-{
- struct eap_peap_data *data = priv;
- struct eap_hdr *resp;
- u8 *pos, flags;
- int left;
- unsigned int tls_msg_len;
- int peer_version;
-
- resp = (struct eap_hdr *) respData;
- pos = (u8 *) (resp + 1);
- pos++;
- flags = *pos++;
- left = htons(resp->length) - sizeof(struct eap_hdr) - 2;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Received packet(len=%lu) - "
- "Flags 0x%02x", (unsigned long) respDataLen, flags);
- peer_version = flags & EAP_PEAP_VERSION_MASK;
- if (data->force_version >= 0 && peer_version != data->force_version) {
- wpa_printf(MSG_INFO, "EAP-PEAP: peer did not select the forced"
- " version (forced=%d peer=%d) - reject",
- data->force_version, peer_version);
- eap_peap_state(data, FAILURE);
- return;
- }
- if (peer_version < data->peap_version) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: peer ver=%d, own ver=%d; "
- "use version %d",
- peer_version, data->peap_version, peer_version);
- data->peap_version = peer_version;
- }
- if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
- if (left < 4) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Short frame with TLS "
- "length");
- eap_peap_state(data, FAILURE);
- return;
- }
- tls_msg_len = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) |
- pos[3];
- wpa_printf(MSG_DEBUG, "EAP-PEAP: TLS Message Length: %d",
- tls_msg_len);
- if (data->ssl.tls_in_left == 0) {
- data->ssl.tls_in_total = tls_msg_len;
- data->ssl.tls_in_left = tls_msg_len;
- free(data->ssl.tls_in);
- data->ssl.tls_in = NULL;
- data->ssl.tls_in_len = 0;
- }
- pos += 4;
- left -= 4;
- }
-
- switch (data->state) {
- case PHASE1:
- if (eap_tls_process_helper(sm, &data->ssl, pos, left) < 0) {
- wpa_printf(MSG_INFO, "EAP-PEAP: TLS processing "
- "failed");
- eap_peap_state(data, FAILURE);
- }
- break;
- case PHASE2_START:
- eap_peap_state(data, PHASE2_ID);
- eap_peap_phase2_init(sm, data, EAP_TYPE_IDENTITY);
- break;
- case PHASE2_ID:
- case PHASE2_METHOD:
- case PHASE2_TLV:
- eap_peap_process_phase2(sm, data, resp, pos, left);
- break;
- case SUCCESS_REQ:
- eap_peap_state(data, SUCCESS);
- break;
- case FAILURE_REQ:
- eap_peap_state(data, FAILURE);
- break;
- default:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Unexpected state %d in %s",
- data->state, __func__);
- break;
- }
-
- if (tls_connection_get_write_alerts(sm->ssl_ctx, data->ssl.conn) > 1) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Locally detected fatal error "
- "in TLS processing");
- eap_peap_state(data, FAILURE);
- }
-}
-
-
-static Boolean eap_peap_isDone(struct eap_sm *sm, void *priv)
-{
- struct eap_peap_data *data = priv;
- return data->state == SUCCESS || data->state == FAILURE;
-}
-
-
-static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
-{
- struct eap_peap_data *data = priv;
- u8 *eapKeyData;
-
- if (data->state != SUCCESS)
- return NULL;
-
- /* TODO: PEAPv1 - different label in some cases */
- eapKeyData = eap_tls_derive_key(sm, &data->ssl,
- "client EAP encryption",
- EAP_TLS_KEY_LEN);
- if (eapKeyData) {
- *len = EAP_TLS_KEY_LEN;
- wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key",
- eapKeyData, EAP_TLS_KEY_LEN);
- } else {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive key");
- }
-
- return eapKeyData;
-}
-
-
-static Boolean eap_peap_isSuccess(struct eap_sm *sm, void *priv)
-{
- struct eap_peap_data *data = priv;
- return data->state == SUCCESS;
-}
-
-
-int eap_server_peap_register(void)
-{
- struct eap_method *eap;
- int ret;
-
- eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
- EAP_VENDOR_IETF, EAP_TYPE_PEAP, "PEAP");
- if (eap == NULL)
- return -1;
-
- eap->init = eap_peap_init;
- eap->reset = eap_peap_reset;
- eap->buildReq = eap_peap_buildReq;
- eap->check = eap_peap_check;
- eap->process = eap_peap_process;
- eap->isDone = eap_peap_isDone;
- eap->getKey = eap_peap_getKey;
- eap->isSuccess = eap_peap_isSuccess;
-
- ret = eap_server_method_register(eap);
- if (ret)
- eap_server_method_free(eap);
- return ret;
-}
+++ /dev/null
-/*
- * hostapd / EAP-TLS/PEAP/TTLS common functions
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
- *
- * 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.
- */
-
-#include "includes.h"
-
-#include "hostapd.h"
-#include "common.h"
-#include "eap_i.h"
-#include "eap_tls_common.h"
-#include "sha1.h"
-#include "tls.h"
-
-
-int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
- int verify_peer)
-{
- data->eap = sm;
- data->phase2 = sm->init_phase2;
-
- data->conn = tls_connection_init(sm->ssl_ctx);
- if (data->conn == NULL) {
- wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
- "connection");
- return -1;
- }
-
- if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer)) {
- wpa_printf(MSG_INFO, "SSL: Failed to configure verification "
- "of TLS peer certificate");
- tls_connection_deinit(sm->ssl_ctx, data->conn);
- data->conn = NULL;
- return -1;
- }
-
- /* TODO: make this configurable */
- data->tls_out_limit = 1398;
- if (data->phase2) {
- /* Limit the fragment size in the inner TLS authentication
- * since the outer authentication with EAP-PEAP does not yet
- * support fragmentation */
- if (data->tls_out_limit > 100)
- data->tls_out_limit -= 100;
- }
- return 0;
-}
-
-
-void eap_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
-{
- tls_connection_deinit(sm->ssl_ctx, data->conn);
- free(data->tls_in);
- free(data->tls_out);
-}
-
-
-u8 * eap_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- char *label, size_t len)
-{
- struct tls_keys keys;
- u8 *rnd = NULL, *out;
-
- out = malloc(len);
- if (out == NULL)
- return NULL;
-
- if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
- 0)
- return out;
-
- if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
- goto fail;
-
- if (keys.client_random == NULL || keys.server_random == NULL ||
- keys.master_key == NULL)
- goto fail;
-
- rnd = malloc(keys.client_random_len + keys.server_random_len);
- if (rnd == NULL)
- goto fail;
- memcpy(rnd, keys.client_random, keys.client_random_len);
- memcpy(rnd + keys.client_random_len, keys.server_random,
- keys.server_random_len);
-
- if (tls_prf(keys.master_key, keys.master_key_len,
- label, rnd, keys.client_random_len +
- keys.server_random_len, out, len))
- goto fail;
-
- free(rnd);
- return out;
-
-fail:
- free(out);
- free(rnd);
- return NULL;
-}
-
-
-int eap_tls_data_reassemble(struct eap_sm *sm, struct eap_ssl_data *data,
- u8 **in_data, size_t *in_len)
-{
- u8 *buf;
-
- if (data->tls_in_left > *in_len || data->tls_in) {
- if (data->tls_in_len + *in_len > 65536) {
- /* Limit length to avoid rogue peers from causing large
- * memory allocations. */
- free(data->tls_in);
- data->tls_in = NULL;
- data->tls_in_len = 0;
- wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size"
- " over 64 kB)");
- return -1;
- }
- buf = realloc(data->tls_in, data->tls_in_len + *in_len);
- if (buf == NULL) {
- free(data->tls_in);
- data->tls_in = NULL;
- data->tls_in_len = 0;
- wpa_printf(MSG_INFO, "SSL: Could not allocate memory "
- "for TLS data");
- return -1;
- }
- memcpy(buf + data->tls_in_len, *in_data, *in_len);
- data->tls_in = buf;
- data->tls_in_len += *in_len;
- if (*in_len > data->tls_in_left) {
- wpa_printf(MSG_INFO, "SSL: more data than TLS message "
- "length indicated");
- data->tls_in_left = 0;
- return -1;
- }
- data->tls_in_left -= *in_len;
- if (data->tls_in_left > 0) {
- wpa_printf(MSG_DEBUG, "SSL: Need %lu bytes more input "
- "data", (unsigned long) data->tls_in_left);
- return 1;
- }
-
- *in_data = data->tls_in;
- *in_len = data->tls_in_len;
- } else
- data->tls_in_left = 0;
-
- return 0;
-}
-
-
-int eap_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
- u8 *in_data, size_t in_len)
-{
- WPA_ASSERT(data->tls_out_len == 0 || in_len == 0);
-
- if (data->tls_out_len == 0) {
- /* No more data to send out - expect to receive more data from
- * the peer. */
- int res = eap_tls_data_reassemble(sm, data, &in_data, &in_len);
- if (res < 0 || res == 1) {
- wpa_printf(MSG_DEBUG, "SSL: data reassembly failed");
- return res;
- }
- /* Full TLS message reassembled - continue handshake processing
- */
- if (data->tls_out) {
- /* This should not happen.. */
- wpa_printf(MSG_INFO, "SSL: eap_tls_process_helper - "
- "pending tls_out data even though "
- "tls_out_len = 0");
- free(data->tls_out);
- WPA_ASSERT(data->tls_out == NULL);
- }
- data->tls_out = tls_connection_server_handshake(
- sm->ssl_ctx, data->conn, in_data, in_len,
- &data->tls_out_len);
-
- /* Clear reassembled input data (if the buffer was needed). */
- data->tls_in_left = data->tls_in_total = data->tls_in_len = 0;
- free(data->tls_in);
- data->tls_in = NULL;
- }
-
- if (data->tls_out == NULL) {
- wpa_printf(MSG_DEBUG, "SSL: failed to generate output data");
- data->tls_out_len = 0;
- return -1;
- }
- if (data->tls_out_len == 0) {
- /* TLS negotiation should now be complete since all other cases
- * needing more that should have been catched above based on
- * the TLS Message Length field. */
- wpa_printf(MSG_DEBUG, "SSL: No data to be sent out");
- free(data->tls_out);
- data->tls_out = NULL;
-
- if (tls_connection_get_read_alerts(sm->ssl_ctx, data->conn)) {
- wpa_printf(MSG_DEBUG, "SSL: Remote end sent a fatal "
- "alert - abort handshake");
- return -1;
- }
-
- return 1;
- }
-
- wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total "
- "%lu bytes)",
- (unsigned long) data->tls_out_len - data->tls_out_pos,
- (unsigned long) data->tls_out_len);
-
- return 0;
-}
-
-
-int eap_tls_buildReq_helper(struct eap_sm *sm, struct eap_ssl_data *data,
- int eap_type, int peap_version, u8 id,
- u8 **out_data, size_t *out_len)
-{
- size_t len;
- u8 *pos, *flags;
- struct eap_hdr *req;
-
- *out_len = 0;
-
- req = malloc(sizeof(struct eap_hdr) + 2 + 4 + data->tls_out_limit);
- if (req == NULL) {
- *out_data = NULL;
- return -1;
- }
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
- pos = (u8 *) (req + 1);
- *pos++ = eap_type;
- flags = pos++;
- *flags = peap_version;
- if (data->tls_out_pos == 0 &&
- data->tls_out_len > data->tls_out_limit) {
- *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
- *pos++ = (data->tls_out_len >> 24) & 0xff;
- *pos++ = (data->tls_out_len >> 16) & 0xff;
- *pos++ = (data->tls_out_len >> 8) & 0xff;
- *pos++ = data->tls_out_len & 0xff;
- }
-
- len = data->tls_out_len - data->tls_out_pos;
- if (len > data->tls_out_limit) {
- *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS;
- len = data->tls_out_limit;
- wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments "
- "will follow", (unsigned long) len);
- }
- memcpy(pos, &data->tls_out[data->tls_out_pos], len);
- data->tls_out_pos += len;
- *out_len = (pos - (u8 *) req) + len;
- req->length = htons(*out_len);
- *out_data = (u8 *) req;
-
- if (!(*flags & EAP_TLS_FLAGS_MORE_FRAGMENTS)) {
- data->tls_out_len = 0;
- data->tls_out_pos = 0;
- free(data->tls_out);
- data->tls_out = NULL;
- }
-
- return 0;
-}
-
-
-u8 * eap_tls_build_ack(size_t *reqDataLen, u8 id, int eap_type,
- int peap_version)
-{
- struct eap_hdr *req;
- u8 *pos;
-
- *reqDataLen = sizeof(struct eap_hdr) + 2;
- req = malloc(*reqDataLen);
- if (req == NULL)
- return NULL;
- wpa_printf(MSG_DEBUG, "SSL: Building ACK");
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
- req->length = htons(*reqDataLen);
- pos = (u8 *) (req + 1);
- *pos++ = eap_type; /* Type */
- *pos = peap_version; /* Flags */
- return (u8 *) req;
-}
+++ /dev/null
-/*
- * hostapd / EAP-TLS/PEAP/TTLS common functions
- * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
- *
- * 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.
- */
-
-#ifndef EAP_TLS_COMMON_H
-#define EAP_TLS_COMMON_H
-
-struct eap_ssl_data {
- struct tls_connection *conn;
-
- u8 *tls_out;
- size_t tls_out_len;
- size_t tls_out_pos;
- size_t tls_out_limit;
- u8 *tls_in;
- size_t tls_in_len;
- size_t tls_in_left;
- size_t tls_in_total;
-
- int phase2;
-
- struct eap_sm *eap;
-};
-
-
-/* EAP TLS Flags */
-#define EAP_TLS_FLAGS_LENGTH_INCLUDED 0x80
-#define EAP_TLS_FLAGS_MORE_FRAGMENTS 0x40
-#define EAP_TLS_FLAGS_START 0x20
-#define EAP_PEAP_VERSION_MASK 0x07
-
- /* could be up to 128 bytes, but only the first 64 bytes are used */
-#define EAP_TLS_KEY_LEN 64
-
-
-int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
- int verify_peer);
-void eap_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
-u8 * eap_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- char *label, size_t len);
-int eap_tls_data_reassemble(struct eap_sm *sm, struct eap_ssl_data *data,
- u8 **in_data, size_t *in_len);
-int eap_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
- u8 *in_data, size_t in_len);
-int eap_tls_buildReq_helper(struct eap_sm *sm, struct eap_ssl_data *data,
- int eap_type, int peap_version, u8 id,
- u8 **out_data, size_t *out_len);
-u8 * eap_tls_build_ack(size_t *reqDataLen, u8 id, int eap_type,
- int peap_version);
-
-#endif /* EAP_TLS_COMMON_H */
+++ /dev/null
-/*
- * hostapd / EAP-TLV (draft-josefsson-pppext-eap-tls-eap-07.txt)
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
- *
- * 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.
- */
-
-#include "includes.h"
-
-#include "hostapd.h"
-#include "common.h"
-#include "eap_i.h"
-
-
-/* EAP-TLV TLVs (draft-josefsson-ppext-eap-tls-eap-07.txt) */
-#define EAP_TLV_RESULT_TLV 3 /* Acknowledged Result */
-#define EAP_TLV_NAK_TLV 4
-#define EAP_TLV_CRYPTO_BINDING_TLV 5
-#define EAP_TLV_CONNECTION_BINDING_TLV 6
-#define EAP_TLV_VENDOR_SPECIFIC_TLV 7
-#define EAP_TLV_URI_TLV 8
-#define EAP_TLV_EAP_PAYLOAD_TLV 9
-#define EAP_TLV_INTERMEDIATE_RESULT_TLV 10
-
-#define EAP_TLV_RESULT_SUCCESS 1
-#define EAP_TLV_RESULT_FAILURE 2
-
-
-struct eap_tlv_data {
- enum { CONTINUE, SUCCESS, FAILURE } state;
-};
-
-
-static void * eap_tlv_init(struct eap_sm *sm)
-{
- struct eap_tlv_data *data;
-
- data = wpa_zalloc(sizeof(*data));
- if (data == NULL)
- return NULL;
- data->state = CONTINUE;
-
- return data;
-}
-
-
-static void eap_tlv_reset(struct eap_sm *sm, void *priv)
-{
- struct eap_tlv_data *data = priv;
- free(data);
-}
-
-
-static u8 * eap_tlv_buildReq(struct eap_sm *sm, void *priv, int id,
- size_t *reqDataLen)
-{
- struct eap_hdr *req;
- u8 *pos;
- u16 status;
-
- if (sm->tlv_request == TLV_REQ_SUCCESS) {
- status = EAP_TLV_RESULT_SUCCESS;
- } else {
- status = EAP_TLV_RESULT_FAILURE;
- }
-
- *reqDataLen = sizeof(struct eap_hdr) + 1 + 6;
- req = malloc(*reqDataLen);
- if (req == NULL)
- return NULL;
-
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
- req->length = host_to_be16(*reqDataLen);
- pos = (u8 *) (req + 1);
- *pos++ = EAP_TYPE_TLV;
- *pos++ = 0x80; /* Mandatory */
- *pos++ = EAP_TLV_RESULT_TLV;
- /* Length */
- *pos++ = 0;
- *pos++ = 2;
- /* Status */
- *pos++ = status >> 8;
- *pos++ = status & 0xff;
-
- return (u8 *) req;
-}
-
-
-static Boolean eap_tlv_check(struct eap_sm *sm, void *priv,
- u8 *respData, size_t respDataLen)
-{
- struct eap_hdr *resp;
- u8 *pos;
-
- resp = (struct eap_hdr *) respData;
- pos = (u8 *) (resp + 1);
- if (respDataLen < sizeof(*resp) + 1 || *pos != EAP_TYPE_TLV ||
- (ntohs(resp->length)) > respDataLen) {
- wpa_printf(MSG_INFO, "EAP-TLV: Invalid frame");
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static void eap_tlv_process(struct eap_sm *sm, void *priv,
- u8 *respData, size_t respDataLen)
-{
- struct eap_tlv_data *data = priv;
- struct eap_hdr *resp;
- u8 *pos;
- size_t left;
- u8 *result_tlv = NULL;
- size_t result_tlv_len = 0;
- int tlv_type, mandatory, tlv_len;
-
- resp = (struct eap_hdr *) respData;
- pos = (u8 *) (resp + 1);
-
- /* Parse TLVs */
- left = be_to_host16(resp->length) - sizeof(struct eap_hdr) - 1;
- pos = (u8 *) (resp + 1);
- pos++;
- wpa_hexdump(MSG_DEBUG, "EAP-TLV: Received TLVs", pos, left);
- while (left >= 4) {
- mandatory = !!(pos[0] & 0x80);
- tlv_type = pos[0] & 0x3f;
- tlv_type = (tlv_type << 8) | pos[1];
- tlv_len = ((int) pos[2] << 8) | pos[3];
- pos += 4;
- left -= 4;
- if ((size_t) tlv_len > left) {
- wpa_printf(MSG_DEBUG, "EAP-TLV: TLV underrun "
- "(tlv_len=%d left=%lu)", tlv_len,
- (unsigned long) left);
- data->state = FAILURE;
- return;
- }
- switch (tlv_type) {
- case EAP_TLV_RESULT_TLV:
- result_tlv = pos;
- result_tlv_len = tlv_len;
- break;
- default:
- wpa_printf(MSG_DEBUG, "EAP-TLV: Unsupported TLV Type "
- "%d%s", tlv_type,
- mandatory ? " (mandatory)" : "");
- if (mandatory) {
- data->state = FAILURE;
- return;
- }
- /* Ignore this TLV, but process other TLVs */
- break;
- }
-
- pos += tlv_len;
- left -= tlv_len;
- }
- if (left) {
- wpa_printf(MSG_DEBUG, "EAP-TLV: Last TLV too short in "
- "Request (left=%lu)", (unsigned long) left);
- data->state = FAILURE;
- return;
- }
-
- /* Process supported TLVs */
- if (result_tlv) {
- int status;
- const char *requested;
-
- wpa_hexdump(MSG_DEBUG, "EAP-TLV: Result TLV",
- result_tlv, result_tlv_len);
- if (result_tlv_len < 2) {
- wpa_printf(MSG_INFO, "EAP-TLV: Too short Result TLV "
- "(len=%lu)",
- (unsigned long) result_tlv_len);
- data->state = FAILURE;
- return;
- }
- requested = sm->tlv_request == TLV_REQ_SUCCESS ? "Success" :
- "Failure";
- status = ((int) result_tlv[0] << 8) | result_tlv[1];
- if (status == EAP_TLV_RESULT_SUCCESS) {
- wpa_printf(MSG_INFO, "EAP-TLV: TLV Result - Success "
- "- requested %s", requested);
- if (sm->tlv_request == TLV_REQ_SUCCESS)
- data->state = SUCCESS;
- else
- data->state = FAILURE;
-
- } else if (status == EAP_TLV_RESULT_FAILURE) {
- wpa_printf(MSG_INFO, "EAP-TLV: TLV Result - Failure - "
- "requested %s", requested);
- if (sm->tlv_request == TLV_REQ_FAILURE)
- data->state = SUCCESS;
- else
- data->state = FAILURE;
- } else {
- wpa_printf(MSG_INFO, "EAP-TLV: Unknown TLV Result "
- "Status %d", status);
- data->state = FAILURE;
- }
- }
-}
-
-
-static Boolean eap_tlv_isDone(struct eap_sm *sm, void *priv)
-{
- struct eap_tlv_data *data = priv;
- return data->state != CONTINUE;
-}
-
-
-static Boolean eap_tlv_isSuccess(struct eap_sm *sm, void *priv)
-{
- struct eap_tlv_data *data = priv;
- return data->state == SUCCESS;
-}
-
-
-int eap_server_tlv_register(void)
-{
- struct eap_method *eap;
- int ret;
-
- eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
- EAP_VENDOR_IETF, EAP_TYPE_TLV, "TLV");
- if (eap == NULL)
- return -1;
-
- eap->init = eap_tlv_init;
- eap->reset = eap_tlv_reset;
- eap->buildReq = eap_tlv_buildReq;
- eap->check = eap_tlv_check;
- eap->process = eap_tlv_process;
- eap->isDone = eap_tlv_isDone;
- eap->isSuccess = eap_tlv_isSuccess;
-
- ret = eap_server_method_register(eap);
- if (ret)
- eap_server_method_free(eap);
- return ret;
-}
+++ /dev/null
-# Parameters for Milenage (Example algorithms for AKA).
-# The example Ki, OPc, and AMF values here are from 3GPP TS 35.208 v6.0.0
-# 4.3.20 Test Set 20. SQN is the last used SQN value.
-# These values can be used for both UMTS (EAP-AKA) and GSM (EAP-SIM)
-# authentication. In case of GSM/EAP-SIM, AMF and SQN values are not used, but
-# dummy values will need to be included in this file.
-
-# IMSI Ki OPc AMF SQN
-232010000000000 90dca4eda45b53cf0f12d7c9c3bc6a89 cb9cccc4b9258e6dca4760379fb82581 61df 000000000000
+++ /dev/null
-# List of MAC addresses that are allowed to authenticate (IEEE 802.11)
-# with the AP.
-00:11:22:33:44:55
-00:66:77:88:99:aa
-00:00:22:33:44:55
+++ /dev/null
-##### hostapd configuration file ##############################################
-# Empty lines and lines starting with # are ignored
-
-# AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for
-# management frames); ath0 for madwifi
-interface=wlan0
-
-# In case of madwifi driver, an additional configuration parameter, bridge,
-# must be used to notify hostapd if the interface is included in a bridge. This
-# parameter is not used with Host AP driver.
-#bridge=br0
-
-# Driver interface type (hostap/wired/madwifi/prism54; default: hostap)
-# driver=hostap
-
-# hostapd event logger configuration
-#
-# Two output method: syslog and stdout (only usable if not forking to
-# background).
-#
-# Module bitfield (ORed bitfield of modules that will be logged; -1 = all
-# modules):
-# bit 0 (1) = IEEE 802.11
-# bit 1 (2) = IEEE 802.1X
-# bit 2 (4) = RADIUS
-# bit 3 (8) = WPA
-# bit 4 (16) = driver interface
-# bit 5 (32) = IAPP
-# bit 6 (64) = MLME
-#
-# Levels (minimum value for logged events):
-# 0 = verbose debugging
-# 1 = debugging
-# 2 = informational messages
-# 3 = notification
-# 4 = warning
-#
-logger_syslog=-1
-logger_syslog_level=2
-logger_stdout=-1
-logger_stdout_level=2
-
-# Debugging: 0 = no, 1 = minimal, 2 = verbose, 3 = msg dumps, 4 = excessive
-debug=0
-
-# Dump file for state information (on SIGUSR1)
-dump_file=/tmp/hostapd.dump
-
-# Interface for separate control program. If this is specified, hostapd
-# will create this directory and a UNIX domain socket for listening to requests
-# from external programs (CLI/GUI, etc.) for status information and
-# configuration. The socket file will be named based on the interface name, so
-# multiple hostapd processes/interfaces can be run at the same time if more
-# than one interface is used.
-# /var/run/hostapd is the recommended directory for sockets and by default,
-# hostapd_cli will use it when trying to connect with hostapd.
-ctrl_interface=/var/run/hostapd
-
-# Access control for the control interface can be configured by setting the
-# directory to allow only members of a group to use sockets. This way, it is
-# possible to run hostapd as root (since it needs to change network
-# configuration and open raw sockets) and still allow GUI/CLI components to be
-# run as non-root users. However, since the control interface can be used to
-# change the network configuration, this access needs to be protected in many
-# cases. By default, hostapd is configured to use gid 0 (root). If you
-# want to allow non-root users to use the contron interface, add a new group
-# and change this value to match with that group. Add users that should have
-# control interface access to this group.
-#
-# This variable can be a group name or gid.
-#ctrl_interface_group=wheel
-ctrl_interface_group=0
-
-
-##### IEEE 802.11 related configuration #######################################
-
-# SSID to be used in IEEE 802.11 management frames
-ssid=test
-
-# Country code (ISO/IEC 3166-1). Used to set regulatory domain.
-# Modify as needed to indicate country in which device is operating.
-# This can limit available channels and transmit power.
-# (default: US)
-#country_code=US
-
-# Enable IEEE 802.11d. This advertises the country_code and the set of allowed
-# channels and transmit power levels based on the regulatory limits. The
-# country_code setting must be configured with the correct country for
-# IEEE 802.11d functions.
-# (default: 0 = disabled)
-#ieee80211d=1
-
-# Enable IEEE 802.11h. This enables the TPC and DFS services when operating
-# in a regulatory domain which requires them. Once enabled it will be
-# operational only when working in hw_mode a and in countries where it is
-# required. The end user should not be allowed to disable this.
-# The country_code setting must be configured with the correct country for
-# IEEE 802.11h to function.
-# When IEEE 802.11h is operational, the channel_policy and configured channel
-# settings will be ignored but will behave as though the channel_policy is
-# set to "3" (automatic channel selection). When IEEE 802.11h is enabled but
-# not operational (for example, if the radio mode is changed from "a" to "b")
-# the channel_policy and channel settings take effect again.
-# (default: 1 = enabled)
-#ieee80211h=1
-
-# Operation mode (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g,
-# Default: IEEE 802.11b
-hw_mode=a
-
-# Channel number (IEEE 802.11)
-# (default: 0, i.e., not set, used with channel_policy=2)
-channel=60
-
-# Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
-beacon_int=100
-
-# DTIM (delivery trafic information message) period (range 1..255):
-# number of beacons between DTIMs (1 = every beacon includes DTIM element)
-# (default: 2)
-dtim_period=2
-
-# Maximum number of stations allowed in station table. New stations will be
-# rejected after the station table is full. IEEE 802.11 has a limit of 2007
-# different association IDs, so this number should not be larger than that.
-# (default: 2007)
-max_num_sta=255
-
-# RTS/CTS threshold; 2347 = disabled (default); range 0..2347
-# If this field is not included in hostapd.conf, hostapd will not control
-# RTS threshold and 'iwconfig wlan# rts <val>' can be used to set it.
-rts_threshold=2347
-
-# Fragmentation threshold; 2346 = disabled (default); range 256..2346
-# If this field is not included in hostapd.conf, hostapd will not control
-# fragmentation threshold and 'iwconfig wlan# frag <val>' can be used to set
-# it.
-fragm_threshold=2346
-
-# Rate configuration
-# Default is to enable all rates supported by the hardware. This configuration
-# item allows this list be filtered so that only the listed rates will be left
-# in the list. If the list is empty, all rates are used. This list can have
-# entries that are not in the list of rates the hardware supports (such entries
-# are ignored). The entries in this list are in 100 kbps, i.e., 11 Mbps = 110.
-# If this item is present, at least one rate have to be matching with the rates
-# hardware supports.
-# default: use the most common supported rate setting for the selected
-# hw_mode (i.e., this line can be removed from configuration file in most
-# cases)
-#supported_rates=10 20 55 110 60 90 120 180 240 360 480 540
-
-# Basic rate set configuration
-# List of rates (in 100 kbps) that are included in the basic rate set.
-# If this item is not included, usually reasonable default set is used.
-#basic_rates=10 20
-#basic_rates=10 20 55 110
-#basic_rates=60 120 240
-
-# Station MAC address -based authentication
-# Please note that this kind of access control requires a driver that uses
-# hostapd to take care of management frame processing and as such, this can be
-# used with driver=hostap or driver=devicescape, but not with driver=madwifi.
-# 0 = accept unless in deny list
-# 1 = deny unless in accept list
-# 2 = use external RADIUS server (accept/deny lists are searched first)
-macaddr_acl=0
-
-# Accept/deny lists are read from separate files (containing list of
-# MAC addresses, one per line). Use absolute path name to make sure that the
-# files can be read on SIGHUP configuration reloads.
-#accept_mac_file=/etc/hostapd.accept
-#deny_mac_file=/etc/hostapd.deny
-
-# IEEE 802.11 specifies two authentication algorithms. hostapd can be
-# configured to allow both of these or only one. Open system authentication
-# should be used with IEEE 802.1X.
-# Bit fields of allowed authentication algorithms:
-# bit 0 = Open System Authentication
-# bit 1 = Shared Key Authentication (requires WEP)
-auth_algs=3
-
-# Send empty SSID in beacons and ignore probe request frames that do not
-# specify full SSID, i.e., require stations to know SSID.
-# default: disabled (0)
-# 1 = send empty (length=0) SSID in beacon and ignore probe request for
-# broadcast SSID
-# 2 = clear SSID (ASCII 0), but keep the original length (this may be required
-# with some clients that do not support empty SSID) and ignore probe
-# requests for broadcast SSID
-ignore_broadcast_ssid=0
-
-# TX queue parameters (EDCF / bursting)
-# default for all these fields: not set, use hardware defaults
-# tx_queue_<queue name>_<param>
-# queues: data0, data1, data2, data3, after_beacon, beacon
-# (data0 is the highest priority queue)
-# parameters:
-# aifs: AIFS (default 2)
-# cwmin: cwMin (1, 3, 7, 15, 31, 63, 127, 255, 511, 1023)
-# cwmax: cwMax (1, 3, 7, 15, 31, 63, 127, 255, 511, 1023); cwMax >= cwMin
-# burst: maximum length (in milliseconds with precision of up to 0.1 ms) for
-# bursting
-#
-# Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e):
-# These parameters are used by the access point when transmitting frames
-# to the clients.
-#
-# Low priority / AC_BK = background
-#tx_queue_data3_aifs=7
-#tx_queue_data3_cwmin=15
-#tx_queue_data3_cwmax=1023
-#tx_queue_data3_burst=0
-# Note: for IEEE 802.11b mode: cWmin=31 cWmax=1023 burst=0
-#
-# Normal priority / AC_BE = best effort
-#tx_queue_data2_aifs=3
-#tx_queue_data2_cwmin=15
-#tx_queue_data2_cwmax=63
-#tx_queue_data2_burst=0
-# Note: for IEEE 802.11b mode: cWmin=31 cWmax=127 burst=0
-#
-# High priority / AC_VI = video
-#tx_queue_data1_aifs=1
-#tx_queue_data1_cwmin=7
-#tx_queue_data1_cwmax=15
-#tx_queue_data1_burst=3.0
-# Note: for IEEE 802.11b mode: cWmin=15 cWmax=31 burst=6.0
-#
-# Highest priority / AC_VO = voice
-#tx_queue_data0_aifs=1
-#tx_queue_data0_cwmin=3
-#tx_queue_data0_cwmax=7
-#tx_queue_data0_burst=1.5
-# Note: for IEEE 802.11b mode: cWmin=7 cWmax=15 burst=3.3
-#
-# Special queues; normally not user configurable
-#
-#tx_queue_after_beacon_aifs=2
-#tx_queue_after_beacon_cwmin=15
-#tx_queue_after_beacon_cwmax=1023
-#tx_queue_after_beacon_burst=0
-#
-#tx_queue_beacon_aifs=2
-#tx_queue_beacon_cwmin=3
-#tx_queue_beacon_cwmax=7
-#tx_queue_beacon_burst=1.5
-
-# 802.1D Tag to AC mappings
-# WMM specifies following mapping of data frames to different ACs. This mapping
-# can be configured using Linux QoS/tc and sch_pktpri.o module.
-# 802.1D Tag 802.1D Designation Access Category WMM Designation
-# 1 BK AC_BK Background
-# 2 - AC_BK Background
-# 0 BE AC_BE Best Effort
-# 3 EE AC_VI Video
-# 4 CL AC_VI Video
-# 5 VI AC_VI Video
-# 6 VO AC_VO Voice
-# 7 NC AC_VO Voice
-# Data frames with no priority information: AC_BE
-# Management frames: AC_VO
-# PS-Poll frames: AC_BE
-
-# Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e):
-# for 802.11a or 802.11g networks
-# These parameters are sent to WMM clients when they associate.
-# The parameters will be used by WMM clients for frames transmitted to the
-# access point.
-#
-# note - txop_limit is in units of 32microseconds
-# note - acm is admission control mandatory flag. 0 = admission control not
-# required, 1 = mandatory
-# note - here cwMin and cmMax are in exponent form. the actual cw value used
-# will be (2^n)-1 where n is the value given here
-#
-wme_enabled=1
-#
-# Low priority / AC_BK = background
-wme_ac_bk_cwmin=4
-wme_ac_bk_cwmax=10
-wme_ac_bk_aifs=7
-wme_ac_bk_txop_limit=0
-wme_ac_bk_acm=0
-# Note: for IEEE 802.11b mode: cWmin=5 cWmax=10
-#
-# Normal priority / AC_BE = best effort
-wme_ac_be_aifs=3
-wme_ac_be_cwmin=4
-wme_ac_be_cwmax=10
-wme_ac_be_txop_limit=0
-wme_ac_be_acm=0
-# Note: for IEEE 802.11b mode: cWmin=5 cWmax=7
-#
-# High priority / AC_VI = video
-wme_ac_vi_aifs=2
-wme_ac_vi_cwmin=3
-wme_ac_vi_cwmax=4
-wme_ac_vi_txop_limit=94
-wme_ac_vi_acm=0
-# Note: for IEEE 802.11b mode: cWmin=4 cWmax=5 txop_limit=188
-#
-# Highest priority / AC_VO = voice
-wme_ac_vo_aifs=2
-wme_ac_vo_cwmin=2
-wme_ac_vo_cwmax=3
-wme_ac_vo_txop_limit=47
-wme_ac_vo_acm=0
-# Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102
-
-# Associate as a station to another AP while still acting as an AP on the same
-# channel.
-#assoc_ap_addr=00:12:34:56:78:9a
-
-# Static WEP key configuration
-#
-# The key number to use when transmitting.
-# It must be between 0 and 3, and the corresponding key must be set.
-# default: not set
-#wep_default_key=0
-# The WEP keys to use.
-# A key may be a quoted string or unquoted hexadecimal digits.
-# The key length should be 5, 13, or 16 characters, or 10, 26, or 32
-# digits, depending on whether 40-bit (64-bit), 104-bit (128-bit), or
-# 128-bit (152-bit) WEP is used.
-# Only the default key must be supplied; the others are optional.
-# default: not set
-#wep_key0=123456789a
-#wep_key1="vwxyz"
-#wep_key2=0102030405060708090a0b0c0d
-#wep_key3=".2.4.6.8.0.23"
-
-# Station inactivity limit
-#
-# If a station does not send anything in ap_max_inactivity seconds, an
-# empty data frame is sent to it in order to verify whether it is
-# still in range. If this frame is not ACKed, the station will be
-# disassociated and then deauthenticated. This feature is used to
-# clear station table of old entries when the STAs move out of the
-# range.
-#
-# The station can associate again with the AP if it is still in range;
-# this inactivity poll is just used as a nicer way of verifying
-# inactivity; i.e., client will not report broken connection because
-# disassociation frame is not sent immediately without first polling
-# the STA with a data frame.
-# default: 300 (i.e., 5 minutes)
-#ap_max_inactivity=300
-
-# Enable/disable internal bridge for packets between associated stations.
-#
-# When IEEE 802.11 is used in managed mode, packets are usually send through
-# the AP even if they are from a wireless station to another wireless station.
-# This functionality requires that the AP has a bridge functionality that sends
-# frames back to the same interface if their destination is another associated
-# station. In addition, broadcast/multicast frames from wireless stations will
-# be sent both to the host system net stack (e.g., to eventually wired network)
-# and back to the wireless interface.
-#
-# The internal bridge is implemented within the wireless kernel module and it
-# bypasses kernel filtering (netfilter/iptables/ebtables). If direct
-# communication between the stations needs to be prevented, the internal
-# bridge can be disabled by setting bridge_packets=0.
-#
-# Note: If this variable is not included in hostapd.conf, hostapd does not
-# change the configuration and iwpriv can be used to set the value with
-# 'iwpriv wlan# param 10 0' command. If the variable is in hostapd.conf,
-# hostapd will override possible iwpriv configuration whenever configuration
-# file is reloaded.
-#
-# default: do not control from hostapd (80211.o defaults to 1=enabled)
-#bridge_packets=1
-
-
-##### IEEE 802.1X-2004 related configuration ##################################
-
-# Require IEEE 802.1X authorization
-#ieee8021x=1
-
-# IEEE 802.1X/EAPOL version
-# hostapd is implemented based on IEEE Std 802.1X-2004 which defines EAPOL
-# version 2. However, there are many client implementations that do not handle
-# the new version number correctly (they seem to drop the frames completely).
-# In order to make hostapd interoperate with these clients, the version number
-# can be set to the older version (1) with this configuration value.
-#eapol_version=2
-
-# Optional displayable message sent with EAP Request-Identity. The first \0
-# in this string will be converted to ASCII-0 (nul). This can be used to
-# separate network info (comma separated list of attribute=value pairs); see,
-# e.g., draft-adrangi-eap-network-discovery-07.txt.
-#eap_message=hello
-#eap_message=hello\0networkid=netw,nasid=foo,portid=0,NAIRealms=example.com
-
-# WEP rekeying (disabled if key lengths are not set or are set to 0)
-# Key lengths for default/broadcast and individual/unicast keys:
-# 5 = 40-bit WEP (also known as 64-bit WEP with 40 secret bits)
-# 13 = 104-bit WEP (also known as 128-bit WEP with 104 secret bits)
-#wep_key_len_broadcast=5
-#wep_key_len_unicast=5
-# Rekeying period in seconds. 0 = do not rekey (i.e., set keys only once)
-#wep_rekey_period=300
-
-# EAPOL-Key index workaround (set bit7) for WinXP Supplicant (needed only if
-# only broadcast keys are used)
-eapol_key_index_workaround=0
-
-# EAP reauthentication period in seconds (default: 3600 seconds; 0 = disable
-# reauthentication).
-#eap_reauth_period=3600
-
-# Use PAE group address (01:80:c2:00:00:03) instead of individual target
-# address when sending EAPOL frames with driver=wired. This is the most common
-# mechanism used in wired authentication, but it also requires that the port
-# is only used by one station.
-#use_pae_group_addr=1
-
-##### Integrated EAP server ###################################################
-
-# Optionally, hostapd can be configured to use an integrated EAP server
-# to process EAP authentication locally without need for an external RADIUS
-# server. This functionality can be used both as a local authentication server
-# for IEEE 802.1X/EAPOL and as a RADIUS server for other devices.
-
-# Use integrated EAP server instead of external RADIUS authentication
-# server. This is also needed if hostapd is configured to act as a RADIUS
-# authentication server.
-eap_server=0
-
-# Path for EAP server user database
-#eap_user_file=/etc/hostapd.eap_user
-
-# CA certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS
-#ca_cert=/etc/hostapd.ca.pem
-
-# Server certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS
-#server_cert=/etc/hostapd.server.pem
-
-# Private key matching with the server certificate for EAP-TLS/PEAP/TTLS
-# This may point to the same file as server_cert if both certificate and key
-# are included in a single file. PKCS#12 (PFX) file (.p12/.pfx) can also be
-# used by commenting out server_cert and specifying the PFX file as the
-# private_key.
-#private_key=/etc/hostapd.server.prv
-
-# Passphrase for private key
-#private_key_passwd=secret passphrase
-
-# Enable CRL verification.
-# Note: hostapd does not yet support CRL downloading based on CDP. Thus, a
-# valid CRL signed by the CA is required to be included in the ca_cert file.
-# This can be done by using PEM format for CA certificate and CRL and
-# concatenating these into one file. Whenever CRL changes, hostapd needs to be
-# restarted to take the new CRL into use.
-# 0 = do not verify CRLs (default)
-# 1 = check the CRL of the user certificate
-# 2 = check all CRLs in the certificate path
-#check_crl=1
-
-# Configuration data for EAP-SIM database/authentication gateway interface.
-# This is a text string in implementation specific format. The example
-# implementation in eap_sim_db.c uses this as the UNIX domain socket name for
-# the HLR/AuC gateway (e.g., hlr_auc_gw). In this case, the path uses "unix:"
-# prefix.
-#eap_sim_db=unix:/tmp/hlr_auc_gw.sock
-
-
-##### IEEE 802.11f - Inter-Access Point Protocol (IAPP) #######################
-
-# Interface to be used for IAPP broadcast packets
-#iapp_interface=eth0
-
-
-##### RADIUS client configuration #############################################
-# for IEEE 802.1X with external Authentication Server, IEEE 802.11
-# authentication with external ACL for MAC addresses, and accounting
-
-# The own IP address of the access point (used as NAS-IP-Address)
-own_ip_addr=127.0.0.1
-
-# Optional NAS-Identifier string for RADIUS messages. When used, this should be
-# a unique to the NAS within the scope of the RADIUS server. For example, a
-# fully qualified domain name can be used here.
-#nas_identifier=ap.example.com
-
-# RADIUS authentication server
-#auth_server_addr=127.0.0.1
-#auth_server_port=1812
-#auth_server_shared_secret=secret
-
-# RADIUS accounting server
-#acct_server_addr=127.0.0.1
-#acct_server_port=1813
-#acct_server_shared_secret=secret
-
-# Secondary RADIUS servers; to be used if primary one does not reply to
-# RADIUS packets. These are optional and there can be more than one secondary
-# server listed.
-#auth_server_addr=127.0.0.2
-#auth_server_port=1812
-#auth_server_shared_secret=secret2
-#
-#acct_server_addr=127.0.0.2
-#acct_server_port=1813
-#acct_server_shared_secret=secret2
-
-# Retry interval for trying to return to the primary RADIUS server (in
-# seconds). RADIUS client code will automatically try to use the next server
-# when the current server is not replying to requests. If this interval is set,
-# primary server will be retried after configured amount of time even if the
-# currently used secondary server is still working.
-#radius_retry_primary_interval=600
-
-
-# Interim accounting update interval
-# If this is set (larger than 0) and acct_server is configured, hostapd will
-# send interim accounting updates every N seconds. Note: if set, this overrides
-# possible Acct-Interim-Interval attribute in Access-Accept message. Thus, this
-# value should not be configured in hostapd.conf, if RADIUS server is used to
-# control the interim interval.
-# This value should not be less 600 (10 minutes) and must not be less than
-# 60 (1 minute).
-#radius_acct_interim_interval=600
-
-# Dynamic VLAN mode; allow RADIUS authentication server to decide which VLAN
-# is used for the stations. This information is parsed from following RADIUS
-# attributes based on RFC 3580 and RFC 2868: Tunnel-Type (value 13 = VLAN),
-# Tunnel-Medium-Type (value 6 = IEEE 802), Tunnel-Private-Group-ID (value
-# VLANID as a string). vlan_file option below must be configured if dynamic
-# VLANs are used.
-# 0 = disabled (default)
-# 1 = option; use default interface if RADIUS server does not include VLAN ID
-# 2 = required; reject authentication if RADIUS server does not include VLAN ID
-#dynamic_vlan=0
-
-# VLAN interface list for dynamic VLAN mode is read from a separate text file.
-# This list is used to map VLAN ID from the RADIUS server to a network
-# interface. Each station is bound to one interface in the same way as with
-# multiple BSSIDs or SSIDs. Each line in this text file is defining a new
-# interface and the line must include VLAN ID and interface name separated by
-# white space (space or tab).
-#vlan_file=/etc/hostapd.vlan
-
-# Interface where 802.1q tagged packets should appear when a RADIUS server is
-# used to determine which VLAN a station is on. hostapd creates a bridge for
-# each VLAN. Then hostapd adds a VLAN interface (associated with the interface
-# indicated by 'vlan_tagged_interface') and the appropriate wireless interface
-# to the bridge.
-#vlan_tagged_interface=eth0
-
-
-##### RADIUS authentication server configuration ##############################
-
-# hostapd can be used as a RADIUS authentication server for other hosts. This
-# requires that the integrated EAP authenticator is also enabled and both
-# authentication services are sharing the same configuration.
-
-# File name of the RADIUS clients configuration for the RADIUS server. If this
-# commented out, RADIUS server is disabled.
-#radius_server_clients=/etc/hostapd.radius_clients
-
-# The UDP port number for the RADIUS authentication server
-#radius_server_auth_port=1812
-
-# Use IPv6 with RADIUS server (IPv4 will also be supported using IPv6 API)
-#radius_server_ipv6=1
-
-
-##### WPA/IEEE 802.11i configuration ##########################################
-
-# Enable WPA. Setting this variable configures the AP to require WPA (either
-# WPA-PSK or WPA-RADIUS/EAP based on other configuration). For WPA-PSK, either
-# wpa_psk or wpa_passphrase must be set and wpa_key_mgmt must include WPA-PSK.
-# For WPA-RADIUS/EAP, ieee8021x must be set (but without dynamic WEP keys),
-# RADIUS authentication server must be configured, and WPA-EAP must be included
-# in wpa_key_mgmt.
-# This field is a bit field that can be used to enable WPA (IEEE 802.11i/D3.0)
-# and/or WPA2 (full IEEE 802.11i/RSN):
-# bit0 = WPA
-# bit1 = IEEE 802.11i/RSN (WPA2) (dot11RSNAEnabled)
-#wpa=1
-
-# WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit
-# secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase
-# (8..63 characters) that will be converted to PSK. This conversion uses SSID
-# so the PSK changes when ASCII passphrase is used and the SSID is changed.
-# wpa_psk (dot11RSNAConfigPSKValue)
-# wpa_passphrase (dot11RSNAConfigPSKPassPhrase)
-#wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
-#wpa_passphrase=secret passphrase
-
-# Optionally, WPA PSKs can be read from a separate text file (containing list
-# of (PSK,MAC address) pairs. This allows more than one PSK to be configured.
-# Use absolute path name to make sure that the files can be read on SIGHUP
-# configuration reloads.
-#wpa_psk_file=/etc/hostapd.wpa_psk
-
-# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
-# entries are separated with a space.
-# (dot11RSNAConfigAuthenticationSuitesTable)
-#wpa_key_mgmt=WPA-PSK WPA-EAP
-
-# Set of accepted cipher suites (encryption algorithms) for pairwise keys
-# (unicast packets). This is a space separated list of algorithms:
-# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
-# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
-# Group cipher suite (encryption algorithm for broadcast and multicast frames)
-# is automatically selected based on this configuration. If only CCMP is
-# allowed as the pairwise cipher, group cipher will also be CCMP. Otherwise,
-# TKIP will be used as the group cipher.
-# (dot11RSNAConfigPairwiseCiphersTable)
-#wpa_pairwise=TKIP CCMP
-
-# Time interval for rekeying GTK (broadcast/multicast encryption keys) in
-# seconds. (dot11RSNAConfigGroupRekeyTime)
-#wpa_group_rekey=600
-
-# Rekey GTK when any STA that possesses the current GTK is leaving the BSS.
-# (dot11RSNAConfigGroupRekeyStrict)
-#wpa_strict_rekey=1
-
-# Time interval for rekeying GMK (master key used internally to generate GTKs
-# (in seconds).
-#wpa_gmk_rekey=86400
-
-# Enable IEEE 802.11i/RSN/WPA2 pre-authentication. This is used to speed up
-# roaming be pre-authenticating IEEE 802.1X/EAP part of the full RSN
-# authentication and key handshake before actually associating with a new AP.
-# (dot11RSNAPreauthenticationEnabled)
-#rsn_preauth=1
-#
-# Space separated list of interfaces from which pre-authentication frames are
-# accepted (e.g., 'eth0' or 'eth0 wlan0wds0'. This list should include all
-# interface that are used for connections to other APs. This could include
-# wired interfaces and WDS links. The normal wireless data interface towards
-# associated stations (e.g., wlan0) should not be added, since
-# pre-authentication is only used with APs other than the currently associated
-# one.
-#rsn_preauth_interfaces=eth0
-
-# peerkey: Whether PeerKey negotiation for direct links (IEEE 802.11e) is
-# allowed. This is only used with RSN/WPA2.
-# 0 = disabled (default)
-# 1 = enabled
-#peerkey=1
-
-# ieee80211w: Whether management frame protection is enabled
-# 0 = disabled (default)
-# 1 = optional
-# 2 = required
-#ieee80211w=0
-
-##### Passive scanning ########################################################
-# Scan different channels every N seconds. 0 = disable passive scanning.
-#passive_scan_interval=60
-
-# Listen N usecs on each channel when doing passive scanning.
-# This value plus the time needed for changing channels should be less than
-# 32 milliseconds (i.e. 32000 usec) to avoid interruptions to normal
-# operations. Time needed for channel changing varies based on the used wlan
-# hardware.
-# default: disabled (0)
-#passive_scan_listen=10000
-
-# Passive scanning mode:
-# 0 = scan all supported modes (802.11a/b/g/Turbo) (default)
-# 1 = scan only the mode that is currently used for normal operations
-#passive_scan_mode=1
-
-# Maximum number of entries kept in AP table (either for passive scanning or
-# for detecting Overlapping Legacy BSS Condition). The oldest entry will be
-# removed when adding a new entry that would make the list grow over this
-# limit. Note! Wi-Fi certification for IEEE 802.11g requires that OLBC is
-# enabled, so this field should not be set to 0 when using IEEE 802.11g.
-# default: 255
-#ap_table_max_size=255
-
-# Number of seconds of no frames received after which entries may be deleted
-# from the AP table. Since passive scanning is not usually performed frequently
-# this should not be set to very small value. In addition, there is no
-# guarantee that every scan cycle will receive beacon frames from the
-# neighboring APs.
-# default: 60
-#ap_table_expiration_time=3600
-
-# Multiple BSSID support
-#
-# Above configuration is using the default interface (wlan#, or multi-SSID VLAN
-# interfaces). Other BSSIDs can be added by using separator 'bss' with
-# default interface name to be allocated for the data packets of the new BSS.
-#
-# hostapd will generate BSSID mask based on the BSSIDs that are
-# configured. hostapd will verify that dev_addr & MASK == dev_addr. If this is
-# not the case, the MAC address of the radio must be changed before starting
-# hostapd (ifconfig wlan0 hw ether <MAC addr>).
-#
-# BSSIDs are assigned in order to each BSS, unless an explicit BSSID is
-# specified using the 'bssid' parameter.
-# If an explicit BSSID is specified, it must be chosen such that it:
-# - results in a valid MASK that covers it and the dev_addr
-# - is not the same as the MAC address of the radio
-# - is not the same as any other explicitly specified BSSID
-#
-# Please note that hostapd uses some of the values configured for the first BSS
-# as the defaults for the following BSSes. However, it is recommended that all
-# BSSes include explicit configuration of all relevant configuration items.
-#
-#bss=wlan0_0
-#ssid=test2
-# most of the above items can be used here (apart from radio interface specific
-# items, like channel)
-
-#bss=wlan0_1
-#bssid=00:13:10:95:fe:0b
-# ...
+++ /dev/null
-# List of MAC addresses that are not allowed to authenticate (IEEE 802.11)
-# with the AP.
-00:20:30:40:50:60
-00:ab:cd:ef:12:34
-00:00:30:40:50:60
+++ /dev/null
-# hostapd user database for integrated EAP authenticator
-
-# Each line must contain an identity, EAP method(s), and an optional password
-# separated with whitespace (space or tab). The identity and password must be
-# double quoted ("user"). Password can alternatively be stored as
-# NtPasswordHash (16-byte MD4 hash of the unicode presentation of the password
-# in unicode) if it is used for MSCHAP or MSCHAPv2 authentication. This means
-# that the plaintext password does not need to be included in the user file.
-# Password hash is stored as hash:<16-octets of hex data> without quotation
-# marks.
-
-# [2] flag in the end of the line can be used to mark users for tunneled phase
-# 2 authentication (e.g., within EAP-PEAP). In these cases, an anonymous
-# identity can be used in the unencrypted phase 1 and the real user identity
-# is transmitted only within the encrypted tunnel in phase 2. If non-anonymous
-# access is needed, two user entries is needed, one for phase 1 and another
-# with the same username for phase 2.
-#
-# EAP-TLS, EAP-PEAP, EAP-TTLS, EAP-SIM, and EAP-AKA do not use password option.
-# EAP-MD5, EAP-MSCHAPV2, EAP-GTC, EAP-PAX, EAP-PSK, and EAP-SAKE require a
-# password.
-# EAP-PEAP and EAP-TTLS require Phase 2 configuration.
-#
-# * can be used as a wildcard to match any user identity. The main purposes for
-# this are to set anonymous phase 1 identity for EAP-PEAP and EAP-TTLS and to
-# avoid having to configure every certificate for EAP-TLS authentication. The
-# first matching entry is selected, so * should be used as the last phase 1
-# user entry.
-#
-# "prefix"* can be used to match the given prefix and anything after this. The
-# main purpose for this is to be able to avoid EAP method negotiation when the
-# method is using known prefix in identities (e.g., EAP-SIM and EAP-AKA). This
-# is only allowed for phase 1 identities.
-#
-# Multiple methods can be configured to make the authenticator try them one by
-# one until the peer accepts one. The method names are separated with a
-# comma (,).
-#
-# [ver=0] and [ver=1] flags after EAP type PEAP can be used to force PEAP
-# version based on the Phase 1 identity. Without this flag, the EAP
-# authenticator advertises the highest supported version and select the version
-# based on the first PEAP packet from the supplicant.
-
-# Phase 1 users
-"user" MD5 "password"
-"test user" MD5 "secret"
-"example user" TLS
-"DOMAIN\user" MSCHAPV2 "password"
-"gtc user" GTC "password"
-"pax user" PAX "unknown"
-"pax.user@example.com" PAX 0123456789abcdef0123456789abcdef
-"psk user" PSK "unknown"
-"psk.user@example.com" PSK 0123456789abcdef0123456789abcdef
-"sake.user@example.com" SAKE 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
-"ttls" TTLS
-"not anonymous" PEAP
-# Default to EAP-SIM and EAP-AKA based on fixed identity prefixes
-"0"* AKA,TTLS,TLS,PEAP,SIM
-"1"* SIM,TTLS,TLS,PEAP,AKA
-"2"* AKA,TTLS,TLS,PEAP,SIM
-"3"* SIM,TTLS,TLS,PEAP,AKA
-"4"* AKA,TTLS,TLS,PEAP,SIM
-"5"* SIM,TTLS,TLS,PEAP,AKA
-
-# Wildcard for all other identities
-* PEAP,TTLS,TLS,SIM,AKA
-
-# Phase 2 (tunnelled within EAP-PEAP or EAP-TTLS) users
-"t-md5" MD5 "password" [2]
-"DOMAIN\t-mschapv2" MSCHAPV2 "password" [2]
-"t-gtc" GTC "password" [2]
-"not anonymous" MSCHAPV2 "password" [2]
-"user" MD5,GTC,MSCHAPV2 "password" [2]
-"test user" MSCHAPV2 hash:000102030405060708090a0b0c0d0e0f [2]
+++ /dev/null
-# RADIUS client configuration for the RADIUS server
-10.1.2.3 secret passphrase
-192.168.1.0/24 another very secret passphrase
-0.0.0.0/0 radius
+++ /dev/null
-# Example GSM authentication triplet file for EAP-SIM authenticator
-# IMSI:Kc:SRES:RAND
-# IMSI: ASCII string (numbers)
-# Kc: hex, 8 octets
-# SRES: hex, 4 octets
-# RAND: hex, 16 octets
-234567898765432:A0A1A2A3A4A5A6A7:D1D2D3D4:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-234567898765432:B0B1B2B3B4B5B6B7:E1E2E3E4:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
-234567898765432:C0C1C2C3C4C5C6C7:F1F2F3F4:CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+++ /dev/null
-# VLAN ID to network interface mapping
-1 vlan1
-2 vlan2
-3 vlan3
-100 guest
-# Optional wildcard entry matching all VLAN IDs. The first # in the interface
-# name will be replaced with the VLAN ID. The network interfaces are created
-# (and removed) dynamically based on the use.
-* vlan#
+++ /dev/null
-# List of WPA PSKs. Each line, except for empty lines and lines starting
-# with #, must contain a MAC address and PSK separated with a space.
-# Special MAC address 00:00:00:00:00:00 can be used to configure PSKs that
-# anyone can use. PSK can be configured as an ASCII passphrase of 8..63
-# characters or as a 256-bit hex PSK (64 hex digits).
-00:00:00:00:00:00 secret passphrase
-00:11:22:33:44:55 another passphrase
-00:22:33:44:55:66 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
-00:00:00:00:00:00 another passphrase for all STAs
--- /dev/null
+ChangeLog for hostapd
+
+2010-01-12 - v0.6.10
+ * fixed SHA-256 based key derivation function to match with the
+ standard when using CCMP (for IEEE 802.11r and IEEE 802.11w)
+ (note: this breaks interoperability with previous version) [Bug 307]
+ * fixed WPS selected registrar expiration for internal PIN registrar
+ * disable PMTU discovery for RADIUS packets
+ * fixed WPS UPnP SSDP on 32-bit targets
+ * fixed WPS AP reconfiguration with drivers that do not use hostapd
+ MLME
+ * fixed RSN parameter setting for multi-BSS case
+ * added WPS workarounds for known interoperability issues with broken,
+ deployed implementation
+ * update IEEE 802.11w implementation to match with the published
+ standard
+ * fixed OpCode when proxying WSC_ACK or WSC_NACK from WPS ER
+ * fixed proxying of WSC_NACK to WPS ER
+ * fixed compilation with newer GnuTLS versions
+ * added support for defining timeout for WPS PINs
+ * fixed WPS Probe Request processing to handle missing required
+ attribute
+ * fixed PKCS#12 use with OpenSSL 1.0.0
+
+2009-03-23 - v0.6.9
+ * driver_nl80211: fixed STA accounting data collection (TX/RX bytes
+ reported correctly; TX/RX packets not yet available from kernel)
+ * fixed EAPOL/EAP reauthentication when using an external RADIUS
+ authentication server
+ * driver_prism54: fixed segmentation fault on initialization
+ * fixed TNC with EAP-TTLS
+ * fixed IEEE 802.11r key derivation function to match with the standard
+ (note: this breaks interoperability with previous version) [Bug 303]
+
+2009-02-15 - v0.6.8
+ * increased hostapd_cli ping interval to 5 seconds and made this
+ configurable with a new command line options (-G<seconds>)
+ * driver_nl80211: use Linux socket filter to improve performance
+ * added support for external Registrars with WPS (UPnP transport)
+
+2009-01-06 - v0.6.7
+ * added support for Wi-Fi Protected Setup (WPS)
+ (hostapd can now be configured to act as an integrated WPS Registrar
+ and provision credentials for WPS Enrollees using PIN and PBC
+ methods; external wireless Registrar can configure the AP, but
+ external WLAN Manager Registrars are not supported); WPS support can
+ be enabled by adding CONFIG_WPS=y into .config and setting the
+ runtime configuration variables in hostapd.conf (see WPS section in
+ the example configuration file); new hostapd_cli commands wps_pin and
+ wps_pbc are used to configure WPS negotiation; see README-WPS for
+ more details
+ * added IEEE 802.11n HT capability configuration (ht_capab)
+ * added support for generating Country IE based on nl80211 regulatory
+ information (added if ieee80211d=1 in configuration)
+ * fixed WEP authentication (both Open System and Shared Key) with
+ mac80211
+ * added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
+ * added support for using driver_test over UDP socket
+ * changed EAP-GPSK to use the IANA assigned EAP method type 51
+ * updated management frame protection to use IEEE 802.11w/D7.0
+ * fixed retransmission of EAP requests if no response is received
+
+2008-11-23 - v0.6.6
+ * added a new configuration option, wpa_ptk_rekey, that can be used to
+ enforce frequent PTK rekeying, e.g., to mitigate some attacks against
+ TKIP deficiencies
+ * updated OpenSSL code for EAP-FAST to use an updated version of the
+ session ticket overriding API that was included into the upstream
+ OpenSSL 0.9.9 tree on 2008-11-15 (no additional OpenSSL patch is
+ needed with that version anymore)
+ * changed channel flags configuration to read the information from
+ the driver (e.g., via driver_nl80211 when using mac80211) instead of
+ using hostapd as the source of the regulatory information (i.e.,
+ information from CRDA is now used with mac80211); this allows 5 GHz
+ channels to be used with hostapd (if allowed in the current
+ regulatory domain)
+ * fixed EAP-TLS message processing for the last TLS message if it is
+ large enough to require fragmentation (e.g., if a large Session
+ Ticket data is included)
+ * fixed listen interval configuration for nl80211 drivers
+
+2008-11-01 - v0.6.5
+ * added support for SHA-256 as X.509 certificate digest when using the
+ internal X.509/TLSv1 implementation
+ * fixed EAP-FAST PAC-Opaque padding (0.6.4 broke this for some peer
+ identity lengths)
+ * fixed internal TLSv1 implementation for abbreviated handshake (used
+ by EAP-FAST server)
+ * added support for setting VLAN ID for STAs based on local MAC ACL
+ (accept_mac_file) as an alternative for RADIUS server-based
+ configuration
+ * updated management frame protection to use IEEE 802.11w/D6.0
+ (adds a new association ping to protect against unauthenticated
+ authenticate or (re)associate request frames dropping association)
+ * added support for using SHA256-based stronger key derivation for WPA2
+ (IEEE 802.11w)
+ * added new "driver wrapper" for RADIUS-only configuration
+ (driver=none in hostapd.conf; CONFIG_DRIVER_NONE=y in .config)
+ * fixed WPA/RSN IE validation to verify that the proto (WPA vs. WPA2)
+ is enabled in configuration
+ * changed EAP-FAST configuration to use separate fields for A-ID and
+ A-ID-Info (eap_fast_a_id_info) to allow A-ID to be set to a fixed
+ 16-octet len binary value for better interoperability with some peer
+ implementations; eap_fast_a_id is now configured as a hex string
+ * driver_nl80211: Updated to match the current Linux mac80211 AP mode
+ configuration (wireless-testing.git and Linux kernel releases
+ starting from 2.6.29)
+
+2008-08-10 - v0.6.4
+ * added peer identity into EAP-FAST PAC-Opaque and skip Phase 2
+ Identity Request if identity is already known
+ * added support for EAP Sequences in EAP-FAST Phase 2
+ * added support for EAP-TNC (Trusted Network Connect)
+ (this version implements the EAP-TNC method and EAP-TTLS/EAP-FAST
+ changes needed to run two methods in sequence (IF-T) and the IF-IMV
+ and IF-TNCCS interfaces from TNCS)
+ * added support for optional cryptobinding with PEAPv0
+ * added fragmentation support for EAP-TNC
+ * added support for fragmenting EAP-TTLS/PEAP/FAST Phase 2 (tunneled)
+ data
+ * added support for opportunistic key caching (OKC)
+
+2008-02-22 - v0.6.3
+ * fixed Reassociation Response callback processing when using internal
+ MLME (driver_{hostap,nl80211,test}.c)
+ * updated FT support to use the latest draft, IEEE 802.11r/D9.0
+ * copy optional Proxy-State attributes into RADIUS response when acting
+ as a RADIUS authentication server
+ * fixed EAPOL state machine to handle a case in which no response is
+ received from the RADIUS authentication server; previous version
+ could have triggered a crash in some cases after a timeout
+ * fixed EAP-SIM/AKA realm processing to allow decorated usernames to
+ be used
+ * added a workaround for EAP-SIM/AKA peers that include incorrect null
+ termination in the username
+ * fixed EAP-SIM/AKA protected result indication to include AT_COUNTER
+ attribute in notification messages only when using fast
+ reauthentication
+ * fixed EAP-SIM Start response processing for fast reauthentication
+ case
+ * added support for pending EAP processing in EAP-{PEAP,TTLS,FAST}
+ phase 2 to allow EAP-SIM and EAP-AKA to be used as the Phase 2 method
+
+2008-01-01 - v0.6.2
+ * fixed EAP-SIM and EAP-AKA message parser to validate attribute
+ lengths properly to avoid potential crash caused by invalid messages
+ * added data structure for storing allocated buffers (struct wpabuf);
+ this does not affect hostapd usage, but many of the APIs changed
+ and various interfaces (e.g., EAP) is not compatible with old
+ versions
+ * added support for protecting EAP-AKA/Identity messages with
+ AT_CHECKCODE (optional feature in RFC 4187)
+ * added support for protected result indication with AT_RESULT_IND for
+ EAP-SIM and EAP-AKA (eap_sim_aka_result_ind=1)
+ * added support for configuring EAP-TTLS phase 2 non-EAP methods in
+ EAP server configuration; previously all four were enabled for every
+ phase 2 user, now all four are disabled by default and need to be
+ enabled with new method names TTLS-PAP, TTLS-CHAP, TTLS-MSCHAP,
+ TTLS-MSCHAPV2
+ * removed old debug printing mechanism and the related 'debug'
+ parameter in the configuration file; debug verbosity is now set with
+ -d (or -dd) command line arguments
+ * added support for EAP-IKEv2 (draft-tschofenig-eap-ikev2-15.txt);
+ only shared key/password authentication is supported in this version
+
+2007-11-24 - v0.6.1
+ * added experimental, integrated TLSv1 server implementation with the
+ needed X.509/ASN.1/RSA/bignum processing (this can be enabled by
+ setting CONFIG_TLS=internal and CONFIG_INTERNAL_LIBTOMMATH=y in
+ .config); this can be useful, e.g., if the target system does not
+ have a suitable TLS library and a minimal code size is required
+ * added support for EAP-FAST server method to the integrated EAP
+ server
+ * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
+ draft (draft-ietf-emu-eap-gpsk-07.txt)
+ * added a new configuration parameter, rsn_pairwise, to allow different
+ pairwise cipher suites to be enabled for WPA and RSN/WPA2
+ (note: if wpa_pairwise differs from rsn_pairwise, the driver will
+ either need to support this or will have to use the WPA/RSN IEs from
+ hostapd; currently, the included madwifi and bsd driver interfaces do
+ not have support for this)
+ * updated FT support to use the latest draft, IEEE 802.11r/D8.0
+
+2007-05-28 - v0.6.0
+ * added experimental IEEE 802.11r/D6.0 support
+ * updated EAP-SAKE to RFC 4763 and the IANA-allocated EAP type 48
+ * updated EAP-PSK to use the IANA-allocated EAP type 47
+ * fixed EAP-PSK bit ordering of the Flags field
+ * fixed configuration reloading (SIGHUP) to re-initialize WPA PSKs
+ by reading wpa_psk_file [Bug 181]
+ * fixed EAP-TTLS AVP parser processing for too short AVP lengths
+ * fixed IPv6 connection to RADIUS accounting server
+ * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
+ draft (draft-ietf-emu-eap-gpsk-04.txt)
+ * hlr_auc_gw: read GSM triplet file into memory and rotate through the
+ entries instead of only using the same three triplets every time
+ (this does not work properly with tests using multiple clients, but
+ provides bit better triplet data for testing a single client; anyway,
+ if a better quality triplets are needed, GSM-Milenage should be used
+ instead of hardcoded triplet file)
+ * fixed EAP-MSCHAPv2 server to use a space between S and M parameters
+ in Success Request [Bug 203]
+ * added support for sending EAP-AKA Notifications in error cases
+ * updated to use IEEE 802.11w/D2.0 for management frame protection
+ (still experimental)
+ * RADIUS server: added support for processing duplicate messages
+ (retransmissions from RADIUS client) by replying with the previous
+ reply
+
+2006-11-24 - v0.5.6
+ * added support for configuring and controlling multiple BSSes per
+ radio interface (bss=<ifname> in hostapd.conf); this is only
+ available with Devicescape and test driver interfaces
+ * fixed PMKSA cache update in the end of successful RSN
+ pre-authentication
+ * added support for dynamic VLAN configuration (i.e., selecting VLAN-ID
+ for each STA based on RADIUS Access-Accept attributes); this requires
+ VLAN support from the kernel driver/802.11 stack and this is
+ currently only available with Devicescape and test driver interfaces
+ * driver_madwifi: fixed configuration of unencrypted modes (plaintext
+ and IEEE 802.1X without WEP)
+ * removed STAKey handshake since PeerKey handshake has replaced it in
+ IEEE 802.11ma and there are no known deployments of STAKey
+ * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
+ draft (draft-ietf-emu-eap-gpsk-01.txt)
+ * added preliminary implementation of IEEE 802.11w/D1.0 (management
+ frame protection)
+ (Note: this requires driver support to work properly.)
+ (Note2: IEEE 802.11w is an unapproved draft and subject to change.)
+ * hlr_auc_gw: added support for GSM-Milenage (for EAP-SIM)
+ * hlr_auc_gw: added support for reading per-IMSI Milenage keys and
+ parameters from a text file to make it possible to implement proper
+ GSM/UMTS authentication server for multiple SIM/USIM cards using
+ EAP-SIM/EAP-AKA
+ * fixed session timeout processing with drivers that do not use
+ ieee802_11.c (e.g., madwifi)
+
+2006-08-27 - v0.5.5
+ * added 'hostapd_cli new_sta <addr>' command for adding a new STA into
+ hostapd (e.g., to initialize wired network authentication based on an
+ external signal)
+ * fixed hostapd to add PMKID KDE into 4-Way Handshake Message 1 when
+ using WPA2 even if PMKSA caching is not used
+ * added -P<pid file> argument for hostapd to write the current process
+ id into a file
+ * added support for RADIUS Authentication Server MIB (RFC 2619)
+
+2006-06-20 - v0.5.4
+ * fixed nt_password_hash build [Bug 144]
+ * added PeerKey handshake implementation for IEEE 802.11e
+ direct link setup (DLS) to replace STAKey handshake
+ * added support for EAP Generalized Pre-Shared Key (EAP-GPSK,
+ draft-clancy-emu-eap-shared-secret-00.txt)
+ * fixed a segmentation fault when RSN pre-authentication was completed
+ successfully [Bug 152]
+
+2006-04-27 - v0.5.3
+ * do not build nt_password_hash and hlr_auc_gw by default to avoid
+ requiring a TLS library for a successful build; these programs can be
+ build with 'make nt_password_hash' and 'make hlr_auc_gw'
+ * added a new configuration option, eapol_version, that can be used to
+ set EAPOL version to 1 (default is 2) to work around broken client
+ implementations that drop EAPOL frames which use version number 2
+ [Bug 89]
+ * added support for EAP-SAKE (no EAP method number allocated yet, so
+ this is using the same experimental type 255 as EAP-PSK)
+ * fixed EAP-MSCHAPv2 message length validation
+
+2006-03-19 - v0.5.2
+ * fixed stdarg use in hostapd_logger(): if both stdout and syslog
+ logging was enabled, hostapd could trigger a segmentation fault in
+ vsyslog on some CPU -- C library combinations
+ * moved HLR/AuC gateway implementation for EAP-SIM/AKA into an external
+ program to make it easier to use for implementing real SS7 gateway;
+ eap_sim_db is not anymore used as a file name for GSM authentication
+ triplets; instead, it is path to UNIX domain socket that will be used
+ to communicate with the external gateway program (e.g., hlr_auc_gw)
+ * added example HLR/AuC gateway implementation, hlr_auc_gw, that uses
+ local information (GSM authentication triplets from a text file and
+ hardcoded AKA authentication data); this can be used to test EAP-SIM
+ and EAP-AKA
+ * added Milenage algorithm (example 3GPP AKA algorithm) to hlr_auc_gw
+ to make it possible to test EAP-AKA with real USIM cards (this is
+ disabled by default; define AKA_USE_MILENAGE when building hlr_auc_gw
+ to enable this)
+ * driver_madwifi: added support for getting station RSN IE from
+ madwifi-ng svn r1453 and newer; this fixes RSN that was apparently
+ broken with earlier change (r1357) in the driver
+ * changed EAP method registration to use a dynamic list of methods
+ instead of a static list generated at build time
+ * fixed WPA message 3/4 not to encrypt Key Data field (WPA IE)
+ [Bug 125]
+ * added ap_max_inactivity configuration parameter
+
+2006-01-29 - v0.5.1
+ * driver_test: added better support for multiple APs and STAs by using
+ a directory with sockets that include MAC address for each device in
+ the name (test_socket=DIR:/tmp/test)
+ * added support for EAP expanded type (vendor specific EAP methods)
+
+2005-12-18 - v0.5.0 (beginning of 0.5.x development releases)
+ * added experimental STAKey handshake implementation for IEEE 802.11e
+ direct link setup (DLS); note: this is disabled by default in both
+ build and runtime configuration (can be enabled with CONFIG_STAKEY=y
+ and stakey=1)
+ * added support for EAP methods to use callbacks to external programs
+ by buffering a pending request and processing it after the EAP method
+ is ready to continue
+ * improved EAP-SIM database interface to allow external request to GSM
+ HLR/AuC without blocking hostapd process
+ * added support for using EAP-SIM pseudonyms and fast re-authentication
+ * added support for EAP-AKA in the integrated EAP authenticator
+ * added support for matching EAP identity prefixes (e.g., "1"*) in EAP
+ user database to allow EAP-SIM/AKA selection without extra roundtrip
+ for EAP-Nak negotiation
+ * added support for storing EAP user password as NtPasswordHash instead
+ of plaintext password when using MSCHAP or MSCHAPv2 for
+ authentication (hash:<16-octet hex value>); added nt_password_hash
+ tool for hashing password to generate NtPasswordHash
+
+2005-11-20 - v0.4.7 (beginning of 0.4.x stable releases)
+ * driver_wired: fixed EAPOL sending to optionally use PAE group address
+ as the destination instead of supplicant MAC address; this is
+ disabled by default, but should be enabled with use_pae_group_addr=1
+ in configuration file if the wired interface is used by only one
+ device at the time (common switch configuration)
+ * driver_madwifi: configure driver to use TKIP countermeasures in order
+ to get correct behavior (IEEE 802.11 association failing; previously,
+ association succeeded, but hostpad forced disassociation immediately)
+ * driver_madwifi: added support for madwifi-ng
+
+2005-10-27 - v0.4.6
+ * added support for replacing user identity from EAP with RADIUS
+ User-Name attribute from Access-Accept message, if that is included,
+ for the RADIUS accounting messages (e.g., for EAP-PEAP/TTLS to get
+ tunneled identity into accounting messages when the RADIUS server
+ does not support better way of doing this with Class attribute)
+ * driver_madwifi: fixed EAPOL packet receive for configuration where
+ ath# is part of a bridge interface
+ * added a configuration file and log analyzer script for logwatch
+ * fixed EAPOL state machine step function to process all state
+ transitions before processing new events; this resolves a race
+ condition in which EAPOL-Start message could trigger hostapd to send
+ two EAP-Response/Identity frames to the authentication server
+
+2005-09-25 - v0.4.5
+ * added client CA list to the TLS certificate request in order to make
+ it easier for the client to select which certificate to use
+ * added experimental support for EAP-PSK
+ * added support for WE-19 (hostap, madwifi)
+
+2005-08-21 - v0.4.4
+ * fixed build without CONFIG_RSN_PREAUTH
+ * fixed FreeBSD build
+
+2005-06-26 - v0.4.3
+ * fixed PMKSA caching to copy User-Name and Class attributes so that
+ RADIUS accounting gets correct information
+ * start RADIUS accounting only after successful completion of WPA
+ 4-Way Handshake if WPA-PSK is used
+ * fixed PMKSA caching for the case where STA (re)associates without
+ first disassociating
+
+2005-06-12 - v0.4.2
+ * EAP-PAX is now registered as EAP type 46
+ * fixed EAP-PAX MAC calculation
+ * fixed EAP-PAX CK and ICK key derivation
+ * renamed eap_authenticator configuration variable to eap_server to
+ better match with RFC 3748 (EAP) terminology
+ * driver_test: added support for testing hostapd with wpa_supplicant
+ by using test driver interface without any kernel drivers or network
+ cards
+
+2005-05-22 - v0.4.1
+ * fixed RADIUS server initialization when only auth or acct server
+ is configured and the other one is left empty
+ * driver_madwifi: added support for RADIUS accounting
+ * driver_madwifi: added preliminary support for compiling against 'BSD'
+ branch of madwifi CVS tree
+ * driver_madwifi: fixed pairwise key removal to allow WPA reauth
+ without disassociation
+ * added support for reading additional certificates from PKCS#12 files
+ and adding them to the certificate chain
+ * fixed RADIUS Class attribute processing to only use Access-Accept
+ packets to update Class; previously, other RADIUS authentication
+ packets could have cleared Class attribute
+ * added support for more than one Class attribute in RADIUS packets
+ * added support for verifying certificate revocation list (CRL) when
+ using integrated EAP authenticator for EAP-TLS; new hostapd.conf
+ options 'check_crl'; CRL must be included in the ca_cert file for now
+
+2005-04-25 - v0.4.0 (beginning of 0.4.x development releases)
+ * added support for including network information into
+ EAP-Request/Identity message (ASCII-0 (nul) in eap_message)
+ (e.g., to implement draft-adrange-eap-network-discovery-07.txt)
+ * fixed a bug which caused some RSN pre-authentication cases to use
+ freed memory and potentially crash hostapd
+ * fixed private key loading for cases where passphrase is not set
+ * added support for sending TLS alerts and aborting authentication
+ when receiving a TLS alert
+ * fixed WPA2 to add PMKSA cache entry when using integrated EAP
+ authenticator
+ * fixed PMKSA caching (EAP authentication was not skipped correctly
+ with the new state machine changes from IEEE 802.1X draft)
+ * added support for RADIUS over IPv6; own_ip_addr, auth_server_addr,
+ and acct_server_addr can now be IPv6 addresses (CONFIG_IPV6=y needs
+ to be added to .config to include IPv6 support); for RADIUS server,
+ radius_server_ipv6=1 needs to be set in hostapd.conf and addresses
+ in RADIUS clients file can then use IPv6 format
+ * added experimental support for EAP-PAX
+ * replaced hostapd control interface library (hostapd_ctrl.[ch]) with
+ the same implementation that wpa_supplicant is using (wpa_ctrl.[ch])
+
+2005-02-12 - v0.3.7 (beginning of 0.3.x stable releases)
+
+2005-01-23 - v0.3.5
+ * added support for configuring a forced PEAP version based on the
+ Phase 1 identity
+ * fixed PEAPv1 to use tunneled EAP-Success/Failure instead of EAP-TLV
+ to terminate authentication
+ * fixed EAP identifier duplicate processing with the new IEEE 802.1X
+ draft
+ * clear accounting data in the driver when starting a new accounting
+ session
+ * driver_madwifi: filter wireless events based on ifindex to allow more
+ than one network interface to be used
+ * fixed WPA message 2/4 processing not to cancel timeout for TimeoutEvt
+ setting if the packet does not pass MIC verification (e.g., due to
+ incorrect PSK); previously, message 1/4 was not tried again if an
+ invalid message 2/4 was received
+ * fixed reconfiguration of RADIUS client retransmission timer when
+ adding a new message to the pending list; previously, timer was not
+ updated at this point and if there was a pending message with long
+ time for the next retry, the new message needed to wait that long for
+ its first retry, too
+
+2005-01-09 - v0.3.4
+ * added support for configuring multiple allowed EAP types for Phase 2
+ authentication (EAP-PEAP, EAP-TTLS)
+ * fixed EAPOL-Start processing to trigger WPA reauthentication
+ (previously, only EAPOL authentication was done)
+
+2005-01-02 - v0.3.3
+ * added support for EAP-PEAP in the integrated EAP authenticator
+ * added support for EAP-GTC in the integrated EAP authenticator
+ * added support for configuring list of EAP methods for Phase 1 so that
+ the integrated EAP authenticator can, e.g., use the wildcard entry
+ for EAP-TLS and EAP-PEAP
+ * added support for EAP-TTLS in the integrated EAP authenticator
+ * added support for EAP-SIM in the integrated EAP authenticator
+ * added support for using hostapd as a RADIUS authentication server
+ with the integrated EAP authenticator taking care of EAP
+ authentication (new hostapd.conf options: radius_server_clients and
+ radius_server_auth_port); this is not included in default build; use
+ CONFIG_RADIUS_SERVER=y in .config to include
+
+2004-12-19 - v0.3.2
+ * removed 'daemonize' configuration file option since it has not really
+ been used at all for more than year
+ * driver_madwifi: fixed group key setup and added get_ssid method
+ * added support for EAP-MSCHAPv2 in the integrated EAP authenticator
+
+2004-12-12 - v0.3.1
+ * added support for integrated EAP-TLS authentication (new hostapd.conf
+ variables: ca_cert, server_cert, private_key, private_key_passwd);
+ this enabled dynamic keying (WPA2/WPA/IEEE 802.1X/WEP) without
+ external RADIUS server
+ * added support for reading PKCS#12 (PFX) files (as a replacement for
+ PEM/DER) to get certificate and private key (CONFIG_PKCS12)
+
+2004-12-05 - v0.3.0 (beginning of 0.3.x development releases)
+ * added support for Acct-{Input,Output}-Gigawords
+ * added support for Event-Timestamp (in RADIUS Accounting-Requests)
+ * added support for RADIUS Authentication Client MIB (RFC2618)
+ * added support for RADIUS Accounting Client MIB (RFC2620)
+ * made EAP re-authentication period configurable (eap_reauth_period)
+ * fixed EAPOL reauthentication to trigger WPA/WPA2 reauthentication
+ * fixed EAPOL state machine to stop if STA is removed during
+ eapol_sm_step(); this fixes at least one segfault triggering bug with
+ IEEE 802.11i pre-authentication
+ * added support for multiple WPA pre-shared keys (e.g., one for each
+ client MAC address or keys shared by a group of clients);
+ new hostapd.conf field wpa_psk_file for setting path to a text file
+ containing PSKs, see hostapd.wpa_psk for an example
+ * added support for multiple driver interfaces to allow hostapd to be
+ used with other drivers
+ * added wired authenticator driver interface (driver=wired in
+ hostapd.conf, see wired.conf for example configuration)
+ * added madwifi driver interface (driver=madwifi in hostapd.conf, see
+ madwifi.conf for example configuration; Note: include files from
+ madwifi project is needed for building and a configuration file,
+ .config, needs to be created in hostapd directory with
+ CONFIG_DRIVER_MADWIFI=y to include this driver interface in hostapd
+ build)
+ * fixed an alignment issue that could cause SHA-1 to fail on some
+ platforms (e.g., Intel ixp425 with a compiler that does not 32-bit
+ align variables)
+ * fixed RADIUS reconnection after an error in sending interim
+ accounting packets
+ * added hostapd control interface for external programs and an example
+ CLI, hostapd_cli (like wpa_cli for wpa_supplicant)
+ * started adding dot11, dot1x, radius MIBs ('hostapd_cli mib',
+ 'hostapd_cli sta <addr>')
+ * finished update from IEEE 802.1X-2001 to IEEE 802.1X-REV (now d11)
+ * added support for strict GTK rekeying (wpa_strict_rekey in
+ hostapd.conf)
+ * updated IAPP to use UDP port 3517 and multicast address 224.0.1.178
+ (instead of broadcast) for IAPP ADD-notify (moved from draft 3 to
+ IEEE 802.11F-2003)
+ * added Prism54 driver interface (driver=prism54 in hostapd.conf;
+ note: .config needs to be created in hostapd directory with
+ CONFIG_DRIVER_PRISM54=y to include this driver interface in hostapd
+ build)
+ * dual-licensed hostapd (GPLv2 and BSD licenses)
+ * fixed RADIUS accounting to generate a new session id for cases where
+ a station reassociates without first being complete deauthenticated
+ * fixed STA disassociation handler to mark next timeout state to
+ deauthenticate the station, i.e., skip long wait for inactivity poll
+ and extra disassociation, if the STA disassociates without
+ deauthenticating
+ * added integrated EAP authenticator that can be used instead of
+ external RADIUS authentication server; currently, only EAP-MD5 is
+ supported, so this cannot yet be used for key distribution; the EAP
+ method interface is generic, though, so adding new EAP methods should
+ be straightforward; new hostapd.conf variables: 'eap_authenticator'
+ and 'eap_user_file'; this obsoletes "minimal authentication server"
+ ('minimal_eap' in hostapd.conf) which is now removed
+ * added support for FreeBSD and driver interface for the BSD net80211
+ layer (driver=bsd in hostapd.conf and CONFIG_DRIVER_BSD=y in
+ .config); please note that some of the required kernel mods have not
+ yet been committed
+
+2004-07-17 - v0.2.4 (beginning of 0.2.x stable releases)
+ * fixed some accounting cases where Accounting-Start was sent when
+ IEEE 802.1X port was being deauthorized
+
+2004-06-20 - v0.2.3
+ * modified RADIUS client to re-connect the socket in case of certain
+ error codes that are generated when a network interface state is
+ changes (e.g., when IP address changes or the interface is set UP)
+ * fixed couple of cases where EAPOL state for a station was freed
+ twice causing a segfault for hostapd
+ * fixed couple of bugs in processing WPA deauthentication (freed data
+ was used)
+
+2004-05-31 - v0.2.2
+ * fixed WPA/WPA2 group rekeying to use key index correctly (GN/GM)
+ * fixed group rekeying to send zero TSC in EAPOL-Key messages to fix
+ cases where STAs dropped multicast frames as replay attacks
+ * added support for copying RADIUS Attribute 'Class' from
+ authentication messages into accounting messages
+ * send canned EAP failure if RADIUS server sends Access-Reject without
+ EAP message (previously, Supplicant was not notified in this case)
+ * fixed mixed WPA-PSK and WPA-EAP mode to work with WPA-PSK (i.e., do
+ not start EAPOL state machines if the STA selected to use WPA-PSK)
+
+2004-05-06 - v0.2.1
+ * added WPA and IEEE 802.11i/RSN (WPA2) Authenticator functionality
+ - based on IEEE 802.11i/D10.0 but modified to interoperate with WPA
+ (i.e., IEEE 802.11i/D3.0)
+ - supports WPA-only, RSN-only, and mixed WPA/RSN mode
+ - both WPA-PSK and WPA-RADIUS/EAP are supported
+ - PMKSA caching and pre-authentication
+ - new hostapd.conf variables: wpa, wpa_psk, wpa_passphrase,
+ wpa_key_mgmt, wpa_pairwise, wpa_group_rekey, wpa_gmk_rekey,
+ rsn_preauth, rsn_preauth_interfaces
+ * fixed interim accounting to remove any pending accounting messages
+ to the STA before sending a new one
+
+2004-02-15 - v0.2.0
+ * added support for Acct-Interim-Interval:
+ - draft-ietf-radius-acct-interim-01.txt
+ - use Acct-Interim-Interval attribute from Access-Accept if local
+ 'radius_acct_interim_interval' is not set
+ - allow different update intervals for each STA
+ * fixed event loop to call signal handlers only after returning from
+ the real signal handler
+ * reset sta->timeout_next after successful association to make sure
+ that the previously registered inactivity timer will not remove the
+ STA immediately (e.g., if STA deauthenticates and re-associates
+ before the timer is triggered).
+ * added new hostapd.conf variable, nas_identifier, that can be used to
+ add an optional RADIUS Attribute, NAS-Identifier, into authentication
+ and accounting messages
+ * added support for Accounting-On and Accounting-Off messages
+ * fixed accounting session handling to send Accounting-Start only once
+ per session and not to send Accounting-Stop if the session was not
+ initialized properly
+ * fixed Accounting-Stop statistics in cases where the message was
+ previously sent after the kernel entry for the STA (and/or IEEE
+ 802.1X data) was removed
+
+
+Note:
+
+Older changes up to and including v0.1.0 are included in the ChangeLog
+of the Host AP driver.
Authenticator and RADIUS authentication server
================================================================
-Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved.
This program is dual-licensed under both the GPL version 2 and BSD
Prism54 driver for Intersil/Conexant Prism GT/Duette/Indigo
(http://www.prism54.org/)
+ mac80211-based drivers that support AP mode (with driver=nl80211).
+ This includes drivers for Atheros (ath9k) and Broadcom (b43)
+ chipsets.
+
Any wired Ethernet driver for wired IEEE 802.1X authentication
(experimental code)
--- /dev/null
+hostapd and Wi-Fi Protected Setup (WPS)
+=======================================
+
+This document describes how the WPS implementation in hostapd can be
+configured and how an external component on an AP (e.g., web UI) is
+used to enable enrollment of client devices.
+
+
+Introduction to WPS
+-------------------
+
+Wi-Fi Protected Setup (WPS) is a mechanism for easy configuration of a
+wireless network. It allows automated generation of random keys (WPA
+passphrase/PSK) and configuration of an access point and client
+devices. WPS includes number of methods for setting up connections
+with PIN method and push-button configuration (PBC) being the most
+commonly deployed options.
+
+While WPS can enable more home networks to use encryption in the
+wireless network, it should be noted that the use of the PIN and
+especially PBC mechanisms for authenticating the initial key setup is
+not very secure. As such, use of WPS may not be suitable for
+environments that require secure network access without chance for
+allowing outsiders to gain access during the setup phase.
+
+WPS uses following terms to describe the entities participating in the
+network setup:
+- access point: the WLAN access point
+- Registrar: a device that control a network and can authorize
+ addition of new devices); this may be either in the AP ("internal
+ Registrar") or in an external device, e.g., a laptop, ("external
+ Registrar")
+- Enrollee: a device that is being authorized to use the network
+
+It should also be noted that the AP and a client device may change
+roles (i.e., AP acts as an Enrollee and client device as a Registrar)
+when WPS is used to configure the access point.
+
+
+More information about WPS is available from Wi-Fi Alliance:
+http://www.wi-fi.org/wifi-protected-setup
+
+
+hostapd implementation
+----------------------
+
+hostapd includes an optional WPS component that can be used as an
+internal WPS Registrar to manage addition of new WPS enabled clients
+to the network. In addition, WPS Enrollee functionality in hostapd can
+be used to allow external WPS Registrars to configure the access
+point, e.g., for initial network setup. In addition, hostapd can proxy a
+WPS registration between a wireless Enrollee and an external Registrar
+(e.g., Microsoft Vista or Atheros JumpStart) with UPnP.
+
+
+hostapd configuration
+---------------------
+
+WPS is an optional component that needs to be enabled in hostapd build
+configuration (.config). Here is an example configuration that
+includes WPS support and uses madwifi driver interface:
+
+CONFIG_DRIVER_MADWIFI=y
+CFLAGS += -I/usr/src/madwifi-0.9.3
+CONFIG_EAP=y
+CONFIG_WPS=y
+CONFIG_WPS_UPNP=y
+
+
+Following section shows an example runtime configuration
+(hostapd.conf) that enables WPS:
+
+# Configure the driver and network interface
+driver=madwifi
+interface=ath0
+
+# WPA2-Personal configuration for the AP
+ssid=wps-test
+wpa=2
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=CCMP
+# Default WPA passphrase for legacy (non-WPS) clients
+wpa_passphrase=12345678
+# Enable random per-device PSK generation for WPS clients
+# Please note that the file has to exists for hostapd to start (i.e., create an
+# empty file as a starting point).
+wpa_psk_file=/etc/hostapd.psk
+
+# Enable control interface for PBC/PIN entry
+ctrl_interface=/var/run/hostapd
+
+# Enable internal EAP server for EAP-WSC (part of Wi-Fi Protected Setup)
+eap_server=1
+
+# WPS configuration (AP configured, do not allow external WPS Registrars)
+wps_state=2
+ap_setup_locked=1
+# If UUID is not configured, it will be generated based on local MAC address.
+uuid=87654321-9abc-def0-1234-56789abc0000
+wps_pin_requests=/var/run/hostapd.pin-req
+device_name=Wireless AP
+manufacturer=Company
+model_name=WAP
+model_number=123
+serial_number=12345
+device_type=6-0050F204-1
+os_version=01020300
+config_methods=label display push_button keypad
+
+# if external Registrars are allowed, UPnP support could be added:
+#upnp_iface=br0
+#friendly_name=WPS Access Point
+
+
+External operations
+-------------------
+
+WPS requires either a device PIN code (usually, 8-digit number) or a
+pushbutton event (for PBC) to allow a new WPS Enrollee to join the
+network. hostapd uses the control interface as an input channel for
+these events.
+
+When a client device (WPS Enrollee) connects to hostapd (WPS
+Registrar) in order to start PIN mode negotiation for WPS, an
+identifier (Enrollee UUID) is sent. hostapd will need to be configured
+with a device password (PIN) for this Enrollee. This is an operation
+that requires user interaction (assuming there are no pre-configured
+PINs on the AP for a set of Enrollee).
+
+The PIN request with information about the device is appended to the
+wps_pin_requests file (/var/run/hostapd.pin-req in this example). In
+addition, hostapd control interface event is sent as a notification of
+a new device. The AP could use, e.g., a web UI for showing active
+Enrollees to the user and request a PIN for an Enrollee.
+
+The PIN request file has one line for every Enrollee that connected to
+the AP, but for which there was no PIN. Following information is
+provided for each Enrollee (separated with tabulators):
+- timestamp (seconds from 1970-01-01)
+- Enrollee UUID
+- MAC address
+- Device name
+- Manufacturer
+- Model Name
+- Model Number
+- Serial Number
+- Device category
+
+Example line in the /var/run/hostapd.pin-req file:
+1200188391 53b63a98-d29e-4457-a2ed-094d7e6a669c Intel(R) Centrino(R) Intel Corporation Intel(R) Centrino(R) - - 1-0050F204-1
+
+Control interface data:
+WPS-PIN-NEEDED [UUID-E|MAC Address|Device Name|Manufacturer|Model Name|Model Number|Serial Number|Device Category]
+For example:
+<2>WPS-PIN-NEEDED [53b63a98-d29e-4457-a2ed-094d7e6a669c|02:12:34:56:78:9a|Device|Manuf|Model|Model Number|Serial Number|1-0050F204-1]
+
+When the user enters a PIN for a pending Enrollee, e.g., on the web
+UI), hostapd needs to be notified of the new PIN over the control
+interface. This can be done either by using the UNIX domain socket
+-based control interface directly (src/common/wpa_ctrl.c provides
+helper functions for using the interface) or by calling hostapd_cli.
+
+Example command to add a PIN (12345670) for an Enrollee:
+
+hostapd_cli wps_pin 53b63a98-d29e-4457-a2ed-094d7e6a669c 12345670
+
+If the UUID-E is not available (e.g., Enrollee waits for the Registrar
+to be selected before connecting), wildcard UUID may be used to allow
+the PIN to be used once with any UUID:
+
+hostapd_cli wps_pin any 12345670
+
+To reduce likelihood of PIN being used with other devices or of
+forgetting an active PIN available for potential attackers, expiration
+time can be set for the new PIN:
+
+hostapd_cli wps_pin any 12345670 300
+
+
+After this, the Enrollee can connect to the AP again and complete WPS
+negotiation. At that point, a new, random WPA PSK is generated for the
+client device and the client can then use that key to connect to the
+AP to access the network.
+
+
+If the AP includes a pushbutton, WPS PBC mode can be used. It is
+enabled by pushing a button on both the AP and the client at about the
+same time (2 minute window). hostapd needs to be notified about the AP
+button pushed event over the control interface, e.g., by calling
+hostapd_cli:
+
+hostapd_cli wps_pbc
+
+At this point, the client has two minutes to complete WPS negotiation
+which will generate a new WPA PSK in the same way as the PIN method
+described above.
+
+
+Credential generation and configuration changes
+-----------------------------------------------
+
+By default, hostapd generates credentials for Enrollees and processing
+AP configuration updates internally. However, it is possible to
+control these operations from external programs, if desired.
+
+The internal credential generation can be disabled with
+skip_cred_build=1 option in the configuration. extra_cred option will
+then need to be used to provide pre-configured Credential attribute(s)
+for hostapd to use. The exact data from this binary file will be sent,
+i.e., it will have to include valid WPS attributes. extra_cred can
+also be used to add additional networks if the Registrar is used to
+configure credentials for multiple networks.
+
+Processing of received configuration updates can be disabled with
+wps_cred_processing=1 option. When this is used, an external program
+is responsible for creating hostapd configuration files and processing
+configuration updates based on messages received from hostapd over
+control interface. This will also include the initial configuration on
+first successful registration if the AP is initially set in
+unconfigured state.
+
+Following control interface messages are sent out for external programs:
+
+WPS-REG-SUCCESS <Enrollee MAC address <UUID-E>
+For example:
+<2>WPS-REG-SUCCESS 02:66:a0:ee:17:27 2b7093f1-d6fb-5108-adbb-bea66bb87333
+
+This can be used to tricker change from unconfigured to configured
+state (random configuration based on the first successful WPS
+registration). In addition, this can be used to update AP UI about the
+status of WPS registration progress.
+
+
+WPS-NEW-AP-SETTINGS <hexdump of AP Setup attributes>
+For example:
+<2>WPS-NEW-AP-SETTINGS 10260001011045000c6a6b6d2d7770732d74657374100300020020100f00020008102700403065346230343536633236366665306433396164313535346131663462663731323433376163666462376633393965353466316631623032306164343438623510200006024231cede15101e000844
+
+This can be used to update the externally stored AP configuration and
+then update hostapd configuration (followed by restarting of hostapd).
/*
* hostapd / RADIUS Accounting
- * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
*
* 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
*/
#include "includes.h"
-#include <assert.h>
#include "hostapd.h"
-#include "radius.h"
-#include "radius_client.h"
+#include "radius/radius.h"
+#include "radius/radius_client.h"
#include "eloop.h"
#include "accounting.h"
#include "ieee802_1x.h"
* input/output octets and updates Acct-{Input,Output}-Gigawords. */
#define ACCT_DEFAULT_UPDATE_INTERVAL 300
-/* from ieee802_1x.c */
-const char *radius_mode_txt(struct hostapd_data *hapd);
-int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta);
+static void accounting_sta_get_id(struct hostapd_data *hapd,
+ struct sta_info *sta);
static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
if (sta) {
radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
- snprintf(buf, sizeof(buf), "%08X-%08X",
- sta->acct_session_id_hi, sta->acct_session_id_lo);
+ os_snprintf(buf, sizeof(buf), "%08X-%08X",
+ sta->acct_session_id_hi, sta->acct_session_id_lo);
if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
- (u8 *) buf, strlen(buf))) {
+ (u8 *) buf, os_strlen(buf))) {
printf("Could not add Acct-Session-Id\n");
goto fail;
}
if (sta) {
val = ieee802_1x_get_identity(sta->eapol_sm, &len);
if (!val) {
- snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
- MAC2STR(sta->addr));
+ os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
+ MAC2STR(sta->addr));
val = (u8 *) buf;
- len = strlen(buf);
+ len = os_strlen(buf);
}
if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, val,
if (hapd->conf->nas_identifier &&
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
(u8 *) hapd->conf->nas_identifier,
- strlen(hapd->conf->nas_identifier))) {
+ os_strlen(hapd->conf->nas_identifier))) {
printf("Could not add NAS-Identifier\n");
goto fail;
}
goto fail;
}
- snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
- MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
+ os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
+