mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-23 11:18:54 +00:00
Import hostapd 0.7.3.
Changes: 2010-09-07 - v0.7.3 * fixed re-association after WPS not initializing WPA state machine in some cases * fixed WPS IE update on reconfiguration * fixed WPS code not to proxy Probe Request frames for foreign SSIDs * added WPS workaround for open networks and some known interop issues * fixed WPS Diffie-Hellman derivation to use correct public key length * fixed FT RRB messages on big endian CPUs * changed WPS protection for brute force AP PIN attacks to disable AP PIN only temporarily (but with increasing time) to avoid usability issues on Label-only devices * added wps_ap_pin command for more secure handling of AP PIN operations (e.g., to generate a random AP PIN and only use it for short amount of time) * fixed HT STBC negotiation 2010-04-18 - v0.7.2 * fix WPS internal Registrar use when an external Registrar is also active * bsd: Cleaned up driver wrapper and added various low-level configuration options * TNC: fixed issues with fragmentation * EAP-TNC: add Flags field into fragment acknowledgement (needed to interoperate with other implementations; may potentially breaks compatibility with older wpa_supplicant/hostapd versions) * cleaned up driver wrapper API for multi-BSS operations * nl80211: fix multi-BSS and VLAN operations * fix number of issues with IEEE 802.11r/FT; this version is not backwards compatible with old versions * add SA Query Request processing in AP mode (IEEE 802.11w) * fix IGTK PN in group rekeying (IEEE 802.11w) * fix WPS PBC session overlap detection to use correct attribute * hostapd_notif_Assoc() can now be called with all IEs to simplify driver wrappers * work around interoperability issue with some WPS External Registrar implementations * nl80211: fix WPS IE update * hostapd_cli: add support for action script operations (run a script on hostapd events) * fix DH padding with internal crypto code (mainly, for WPS) * fix WPS association with both WPS IE and WPA/RSN IE present with driver wrappers that use hostapd MLME (e.g., nl80211) 2010-01-16 - v0.7.1 * cleaned up driver wrapper API (struct wpa_driver_ops); the new API is not fully backwards compatible, so out-of-tree driver wrappers will need modifications * cleaned up various module interfaces * merge hostapd and wpa_supplicant developers' documentation into a single document * fixed HT Capabilities IE with nl80211 drivers * moved generic AP functionality code into src/ap * WPS: handle Selected Registrar as union of info from all Registrars * remove obsolte Prism54.org driver wrapper * added internal debugging mechanism with backtrace support and memory allocation/freeing validation, etc. tests (CONFIG_WPA_TRACE=y) * EAP-FAST server: piggyback Phase 2 start with the end of Phase 1 * WPS: add support for dynamically selecting whether to provision the PSK as an ASCII passphrase or PSK * added support for WDS (4-address frame) mode with per-station virtual interfaces (wds_sta=1 in config file; only supported with driver=nl80211 for now) * fixed WPS Probe Request processing to handle missing required attribute * fixed PKCS#12 use with OpenSSL 1.0.0 * detect bridge interface automatically so that bridge parameter in hostapd.conf becomes optional (though, it may now be used to automatically add then WLAN interface into a bridge with driver=nl80211) 2009-11-21 - v0.7.0 * 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) * 802.11n: scan for overlapping BSSes before starting 20/40 MHz channel * driver_nl80211: fixed STA accounting data collection (TX/RX bytes reported correctly; TX/RX packets not yet available from kernel) * added support for WPS USBA out-of-band mechanism with USB Flash Drives (UFD) (CONFIG_WPS_UFD=y) * fixed EAPOL/EAP reauthentication when using an external RADIUS authentication server * 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] * 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] * added number of code size optimizations to remove unnecessary functionality from the program binary based on build configuration (part of this automatic; part configurable with CONFIG_NO_* build options) * use shared driver wrapper files with wpa_supplicant * driver_nl80211: multiple updates to provide support for new Linux nl80211/mac80211 functionality * updated management frame protection to use IEEE Std 802.11w-2009 * fixed number of small WPS issues and added workarounds to interoperate with common deployed broken implementations * added some IEEE 802.11n co-existance rules to disable 40 MHz channels or modify primary/secondary channels if needed based on neighboring networks * added support for NFC out-of-band mechanism with WPS * added preliminary support for IEEE 802.11r RIC processing
This commit is contained in:
parent
02b5aa59ff
commit
1160bdd6ba
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/wpa/dist/; revision=214503 svn path=/vendor/wpa/0.7.3/; revision=214505; tag=vendor/wpa/0.7.3
7
hostapd/.gitignore
vendored
Normal file
7
hostapd/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
*.d
|
||||||
|
.config
|
||||||
|
driver_conf.c
|
||||||
|
hostapd
|
||||||
|
hostapd_cli
|
||||||
|
hlr_auc_gw
|
||||||
|
nt_password_hash
|
663
hostapd/ChangeLog
Normal file
663
hostapd/ChangeLog
Normal file
@ -0,0 +1,663 @@
|
|||||||
|
ChangeLog for hostapd
|
||||||
|
|
||||||
|
2010-09-07 - v0.7.3
|
||||||
|
* fixed re-association after WPS not initializing WPA state machine in
|
||||||
|
some cases
|
||||||
|
* fixed WPS IE update on reconfiguration
|
||||||
|
* fixed WPS code not to proxy Probe Request frames for foreign SSIDs
|
||||||
|
* added WPS workaround for open networks and some known interop issues
|
||||||
|
* fixed WPS Diffie-Hellman derivation to use correct public key length
|
||||||
|
* fixed FT RRB messages on big endian CPUs
|
||||||
|
* changed WPS protection for brute force AP PIN attacks to disable AP
|
||||||
|
PIN only temporarily (but with increasing time) to avoid usability
|
||||||
|
issues on Label-only devices
|
||||||
|
* added wps_ap_pin command for more secure handling of AP PIN
|
||||||
|
operations (e.g., to generate a random AP PIN and only use it for
|
||||||
|
short amount of time)
|
||||||
|
* fixed HT STBC negotiation
|
||||||
|
|
||||||
|
2010-04-18 - v0.7.2
|
||||||
|
* fix WPS internal Registrar use when an external Registrar is also
|
||||||
|
active
|
||||||
|
* bsd: Cleaned up driver wrapper and added various low-level
|
||||||
|
configuration options
|
||||||
|
* TNC: fixed issues with fragmentation
|
||||||
|
* EAP-TNC: add Flags field into fragment acknowledgement (needed to
|
||||||
|
interoperate with other implementations; may potentially breaks
|
||||||
|
compatibility with older wpa_supplicant/hostapd versions)
|
||||||
|
* cleaned up driver wrapper API for multi-BSS operations
|
||||||
|
* nl80211: fix multi-BSS and VLAN operations
|
||||||
|
* fix number of issues with IEEE 802.11r/FT; this version is not
|
||||||
|
backwards compatible with old versions
|
||||||
|
* add SA Query Request processing in AP mode (IEEE 802.11w)
|
||||||
|
* fix IGTK PN in group rekeying (IEEE 802.11w)
|
||||||
|
* fix WPS PBC session overlap detection to use correct attribute
|
||||||
|
* hostapd_notif_Assoc() can now be called with all IEs to simplify
|
||||||
|
driver wrappers
|
||||||
|
* work around interoperability issue with some WPS External Registrar
|
||||||
|
implementations
|
||||||
|
* nl80211: fix WPS IE update
|
||||||
|
* hostapd_cli: add support for action script operations (run a script
|
||||||
|
on hostapd events)
|
||||||
|
* fix DH padding with internal crypto code (mainly, for WPS)
|
||||||
|
* fix WPS association with both WPS IE and WPA/RSN IE present with
|
||||||
|
driver wrappers that use hostapd MLME (e.g., nl80211)
|
||||||
|
|
||||||
|
2010-01-16 - v0.7.1
|
||||||
|
* cleaned up driver wrapper API (struct wpa_driver_ops); the new API
|
||||||
|
is not fully backwards compatible, so out-of-tree driver wrappers
|
||||||
|
will need modifications
|
||||||
|
* cleaned up various module interfaces
|
||||||
|
* merge hostapd and wpa_supplicant developers' documentation into a
|
||||||
|
single document
|
||||||
|
* fixed HT Capabilities IE with nl80211 drivers
|
||||||
|
* moved generic AP functionality code into src/ap
|
||||||
|
* WPS: handle Selected Registrar as union of info from all Registrars
|
||||||
|
* remove obsolte Prism54.org driver wrapper
|
||||||
|
* added internal debugging mechanism with backtrace support and memory
|
||||||
|
allocation/freeing validation, etc. tests (CONFIG_WPA_TRACE=y)
|
||||||
|
* EAP-FAST server: piggyback Phase 2 start with the end of Phase 1
|
||||||
|
* WPS: add support for dynamically selecting whether to provision the
|
||||||
|
PSK as an ASCII passphrase or PSK
|
||||||
|
* added support for WDS (4-address frame) mode with per-station virtual
|
||||||
|
interfaces (wds_sta=1 in config file; only supported with
|
||||||
|
driver=nl80211 for now)
|
||||||
|
* fixed WPS Probe Request processing to handle missing required
|
||||||
|
attribute
|
||||||
|
* fixed PKCS#12 use with OpenSSL 1.0.0
|
||||||
|
* detect bridge interface automatically so that bridge parameter in
|
||||||
|
hostapd.conf becomes optional (though, it may now be used to
|
||||||
|
automatically add then WLAN interface into a bridge with
|
||||||
|
driver=nl80211)
|
||||||
|
|
||||||
|
2009-11-21 - v0.7.0
|
||||||
|
* 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)
|
||||||
|
* 802.11n: scan for overlapping BSSes before starting 20/40 MHz channel
|
||||||
|
* driver_nl80211: fixed STA accounting data collection (TX/RX bytes
|
||||||
|
reported correctly; TX/RX packets not yet available from kernel)
|
||||||
|
* added support for WPS USBA out-of-band mechanism with USB Flash
|
||||||
|
Drives (UFD) (CONFIG_WPS_UFD=y)
|
||||||
|
* fixed EAPOL/EAP reauthentication when using an external RADIUS
|
||||||
|
authentication server
|
||||||
|
* 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]
|
||||||
|
* 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]
|
||||||
|
* added number of code size optimizations to remove unnecessary
|
||||||
|
functionality from the program binary based on build configuration
|
||||||
|
(part of this automatic; part configurable with CONFIG_NO_* build
|
||||||
|
options)
|
||||||
|
* use shared driver wrapper files with wpa_supplicant
|
||||||
|
* driver_nl80211: multiple updates to provide support for new Linux
|
||||||
|
nl80211/mac80211 functionality
|
||||||
|
* updated management frame protection to use IEEE Std 802.11w-2009
|
||||||
|
* fixed number of small WPS issues and added workarounds to
|
||||||
|
interoperate with common deployed broken implementations
|
||||||
|
* added some IEEE 802.11n co-existance rules to disable 40 MHz channels
|
||||||
|
or modify primary/secondary channels if needed based on neighboring
|
||||||
|
networks
|
||||||
|
* added support for NFC out-of-band mechanism with WPS
|
||||||
|
* added preliminary support for IEEE 802.11r RIC processing
|
||||||
|
|
||||||
|
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.
|
791
hostapd/Makefile
Normal file
791
hostapd/Makefile
Normal file
@ -0,0 +1,791 @@
|
|||||||
|
ifndef CC
|
||||||
|
CC=gcc
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef CFLAGS
|
||||||
|
CFLAGS = -MMD -O2 -Wall -g
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS += -I../src
|
||||||
|
CFLAGS += -I../src/utils
|
||||||
|
|
||||||
|
# Uncomment following line and set the path to your kernel tree include
|
||||||
|
# directory if your C library does not include all header files.
|
||||||
|
# CFLAGS += -DUSE_KERNEL_HEADERS -I/usr/src/linux/include
|
||||||
|
|
||||||
|
-include .config
|
||||||
|
|
||||||
|
ifndef CONFIG_OS
|
||||||
|
ifdef CONFIG_NATIVE_WINDOWS
|
||||||
|
CONFIG_OS=win32
|
||||||
|
else
|
||||||
|
CONFIG_OS=unix
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_OS), internal)
|
||||||
|
CFLAGS += -DOS_NO_C_LIB_DEFINES
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_NATIVE_WINDOWS
|
||||||
|
CFLAGS += -DCONFIG_NATIVE_WINDOWS
|
||||||
|
LIBS += -lws2_32
|
||||||
|
endif
|
||||||
|
|
||||||
|
OBJS += main.o
|
||||||
|
OBJS += config_file.o
|
||||||
|
|
||||||
|
OBJS += ../src/ap/hostapd.o
|
||||||
|
OBJS += ../src/ap/wpa_auth_glue.o
|
||||||
|
OBJS += ../src/ap/drv_callbacks.o
|
||||||
|
OBJS += ../src/ap/ap_drv_ops.o
|
||||||
|
OBJS += ../src/ap/utils.o
|
||||||
|
OBJS += ../src/ap/authsrv.o
|
||||||
|
OBJS += ../src/ap/ieee802_1x.o
|
||||||
|
OBJS += ../src/ap/ap_config.o
|
||||||
|
OBJS += ../src/ap/ieee802_11_auth.o
|
||||||
|
OBJS += ../src/ap/sta_info.o
|
||||||
|
OBJS += ../src/ap/wpa_auth.o
|
||||||
|
OBJS += ../src/ap/tkip_countermeasures.o
|
||||||
|
OBJS += ../src/ap/ap_mlme.o
|
||||||
|
OBJS += ../src/ap/wpa_auth_ie.o
|
||||||
|
OBJS += ../src/ap/preauth_auth.o
|
||||||
|
OBJS += ../src/ap/pmksa_cache_auth.o
|
||||||
|
|
||||||
|
NEED_RC4=y
|
||||||
|
NEED_AES=y
|
||||||
|
NEED_MD5=y
|
||||||
|
NEED_SHA1=y
|
||||||
|
|
||||||
|
OBJS += ../src/drivers/drivers.o
|
||||||
|
CFLAGS += -DHOSTAPD
|
||||||
|
|
||||||
|
ifdef CONFIG_WPA_TRACE
|
||||||
|
CFLAGS += -DWPA_TRACE
|
||||||
|
OBJS += ../src/utils/trace.o
|
||||||
|
LDFLAGS += -rdynamic
|
||||||
|
CFLAGS += -funwind-tables
|
||||||
|
ifdef CONFIG_WPA_TRACE_BFD
|
||||||
|
CFLAGS += -DWPA_TRACE_BFD
|
||||||
|
LIBS += -lbfd
|
||||||
|
LIBS_c += -lbfd
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
OBJS += ../src/utils/eloop.o
|
||||||
|
OBJS += ../src/utils/common.o
|
||||||
|
OBJS += ../src/utils/wpa_debug.o
|
||||||
|
OBJS += ../src/utils/wpabuf.o
|
||||||
|
OBJS += ../src/utils/os_$(CONFIG_OS).o
|
||||||
|
OBJS += ../src/utils/ip_addr.o
|
||||||
|
|
||||||
|
OBJS += ../src/common/ieee802_11_common.o
|
||||||
|
OBJS += ../src/common/wpa_common.o
|
||||||
|
|
||||||
|
OBJS += ../src/eapol_auth/eapol_auth_sm.o
|
||||||
|
|
||||||
|
|
||||||
|
ifndef CONFIG_NO_DUMP_STATE
|
||||||
|
# define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to
|
||||||
|
# a file (undefine it, if you want to save in binary size)
|
||||||
|
CFLAGS += -DHOSTAPD_DUMP_STATE
|
||||||
|
OBJS += dump_state.o
|
||||||
|
OBJS += ../src/eapol_auth/eapol_auth_dump.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_NO_RADIUS
|
||||||
|
CFLAGS += -DCONFIG_NO_RADIUS
|
||||||
|
CONFIG_NO_ACCOUNTING=y
|
||||||
|
else
|
||||||
|
OBJS += ../src/radius/radius.o
|
||||||
|
OBJS += ../src/radius/radius_client.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_NO_ACCOUNTING
|
||||||
|
CFLAGS += -DCONFIG_NO_ACCOUNTING
|
||||||
|
else
|
||||||
|
OBJS += ../src/ap/accounting.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_NO_VLAN
|
||||||
|
CFLAGS += -DCONFIG_NO_VLAN
|
||||||
|
else
|
||||||
|
OBJS += ../src/ap/vlan_init.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_NO_CTRL_IFACE
|
||||||
|
CFLAGS += -DCONFIG_NO_CTRL_IFACE
|
||||||
|
else
|
||||||
|
OBJS += ctrl_iface.o
|
||||||
|
OBJS += ../src/ap/ctrl_iface_ap.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
OBJS += ../src/crypto/md5.o
|
||||||
|
|
||||||
|
CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
|
||||||
|
|
||||||
|
ifdef CONFIG_IAPP
|
||||||
|
CFLAGS += -DCONFIG_IAPP
|
||||||
|
OBJS += ../src/ap/iapp.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_RSN_PREAUTH
|
||||||
|
CFLAGS += -DCONFIG_RSN_PREAUTH
|
||||||
|
CONFIG_L2_PACKET=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_PEERKEY
|
||||||
|
CFLAGS += -DCONFIG_PEERKEY
|
||||||
|
OBJS += ../src/ap/peerkey_auth.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_IEEE80211W
|
||||||
|
CFLAGS += -DCONFIG_IEEE80211W
|
||||||
|
NEED_SHA256=y
|
||||||
|
NEED_AES_OMAC1=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_IEEE80211R
|
||||||
|
CFLAGS += -DCONFIG_IEEE80211R
|
||||||
|
OBJS += ../src/ap/wpa_auth_ft.o
|
||||||
|
NEED_SHA256=y
|
||||||
|
NEED_AES_OMAC1=y
|
||||||
|
NEED_AES_UNWRAP=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_IEEE80211N
|
||||||
|
CFLAGS += -DCONFIG_IEEE80211N
|
||||||
|
endif
|
||||||
|
|
||||||
|
include ../src/drivers/drivers.mak
|
||||||
|
OBJS += $(DRV_AP_OBJS)
|
||||||
|
CFLAGS += $(DRV_AP_CFLAGS)
|
||||||
|
LDFLAGS += $(DRV_AP_LDFLAGS)
|
||||||
|
LIBS += $(DRV_AP_LIBS)
|
||||||
|
|
||||||
|
ifdef CONFIG_L2_PACKET
|
||||||
|
ifdef CONFIG_DNET_PCAP
|
||||||
|
ifdef CONFIG_L2_FREEBSD
|
||||||
|
LIBS += -lpcap
|
||||||
|
OBJS += ../src/l2_packet/l2_packet_freebsd.o
|
||||||
|
else
|
||||||
|
LIBS += -ldnet -lpcap
|
||||||
|
OBJS += ../src/l2_packet/l2_packet_pcap.o
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
OBJS += ../src/l2_packet/l2_packet_linux.o
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
OBJS += ../src/l2_packet/l2_packet_none.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_MD5
|
||||||
|
CFLAGS += -DEAP_SERVER_MD5
|
||||||
|
OBJS += ../src/eap_server/eap_server_md5.o
|
||||||
|
CHAP=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_TLS
|
||||||
|
CFLAGS += -DEAP_SERVER_TLS
|
||||||
|
OBJS += ../src/eap_server/eap_server_tls.o
|
||||||
|
TLS_FUNCS=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_PEAP
|
||||||
|
CFLAGS += -DEAP_SERVER_PEAP
|
||||||
|
OBJS += ../src/eap_server/eap_server_peap.o
|
||||||
|
OBJS += ../src/eap_common/eap_peap_common.o
|
||||||
|
TLS_FUNCS=y
|
||||||
|
CONFIG_EAP_MSCHAPV2=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_TTLS
|
||||||
|
CFLAGS += -DEAP_SERVER_TTLS
|
||||||
|
OBJS += ../src/eap_server/eap_server_ttls.o
|
||||||
|
TLS_FUNCS=y
|
||||||
|
CHAP=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_MSCHAPV2
|
||||||
|
CFLAGS += -DEAP_SERVER_MSCHAPV2
|
||||||
|
OBJS += ../src/eap_server/eap_server_mschapv2.o
|
||||||
|
MS_FUNCS=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_GTC
|
||||||
|
CFLAGS += -DEAP_SERVER_GTC
|
||||||
|
OBJS += ../src/eap_server/eap_server_gtc.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_SIM
|
||||||
|
CFLAGS += -DEAP_SERVER_SIM
|
||||||
|
OBJS += ../src/eap_server/eap_server_sim.o
|
||||||
|
CONFIG_EAP_SIM_COMMON=y
|
||||||
|
NEED_AES_CBC=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_AKA
|
||||||
|
CFLAGS += -DEAP_SERVER_AKA
|
||||||
|
OBJS += ../src/eap_server/eap_server_aka.o
|
||||||
|
CONFIG_EAP_SIM_COMMON=y
|
||||||
|
NEED_SHA256=y
|
||||||
|
NEED_AES_CBC=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_AKA_PRIME
|
||||||
|
CFLAGS += -DEAP_SERVER_AKA_PRIME
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_SIM_COMMON
|
||||||
|
OBJS += ../src/eap_common/eap_sim_common.o
|
||||||
|
# Example EAP-SIM/AKA interface for GSM/UMTS authentication. This can be
|
||||||
|
# replaced with another file implementating the interface specified in
|
||||||
|
# eap_sim_db.h.
|
||||||
|
OBJS += ../src/eap_server/eap_sim_db.o
|
||||||
|
NEED_FIPS186_2_PRF=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_PAX
|
||||||
|
CFLAGS += -DEAP_SERVER_PAX
|
||||||
|
OBJS += ../src/eap_server/eap_server_pax.o ../src/eap_common/eap_pax_common.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_PSK
|
||||||
|
CFLAGS += -DEAP_SERVER_PSK
|
||||||
|
OBJS += ../src/eap_server/eap_server_psk.o ../src/eap_common/eap_psk_common.o
|
||||||
|
NEED_AES_OMAC1=y
|
||||||
|
NEED_AES_ENCBLOCK=y
|
||||||
|
NEED_AES_EAX=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_SAKE
|
||||||
|
CFLAGS += -DEAP_SERVER_SAKE
|
||||||
|
OBJS += ../src/eap_server/eap_server_sake.o ../src/eap_common/eap_sake_common.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_GPSK
|
||||||
|
CFLAGS += -DEAP_SERVER_GPSK
|
||||||
|
OBJS += ../src/eap_server/eap_server_gpsk.o ../src/eap_common/eap_gpsk_common.o
|
||||||
|
ifdef CONFIG_EAP_GPSK_SHA256
|
||||||
|
CFLAGS += -DEAP_SERVER_GPSK_SHA256
|
||||||
|
endif
|
||||||
|
NEED_SHA256=y
|
||||||
|
NEED_AES_OMAC1=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_VENDOR_TEST
|
||||||
|
CFLAGS += -DEAP_SERVER_VENDOR_TEST
|
||||||
|
OBJS += ../src/eap_server/eap_server_vendor_test.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_FAST
|
||||||
|
CFLAGS += -DEAP_SERVER_FAST
|
||||||
|
OBJS += ../src/eap_server/eap_server_fast.o
|
||||||
|
OBJS += ../src/eap_common/eap_fast_common.o
|
||||||
|
TLS_FUNCS=y
|
||||||
|
NEED_T_PRF=y
|
||||||
|
NEED_AES_UNWRAP=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_WPS
|
||||||
|
CFLAGS += -DCONFIG_WPS -DEAP_SERVER_WSC
|
||||||
|
OBJS += ../src/utils/uuid.o
|
||||||
|
OBJS += ../src/ap/wps_hostapd.o
|
||||||
|
OBJS += ../src/eap_server/eap_server_wsc.o ../src/eap_common/eap_wsc_common.o
|
||||||
|
OBJS += ../src/wps/wps.o
|
||||||
|
OBJS += ../src/wps/wps_common.o
|
||||||
|
OBJS += ../src/wps/wps_attr_parse.o
|
||||||
|
OBJS += ../src/wps/wps_attr_build.o
|
||||||
|
OBJS += ../src/wps/wps_attr_process.o
|
||||||
|
OBJS += ../src/wps/wps_dev_attr.o
|
||||||
|
OBJS += ../src/wps/wps_enrollee.o
|
||||||
|
OBJS += ../src/wps/wps_registrar.o
|
||||||
|
NEED_DH_GROUPS=y
|
||||||
|
NEED_SHA256=y
|
||||||
|
NEED_BASE64=y
|
||||||
|
NEED_AES_CBC=y
|
||||||
|
NEED_MODEXP=y
|
||||||
|
CONFIG_EAP=y
|
||||||
|
|
||||||
|
ifdef CONFIG_WPS_UFD
|
||||||
|
CFLAGS += -DCONFIG_WPS_UFD
|
||||||
|
OBJS += ../src/wps/wps_ufd.o
|
||||||
|
NEED_WPS_OOB=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_WPS_NFC
|
||||||
|
CFLAGS += -DCONFIG_WPS_NFC
|
||||||
|
OBJS += ../src/wps/ndef.o
|
||||||
|
OBJS += ../src/wps/wps_nfc.o
|
||||||
|
NEED_WPS_OOB=y
|
||||||
|
ifdef CONFIG_WPS_NFC_PN531
|
||||||
|
PN531_PATH ?= /usr/local/src/nfc
|
||||||
|
CFLAGS += -DCONFIG_WPS_NFC_PN531
|
||||||
|
CFLAGS += -I${PN531_PATH}/inc
|
||||||
|
OBJS += ../src/wps/wps_nfc_pn531.o
|
||||||
|
LIBS += ${PN531_PATH}/lib/wpsnfc.dll
|
||||||
|
LIBS += ${PN531_PATH}/lib/libnfc_mapping_pn53x.dll
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_WPS_OOB
|
||||||
|
CFLAGS += -DCONFIG_WPS_OOB
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_WPS_UPNP
|
||||||
|
CFLAGS += -DCONFIG_WPS_UPNP
|
||||||
|
OBJS += ../src/wps/wps_upnp.o
|
||||||
|
OBJS += ../src/wps/wps_upnp_ssdp.o
|
||||||
|
OBJS += ../src/wps/wps_upnp_web.o
|
||||||
|
OBJS += ../src/wps/wps_upnp_event.o
|
||||||
|
OBJS += ../src/wps/wps_upnp_ap.o
|
||||||
|
OBJS += ../src/wps/upnp_xml.o
|
||||||
|
OBJS += ../src/wps/httpread.o
|
||||||
|
OBJS += ../src/wps/http_client.o
|
||||||
|
OBJS += ../src/wps/http_server.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_IKEV2
|
||||||
|
CFLAGS += -DEAP_SERVER_IKEV2
|
||||||
|
OBJS += ../src/eap_server/eap_server_ikev2.o ../src/eap_server/ikev2.o
|
||||||
|
OBJS += ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.o
|
||||||
|
NEED_DH_GROUPS=y
|
||||||
|
NEED_DH_GROUPS_ALL=y
|
||||||
|
NEED_MODEXP=y
|
||||||
|
NEED_CIPHER=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP_TNC
|
||||||
|
CFLAGS += -DEAP_SERVER_TNC
|
||||||
|
OBJS += ../src/eap_server/eap_server_tnc.o
|
||||||
|
OBJS += ../src/eap_server/tncs.o
|
||||||
|
NEED_BASE64=y
|
||||||
|
ifndef CONFIG_DRIVER_BSD
|
||||||
|
LIBS += -ldl
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Basic EAP functionality is needed for EAPOL
|
||||||
|
OBJS += eap_register.o
|
||||||
|
OBJS += ../src/eap_server/eap_server.o
|
||||||
|
OBJS += ../src/eap_common/eap_common.o
|
||||||
|
OBJS += ../src/eap_server/eap_server_methods.o
|
||||||
|
OBJS += ../src/eap_server/eap_server_identity.o
|
||||||
|
CFLAGS += -DEAP_SERVER_IDENTITY
|
||||||
|
|
||||||
|
ifdef CONFIG_EAP
|
||||||
|
CFLAGS += -DEAP_SERVER
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_PKCS12
|
||||||
|
CFLAGS += -DPKCS12_FUNCS
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef MS_FUNCS
|
||||||
|
OBJS += ../src/crypto/ms_funcs.o
|
||||||
|
NEED_DES=y
|
||||||
|
NEED_MD4=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CHAP
|
||||||
|
OBJS += ../src/eap_common/chap.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef TLS_FUNCS
|
||||||
|
NEED_DES=y
|
||||||
|
# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
|
||||||
|
CFLAGS += -DEAP_TLS_FUNCS
|
||||||
|
OBJS += ../src/eap_server/eap_server_tls_common.o
|
||||||
|
NEED_TLS_PRF=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef CONFIG_TLS
|
||||||
|
CONFIG_TLS=openssl
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_TLS), openssl)
|
||||||
|
ifdef TLS_FUNCS
|
||||||
|
OBJS += ../src/crypto/tls_openssl.o
|
||||||
|
LIBS += -lssl
|
||||||
|
endif
|
||||||
|
OBJS += ../src/crypto/crypto_openssl.o
|
||||||
|
HOBJS += ../src/crypto/crypto_openssl.o
|
||||||
|
ifdef NEED_FIPS186_2_PRF
|
||||||
|
OBJS += ../src/crypto/fips_prf_openssl.o
|
||||||
|
endif
|
||||||
|
LIBS += -lcrypto
|
||||||
|
LIBS_h += -lcrypto
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_TLS), gnutls)
|
||||||
|
ifdef TLS_FUNCS
|
||||||
|
OBJS += ../src/crypto/tls_gnutls.o
|
||||||
|
LIBS += -lgnutls -lgpg-error
|
||||||
|
ifdef CONFIG_GNUTLS_EXTRA
|
||||||
|
CFLAGS += -DCONFIG_GNUTLS_EXTRA
|
||||||
|
LIBS += -lgnutls-extra
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
OBJS += ../src/crypto/crypto_gnutls.o
|
||||||
|
HOBJS += ../src/crypto/crypto_gnutls.o
|
||||||
|
ifdef NEED_FIPS186_2_PRF
|
||||||
|
OBJS += ../src/crypto/fips_prf_gnutls.o
|
||||||
|
endif
|
||||||
|
LIBS += -lgcrypt
|
||||||
|
LIBS_h += -lgcrypt
|
||||||
|
CONFIG_INTERNAL_SHA256=y
|
||||||
|
CONFIG_INTERNAL_RC4=y
|
||||||
|
CONFIG_INTERNAL_DH_GROUP5=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_TLS), schannel)
|
||||||
|
ifdef TLS_FUNCS
|
||||||
|
OBJS += ../src/crypto/tls_schannel.o
|
||||||
|
endif
|
||||||
|
OBJS += ../src/crypto/crypto_cryptoapi.o
|
||||||
|
OBJS_p += ../src/crypto/crypto_cryptoapi.o
|
||||||
|
CONFIG_INTERNAL_SHA256=y
|
||||||
|
CONFIG_INTERNAL_RC4=y
|
||||||
|
CONFIG_INTERNAL_DH_GROUP5=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_TLS), nss)
|
||||||
|
ifdef TLS_FUNCS
|
||||||
|
OBJS += ../src/crypto/tls_nss.o
|
||||||
|
LIBS += -lssl3
|
||||||
|
endif
|
||||||
|
OBJS += ../src/crypto/crypto_nss.o
|
||||||
|
ifdef NEED_FIPS186_2_PRF
|
||||||
|
OBJS += ../src/crypto/fips_prf_nss.o
|
||||||
|
endif
|
||||||
|
LIBS += -lnss3
|
||||||
|
LIBS_h += -lnss3
|
||||||
|
CONFIG_INTERNAL_MD4=y
|
||||||
|
CONFIG_INTERNAL_DH_GROUP5=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_TLS), internal)
|
||||||
|
ifndef CONFIG_CRYPTO
|
||||||
|
CONFIG_CRYPTO=internal
|
||||||
|
endif
|
||||||
|
ifdef TLS_FUNCS
|
||||||
|
OBJS += ../src/crypto/crypto_internal-rsa.o
|
||||||
|
OBJS += ../src/crypto/tls_internal.o
|
||||||
|
OBJS += ../src/tls/tlsv1_common.o
|
||||||
|
OBJS += ../src/tls/tlsv1_record.o
|
||||||
|
OBJS += ../src/tls/tlsv1_cred.o
|
||||||
|
OBJS += ../src/tls/tlsv1_server.o
|
||||||
|
OBJS += ../src/tls/tlsv1_server_write.o
|
||||||
|
OBJS += ../src/tls/tlsv1_server_read.o
|
||||||
|
OBJS += ../src/tls/asn1.o
|
||||||
|
OBJS += ../src/tls/rsa.o
|
||||||
|
OBJS += ../src/tls/x509v3.o
|
||||||
|
OBJS += ../src/tls/pkcs1.o
|
||||||
|
OBJS += ../src/tls/pkcs5.o
|
||||||
|
OBJS += ../src/tls/pkcs8.o
|
||||||
|
NEED_SHA256=y
|
||||||
|
NEED_BASE64=y
|
||||||
|
NEED_TLS_PRF=y
|
||||||
|
NEED_MODEXP=y
|
||||||
|
NEED_CIPHER=y
|
||||||
|
CFLAGS += -DCONFIG_TLS_INTERNAL
|
||||||
|
CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
|
||||||
|
endif
|
||||||
|
ifdef NEED_CIPHER
|
||||||
|
NEED_DES=y
|
||||||
|
OBJS += ../src/crypto/crypto_internal-cipher.o
|
||||||
|
endif
|
||||||
|
ifdef NEED_MODEXP
|
||||||
|
OBJS += ../src/crypto/crypto_internal-modexp.o
|
||||||
|
OBJS += ../src/tls/bignum.o
|
||||||
|
endif
|
||||||
|
ifeq ($(CONFIG_CRYPTO), libtomcrypt)
|
||||||
|
OBJS += ../src/crypto/crypto_libtomcrypt.o
|
||||||
|
LIBS += -ltomcrypt -ltfm
|
||||||
|
LIBS_h += -ltomcrypt -ltfm
|
||||||
|
CONFIG_INTERNAL_SHA256=y
|
||||||
|
CONFIG_INTERNAL_RC4=y
|
||||||
|
CONFIG_INTERNAL_DH_GROUP5=y
|
||||||
|
endif
|
||||||
|
ifeq ($(CONFIG_CRYPTO), internal)
|
||||||
|
OBJS += ../src/crypto/crypto_internal.o
|
||||||
|
NEED_AES_DEC=y
|
||||||
|
CFLAGS += -DCONFIG_CRYPTO_INTERNAL
|
||||||
|
ifdef CONFIG_INTERNAL_LIBTOMMATH
|
||||||
|
CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
|
||||||
|
ifdef CONFIG_INTERNAL_LIBTOMMATH_FAST
|
||||||
|
CFLAGS += -DLTM_FAST
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
LIBS += -ltommath
|
||||||
|
LIBS_h += -ltommath
|
||||||
|
endif
|
||||||
|
CONFIG_INTERNAL_AES=y
|
||||||
|
CONFIG_INTERNAL_DES=y
|
||||||
|
CONFIG_INTERNAL_SHA1=y
|
||||||
|
CONFIG_INTERNAL_MD4=y
|
||||||
|
CONFIG_INTERNAL_MD5=y
|
||||||
|
CONFIG_INTERNAL_SHA256=y
|
||||||
|
CONFIG_INTERNAL_RC4=y
|
||||||
|
CONFIG_INTERNAL_DH_GROUP5=y
|
||||||
|
endif
|
||||||
|
ifeq ($(CONFIG_CRYPTO), cryptoapi)
|
||||||
|
OBJS += ../src/crypto/crypto_cryptoapi.o
|
||||||
|
OBJS_p += ../src/crypto/crypto_cryptoapi.o
|
||||||
|
CFLAGS += -DCONFIG_CRYPTO_CRYPTOAPI
|
||||||
|
CONFIG_INTERNAL_SHA256=y
|
||||||
|
CONFIG_INTERNAL_RC4=y
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_TLS), none)
|
||||||
|
ifdef TLS_FUNCS
|
||||||
|
OBJS += ../src/crypto/tls_none.o
|
||||||
|
CFLAGS += -DEAP_TLS_NONE
|
||||||
|
CONFIG_INTERNAL_AES=y
|
||||||
|
CONFIG_INTERNAL_SHA1=y
|
||||||
|
CONFIG_INTERNAL_MD5=y
|
||||||
|
endif
|
||||||
|
OBJS += ../src/crypto/crypto_none.o
|
||||||
|
OBJS_p += ../src/crypto/crypto_none.o
|
||||||
|
CONFIG_INTERNAL_SHA256=y
|
||||||
|
CONFIG_INTERNAL_RC4=y
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef TLS_FUNCS
|
||||||
|
OBJS += ../src/crypto/tls_none.o
|
||||||
|
ifeq ($(CONFIG_TLS), internal)
|
||||||
|
CONFIG_INTERNAL_AES=y
|
||||||
|
CONFIG_INTERNAL_SHA1=y
|
||||||
|
CONFIG_INTERNAL_MD5=y
|
||||||
|
CONFIG_INTERNAL_RC4=y
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
AESOBJS = # none so far
|
||||||
|
ifdef CONFIG_INTERNAL_AES
|
||||||
|
AESOBJS += ../src/crypto/aes-internal.o ../src/crypto/aes-internal-enc.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
AESOBJS += ../src/crypto/aes-wrap.o
|
||||||
|
ifdef NEED_AES_EAX
|
||||||
|
AESOBJS += ../src/crypto/aes-eax.o
|
||||||
|
NEED_AES_CTR=y
|
||||||
|
endif
|
||||||
|
ifdef NEED_AES_CTR
|
||||||
|
AESOBJS += ../src/crypto/aes-ctr.o
|
||||||
|
endif
|
||||||
|
ifdef NEED_AES_ENCBLOCK
|
||||||
|
AESOBJS += ../src/crypto/aes-encblock.o
|
||||||
|
endif
|
||||||
|
ifdef NEED_AES_OMAC1
|
||||||
|
AESOBJS += ../src/crypto/aes-omac1.o
|
||||||
|
endif
|
||||||
|
ifdef NEED_AES_UNWRAP
|
||||||
|
NEED_AES_DEC=y
|
||||||
|
AESOBJS += ../src/crypto/aes-unwrap.o
|
||||||
|
endif
|
||||||
|
ifdef NEED_AES_CBC
|
||||||
|
NEED_AES_DEC=y
|
||||||
|
AESOBJS += ../src/crypto/aes-cbc.o
|
||||||
|
endif
|
||||||
|
ifdef NEED_AES_DEC
|
||||||
|
ifdef CONFIG_INTERNAL_AES
|
||||||
|
AESOBJS += ../src/crypto/aes-internal-dec.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifdef NEED_AES
|
||||||
|
OBJS += $(AESOBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_SHA1
|
||||||
|
SHA1OBJS += ../src/crypto/sha1.o
|
||||||
|
ifdef CONFIG_INTERNAL_SHA1
|
||||||
|
SHA1OBJS += ../src/crypto/sha1-internal.o
|
||||||
|
ifdef NEED_FIPS186_2_PRF
|
||||||
|
SHA1OBJS += ../src/crypto/fips_prf_internal.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
SHA1OBJS += ../src/crypto/sha1-pbkdf2.o
|
||||||
|
ifdef NEED_T_PRF
|
||||||
|
SHA1OBJS += ../src/crypto/sha1-tprf.o
|
||||||
|
endif
|
||||||
|
ifdef NEED_TLS_PRF
|
||||||
|
SHA1OBJS += ../src/crypto/sha1-tlsprf.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_SHA1
|
||||||
|
OBJS += $(SHA1OBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_MD5
|
||||||
|
ifdef CONFIG_INTERNAL_MD5
|
||||||
|
OBJS += ../src/crypto/md5-internal.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_MD4
|
||||||
|
ifdef CONFIG_INTERNAL_MD4
|
||||||
|
OBJS += ../src/crypto/md4-internal.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_DES
|
||||||
|
ifdef CONFIG_INTERNAL_DES
|
||||||
|
OBJS += ../src/crypto/des-internal.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_RC4
|
||||||
|
ifdef CONFIG_INTERNAL_RC4
|
||||||
|
OBJS += ../src/crypto/rc4.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_SHA256
|
||||||
|
OBJS += ../src/crypto/sha256.o
|
||||||
|
ifdef CONFIG_INTERNAL_SHA256
|
||||||
|
OBJS += ../src/crypto/sha256-internal.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_DH_GROUPS
|
||||||
|
OBJS += ../src/crypto/dh_groups.o
|
||||||
|
endif
|
||||||
|
ifdef NEED_DH_GROUPS_ALL
|
||||||
|
CFLAGS += -DALL_DH_GROUPS
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_INTERNAL_DH_GROUP5
|
||||||
|
ifdef NEED_DH_GROUPS
|
||||||
|
OBJS += ../src/crypto/dh_group5.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_RADIUS_SERVER
|
||||||
|
CFLAGS += -DRADIUS_SERVER
|
||||||
|
OBJS += ../src/radius/radius_server.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_IPV6
|
||||||
|
CFLAGS += -DCONFIG_IPV6
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_DRIVER_RADIUS_ACL
|
||||||
|
CFLAGS += -DCONFIG_DRIVER_RADIUS_ACL
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_FULL_DYNAMIC_VLAN
|
||||||
|
# define CONFIG_FULL_DYNAMIC_VLAN to have hostapd manipulate bridges
|
||||||
|
# and vlan interfaces for the vlan feature.
|
||||||
|
CFLAGS += -DCONFIG_FULL_DYNAMIC_VLAN
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_BASE64
|
||||||
|
OBJS += ../src/utils/base64.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef NEED_AP_MLME
|
||||||
|
OBJS += ../src/ap/beacon.o
|
||||||
|
OBJS += ../src/ap/wmm.o
|
||||||
|
OBJS += ../src/ap/ap_list.o
|
||||||
|
OBJS += ../src/ap/ieee802_11.o
|
||||||
|
OBJS += ../src/ap/hw_features.o
|
||||||
|
CFLAGS += -DNEED_AP_MLME
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_IEEE80211N
|
||||||
|
OBJS += ../src/ap/ieee802_11_ht.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_NO_STDOUT_DEBUG
|
||||||
|
CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
|
ALL=hostapd hostapd_cli
|
||||||
|
|
||||||
|
all: verify_config $(ALL)
|
||||||
|
|
||||||
|
Q=@
|
||||||
|
E=echo
|
||||||
|
ifeq ($(V), 1)
|
||||||
|
Q=
|
||||||
|
E=true
|
||||||
|
endif
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(Q)$(CC) -c -o $@ $(CFLAGS) $<
|
||||||
|
@$(E) " CC " $<
|
||||||
|
|
||||||
|
verify_config:
|
||||||
|
@if [ ! -r .config ]; then \
|
||||||
|
echo 'Building hostapd requires a configuration file'; \
|
||||||
|
echo '(.config). See README for more instructions. You can'; \
|
||||||
|
echo 'run "cp defconfig .config" to create an example'; \
|
||||||
|
echo 'configuration.'; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
install: all
|
||||||
|
for i in $(ALL); do cp -f $$i /usr/local/bin/$$i; done
|
||||||
|
|
||||||
|
../src/drivers/build.hostapd:
|
||||||
|
@if [ -f ../src/drivers/build.wpa_supplicant ]; then \
|
||||||
|
$(MAKE) -C ../src/drivers clean; \
|
||||||
|
fi
|
||||||
|
@touch ../src/drivers/build.hostapd
|
||||||
|
|
||||||
|
BCHECK=../src/drivers/build.hostapd
|
||||||
|
|
||||||
|
hostapd: $(BCHECK) $(OBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
|
||||||
|
|
||||||
|
OBJS_c = hostapd_cli.o ../src/common/wpa_ctrl.o ../src/utils/os_$(CONFIG_OS).o
|
||||||
|
ifdef CONFIG_WPA_TRACE
|
||||||
|
OBJS_c += ../src/utils/trace.o
|
||||||
|
OBJS_c += ../src/utils/wpa_debug.o
|
||||||
|
endif
|
||||||
|
hostapd_cli: $(OBJS_c)
|
||||||
|
$(CC) $(LDFLAGS) -o hostapd_cli $(OBJS_c) $(LIBS_c)
|
||||||
|
|
||||||
|
NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS) ../src/crypto/md5.o
|
||||||
|
ifdef NEED_RC4
|
||||||
|
ifdef CONFIG_INTERNAL_RC4
|
||||||
|
NOBJS += ../src/crypto/rc4.o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_INTERNAL_MD5
|
||||||
|
NOBJS += ../src/crypto/md5-internal.o
|
||||||
|
endif
|
||||||
|
NOBJS += ../src/crypto/crypto_openssl.o ../src/utils/os_$(CONFIG_OS).o
|
||||||
|
NOBJS += ../src/utils/wpa_debug.o
|
||||||
|
NOBJS += ../src/utils/wpabuf.o
|
||||||
|
ifdef CONFIG_WPA_TRACE
|
||||||
|
NOBJS += ../src/utils/trace.o
|
||||||
|
LIBS_n += -lbfd
|
||||||
|
endif
|
||||||
|
ifdef TLS_FUNCS
|
||||||
|
LIBS_n += -lcrypto
|
||||||
|
endif
|
||||||
|
|
||||||
|
HOBJS += hlr_auc_gw.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).o ../src/utils/wpabuf.o ../src/crypto/milenage.o
|
||||||
|
HOBJS += ../src/crypto/aes-encblock.o
|
||||||
|
ifdef CONFIG_INTERNAL_AES
|
||||||
|
HOBJS += ../src/crypto/aes-internal.o
|
||||||
|
HOBJS += ../src/crypto/aes-internal-enc.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
nt_password_hash: $(NOBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o nt_password_hash $(NOBJS) $(LIBS_n)
|
||||||
|
|
||||||
|
hlr_auc_gw: $(HOBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o hlr_auc_gw $(HOBJS) $(LIBS_h)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C ../src clean
|
||||||
|
rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw
|
||||||
|
rm -f *.d
|
||||||
|
|
||||||
|
-include $(OBJS:%.o=%.d)
|
387
hostapd/README
Normal file
387
hostapd/README
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
|
||||||
|
Authenticator and RADIUS authentication server
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi> and contributors
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
This program is dual-licensed under both the GPL version 2 and BSD
|
||||||
|
license. Either license may be used at your option.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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>)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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
|
265
hostapd/README-WPS
Normal file
265
hostapd/README-WPS
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
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_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.
|
||||||
|
|
||||||
|
|
||||||
|
When an external Registrar is used, the AP can act as an Enrollee and
|
||||||
|
use its AP PIN. A static AP PIN (e.g., one one a label in the AP
|
||||||
|
device) can be configured in hostapd.conf (ap_pin parameter). A more
|
||||||
|
secure option is to use hostapd_cli wps_ap_pin command to enable the
|
||||||
|
AP PIN only based on user action (and even better security by using a
|
||||||
|
random AP PIN for each session, i.e., by using "wps_ap_pin random"
|
||||||
|
command with a timeout value). Following commands are available for
|
||||||
|
managing the dynamic AP PIN operations:
|
||||||
|
|
||||||
|
hostapd_cli wps_ap_pin disable
|
||||||
|
- disable AP PIN (i.e., do not allow external Registrars to use it to
|
||||||
|
learn the current AP settings or to reconfigure the AP)
|
||||||
|
|
||||||
|
hostapd_cli wps_ap_pin random [timeout]
|
||||||
|
- generate a random AP PIN and enable it
|
||||||
|
- if the optional timeout parameter is given, the AP PIN will be enabled
|
||||||
|
for the specified number of seconds
|
||||||
|
|
||||||
|
hostapd_cli wps_ap_pin get
|
||||||
|
- fetch the current AP PIN
|
||||||
|
|
||||||
|
hostapd_cli wps_ap_pin set <PIN> [timeout]
|
||||||
|
- set the AP PIN and enable it
|
||||||
|
- if the optional timeout parameter is given, the AP PIN will be enabled
|
||||||
|
for the specified number of seconds
|
||||||
|
|
||||||
|
|
||||||
|
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).
|
2049
hostapd/config_file.c
Normal file
2049
hostapd/config_file.c
Normal file
File diff suppressed because it is too large
Load Diff
20
hostapd/config_file.h
Normal file
20
hostapd/config_file.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* hostapd / Configuration file parser
|
||||||
|
* Copyright (c) 2003-2009, 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 CONFIG_FILE_H
|
||||||
|
#define CONFIG_FILE_H
|
||||||
|
|
||||||
|
struct hostapd_config * hostapd_config_read(const char *fname);
|
||||||
|
|
||||||
|
#endif /* CONFIG_FILE_H */
|
726
hostapd/ctrl_iface.c
Normal file
726
hostapd/ctrl_iface.c
Normal file
@ -0,0 +1,726 @@
|
|||||||
|
/*
|
||||||
|
* hostapd / UNIX domain socket -based control interface
|
||||||
|
* Copyright (c) 2004-2009, 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 "utils/includes.h"
|
||||||
|
|
||||||
|
#ifndef CONFIG_NATIVE_WINDOWS
|
||||||
|
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "utils/common.h"
|
||||||
|
#include "utils/eloop.h"
|
||||||
|
#include "common/ieee802_11_defs.h"
|
||||||
|
#include "drivers/driver.h"
|
||||||
|
#include "radius/radius_client.h"
|
||||||
|
#include "ap/hostapd.h"
|
||||||
|
#include "ap/ap_config.h"
|
||||||
|
#include "ap/ieee802_1x.h"
|
||||||
|
#include "ap/wpa_auth.h"
|
||||||
|
#include "ap/ieee802_11.h"
|
||||||
|
#include "ap/sta_info.h"
|
||||||
|
#include "ap/accounting.h"
|
||||||
|
#include "ap/wps_hostapd.h"
|
||||||
|
#include "ap/ctrl_iface_ap.h"
|
||||||
|
#include "ctrl_iface.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct wpa_ctrl_dst {
|
||||||
|
struct wpa_ctrl_dst *next;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
socklen_t addrlen;
|
||||||
|
int debug_level;
|
||||||
|
int errors;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
|
||||||
|
const char *buf, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd,
|
||||||
|
struct sockaddr_un *from,
|
||||||
|
socklen_t fromlen)
|
||||||
|
{
|
||||||
|
struct wpa_ctrl_dst *dst;
|
||||||
|
|
||||||
|
dst = os_zalloc(sizeof(*dst));
|
||||||
|
if (dst == NULL)
|
||||||
|
return -1;
|
||||||
|
os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un));
|
||||||
|
dst->addrlen = fromlen;
|
||||||
|
dst->debug_level = MSG_INFO;
|
||||||
|
dst->next = hapd->ctrl_dst;
|
||||||
|
hapd->ctrl_dst = dst;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached",
|
||||||
|
(u8 *) from->sun_path,
|
||||||
|
fromlen - offsetof(struct sockaddr_un, sun_path));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_detach(struct hostapd_data *hapd,
|
||||||
|
struct sockaddr_un *from,
|
||||||
|
socklen_t fromlen)
|
||||||
|
{
|
||||||
|
struct wpa_ctrl_dst *dst, *prev = NULL;
|
||||||
|
|
||||||
|
dst = hapd->ctrl_dst;
|
||||||
|
while (dst) {
|
||||||
|
if (fromlen == dst->addrlen &&
|
||||||
|
os_memcmp(from->sun_path, dst->addr.sun_path,
|
||||||
|
fromlen - offsetof(struct sockaddr_un, sun_path))
|
||||||
|
== 0) {
|
||||||
|
if (prev == NULL)
|
||||||
|
hapd->ctrl_dst = dst->next;
|
||||||
|
else
|
||||||
|
prev->next = dst->next;
|
||||||
|
os_free(dst);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached",
|
||||||
|
(u8 *) from->sun_path,
|
||||||
|
fromlen -
|
||||||
|
offsetof(struct sockaddr_un, sun_path));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
prev = dst;
|
||||||
|
dst = dst->next;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_level(struct hostapd_data *hapd,
|
||||||
|
struct sockaddr_un *from,
|
||||||
|
socklen_t fromlen,
|
||||||
|
char *level)
|
||||||
|
{
|
||||||
|
struct wpa_ctrl_dst *dst;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
|
||||||
|
|
||||||
|
dst = hapd->ctrl_dst;
|
||||||
|
while (dst) {
|
||||||
|
if (fromlen == dst->addrlen &&
|
||||||
|
os_memcmp(from->sun_path, dst->addr.sun_path,
|
||||||
|
fromlen - offsetof(struct sockaddr_un, sun_path))
|
||||||
|
== 0) {
|
||||||
|
wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor "
|
||||||
|
"level", (u8 *) from->sun_path, fromlen -
|
||||||
|
offsetof(struct sockaddr_un, sun_path));
|
||||||
|
dst->debug_level = atoi(level);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dst = dst->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
|
||||||
|
const char *txtaddr)
|
||||||
|
{
|
||||||
|
u8 addr[ETH_ALEN];
|
||||||
|
struct sta_info *sta;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE NEW_STA %s", txtaddr);
|
||||||
|
|
||||||
|
if (hwaddr_aton(txtaddr, addr))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sta = ap_get_sta(hapd, addr);
|
||||||
|
if (sta)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "Add new STA " MACSTR " based on ctrl_iface "
|
||||||
|
"notification", MAC2STR(addr));
|
||||||
|
sta = ap_sta_add(hapd, addr);
|
||||||
|
if (sta == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
hostapd_new_assoc_sta(hapd, sta, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
|
||||||
|
const char *txtaddr)
|
||||||
|
{
|
||||||
|
u8 addr[ETH_ALEN];
|
||||||
|
struct sta_info *sta;
|
||||||
|
const char *pos;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE DEAUTHENTICATE %s", txtaddr);
|
||||||
|
|
||||||
|
if (hwaddr_aton(txtaddr, addr))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pos = os_strstr(txtaddr, " test=");
|
||||||
|
if (pos) {
|
||||||
|
struct ieee80211_mgmt mgmt;
|
||||||
|
int encrypt;
|
||||||
|
if (hapd->driver->send_frame == NULL)
|
||||||
|
return -1;
|
||||||
|
pos += 6;
|
||||||
|
encrypt = atoi(pos);
|
||||||
|
os_memset(&mgmt, 0, sizeof(mgmt));
|
||||||
|
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||||
|
WLAN_FC_STYPE_DEAUTH);
|
||||||
|
os_memcpy(mgmt.da, addr, ETH_ALEN);
|
||||||
|
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
|
||||||
|
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
|
||||||
|
mgmt.u.deauth.reason_code =
|
||||||
|
host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
|
if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
|
||||||
|
IEEE80211_HDRLEN +
|
||||||
|
sizeof(mgmt.u.deauth),
|
||||||
|
encrypt) < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
|
sta = ap_get_sta(hapd, addr);
|
||||||
|
if (sta)
|
||||||
|
ap_sta_deauthenticate(hapd, sta,
|
||||||
|
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
|
||||||
|
const char *txtaddr)
|
||||||
|
{
|
||||||
|
u8 addr[ETH_ALEN];
|
||||||
|
struct sta_info *sta;
|
||||||
|
const char *pos;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s", txtaddr);
|
||||||
|
|
||||||
|
if (hwaddr_aton(txtaddr, addr))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pos = os_strstr(txtaddr, " test=");
|
||||||
|
if (pos) {
|
||||||
|
struct ieee80211_mgmt mgmt;
|
||||||
|
int encrypt;
|
||||||
|
if (hapd->driver->send_frame == NULL)
|
||||||
|
return -1;
|
||||||
|
pos += 6;
|
||||||
|
encrypt = atoi(pos);
|
||||||
|
os_memset(&mgmt, 0, sizeof(mgmt));
|
||||||
|
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||||
|
WLAN_FC_STYPE_DISASSOC);
|
||||||
|
os_memcpy(mgmt.da, addr, ETH_ALEN);
|
||||||
|
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
|
||||||
|
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
|
||||||
|
mgmt.u.disassoc.reason_code =
|
||||||
|
host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
|
if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
|
||||||
|
IEEE80211_HDRLEN +
|
||||||
|
sizeof(mgmt.u.deauth),
|
||||||
|
encrypt) < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hapd->drv.sta_disassoc(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
|
sta = ap_get_sta(hapd, addr);
|
||||||
|
if (sta)
|
||||||
|
ap_sta_disassociate(hapd, sta,
|
||||||
|
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211W
|
||||||
|
#ifdef NEED_AP_MLME
|
||||||
|
static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
|
||||||
|
const char *txtaddr)
|
||||||
|
{
|
||||||
|
u8 addr[ETH_ALEN];
|
||||||
|
u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE SA_QUERY %s", txtaddr);
|
||||||
|
|
||||||
|
if (hwaddr_aton(txtaddr, addr) ||
|
||||||
|
os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ieee802_11_send_sa_query_req(hapd, addr, trans_id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* NEED_AP_MLME */
|
||||||
|
#endif /* CONFIG_IEEE80211W */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
|
||||||
|
{
|
||||||
|
char *pin = os_strchr(txt, ' ');
|
||||||
|
char *timeout_txt;
|
||||||
|
int timeout;
|
||||||
|
|
||||||
|
if (pin == NULL)
|
||||||
|
return -1;
|
||||||
|
*pin++ = '\0';
|
||||||
|
|
||||||
|
timeout_txt = os_strchr(pin, ' ');
|
||||||
|
if (timeout_txt) {
|
||||||
|
*timeout_txt++ = '\0';
|
||||||
|
timeout = atoi(timeout_txt);
|
||||||
|
} else
|
||||||
|
timeout = 0;
|
||||||
|
|
||||||
|
return hostapd_wps_add_pin(hapd, txt, pin, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS_OOB
|
||||||
|
static int hostapd_ctrl_iface_wps_oob(struct hostapd_data *hapd, char *txt)
|
||||||
|
{
|
||||||
|
char *path, *method, *name;
|
||||||
|
|
||||||
|
path = os_strchr(txt, ' ');
|
||||||
|
if (path == NULL)
|
||||||
|
return -1;
|
||||||
|
*path++ = '\0';
|
||||||
|
|
||||||
|
method = os_strchr(path, ' ');
|
||||||
|
if (method == NULL)
|
||||||
|
return -1;
|
||||||
|
*method++ = '\0';
|
||||||
|
|
||||||
|
name = os_strchr(method, ' ');
|
||||||
|
if (name != NULL)
|
||||||
|
*name++ = '\0';
|
||||||
|
|
||||||
|
return hostapd_wps_start_oob(hapd, txt, path, method, name);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_WPS_OOB */
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt,
|
||||||
|
char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
int timeout = 300;
|
||||||
|
char *pos;
|
||||||
|
const char *pin_txt;
|
||||||
|
|
||||||
|
pos = os_strchr(txt, ' ');
|
||||||
|
if (pos)
|
||||||
|
*pos++ = '\0';
|
||||||
|
|
||||||
|
if (os_strcmp(txt, "disable") == 0) {
|
||||||
|
hostapd_wps_ap_pin_disable(hapd);
|
||||||
|
return os_snprintf(buf, buflen, "OK\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os_strcmp(txt, "random") == 0) {
|
||||||
|
if (pos)
|
||||||
|
timeout = atoi(pos);
|
||||||
|
pin_txt = hostapd_wps_ap_pin_random(hapd, timeout);
|
||||||
|
if (pin_txt == NULL)
|
||||||
|
return -1;
|
||||||
|
return os_snprintf(buf, buflen, "%s", pin_txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os_strcmp(txt, "get") == 0) {
|
||||||
|
pin_txt = hostapd_wps_ap_pin_get(hapd);
|
||||||
|
if (pin_txt == NULL)
|
||||||
|
return -1;
|
||||||
|
return os_snprintf(buf, buflen, "%s", pin_txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os_strcmp(txt, "set") == 0) {
|
||||||
|
char *pin;
|
||||||
|
if (pos == NULL)
|
||||||
|
return -1;
|
||||||
|
pin = pos;
|
||||||
|
pos = os_strchr(pos, ' ');
|
||||||
|
if (pos) {
|
||||||
|
*pos++ = '\0';
|
||||||
|
timeout = atoi(pos);
|
||||||
|
}
|
||||||
|
if (os_strlen(pin) > buflen)
|
||||||
|
return -1;
|
||||||
|
if (hostapd_wps_ap_pin_set(hapd, pin, timeout) < 0)
|
||||||
|
return -1;
|
||||||
|
return os_snprintf(buf, buflen, "%s", pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
|
||||||
|
void *sock_ctx)
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd = eloop_ctx;
|
||||||
|
char buf[256];
|
||||||
|
int res;
|
||||||
|
struct sockaddr_un from;
|
||||||
|
socklen_t fromlen = sizeof(from);
|
||||||
|
char *reply;
|
||||||
|
const int reply_size = 4096;
|
||||||
|
int reply_len;
|
||||||
|
|
||||||
|
res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
|
||||||
|
(struct sockaddr *) &from, &fromlen);
|
||||||
|
if (res < 0) {
|
||||||
|
perror("recvfrom(ctrl_iface)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buf[res] = '\0';
|
||||||
|
wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface", (u8 *) buf, res);
|
||||||
|
|
||||||
|
reply = os_malloc(reply_size);
|
||||||
|
if (reply == NULL) {
|
||||||
|
sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
|
||||||
|
fromlen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
os_memcpy(reply, "OK\n", 3);
|
||||||
|
reply_len = 3;
|
||||||
|
|
||||||
|
if (os_strcmp(buf, "PING") == 0) {
|
||||||
|
os_memcpy(reply, "PONG\n", 5);
|
||||||
|
reply_len = 5;
|
||||||
|
} else if (os_strcmp(buf, "MIB") == 0) {
|
||||||
|
reply_len = ieee802_11_get_mib(hapd, reply, reply_size);
|
||||||
|
if (reply_len >= 0) {
|
||||||
|
res = wpa_get_mib(hapd->wpa_auth, reply + reply_len,
|
||||||
|
reply_size - reply_len);
|
||||||
|
if (res < 0)
|
||||||
|
reply_len = -1;
|
||||||
|
else
|
||||||
|
reply_len += res;
|
||||||
|
}
|
||||||
|
if (reply_len >= 0) {
|
||||||
|
res = ieee802_1x_get_mib(hapd, reply + reply_len,
|
||||||
|
reply_size - reply_len);
|
||||||
|
if (res < 0)
|
||||||
|
reply_len = -1;
|
||||||
|
else
|
||||||
|
reply_len += res;
|
||||||
|
}
|
||||||
|
#ifndef CONFIG_NO_RADIUS
|
||||||
|
if (reply_len >= 0) {
|
||||||
|
res = radius_client_get_mib(hapd->radius,
|
||||||
|
reply + reply_len,
|
||||||
|
reply_size - reply_len);
|
||||||
|
if (res < 0)
|
||||||
|
reply_len = -1;
|
||||||
|
else
|
||||||
|
reply_len += res;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NO_RADIUS */
|
||||||
|
} else if (os_strcmp(buf, "STA-FIRST") == 0) {
|
||||||
|
reply_len = hostapd_ctrl_iface_sta_first(hapd, reply,
|
||||||
|
reply_size);
|
||||||
|
} else if (os_strncmp(buf, "STA ", 4) == 0) {
|
||||||
|
reply_len = hostapd_ctrl_iface_sta(hapd, buf + 4, reply,
|
||||||
|
reply_size);
|
||||||
|
} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
|
||||||
|
reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,
|
||||||
|
reply_size);
|
||||||
|
} else if (os_strcmp(buf, "ATTACH") == 0) {
|
||||||
|
if (hostapd_ctrl_iface_attach(hapd, &from, fromlen))
|
||||||
|
reply_len = -1;
|
||||||
|
} else if (os_strcmp(buf, "DETACH") == 0) {
|
||||||
|
if (hostapd_ctrl_iface_detach(hapd, &from, fromlen))
|
||||||
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_level(hapd, &from, fromlen,
|
||||||
|
buf + 6))
|
||||||
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
|
||||||
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_deauthenticate(hapd, buf + 15))
|
||||||
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_disassociate(hapd, buf + 13))
|
||||||
|
reply_len = -1;
|
||||||
|
#ifdef CONFIG_IEEE80211W
|
||||||
|
#ifdef NEED_AP_MLME
|
||||||
|
} else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_sa_query(hapd, buf + 9))
|
||||||
|
reply_len = -1;
|
||||||
|
#endif /* NEED_AP_MLME */
|
||||||
|
#endif /* CONFIG_IEEE80211W */
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
} else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_wps_pin(hapd, buf + 8))
|
||||||
|
reply_len = -1;
|
||||||
|
} else if (os_strcmp(buf, "WPS_PBC") == 0) {
|
||||||
|
if (hostapd_wps_button_pushed(hapd))
|
||||||
|
reply_len = -1;
|
||||||
|
#ifdef CONFIG_WPS_OOB
|
||||||
|
} else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_wps_oob(hapd, buf + 8))
|
||||||
|
reply_len = -1;
|
||||||
|
#endif /* CONFIG_WPS_OOB */
|
||||||
|
} else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
|
||||||
|
reply_len = hostapd_ctrl_iface_wps_ap_pin(hapd, buf + 11,
|
||||||
|
reply, reply_size);
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
|
} else {
|
||||||
|
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
|
||||||
|
reply_len = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply_len < 0) {
|
||||||
|
os_memcpy(reply, "FAIL\n", 5);
|
||||||
|
reply_len = 5;
|
||||||
|
}
|
||||||
|
sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, fromlen);
|
||||||
|
os_free(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char * hostapd_ctrl_iface_path(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (hapd->conf->ctrl_interface == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
len = os_strlen(hapd->conf->ctrl_interface) +
|
||||||
|
os_strlen(hapd->conf->iface) + 2;
|
||||||
|
buf = os_malloc(len);
|
||||||
|
if (buf == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
os_snprintf(buf, len, "%s/%s",
|
||||||
|
hapd->conf->ctrl_interface, hapd->conf->iface);
|
||||||
|
buf[len - 1] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_ctrl_iface_msg_cb(void *ctx, int level,
|
||||||
|
const char *txt, size_t len)
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd = ctx;
|
||||||
|
if (hapd == NULL)
|
||||||
|
return;
|
||||||
|
hostapd_ctrl_iface_send(hapd, level, txt, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
int s = -1;
|
||||||
|
char *fname = NULL;
|
||||||
|
|
||||||
|
hapd->ctrl_sock = -1;
|
||||||
|
|
||||||
|
if (hapd->conf->ctrl_interface == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (mkdir(hapd->conf->ctrl_interface, S_IRWXU | S_IRWXG) < 0) {
|
||||||
|
if (errno == EEXIST) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Using existing control "
|
||||||
|
"interface directory.");
|
||||||
|
} else {
|
||||||
|
perror("mkdir[ctrl_interface]");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hapd->conf->ctrl_interface_gid_set &&
|
||||||
|
chown(hapd->conf->ctrl_interface, 0,
|
||||||
|
hapd->conf->ctrl_interface_gid) < 0) {
|
||||||
|
perror("chown[ctrl_interface]");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os_strlen(hapd->conf->ctrl_interface) + 1 +
|
||||||
|
os_strlen(hapd->conf->iface) >= sizeof(addr.sun_path))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
s = socket(PF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
if (s < 0) {
|
||||||
|
perror("socket(PF_UNIX)");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
os_memset(&addr, 0, sizeof(addr));
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
addr.sun_len = sizeof(addr);
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
fname = hostapd_ctrl_iface_path(hapd);
|
||||||
|
if (fname == NULL)
|
||||||
|
goto fail;
|
||||||
|
os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
|
||||||
|
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
|
||||||
|
strerror(errno));
|
||||||
|
if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
|
||||||
|
" allow connections - assuming it was left"
|
||||||
|
"over from forced program termination");
|
||||||
|
if (unlink(fname) < 0) {
|
||||||
|
perror("unlink[ctrl_iface]");
|
||||||
|
wpa_printf(MSG_ERROR, "Could not unlink "
|
||||||
|
"existing ctrl_iface socket '%s'",
|
||||||
|
fname);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) <
|
||||||
|
0) {
|
||||||
|
perror("bind(PF_UNIX)");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
|
||||||
|
"ctrl_iface socket '%s'", fname);
|
||||||
|
} else {
|
||||||
|
wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
|
||||||
|
"be in use - cannot override it");
|
||||||
|
wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
|
||||||
|
"not used anymore", fname);
|
||||||
|
os_free(fname);
|
||||||
|
fname = NULL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hapd->conf->ctrl_interface_gid_set &&
|
||||||
|
chown(fname, 0, hapd->conf->ctrl_interface_gid) < 0) {
|
||||||
|
perror("chown[ctrl_interface/ifname]");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
|
||||||
|
perror("chmod[ctrl_interface/ifname]");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
os_free(fname);
|
||||||
|
|
||||||
|
hapd->ctrl_sock = s;
|
||||||
|
eloop_register_read_sock(s, hostapd_ctrl_iface_receive, hapd,
|
||||||
|
NULL);
|
||||||
|
hapd->msg_ctx = hapd;
|
||||||
|
wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (s >= 0)
|
||||||
|
close(s);
|
||||||
|
if (fname) {
|
||||||
|
unlink(fname);
|
||||||
|
os_free(fname);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
struct wpa_ctrl_dst *dst, *prev;
|
||||||
|
|
||||||
|
if (hapd->ctrl_sock > -1) {
|
||||||
|
char *fname;
|
||||||
|
eloop_unregister_read_sock(hapd->ctrl_sock);
|
||||||
|
close(hapd->ctrl_sock);
|
||||||
|
hapd->ctrl_sock = -1;
|
||||||
|
fname = hostapd_ctrl_iface_path(hapd);
|
||||||
|
if (fname)
|
||||||
|
unlink(fname);
|
||||||
|
os_free(fname);
|
||||||
|
|
||||||
|
if (hapd->conf->ctrl_interface &&
|
||||||
|
rmdir(hapd->conf->ctrl_interface) < 0) {
|
||||||
|
if (errno == ENOTEMPTY) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Control interface "
|
||||||
|
"directory not empty - leaving it "
|
||||||
|
"behind");
|
||||||
|
} else {
|
||||||
|
perror("rmdir[ctrl_interface]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = hapd->ctrl_dst;
|
||||||
|
while (dst) {
|
||||||
|
prev = dst;
|
||||||
|
dst = dst->next;
|
||||||
|
os_free(prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
|
||||||
|
const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
struct wpa_ctrl_dst *dst, *next;
|
||||||
|
struct msghdr msg;
|
||||||
|
int idx;
|
||||||
|
struct iovec io[2];
|
||||||
|
char levelstr[10];
|
||||||
|
|
||||||
|
dst = hapd->ctrl_dst;
|
||||||
|
if (hapd->ctrl_sock < 0 || dst == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
|
||||||
|
io[0].iov_base = levelstr;
|
||||||
|
io[0].iov_len = os_strlen(levelstr);
|
||||||
|
io[1].iov_base = (char *) buf;
|
||||||
|
io[1].iov_len = len;
|
||||||
|
os_memset(&msg, 0, sizeof(msg));
|
||||||
|
msg.msg_iov = io;
|
||||||
|
msg.msg_iovlen = 2;
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
while (dst) {
|
||||||
|
next = dst->next;
|
||||||
|
if (level >= dst->debug_level) {
|
||||||
|
wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send",
|
||||||
|
(u8 *) dst->addr.sun_path, dst->addrlen -
|
||||||
|
offsetof(struct sockaddr_un, sun_path));
|
||||||
|
msg.msg_name = &dst->addr;
|
||||||
|
msg.msg_namelen = dst->addrlen;
|
||||||
|
if (sendmsg(hapd->ctrl_sock, &msg, 0) < 0) {
|
||||||
|
int _errno = errno;
|
||||||
|
wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
|
||||||
|
"%d - %s",
|
||||||
|
idx, errno, strerror(errno));
|
||||||
|
dst->errors++;
|
||||||
|
if (dst->errors > 10 || _errno == ENOENT) {
|
||||||
|
hostapd_ctrl_iface_detach(
|
||||||
|
hapd, &dst->addr,
|
||||||
|
dst->addrlen);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
dst->errors = 0;
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
dst = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_NATIVE_WINDOWS */
|
32
hostapd/ctrl_iface.h
Normal file
32
hostapd/ctrl_iface.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* hostapd / UNIX domain socket -based control interface
|
||||||
|
* Copyright (c) 2004, 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 CTRL_IFACE_H
|
||||||
|
#define CTRL_IFACE_H
|
||||||
|
|
||||||
|
#ifndef CONFIG_NO_CTRL_IFACE
|
||||||
|
int hostapd_ctrl_iface_init(struct hostapd_data *hapd);
|
||||||
|
void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd);
|
||||||
|
#else /* CONFIG_NO_CTRL_IFACE */
|
||||||
|
static inline int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NO_CTRL_IFACE */
|
||||||
|
|
||||||
|
#endif /* CTRL_IFACE_H */
|
175
hostapd/defconfig
Normal file
175
hostapd/defconfig
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
# Example hostapd build time configuration
|
||||||
|
#
|
||||||
|
# This file lists the configuration options that are used when building the
|
||||||
|
# hostapd binary. All lines starting with # are ignored. Configuration option
|
||||||
|
# lines must be commented out complete, if they are not to be included, i.e.,
|
||||||
|
# just setting VARIABLE=n is not disabling that variable.
|
||||||
|
#
|
||||||
|
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
|
||||||
|
# be modified from here. In most cass, these lines should use += in order not
|
||||||
|
# to override previous values of the variables.
|
||||||
|
|
||||||
|
# Driver interface for Host AP driver
|
||||||
|
CONFIG_DRIVER_HOSTAP=y
|
||||||
|
|
||||||
|
# Driver interface for wired authenticator
|
||||||
|
#CONFIG_DRIVER_WIRED=y
|
||||||
|
|
||||||
|
# Driver interface for madwifi driver
|
||||||
|
#CONFIG_DRIVER_MADWIFI=y
|
||||||
|
#CFLAGS += -I../../madwifi # change to the madwifi source directory
|
||||||
|
|
||||||
|
# Driver interface for drivers using the nl80211 kernel interface
|
||||||
|
#CONFIG_DRIVER_NL80211=y
|
||||||
|
# driver_nl80211.c requires a rather new libnl (version 1.1) which may not be
|
||||||
|
# shipped with your distribution yet. If that is the case, you need to build
|
||||||
|
# newer libnl version and point the hostapd build to use it.
|
||||||
|
#LIBNL=/usr/src/libnl
|
||||||
|
#CFLAGS += -I$(LIBNL)/include
|
||||||
|
#LIBS += -L$(LIBNL)/lib
|
||||||
|
|
||||||
|
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
|
||||||
|
#CONFIG_DRIVER_BSD=y
|
||||||
|
#CFLAGS += -I/usr/local/include
|
||||||
|
#LIBS += -L/usr/local/lib
|
||||||
|
#LIBS_p += -L/usr/local/lib
|
||||||
|
#LIBS_c += -L/usr/local/lib
|
||||||
|
|
||||||
|
# Driver interface for no driver (e.g., RADIUS server only)
|
||||||
|
#CONFIG_DRIVER_NONE=y
|
||||||
|
|
||||||
|
# IEEE 802.11F/IAPP
|
||||||
|
CONFIG_IAPP=y
|
||||||
|
|
||||||
|
# WPA2/IEEE 802.11i RSN pre-authentication
|
||||||
|
CONFIG_RSN_PREAUTH=y
|
||||||
|
|
||||||
|
# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
|
||||||
|
CONFIG_PEERKEY=y
|
||||||
|
|
||||||
|
# IEEE 802.11w (management frame protection)
|
||||||
|
# This version is an experimental implementation based on IEEE 802.11w/D1.0
|
||||||
|
# draft and is subject to change since the standard has not yet been finalized.
|
||||||
|
# Driver support is also needed for IEEE 802.11w.
|
||||||
|
#CONFIG_IEEE80211W=y
|
||||||
|
|
||||||
|
# Integrated EAP server
|
||||||
|
CONFIG_EAP=y
|
||||||
|
|
||||||
|
# EAP-MD5 for the integrated EAP server
|
||||||
|
CONFIG_EAP_MD5=y
|
||||||
|
|
||||||
|
# EAP-TLS for the integrated EAP server
|
||||||
|
CONFIG_EAP_TLS=y
|
||||||
|
|
||||||
|
# EAP-MSCHAPv2 for the integrated EAP server
|
||||||
|
CONFIG_EAP_MSCHAPV2=y
|
||||||
|
|
||||||
|
# EAP-PEAP for the integrated EAP server
|
||||||
|
CONFIG_EAP_PEAP=y
|
||||||
|
|
||||||
|
# EAP-GTC for the integrated EAP server
|
||||||
|
CONFIG_EAP_GTC=y
|
||||||
|
|
||||||
|
# EAP-TTLS for the integrated EAP server
|
||||||
|
CONFIG_EAP_TTLS=y
|
||||||
|
|
||||||
|
# EAP-SIM for the integrated EAP server
|
||||||
|
#CONFIG_EAP_SIM=y
|
||||||
|
|
||||||
|
# EAP-AKA for the integrated EAP server
|
||||||
|
#CONFIG_EAP_AKA=y
|
||||||
|
|
||||||
|
# EAP-AKA' for the integrated EAP server
|
||||||
|
# This requires CONFIG_EAP_AKA to be enabled, too.
|
||||||
|
#CONFIG_EAP_AKA_PRIME=y
|
||||||
|
|
||||||
|
# EAP-PAX for the integrated EAP server
|
||||||
|
#CONFIG_EAP_PAX=y
|
||||||
|
|
||||||
|
# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
|
||||||
|
#CONFIG_EAP_PSK=y
|
||||||
|
|
||||||
|
# EAP-SAKE for the integrated EAP server
|
||||||
|
#CONFIG_EAP_SAKE=y
|
||||||
|
|
||||||
|
# EAP-GPSK for the integrated EAP server
|
||||||
|
#CONFIG_EAP_GPSK=y
|
||||||
|
# Include support for optional SHA256 cipher suite in EAP-GPSK
|
||||||
|
#CONFIG_EAP_GPSK_SHA256=y
|
||||||
|
|
||||||
|
# EAP-FAST for the integrated EAP server
|
||||||
|
# Note: Default OpenSSL package does not include support for all the
|
||||||
|
# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
|
||||||
|
# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
|
||||||
|
# to add the needed functions.
|
||||||
|
#CONFIG_EAP_FAST=y
|
||||||
|
|
||||||
|
# Wi-Fi Protected Setup (WPS)
|
||||||
|
#CONFIG_WPS=y
|
||||||
|
# Enable UPnP support for external WPS Registrars
|
||||||
|
#CONFIG_WPS_UPNP=y
|
||||||
|
|
||||||
|
# EAP-IKEv2
|
||||||
|
#CONFIG_EAP_IKEV2=y
|
||||||
|
|
||||||
|
# Trusted Network Connect (EAP-TNC)
|
||||||
|
#CONFIG_EAP_TNC=y
|
||||||
|
|
||||||
|
# PKCS#12 (PFX) support (used to read private key and certificate file from
|
||||||
|
# a file that usually has extension .p12 or .pfx)
|
||||||
|
CONFIG_PKCS12=y
|
||||||
|
|
||||||
|
# RADIUS authentication server. This provides access to the integrated EAP
|
||||||
|
# server from external hosts using RADIUS.
|
||||||
|
#CONFIG_RADIUS_SERVER=y
|
||||||
|
|
||||||
|
# Build IPv6 support for RADIUS operations
|
||||||
|
CONFIG_IPV6=y
|
||||||
|
|
||||||
|
# IEEE Std 802.11r-2008 (Fast BSS Transition)
|
||||||
|
#CONFIG_IEEE80211R=y
|
||||||
|
|
||||||
|
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
|
||||||
|
# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211)
|
||||||
|
#CONFIG_DRIVER_RADIUS_ACL=y
|
||||||
|
|
||||||
|
# IEEE 802.11n (High Throughput) support
|
||||||
|
#CONFIG_IEEE80211N=y
|
||||||
|
|
||||||
|
# Remove debugging code that is printing out debug messages to stdout.
|
||||||
|
# This can be used to reduce the size of the hostapd considerably if debugging
|
||||||
|
# code is not needed.
|
||||||
|
#CONFIG_NO_STDOUT_DEBUG=y
|
||||||
|
|
||||||
|
# Remove support for RADIUS accounting
|
||||||
|
#CONFIG_NO_ACCOUNTING=y
|
||||||
|
|
||||||
|
# Remove support for RADIUS
|
||||||
|
#CONFIG_NO_RADIUS=y
|
||||||
|
|
||||||
|
# Remove support for VLANs
|
||||||
|
#CONFIG_NO_VLAN=y
|
||||||
|
|
||||||
|
# Remove support for dumping state into a file on SIGUSR1 signal
|
||||||
|
# This can be used to reduce binary size at the cost of disabling a debugging
|
||||||
|
# option.
|
||||||
|
#CONFIG_NO_DUMP_STATE=y
|
||||||
|
|
||||||
|
# Enable tracing code for developer debugging
|
||||||
|
# This tracks use of memory allocations and other registrations and reports
|
||||||
|
# incorrect use with a backtrace of call (or allocation) location.
|
||||||
|
#CONFIG_WPA_TRACE=y
|
||||||
|
# For BSD, comment out these.
|
||||||
|
#LIBS += -lexecinfo
|
||||||
|
#LIBS_p += -lexecinfo
|
||||||
|
#LIBS_c += -lexecinfo
|
||||||
|
|
||||||
|
# Use libbfd to get more details for developer debugging
|
||||||
|
# This enables use of libbfd to get more detailed symbols for the backtraces
|
||||||
|
# generated by CONFIG_WPA_TRACE=y.
|
||||||
|
#CONFIG_WPA_TRACE_BFD=y
|
||||||
|
# For BSD, comment out these.
|
||||||
|
#LIBS += -lbfd -liberty -lz
|
||||||
|
#LIBS_p += -lbfd -liberty -lz
|
||||||
|
#LIBS_c += -lbfd -liberty -lz
|
184
hostapd/dump_state.c
Normal file
184
hostapd/dump_state.c
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* hostapd / State dump
|
||||||
|
* Copyright (c) 2002-2009, 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 "utils/includes.h"
|
||||||
|
|
||||||
|
#include "utils/common.h"
|
||||||
|
#include "radius/radius_client.h"
|
||||||
|
#include "radius/radius_server.h"
|
||||||
|
#include "eapol_auth/eapol_auth_sm.h"
|
||||||
|
#include "eapol_auth/eapol_auth_sm_i.h"
|
||||||
|
#include "eap_server/eap.h"
|
||||||
|
#include "ap/hostapd.h"
|
||||||
|
#include "ap/ap_config.h"
|
||||||
|
#include "ap/sta_info.h"
|
||||||
|
#include "dump_state.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void fprint_char(FILE *f, char c)
|
||||||
|
{
|
||||||
|
if (c >= 32 && c < 127)
|
||||||
|
fprintf(f, "%c", c);
|
||||||
|
else
|
||||||
|
fprintf(f, "<%02x>", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ieee802_1x_dump_state(FILE *f, const char *prefix,
|
||||||
|
struct sta_info *sta)
|
||||||
|
{
|
||||||
|
struct eapol_state_machine *sm = sta->eapol_sm;
|
||||||
|
if (sm == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fprintf(f, "%sIEEE 802.1X:\n", prefix);
|
||||||
|
|
||||||
|
if (sm->identity) {
|
||||||
|
size_t i;
|
||||||
|
fprintf(f, "%sidentity=", prefix);
|
||||||
|
for (i = 0; i < sm->identity_len; i++)
|
||||||
|
fprint_char(f, sm->identity[i]);
|
||||||
|
fprintf(f, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(f, "%slast EAP type: Authentication Server: %d (%s) "
|
||||||
|
"Supplicant: %d (%s)\n", prefix,
|
||||||
|
sm->eap_type_authsrv,
|
||||||
|
eap_server_get_name(0, sm->eap_type_authsrv),
|
||||||
|
sm->eap_type_supp, eap_server_get_name(0, sm->eap_type_supp));
|
||||||
|
|
||||||
|
fprintf(f, "%scached_packets=%s\n", prefix,
|
||||||
|
sm->last_recv_radius ? "[RX RADIUS]" : "");
|
||||||
|
|
||||||
|
eapol_auth_dump_state(f, prefix, sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hostapd_dump_state - SIGUSR1 handler to dump hostapd state to a text file
|
||||||
|
*/
|
||||||
|
static void hostapd_dump_state(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
time_t now;
|
||||||
|
struct sta_info *sta;
|
||||||
|
int i;
|
||||||
|
#ifndef CONFIG_NO_RADIUS
|
||||||
|
char *buf;
|
||||||
|
#endif /* CONFIG_NO_RADIUS */
|
||||||
|
|
||||||
|
if (!hapd->conf->dump_log_name) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Dump file not defined - ignoring dump "
|
||||||
|
"request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "Dumping hostapd state to '%s'",
|
||||||
|
hapd->conf->dump_log_name);
|
||||||
|
f = fopen(hapd->conf->dump_log_name, "w");
|
||||||
|
if (f == NULL) {
|
||||||
|
wpa_printf(MSG_WARNING, "Could not open dump file '%s' for "
|
||||||
|
"writing.", hapd->conf->dump_log_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
time(&now);
|
||||||
|
fprintf(f, "hostapd state dump - %s", ctime(&now));
|
||||||
|
fprintf(f, "num_sta=%d num_sta_non_erp=%d "
|
||||||
|
"num_sta_no_short_slot_time=%d\n"
|
||||||
|
"num_sta_no_short_preamble=%d\n",
|
||||||
|
hapd->num_sta, hapd->iface->num_sta_non_erp,
|
||||||
|
hapd->iface->num_sta_no_short_slot_time,
|
||||||
|
hapd->iface->num_sta_no_short_preamble);
|
||||||
|
|
||||||
|
for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
|
||||||
|
fprintf(f, "\nSTA=" MACSTR "\n", MAC2STR(sta->addr));
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
" AID=%d flags=0x%x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
|
||||||
|
" capability=0x%x listen_interval=%d\n",
|
||||||
|
sta->aid,
|
||||||
|
sta->flags,
|
||||||
|
(sta->flags & WLAN_STA_AUTH ? "[AUTH]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_PS ? "[PS]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_TIM ? "[TIM]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_PERM ? "[PERM]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" :
|
||||||
|
""),
|
||||||
|
(sta->flags & WLAN_STA_PENDING_POLL ? "[PENDING_POLL" :
|
||||||
|
""),
|
||||||
|
(sta->flags & WLAN_STA_SHORT_PREAMBLE ?
|
||||||
|
"[SHORT_PREAMBLE]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_PREAUTH ? "[PREAUTH]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_WMM ? "[WMM]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_MFP ? "[MFP]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_WPS ? "[WPS]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_MAYBE_WPS ? "[MAYBE_WPS]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_WDS ? "[WDS]" : ""),
|
||||||
|
(sta->flags & WLAN_STA_NONERP ? "[NonERP]" : ""),
|
||||||
|
sta->capability,
|
||||||
|
sta->listen_interval);
|
||||||
|
|
||||||
|
fprintf(f, " supported_rates=");
|
||||||
|
for (i = 0; i < sta->supported_rates_len; i++)
|
||||||
|
fprintf(f, "%02x ", sta->supported_rates[i]);
|
||||||
|
fprintf(f, "\n");
|
||||||
|
|
||||||
|
fprintf(f,
|
||||||
|
" timeout_next=%s\n",
|
||||||
|
(sta->timeout_next == STA_NULLFUNC ? "NULLFUNC POLL" :
|
||||||
|
(sta->timeout_next == STA_DISASSOC ? "DISASSOC" :
|
||||||
|
"DEAUTH")));
|
||||||
|
|
||||||
|
ieee802_1x_dump_state(f, " ", sta);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_NO_RADIUS
|
||||||
|
buf = os_malloc(4096);
|
||||||
|
if (buf) {
|
||||||
|
int count = radius_client_get_mib(hapd->radius, buf, 4096);
|
||||||
|
if (count < 0)
|
||||||
|
count = 0;
|
||||||
|
else if (count > 4095)
|
||||||
|
count = 4095;
|
||||||
|
buf[count] = '\0';
|
||||||
|
fprintf(f, "%s", buf);
|
||||||
|
|
||||||
|
#ifdef RADIUS_SERVER
|
||||||
|
count = radius_server_get_mib(hapd->radius_srv, buf, 4096);
|
||||||
|
if (count < 0)
|
||||||
|
count = 0;
|
||||||
|
else if (count > 4095)
|
||||||
|
count = 4095;
|
||||||
|
buf[count] = '\0';
|
||||||
|
fprintf(f, "%s", buf);
|
||||||
|
#endif /* RADIUS_SERVER */
|
||||||
|
|
||||||
|
os_free(buf);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NO_RADIUS */
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int handle_dump_state_iface(struct hostapd_iface *iface, void *ctx)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < iface->num_bss; i++)
|
||||||
|
hostapd_dump_state(iface->bss[i]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
20
hostapd/dump_state.h
Normal file
20
hostapd/dump_state.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* hostapd / State dump
|
||||||
|
* Copyright (c) 2002-2009, 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 DUMP_STATE_H
|
||||||
|
#define DUMP_STATE_H
|
||||||
|
|
||||||
|
int handle_dump_state_iface(struct hostapd_iface *iface, void *ctx);
|
||||||
|
|
||||||
|
#endif /* DUMP_STATE_H */
|
134
hostapd/eap_register.c
Normal file
134
hostapd/eap_register.c
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* EAP method registration
|
||||||
|
* Copyright (c) 2004-2009, 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 "common.h"
|
||||||
|
#include "eap_server/eap_methods.h"
|
||||||
|
#include "eap_register.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eap_server_register_methods - Register statically linked EAP server methods
|
||||||
|
* Returns: 0 on success, -1 or -2 on failure
|
||||||
|
*
|
||||||
|
* This function is called at program initialization to register all EAP
|
||||||
|
* methods that were linked in statically.
|
||||||
|
*/
|
||||||
|
int eap_server_register_methods(void)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_IDENTITY
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_identity_register();
|
||||||
|
#endif /* EAP_SERVER_IDENTITY */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_MD5
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_md5_register();
|
||||||
|
#endif /* EAP_SERVER_MD5 */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_TLS
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_tls_register();
|
||||||
|
#endif /* EAP_SERVER_TLS */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_MSCHAPV2
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_mschapv2_register();
|
||||||
|
#endif /* EAP_SERVER_MSCHAPV2 */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_PEAP
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_peap_register();
|
||||||
|
#endif /* EAP_SERVER_PEAP */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_TLV
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_tlv_register();
|
||||||
|
#endif /* EAP_SERVER_TLV */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_GTC
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_gtc_register();
|
||||||
|
#endif /* EAP_SERVER_GTC */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_TTLS
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_ttls_register();
|
||||||
|
#endif /* EAP_SERVER_TTLS */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_SIM
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_sim_register();
|
||||||
|
#endif /* EAP_SERVER_SIM */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_AKA
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_aka_register();
|
||||||
|
#endif /* EAP_SERVER_AKA */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_AKA_PRIME
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_aka_prime_register();
|
||||||
|
#endif /* EAP_SERVER_AKA_PRIME */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_PAX
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_pax_register();
|
||||||
|
#endif /* EAP_SERVER_PAX */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_PSK
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_psk_register();
|
||||||
|
#endif /* EAP_SERVER_PSK */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_SAKE
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_sake_register();
|
||||||
|
#endif /* EAP_SERVER_SAKE */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_GPSK
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_gpsk_register();
|
||||||
|
#endif /* EAP_SERVER_GPSK */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_VENDOR_TEST
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_vendor_test_register();
|
||||||
|
#endif /* EAP_SERVER_VENDOR_TEST */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_FAST
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_fast_register();
|
||||||
|
#endif /* EAP_SERVER_FAST */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_WSC
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_wsc_register();
|
||||||
|
#endif /* EAP_SERVER_WSC */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_IKEV2
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_ikev2_register();
|
||||||
|
#endif /* EAP_SERVER_IKEV2 */
|
||||||
|
|
||||||
|
#ifdef EAP_SERVER_TNC
|
||||||
|
if (ret == 0)
|
||||||
|
ret = eap_server_tnc_register();
|
||||||
|
#endif /* EAP_SERVER_TNC */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
20
hostapd/eap_register.h
Normal file
20
hostapd/eap_register.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* EAP method registration
|
||||||
|
* Copyright (c) 2004-2009, 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_REGISTER_H
|
||||||
|
#define EAP_REGISTER_H
|
||||||
|
|
||||||
|
int eap_server_register_methods(void);
|
||||||
|
|
||||||
|
#endif /* EAP_REGISTER_H */
|
77
hostapd/eap_testing.txt
Normal file
77
hostapd/eap_testing.txt
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
Interoperability testing of hostapd's IEEE 802.1X/EAPOL authentication
|
||||||
|
|
||||||
|
Test matrix
|
||||||
|
|
||||||
|
+) tested successfully
|
||||||
|
F) failed
|
||||||
|
-) peer did not support
|
||||||
|
?) not tested
|
||||||
|
|
||||||
|
XSupplicant --------------------------------.
|
||||||
|
Intel PROSet ---------------------------. |
|
||||||
|
Windows XP -------------------------. | |
|
||||||
|
Mac OS X 10.4 ------------------. | | |
|
||||||
|
Nokia S60 ------------------. | | | |
|
||||||
|
wpa_supplicant ---------. | | | | |
|
||||||
|
| | | | | |
|
||||||
|
|
||||||
|
EAP-MD5 + - ? ? -
|
||||||
|
EAP-GTC + - ? - -
|
||||||
|
EAP-MSCHAPv2 + - ? - -
|
||||||
|
EAP-TLS + + +1 + +
|
||||||
|
EAP-PEAPv0/MSCHAPv2 + + + + + +
|
||||||
|
EAP-PEAPv0/GTC + + + - +
|
||||||
|
EAP-PEAPv0/MD5 + - + - -
|
||||||
|
EAP-PEAPv0/TLS + F - + +
|
||||||
|
EAP-PEAPv0/SIM + + - - -
|
||||||
|
EAP-PEAPv0/AKA + + - - -
|
||||||
|
EAP-PEAPv0/PSK + - - - -
|
||||||
|
EAP-PEAPv0/PAX + - - - -
|
||||||
|
EAP-PEAPv0/SAKE + - - - -
|
||||||
|
EAP-PEAPv0/GPSK + - - - -
|
||||||
|
EAP-PEAPv1/MSCHAPv2 + + + - + +
|
||||||
|
EAP-PEAPv1/GTC + + + - +
|
||||||
|
EAP-PEAPv1/MD5 + - + - -
|
||||||
|
EAP-PEAPv1/TLS + F - - +
|
||||||
|
EAP-PEAPv1/SIM + + - - -
|
||||||
|
EAP-PEAPv1/AKA + + - - -
|
||||||
|
EAP-PEAPv1/PSK + - - - -
|
||||||
|
EAP-PEAPv1/PAX + - - - -
|
||||||
|
EAP-PEAPv1/SAKE + - - - -
|
||||||
|
EAP-PEAPv1/GPSK + - - - -
|
||||||
|
EAP-TTLS/CHAP + - + - + +
|
||||||
|
EAP-TTLS/MSCHAP + - + - + +
|
||||||
|
EAP-TTLS/MSCHAPv2 + + + - + +
|
||||||
|
EAP-TTLS/PAP + - + - + +
|
||||||
|
EAP-TTLS/EAP-MD5 + - - - - +
|
||||||
|
EAP-TTLS/EAP-GTC + + - - -
|
||||||
|
EAP-TTLS/EAP-MSCHAPv2 + + - - -
|
||||||
|
EAP-TTLS/EAP-TLS + F - - -
|
||||||
|
EAP-TTLS/EAP-SIM + + - - -
|
||||||
|
EAP-TTLS/EAP-AKA + + - - -
|
||||||
|
EAP-TTLS + TNC + - - - -
|
||||||
|
EAP-SIM + + - - +
|
||||||
|
EAP-AKA + + - - -
|
||||||
|
EAP-PAX + - - - -
|
||||||
|
EAP-SAKE + - - - -
|
||||||
|
EAP-GPSK + - - - -
|
||||||
|
EAP-FAST/MSCHAPv2(prov) + - F - F
|
||||||
|
EAP-FAST/GTC(auth) + - + - +
|
||||||
|
EAP-FAST/MSCHAPv2(aprov)+ - F - F
|
||||||
|
EAP-FAST/GTC(aprov) + - F - F
|
||||||
|
EAP-FAST/MD5(aprov) + - - - -
|
||||||
|
EAP-FAST/TLS(aprov) + - - - -
|
||||||
|
EAP-FAST/SIM(aprov) + - - - -
|
||||||
|
EAP-FAST/AKA(aprov) + - - - -
|
||||||
|
EAP-FAST/MSCHAPv2(auth) + - + - +
|
||||||
|
EAP-FAST/MD5(auth) + - + - -
|
||||||
|
EAP-FAST/TLS(auth) + - - - -
|
||||||
|
EAP-FAST/SIM(auth) + - - - -
|
||||||
|
EAP-FAST/AKA(auth) + - - - -
|
||||||
|
EAP-FAST + TNC + - - - -
|
||||||
|
EAP-IKEv2 + - - - -
|
||||||
|
EAP-TNC + - - - -
|
||||||
|
|
||||||
|
1) EAP-TLS itself worked, but peer certificate validation failed at
|
||||||
|
least when using the internal TLS server (peer included incorrect
|
||||||
|
certificates in the chain?)
|
714
hostapd/hlr_auc_gw.c
Normal file
714
hostapd/hlr_auc_gw.c
Normal file
@ -0,0 +1,714 @@
|
|||||||
|
/*
|
||||||
|
* HLR/AuC testing gateway for hostapd EAP-SIM/AKA database/authenticator
|
||||||
|
* Copyright (c) 2005-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.
|
||||||
|
*
|
||||||
|
* This is an example implementation of the EAP-SIM/AKA database/authentication
|
||||||
|
* gateway interface to HLR/AuC. It is expected to be replaced with an
|
||||||
|
* implementation of SS7 gateway to GSM/UMTS authentication center (HLR/AuC) or
|
||||||
|
* a local implementation of SIM triplet and AKA authentication data generator.
|
||||||
|
*
|
||||||
|
* hostapd will send SIM/AKA authentication queries over a UNIX domain socket
|
||||||
|
* to and external program, e.g., this hlr_auc_gw. This interface uses simple
|
||||||
|
* text-based format:
|
||||||
|
*
|
||||||
|
* EAP-SIM / GSM triplet query/response:
|
||||||
|
* SIM-REQ-AUTH <IMSI> <max_chal>
|
||||||
|
* SIM-RESP-AUTH <IMSI> Kc1:SRES1:RAND1 Kc2:SRES2:RAND2 [Kc3:SRES3:RAND3]
|
||||||
|
* SIM-RESP-AUTH <IMSI> FAILURE
|
||||||
|
*
|
||||||
|
* EAP-AKA / UMTS query/response:
|
||||||
|
* AKA-REQ-AUTH <IMSI>
|
||||||
|
* AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES>
|
||||||
|
* AKA-RESP-AUTH <IMSI> FAILURE
|
||||||
|
*
|
||||||
|
* EAP-AKA / UMTS AUTS (re-synchronization):
|
||||||
|
* AKA-AUTS <IMSI> <AUTS> <RAND>
|
||||||
|
*
|
||||||
|
* IMSI and max_chal are sent as an ASCII string,
|
||||||
|
* Kc/SRES/RAND/AUTN/IK/CK/RES/AUTS as hex strings.
|
||||||
|
*
|
||||||
|
* The example implementation here reads GSM authentication triplets from a
|
||||||
|
* text file in IMSI:Kc:SRES:RAND format, IMSI in ASCII, other fields as hex
|
||||||
|
* strings. This is used to simulate an HLR/AuC. As such, it is not very useful
|
||||||
|
* for real life authentication, but it is useful both as an example
|
||||||
|
* implementation and for EAP-SIM testing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "crypto/milenage.h"
|
||||||
|
|
||||||
|
static const char *default_socket_path = "/tmp/hlr_auc_gw.sock";
|
||||||
|
static const char *socket_path;
|
||||||
|
static int serv_sock = -1;
|
||||||
|
|
||||||
|
/* GSM triplets */
|
||||||
|
struct gsm_triplet {
|
||||||
|
struct gsm_triplet *next;
|
||||||
|
char imsi[20];
|
||||||
|
u8 kc[8];
|
||||||
|
u8 sres[4];
|
||||||
|
u8 _rand[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gsm_triplet *gsm_db = NULL, *gsm_db_pos = NULL;
|
||||||
|
|
||||||
|
/* OPc and AMF parameters for Milenage (Example algorithms for AKA). */
|
||||||
|
struct milenage_parameters {
|
||||||
|
struct milenage_parameters *next;
|
||||||
|
char imsi[20];
|
||||||
|
u8 ki[16];
|
||||||
|
u8 opc[16];
|
||||||
|
u8 amf[2];
|
||||||
|
u8 sqn[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct milenage_parameters *milenage_db = NULL;
|
||||||
|
|
||||||
|
#define EAP_SIM_MAX_CHAL 3
|
||||||
|
|
||||||
|
#define EAP_AKA_RAND_LEN 16
|
||||||
|
#define EAP_AKA_AUTN_LEN 16
|
||||||
|
#define EAP_AKA_AUTS_LEN 14
|
||||||
|
#define EAP_AKA_RES_MAX_LEN 16
|
||||||
|
#define EAP_AKA_IK_LEN 16
|
||||||
|
#define EAP_AKA_CK_LEN 16
|
||||||
|
|
||||||
|
|
||||||
|
static int open_socket(const char *path)
|
||||||
|
{
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
s = socket(PF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
if (s < 0) {
|
||||||
|
perror("socket(PF_UNIX)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
os_strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
|
||||||
|
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
|
perror("bind(PF_UNIX)");
|
||||||
|
close(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int read_gsm_triplets(const char *fname)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
char buf[200], *pos, *pos2;
|
||||||
|
struct gsm_triplet *g = NULL;
|
||||||
|
int line, ret = 0;
|
||||||
|
|
||||||
|
if (fname == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
f = fopen(fname, "r");
|
||||||
|
if (f == NULL) {
|
||||||
|
printf("Could not open GSM tripler data file '%s'\n", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
line = 0;
|
||||||
|
while (fgets(buf, sizeof(buf), f)) {
|
||||||
|
line++;
|
||||||
|
|
||||||
|
/* Parse IMSI:Kc:SRES:RAND */
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
if (buf[0] == '#')
|
||||||
|
continue;
|
||||||
|
pos = buf;
|
||||||
|
while (*pos != '\0' && *pos != '\n')
|
||||||
|
pos++;
|
||||||
|
if (*pos == '\n')
|
||||||
|
*pos = '\0';
|
||||||
|
pos = buf;
|
||||||
|
if (*pos == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
g = os_zalloc(sizeof(*g));
|
||||||
|
if (g == NULL) {
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IMSI */
|
||||||
|
pos2 = strchr(pos, ':');
|
||||||
|
if (pos2 == NULL) {
|
||||||
|
printf("%s:%d - Invalid IMSI (%s)\n",
|
||||||
|
fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) >= sizeof(g->imsi)) {
|
||||||
|
printf("%s:%d - Too long IMSI (%s)\n",
|
||||||
|
fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
os_strlcpy(g->imsi, pos, sizeof(g->imsi));
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
/* Kc */
|
||||||
|
pos2 = strchr(pos, ':');
|
||||||
|
if (pos2 == NULL) {
|
||||||
|
printf("%s:%d - Invalid Kc (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) != 16 || hexstr2bin(pos, g->kc, 8)) {
|
||||||
|
printf("%s:%d - Invalid Kc (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
/* SRES */
|
||||||
|
pos2 = strchr(pos, ':');
|
||||||
|
if (pos2 == NULL) {
|
||||||
|
printf("%s:%d - Invalid SRES (%s)\n", fname, line,
|
||||||
|
pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) != 8 || hexstr2bin(pos, g->sres, 4)) {
|
||||||
|
printf("%s:%d - Invalid SRES (%s)\n", fname, line,
|
||||||
|
pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
/* RAND */
|
||||||
|
pos2 = strchr(pos, ':');
|
||||||
|
if (pos2)
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) != 32 || hexstr2bin(pos, g->_rand, 16)) {
|
||||||
|
printf("%s:%d - Invalid RAND (%s)\n", fname, line,
|
||||||
|
pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
g->next = gsm_db;
|
||||||
|
gsm_db = g;
|
||||||
|
g = NULL;
|
||||||
|
}
|
||||||
|
free(g);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct gsm_triplet * get_gsm_triplet(const char *imsi)
|
||||||
|
{
|
||||||
|
struct gsm_triplet *g = gsm_db_pos;
|
||||||
|
|
||||||
|
while (g) {
|
||||||
|
if (strcmp(g->imsi, imsi) == 0) {
|
||||||
|
gsm_db_pos = g->next;
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
g = g->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
g = gsm_db;
|
||||||
|
while (g && g != gsm_db_pos) {
|
||||||
|
if (strcmp(g->imsi, imsi) == 0) {
|
||||||
|
gsm_db_pos = g->next;
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
g = g->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int read_milenage(const char *fname)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
char buf[200], *pos, *pos2;
|
||||||
|
struct milenage_parameters *m = NULL;
|
||||||
|
int line, ret = 0;
|
||||||
|
|
||||||
|
if (fname == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
f = fopen(fname, "r");
|
||||||
|
if (f == NULL) {
|
||||||
|
printf("Could not open Milenage data file '%s'\n", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
line = 0;
|
||||||
|
while (fgets(buf, sizeof(buf), f)) {
|
||||||
|
line++;
|
||||||
|
|
||||||
|
/* Parse IMSI Ki OPc AMF SQN */
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
if (buf[0] == '#')
|
||||||
|
continue;
|
||||||
|
pos = buf;
|
||||||
|
while (*pos != '\0' && *pos != '\n')
|
||||||
|
pos++;
|
||||||
|
if (*pos == '\n')
|
||||||
|
*pos = '\0';
|
||||||
|
pos = buf;
|
||||||
|
if (*pos == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m = os_zalloc(sizeof(*m));
|
||||||
|
if (m == NULL) {
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IMSI */
|
||||||
|
pos2 = strchr(pos, ' ');
|
||||||
|
if (pos2 == NULL) {
|
||||||
|
printf("%s:%d - Invalid IMSI (%s)\n",
|
||||||
|
fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) >= sizeof(m->imsi)) {
|
||||||
|
printf("%s:%d - Too long IMSI (%s)\n",
|
||||||
|
fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
os_strlcpy(m->imsi, pos, sizeof(m->imsi));
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
/* Ki */
|
||||||
|
pos2 = strchr(pos, ' ');
|
||||||
|
if (pos2 == NULL) {
|
||||||
|
printf("%s:%d - Invalid Ki (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) != 32 || hexstr2bin(pos, m->ki, 16)) {
|
||||||
|
printf("%s:%d - Invalid Ki (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
/* OPc */
|
||||||
|
pos2 = strchr(pos, ' ');
|
||||||
|
if (pos2 == NULL) {
|
||||||
|
printf("%s:%d - Invalid OPc (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) != 32 || hexstr2bin(pos, m->opc, 16)) {
|
||||||
|
printf("%s:%d - Invalid OPc (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
/* AMF */
|
||||||
|
pos2 = strchr(pos, ' ');
|
||||||
|
if (pos2 == NULL) {
|
||||||
|
printf("%s:%d - Invalid AMF (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) != 4 || hexstr2bin(pos, m->amf, 2)) {
|
||||||
|
printf("%s:%d - Invalid AMF (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
/* SQN */
|
||||||
|
pos2 = strchr(pos, ' ');
|
||||||
|
if (pos2)
|
||||||
|
*pos2 = '\0';
|
||||||
|
if (strlen(pos) != 12 || hexstr2bin(pos, m->sqn, 6)) {
|
||||||
|
printf("%s:%d - Invalid SEQ (%s)\n", fname, line, pos);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos = pos2 + 1;
|
||||||
|
|
||||||
|
m->next = milenage_db;
|
||||||
|
milenage_db = m;
|
||||||
|
m = NULL;
|
||||||
|
}
|
||||||
|
free(m);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct milenage_parameters * get_milenage(const char *imsi)
|
||||||
|
{
|
||||||
|
struct milenage_parameters *m = milenage_db;
|
||||||
|
|
||||||
|
while (m) {
|
||||||
|
if (strcmp(m->imsi, imsi) == 0)
|
||||||
|
break;
|
||||||
|
m = m->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void sim_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
|
||||||
|
char *imsi)
|
||||||
|
{
|
||||||
|
int count, max_chal, ret;
|
||||||
|
char *pos;
|
||||||
|
char reply[1000], *rpos, *rend;
|
||||||
|
struct milenage_parameters *m;
|
||||||
|
struct gsm_triplet *g;
|
||||||
|
|
||||||
|
reply[0] = '\0';
|
||||||
|
|
||||||
|
pos = strchr(imsi, ' ');
|
||||||
|
if (pos) {
|
||||||
|
*pos++ = '\0';
|
||||||
|
max_chal = atoi(pos);
|
||||||
|
if (max_chal < 1 || max_chal < EAP_SIM_MAX_CHAL)
|
||||||
|
max_chal = EAP_SIM_MAX_CHAL;
|
||||||
|
} else
|
||||||
|
max_chal = EAP_SIM_MAX_CHAL;
|
||||||
|
|
||||||
|
rend = &reply[sizeof(reply)];
|
||||||
|
rpos = reply;
|
||||||
|
ret = snprintf(rpos, rend - rpos, "SIM-RESP-AUTH %s", imsi);
|
||||||
|
if (ret < 0 || ret >= rend - rpos)
|
||||||
|
return;
|
||||||
|
rpos += ret;
|
||||||
|
|
||||||
|
m = get_milenage(imsi);
|
||||||
|
if (m) {
|
||||||
|
u8 _rand[16], sres[4], kc[8];
|
||||||
|
for (count = 0; count < max_chal; count++) {
|
||||||
|
if (os_get_random(_rand, 16) < 0)
|
||||||
|
return;
|
||||||
|
gsm_milenage(m->opc, m->ki, _rand, sres, kc);
|
||||||
|
*rpos++ = ' ';
|
||||||
|
rpos += wpa_snprintf_hex(rpos, rend - rpos, kc, 8);
|
||||||
|
*rpos++ = ':';
|
||||||
|
rpos += wpa_snprintf_hex(rpos, rend - rpos, sres, 4);
|
||||||
|
*rpos++ = ':';
|
||||||
|
rpos += wpa_snprintf_hex(rpos, rend - rpos, _rand, 16);
|
||||||
|
}
|
||||||
|
*rpos = '\0';
|
||||||
|
goto send;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
while (count < max_chal && (g = get_gsm_triplet(imsi))) {
|
||||||
|
if (strcmp(g->imsi, imsi) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (rpos < rend)
|
||||||
|
*rpos++ = ' ';
|
||||||
|
rpos += wpa_snprintf_hex(rpos, rend - rpos, g->kc, 8);
|
||||||
|
if (rpos < rend)
|
||||||
|
*rpos++ = ':';
|
||||||
|
rpos += wpa_snprintf_hex(rpos, rend - rpos, g->sres, 4);
|
||||||
|
if (rpos < rend)
|
||||||
|
*rpos++ = ':';
|
||||||
|
rpos += wpa_snprintf_hex(rpos, rend - rpos, g->_rand, 16);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
printf("No GSM triplets found for %s\n", imsi);
|
||||||
|
ret = snprintf(rpos, rend - rpos, " FAILURE");
|
||||||
|
if (ret < 0 || ret >= rend - rpos)
|
||||||
|
return;
|
||||||
|
rpos += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
send:
|
||||||
|
printf("Send: %s\n", reply);
|
||||||
|
if (sendto(s, reply, rpos - reply, 0,
|
||||||
|
(struct sockaddr *) from, fromlen) < 0)
|
||||||
|
perror("send");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void aka_req_auth(int s, struct sockaddr_un *from, socklen_t fromlen,
|
||||||
|
char *imsi)
|
||||||
|
{
|
||||||
|
/* AKA-RESP-AUTH <IMSI> <RAND> <AUTN> <IK> <CK> <RES> */
|
||||||
|
char reply[1000], *pos, *end;
|
||||||
|
u8 _rand[EAP_AKA_RAND_LEN];
|
||||||
|
u8 autn[EAP_AKA_AUTN_LEN];
|
||||||
|
u8 ik[EAP_AKA_IK_LEN];
|
||||||
|
u8 ck[EAP_AKA_CK_LEN];
|
||||||
|
u8 res[EAP_AKA_RES_MAX_LEN];
|
||||||
|
size_t res_len;
|
||||||
|
int ret;
|
||||||
|
struct milenage_parameters *m;
|
||||||
|
|
||||||
|
m = get_milenage(imsi);
|
||||||
|
if (m) {
|
||||||
|
if (os_get_random(_rand, EAP_AKA_RAND_LEN) < 0)
|
||||||
|
return;
|
||||||
|
res_len = EAP_AKA_RES_MAX_LEN;
|
||||||
|
inc_byte_array(m->sqn, 6);
|
||||||
|
printf("AKA: Milenage with SQN=%02x%02x%02x%02x%02x%02x\n",
|
||||||
|
m->sqn[0], m->sqn[1], m->sqn[2],
|
||||||
|
m->sqn[3], m->sqn[4], m->sqn[5]);
|
||||||
|
milenage_generate(m->opc, m->amf, m->ki, m->sqn, _rand,
|
||||||
|
autn, ik, ck, res, &res_len);
|
||||||
|
} else {
|
||||||
|
printf("Unknown IMSI: %s\n", imsi);
|
||||||
|
#ifdef AKA_USE_FIXED_TEST_VALUES
|
||||||
|
printf("Using fixed test values for AKA\n");
|
||||||
|
memset(_rand, '0', EAP_AKA_RAND_LEN);
|
||||||
|
memset(autn, '1', EAP_AKA_AUTN_LEN);
|
||||||
|
memset(ik, '3', EAP_AKA_IK_LEN);
|
||||||
|
memset(ck, '4', EAP_AKA_CK_LEN);
|
||||||
|
memset(res, '2', EAP_AKA_RES_MAX_LEN);
|
||||||
|
res_len = EAP_AKA_RES_MAX_LEN;
|
||||||
|
#else /* AKA_USE_FIXED_TEST_VALUES */
|
||||||
|
return;
|
||||||
|
#endif /* AKA_USE_FIXED_TEST_VALUES */
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = reply;
|
||||||
|
end = &reply[sizeof(reply)];
|
||||||
|
ret = snprintf(pos, end - pos, "AKA-RESP-AUTH %s ", imsi);
|
||||||
|
if (ret < 0 || ret >= end - pos)
|
||||||
|
return;
|
||||||
|
pos += ret;
|
||||||
|
pos += wpa_snprintf_hex(pos, end - pos, _rand, EAP_AKA_RAND_LEN);
|
||||||
|
*pos++ = ' ';
|
||||||
|
pos += wpa_snprintf_hex(pos, end - pos, autn, EAP_AKA_AUTN_LEN);
|
||||||
|
*pos++ = ' ';
|
||||||
|
pos += wpa_snprintf_hex(pos, end - pos, ik, EAP_AKA_IK_LEN);
|
||||||
|
*pos++ = ' ';
|
||||||
|
pos += wpa_snprintf_hex(pos, end - pos, ck, EAP_AKA_CK_LEN);
|
||||||
|
*pos++ = ' ';
|
||||||
|
pos += wpa_snprintf_hex(pos, end - pos, res, res_len);
|
||||||
|
|
||||||
|
printf("Send: %s\n", reply);
|
||||||
|
|
||||||
|
if (sendto(s, reply, pos - reply, 0, (struct sockaddr *) from,
|
||||||
|
fromlen) < 0)
|
||||||
|
perror("send");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void aka_auts(int s, struct sockaddr_un *from, socklen_t fromlen,
|
||||||
|
char *imsi)
|
||||||
|
{
|
||||||
|
char *auts, *__rand;
|
||||||
|
u8 _auts[EAP_AKA_AUTS_LEN], _rand[EAP_AKA_RAND_LEN], sqn[6];
|
||||||
|
struct milenage_parameters *m;
|
||||||
|
|
||||||
|
/* AKA-AUTS <IMSI> <AUTS> <RAND> */
|
||||||
|
|
||||||
|
auts = strchr(imsi, ' ');
|
||||||
|
if (auts == NULL)
|
||||||
|
return;
|
||||||
|
*auts++ = '\0';
|
||||||
|
|
||||||
|
__rand = strchr(auts, ' ');
|
||||||
|
if (__rand == NULL)
|
||||||
|
return;
|
||||||
|
*__rand++ = '\0';
|
||||||
|
|
||||||
|
printf("AKA-AUTS: IMSI=%s AUTS=%s RAND=%s\n", imsi, auts, __rand);
|
||||||
|
if (hexstr2bin(auts, _auts, EAP_AKA_AUTS_LEN) ||
|
||||||
|
hexstr2bin(__rand, _rand, EAP_AKA_RAND_LEN)) {
|
||||||
|
printf("Could not parse AUTS/RAND\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m = get_milenage(imsi);
|
||||||
|
if (m == NULL) {
|
||||||
|
printf("Unknown IMSI: %s\n", imsi);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (milenage_auts(m->opc, m->ki, _rand, _auts, sqn)) {
|
||||||
|
printf("AKA-AUTS: Incorrect MAC-S\n");
|
||||||
|
} else {
|
||||||
|
memcpy(m->sqn, sqn, 6);
|
||||||
|
printf("AKA-AUTS: Re-synchronized: "
|
||||||
|
"SQN=%02x%02x%02x%02x%02x%02x\n",
|
||||||
|
sqn[0], sqn[1], sqn[2], sqn[3], sqn[4], sqn[5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int process(int s)
|
||||||
|
{
|
||||||
|
char buf[1000];
|
||||||
|
struct sockaddr_un from;
|
||||||
|
socklen_t fromlen;
|
||||||
|
ssize_t res;
|
||||||
|
|
||||||
|
fromlen = sizeof(from);
|
||||||
|
res = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *) &from,
|
||||||
|
&fromlen);
|
||||||
|
if (res < 0) {
|
||||||
|
perror("recvfrom");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((size_t) res >= sizeof(buf))
|
||||||
|
res = sizeof(buf) - 1;
|
||||||
|
buf[res] = '\0';
|
||||||
|
|
||||||
|
printf("Received: %s\n", buf);
|
||||||
|
|
||||||
|
if (strncmp(buf, "SIM-REQ-AUTH ", 13) == 0)
|
||||||
|
sim_req_auth(s, &from, fromlen, buf + 13);
|
||||||
|
else if (strncmp(buf, "AKA-REQ-AUTH ", 13) == 0)
|
||||||
|
aka_req_auth(s, &from, fromlen, buf + 13);
|
||||||
|
else if (strncmp(buf, "AKA-AUTS ", 9) == 0)
|
||||||
|
aka_auts(s, &from, fromlen, buf + 9);
|
||||||
|
else
|
||||||
|
printf("Unknown request: %s\n", buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void cleanup(void)
|
||||||
|
{
|
||||||
|
struct gsm_triplet *g, *gprev;
|
||||||
|
struct milenage_parameters *m, *prev;
|
||||||
|
|
||||||
|
g = gsm_db;
|
||||||
|
while (g) {
|
||||||
|
gprev = g;
|
||||||
|
g = g->next;
|
||||||
|
free(gprev);
|
||||||
|
}
|
||||||
|
|
||||||
|
m = milenage_db;
|
||||||
|
while (m) {
|
||||||
|
prev = m;
|
||||||
|
m = m->next;
|
||||||
|
free(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(serv_sock);
|
||||||
|
unlink(socket_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_term(int sig)
|
||||||
|
{
|
||||||
|
printf("Signal %d - terminate\n", sig);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
printf("HLR/AuC testing gateway for hostapd EAP-SIM/AKA "
|
||||||
|
"database/authenticator\n"
|
||||||
|
"Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>\n"
|
||||||
|
"\n"
|
||||||
|
"usage:\n"
|
||||||
|
"hlr_auc_gw [-h] [-s<socket path>] [-g<triplet file>] "
|
||||||
|
"[-m<milenage file>]\n"
|
||||||
|
"\n"
|
||||||
|
"options:\n"
|
||||||
|
" -h = show this usage help\n"
|
||||||
|
" -s<socket path> = path for UNIX domain socket\n"
|
||||||
|
" (default: %s)\n"
|
||||||
|
" -g<triplet file> = path for GSM authentication triplets\n"
|
||||||
|
" -m<milenage file> = path for Milenage keys\n",
|
||||||
|
default_socket_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
char *milenage_file = NULL;
|
||||||
|
char *gsm_triplet_file = NULL;
|
||||||
|
|
||||||
|
socket_path = default_socket_path;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c = getopt(argc, argv, "g:hm:s:");
|
||||||
|
if (c < 0)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 'g':
|
||||||
|
gsm_triplet_file = optarg;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
case 'm':
|
||||||
|
milenage_file = optarg;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
socket_path = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gsm_triplet_file && read_gsm_triplets(gsm_triplet_file) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (milenage_file && read_milenage(milenage_file) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
serv_sock = open_socket(socket_path);
|
||||||
|
if (serv_sock < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
printf("Listening for requests on %s\n", socket_path);
|
||||||
|
|
||||||
|
atexit(cleanup);
|
||||||
|
signal(SIGTERM, handle_term);
|
||||||
|
signal(SIGINT, handle_term);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
process(serv_sock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
13
hostapd/hlr_auc_gw.milenage_db
Normal file
13
hostapd/hlr_auc_gw.milenage_db
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
# These values are from Test Set 19 which has the AMF separation bit set to 1
|
||||||
|
# and as such, is suitable for EAP-AKA' test.
|
||||||
|
555444333222111 5122250214c33e723a5dd523fc145fc0 981d464c7c52eb6e5036234984ad0bcf c3ab 16f3b3f70fc1
|
59
hostapd/hostapd.8
Normal file
59
hostapd/hostapd.8
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
.TH HOSTAPD 8 "April 7, 2005" hostapd hostapd
|
||||||
|
.SH NAME
|
||||||
|
hostapd \- IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B hostapd
|
||||||
|
[\-hdBKtv] [\-P <PID file>] <configuration file(s)>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This manual page documents briefly the
|
||||||
|
.B hostapd
|
||||||
|
daemon.
|
||||||
|
.PP
|
||||||
|
.B hostapd
|
||||||
|
is a user space daemon for access point and authentication servers.
|
||||||
|
It implements IEEE 802.11 access point management, IEEE 802.1X/WPA/WPA2/EAP Authenticators and RADIUS authentication server.
|
||||||
|
The current version supports Linux (Host AP, madwifi, mac80211-based drivers) and FreeBSD (net80211).
|
||||||
|
|
||||||
|
.B hostapd
|
||||||
|
is designed to be a "daemon" program that runs in the background and acts as the backend component controlling authentication.
|
||||||
|
.B hostapd
|
||||||
|
supports separate frontend programs and an example text-based frontend,
|
||||||
|
.BR hostapd_cli ,
|
||||||
|
is included with
|
||||||
|
.BR hostapd .
|
||||||
|
.SH OPTIONS
|
||||||
|
A summary of options is included below.
|
||||||
|
For a complete description, run
|
||||||
|
.BR hostapd
|
||||||
|
from the command line.
|
||||||
|
.TP
|
||||||
|
.B \-h
|
||||||
|
Show usage.
|
||||||
|
.TP
|
||||||
|
.B \-d
|
||||||
|
Show more debug messages.
|
||||||
|
.TP
|
||||||
|
.B \-dd
|
||||||
|
Show even more debug messages.
|
||||||
|
.TP
|
||||||
|
.B \-B
|
||||||
|
Run daemon in the background.
|
||||||
|
.TP
|
||||||
|
.B \-P <PID file>
|
||||||
|
Path to PID file.
|
||||||
|
.TP
|
||||||
|
.B \-K
|
||||||
|
Include key data in debug messages.
|
||||||
|
.TP
|
||||||
|
.B \-t
|
||||||
|
Include timestamps in some debug messages.
|
||||||
|
.TP
|
||||||
|
.B \-v
|
||||||
|
Show hostapd version.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR hostapd_cli (1).
|
||||||
|
.SH AUTHOR
|
||||||
|
hostapd was written by Jouni Malinen <j@w1.fi>.
|
||||||
|
.PP
|
||||||
|
This manual page was written by Faidon Liambotis <faidon@cube.gr>,
|
||||||
|
for the Debian project (but may be used by others).
|
6
hostapd/hostapd.accept
Normal file
6
hostapd/hostapd.accept
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# List of MAC addresses that are allowed to authenticate (IEEE 802.11)
|
||||||
|
# with the AP. Optional VLAN ID can be assigned for clients based on the
|
||||||
|
# MAC address if dynamic VLANs (hostapd.conf dynamic_vlan option) are used.
|
||||||
|
00:11:22:33:44:55
|
||||||
|
00:66:77:88:99:aa
|
||||||
|
00:00:22:33:44:55 1
|
1016
hostapd/hostapd.conf
Normal file
1016
hostapd/hostapd.conf
Normal file
File diff suppressed because it is too large
Load Diff
5
hostapd/hostapd.deny
Normal file
5
hostapd/hostapd.deny
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# 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
|
91
hostapd/hostapd.eap_user
Normal file
91
hostapd/hostapd.eap_user
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# hostapd user database for integrated EAP server
|
||||||
|
|
||||||
|
# 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-FAST, 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, EAP-TTLS, and EAP-FAST 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.
|
||||||
|
#
|
||||||
|
# EAP-TTLS supports both EAP and non-EAP authentication inside the tunnel.
|
||||||
|
# Tunneled EAP methods are configured with standard EAP method name and [2]
|
||||||
|
# flag. Non-EAP methods can be enabled by following method names: TTLS-PAP,
|
||||||
|
# TTLS-CHAP, TTLS-MSCHAP, TTLS-MSCHAPV2. TTLS-PAP and TTLS-CHAP require a
|
||||||
|
# plaintext password while TTLS-MSCHAP and TTLS-MSCHAPV2 can use NT password
|
||||||
|
# hash.
|
||||||
|
|
||||||
|
# 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]
|
||||||
|
"ttls-user" TTLS-PAP,TTLS-CHAP,TTLS-MSCHAP,TTLS-MSCHAPV2 "password" [2]
|
||||||
|
|
||||||
|
# Default to EAP-SIM and EAP-AKA based on fixed identity prefixes in phase 2
|
||||||
|
"0"* AKA [2]
|
||||||
|
"1"* SIM [2]
|
||||||
|
"2"* AKA [2]
|
||||||
|
"3"* SIM [2]
|
||||||
|
"4"* AKA [2]
|
||||||
|
"5"* SIM [2]
|
4
hostapd/hostapd.radius_clients
Normal file
4
hostapd/hostapd.radius_clients
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# 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
|
9
hostapd/hostapd.sim_db
Normal file
9
hostapd/hostapd.sim_db
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# 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
|
9
hostapd/hostapd.vlan
Normal file
9
hostapd/hostapd.vlan
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# 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#
|
9
hostapd/hostapd.wpa_psk
Normal file
9
hostapd/hostapd.wpa_psk
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# 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
|
89
hostapd/hostapd_cli.1
Normal file
89
hostapd/hostapd_cli.1
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
.TH HOSTAPD_CLI 1 "April 7, 2005" hostapd_cli "hostapd command-line interface"
|
||||||
|
.SH NAME
|
||||||
|
hostapd_cli \- hostapd command-line interface
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B hostapd_cli
|
||||||
|
[\-p<path>] [\-i<ifname>] [\-a<path>] [\-hvB] [command..]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This manual page documents briefly the
|
||||||
|
.B hostapd_cli
|
||||||
|
utility.
|
||||||
|
.PP
|
||||||
|
.B hostapd_cli
|
||||||
|
is a command-line interface for the
|
||||||
|
.B hostapd
|
||||||
|
daemon.
|
||||||
|
|
||||||
|
.B hostapd
|
||||||
|
is a user space daemon for access point and authentication servers.
|
||||||
|
It implements IEEE 802.11 access point management, IEEE 802.1X/WPA/WPA2/EAP Authenticators and RADIUS authentication server.
|
||||||
|
For more information about
|
||||||
|
.B hostapd
|
||||||
|
refer to the
|
||||||
|
.BR hostapd (8)
|
||||||
|
man page.
|
||||||
|
.SH OPTIONS
|
||||||
|
A summary of options is included below.
|
||||||
|
For a complete description, run
|
||||||
|
.BR hostapd_cli
|
||||||
|
from the command line.
|
||||||
|
.TP
|
||||||
|
.B \-p<path>
|
||||||
|
Path to find control sockets.
|
||||||
|
|
||||||
|
Default: /var/run/hostapd
|
||||||
|
.TP
|
||||||
|
.B \-i<ifname>
|
||||||
|
Interface to listen on.
|
||||||
|
|
||||||
|
Default: first interface found in socket path.
|
||||||
|
.TP
|
||||||
|
.B \-a<path>
|
||||||
|
Run in daemon mode executing the action file based on events from hostapd.
|
||||||
|
.TP
|
||||||
|
.B \-B
|
||||||
|
Run a daemon in the background.
|
||||||
|
.TP
|
||||||
|
.B \-h
|
||||||
|
Show usage.
|
||||||
|
.TP
|
||||||
|
.B \-v
|
||||||
|
Show hostapd_cli version.
|
||||||
|
.SH COMMANDS
|
||||||
|
A summary of commands is included below.
|
||||||
|
For a complete description, run
|
||||||
|
.BR hostapd_cli
|
||||||
|
from the command line.
|
||||||
|
.TP
|
||||||
|
.B mib
|
||||||
|
Get MIB variables (dot1x, dot11, radius).
|
||||||
|
.TP
|
||||||
|
.B sta <addr>
|
||||||
|
Get MIB variables for one station.
|
||||||
|
.TP
|
||||||
|
.B all_sta
|
||||||
|
Get MIB variables for all stations.
|
||||||
|
.TP
|
||||||
|
.B help
|
||||||
|
Get usage help.
|
||||||
|
.TP
|
||||||
|
.B interface [ifname]
|
||||||
|
Show interfaces/select interface.
|
||||||
|
.TP
|
||||||
|
.B level <debug level>
|
||||||
|
Change debug level.
|
||||||
|
.TP
|
||||||
|
.B license
|
||||||
|
Show full
|
||||||
|
.B hostapd_cli
|
||||||
|
license.
|
||||||
|
.TP
|
||||||
|
.B quit
|
||||||
|
Exit hostapd_cli.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR hostapd (8).
|
||||||
|
.SH AUTHOR
|
||||||
|
hostapd_cli was written by Jouni Malinen <j@w1.fi>.
|
||||||
|
.PP
|
||||||
|
This manual page was written by Faidon Liambotis <faidon@cube.gr>,
|
||||||
|
for the Debian project (but may be used by others).
|
904
hostapd/hostapd_cli.c
Normal file
904
hostapd/hostapd_cli.c
Normal file
@ -0,0 +1,904 @@
|
|||||||
|
/*
|
||||||
|
* hostapd - command line interface for hostapd daemon
|
||||||
|
* Copyright (c) 2004-2010, 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 <dirent.h>
|
||||||
|
|
||||||
|
#include "common/wpa_ctrl.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "common/version.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const char *hostapd_cli_version =
|
||||||
|
"hostapd_cli v" VERSION_STR "\n"
|
||||||
|
"Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
|
||||||
|
|
||||||
|
|
||||||
|
static const char *hostapd_cli_license =
|
||||||
|
"This program is free software. You can distribute it and/or modify it\n"
|
||||||
|
"under the terms of the GNU General Public License version 2.\n"
|
||||||
|
"\n"
|
||||||
|
"Alternatively, this software may be distributed under the terms of the\n"
|
||||||
|
"BSD license. See README and COPYING for more details.\n";
|
||||||
|
|
||||||
|
static const char *hostapd_cli_full_license =
|
||||||
|
"This program is free software; you can redistribute it and/or modify\n"
|
||||||
|
"it under the terms of the GNU General Public License version 2 as\n"
|
||||||
|
"published by the Free Software Foundation.\n"
|
||||||
|
"\n"
|
||||||
|
"This program is distributed in the hope that it will be useful,\n"
|
||||||
|
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||||
|
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||||
|
"GNU General Public License for more details.\n"
|
||||||
|
"\n"
|
||||||
|
"You should have received a copy of the GNU General Public License\n"
|
||||||
|
"along with this program; if not, write to the Free Software\n"
|
||||||
|
"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
|
||||||
|
"\n"
|
||||||
|
"Alternatively, this software may be distributed under the terms of the\n"
|
||||||
|
"BSD license.\n"
|
||||||
|
"\n"
|
||||||
|
"Redistribution and use in source and binary forms, with or without\n"
|
||||||
|
"modification, are permitted provided that the following conditions are\n"
|
||||||
|
"met:\n"
|
||||||
|
"\n"
|
||||||
|
"1. Redistributions of source code must retain the above copyright\n"
|
||||||
|
" notice, this list of conditions and the following disclaimer.\n"
|
||||||
|
"\n"
|
||||||
|
"2. Redistributions in binary form must reproduce the above copyright\n"
|
||||||
|
" notice, this list of conditions and the following disclaimer in the\n"
|
||||||
|
" documentation and/or other materials provided with the distribution.\n"
|
||||||
|
"\n"
|
||||||
|
"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
|
||||||
|
" names of its contributors may be used to endorse or promote products\n"
|
||||||
|
" derived from this software without specific prior written permission.\n"
|
||||||
|
"\n"
|
||||||
|
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
|
||||||
|
"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
|
||||||
|
"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
|
||||||
|
"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
|
||||||
|
"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
|
||||||
|
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
|
||||||
|
"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
|
||||||
|
"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
|
||||||
|
"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
|
||||||
|
"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
|
||||||
|
"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
static const char *commands_help =
|
||||||
|
"Commands:\n"
|
||||||
|
" mib get MIB variables (dot1x, dot11, radius)\n"
|
||||||
|
" sta <addr> get MIB variables for one station\n"
|
||||||
|
" all_sta get MIB variables for all stations\n"
|
||||||
|
" new_sta <addr> add a new station\n"
|
||||||
|
" deauthenticate <addr> deauthenticate a station\n"
|
||||||
|
" disassociate <addr> disassociate a station\n"
|
||||||
|
#ifdef CONFIG_IEEE80211W
|
||||||
|
" sa_query <addr> send SA Query to a station\n"
|
||||||
|
#endif /* CONFIG_IEEE80211W */
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
" wps_pin <uuid> <pin> [timeout] add WPS Enrollee PIN (Device Password)\n"
|
||||||
|
" wps_pbc indicate button pushed to initiate PBC\n"
|
||||||
|
#ifdef CONFIG_WPS_OOB
|
||||||
|
" wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
|
||||||
|
#endif /* CONFIG_WPS_OOB */
|
||||||
|
" wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
|
" help show this usage help\n"
|
||||||
|
" interface [ifname] show interfaces/select interface\n"
|
||||||
|
" level <debug level> change debug level\n"
|
||||||
|
" license show full hostapd_cli license\n"
|
||||||
|
" quit exit hostapd_cli\n";
|
||||||
|
|
||||||
|
static struct wpa_ctrl *ctrl_conn;
|
||||||
|
static int hostapd_cli_quit = 0;
|
||||||
|
static int hostapd_cli_attached = 0;
|
||||||
|
static const char *ctrl_iface_dir = "/var/run/hostapd";
|
||||||
|
static char *ctrl_ifname = NULL;
|
||||||
|
static const char *pid_file = NULL;
|
||||||
|
static const char *action_file = NULL;
|
||||||
|
static int ping_interval = 5;
|
||||||
|
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", hostapd_cli_version);
|
||||||
|
fprintf(stderr,
|
||||||
|
"\n"
|
||||||
|
"usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvB] "
|
||||||
|
"[-a<path>] \\\n"
|
||||||
|
" [-G<ping interval>] [command..]\n"
|
||||||
|
"\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -h help (show this usage text)\n"
|
||||||
|
" -v shown version information\n"
|
||||||
|
" -p<path> path to find control sockets (default: "
|
||||||
|
"/var/run/hostapd)\n"
|
||||||
|
" -a<file> run in daemon mode executing the action file "
|
||||||
|
"based on events\n"
|
||||||
|
" from hostapd\n"
|
||||||
|
" -B run a daemon in the background\n"
|
||||||
|
" -i<ifname> Interface to listen on (default: first "
|
||||||
|
"interface found in the\n"
|
||||||
|
" socket path)\n\n"
|
||||||
|
"%s",
|
||||||
|
commands_help);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpa_ctrl * hostapd_cli_open_connection(const char *ifname)
|
||||||
|
{
|
||||||
|
char *cfile;
|
||||||
|
int flen;
|
||||||
|
|
||||||
|
if (ifname == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2;
|
||||||
|
cfile = malloc(flen);
|
||||||
|
if (cfile == NULL)
|
||||||
|
return NULL;
|
||||||
|
snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
|
||||||
|
|
||||||
|
ctrl_conn = wpa_ctrl_open(cfile);
|
||||||
|
free(cfile);
|
||||||
|
return ctrl_conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_close_connection(void)
|
||||||
|
{
|
||||||
|
if (ctrl_conn == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (hostapd_cli_attached) {
|
||||||
|
wpa_ctrl_detach(ctrl_conn);
|
||||||
|
hostapd_cli_attached = 0;
|
||||||
|
}
|
||||||
|
wpa_ctrl_close(ctrl_conn);
|
||||||
|
ctrl_conn = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_msg_cb(char *msg, size_t len)
|
||||||
|
{
|
||||||
|
printf("%s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
|
||||||
|
{
|
||||||
|
char buf[4096];
|
||||||
|
size_t len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ctrl_conn == NULL) {
|
||||||
|
printf("Not connected to hostapd - command dropped.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
len = sizeof(buf) - 1;
|
||||||
|
ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
|
||||||
|
hostapd_cli_msg_cb);
|
||||||
|
if (ret == -2) {
|
||||||
|
printf("'%s' command timed out.\n", cmd);
|
||||||
|
return -2;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
printf("'%s' command failed.\n", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (print) {
|
||||||
|
buf[len] = '\0';
|
||||||
|
printf("%s", buf);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
|
||||||
|
{
|
||||||
|
return _wpa_ctrl_command(ctrl, cmd, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_ctrl_command(ctrl, "PING");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_ctrl_command(ctrl, "MIB");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_exec(const char *program, const char *arg1,
|
||||||
|
const char *arg2)
|
||||||
|
{
|
||||||
|
char *cmd;
|
||||||
|
size_t len;
|
||||||
|
int res;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
|
||||||
|
cmd = os_malloc(len);
|
||||||
|
if (cmd == NULL)
|
||||||
|
return -1;
|
||||||
|
res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
|
||||||
|
if (res < 0 || (size_t) res >= len) {
|
||||||
|
os_free(cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cmd[len - 1] = '\0';
|
||||||
|
#ifndef _WIN32_WCE
|
||||||
|
if (system(cmd) < 0)
|
||||||
|
ret = -1;
|
||||||
|
#endif /* _WIN32_WCE */
|
||||||
|
os_free(cmd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_action_process(char *msg, size_t len)
|
||||||
|
{
|
||||||
|
const char *pos;
|
||||||
|
|
||||||
|
pos = msg;
|
||||||
|
if (*pos == '<') {
|
||||||
|
pos = os_strchr(pos, '>');
|
||||||
|
if (pos)
|
||||||
|
pos++;
|
||||||
|
else
|
||||||
|
pos = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
hostapd_cli_exec(action_file, ctrl_ifname, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
if (argc != 1) {
|
||||||
|
printf("Invalid 'sta' command - exactly one argument, STA "
|
||||||
|
"address, is required.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "STA %s", argv[0]);
|
||||||
|
return wpa_ctrl_command(ctrl, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
if (argc != 1) {
|
||||||
|
printf("Invalid 'new_sta' command - exactly one argument, STA "
|
||||||
|
"address, is required.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]);
|
||||||
|
return wpa_ctrl_command(ctrl, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_deauthenticate(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
if (argc < 1) {
|
||||||
|
printf("Invalid 'deauthenticate' command - exactly one "
|
||||||
|
"argument, STA address, is required.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (argc > 1)
|
||||||
|
os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s %s",
|
||||||
|
argv[0], argv[1]);
|
||||||
|
else
|
||||||
|
os_snprintf(buf, sizeof(buf), "DEAUTHENTICATE %s", argv[0]);
|
||||||
|
return wpa_ctrl_command(ctrl, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_disassociate(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
if (argc < 1) {
|
||||||
|
printf("Invalid 'disassociate' command - exactly one "
|
||||||
|
"argument, STA address, is required.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (argc > 1)
|
||||||
|
os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s %s",
|
||||||
|
argv[0], argv[1]);
|
||||||
|
else
|
||||||
|
os_snprintf(buf, sizeof(buf), "DISASSOCIATE %s", argv[0]);
|
||||||
|
return wpa_ctrl_command(ctrl, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_IEEE80211W
|
||||||
|
static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
if (argc != 1) {
|
||||||
|
printf("Invalid 'sa_query' command - exactly one argument, "
|
||||||
|
"STA address, is required.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
|
||||||
|
return wpa_ctrl_command(ctrl, buf);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE80211W */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Invalid 'wps_pin' command - at least two arguments, "
|
||||||
|
"UUID and PIN, are required.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (argc > 2)
|
||||||
|
snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2]);
|
||||||
|
else
|
||||||
|
snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
|
||||||
|
return wpa_ctrl_command(ctrl, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_ctrl_command(ctrl, "WPS_PBC");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS_OOB
|
||||||
|
static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char cmd[256];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (argc != 3 && argc != 4) {
|
||||||
|
printf("Invalid WPS_OOB command: need three or four "
|
||||||
|
"arguments:\n"
|
||||||
|
"- DEV_TYPE: use 'ufd' or 'nfc'\n"
|
||||||
|
"- PATH: path of OOB device like '/mnt'\n"
|
||||||
|
"- METHOD: OOB method 'pin-e' or 'pin-r', "
|
||||||
|
"'cred'\n"
|
||||||
|
"- DEV_NAME: (only for NFC) device name like "
|
||||||
|
"'pn531'\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 3)
|
||||||
|
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2]);
|
||||||
|
else
|
||||||
|
res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2], argv[3]);
|
||||||
|
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||||
|
printf("Too long WPS_OOB command.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return wpa_ctrl_command(ctrl, cmd);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_WPS_OOB */
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
if (argc < 1) {
|
||||||
|
printf("Invalid 'wps_ap_pin' command - at least one argument "
|
||||||
|
"is required.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (argc > 2)
|
||||||
|
snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2]);
|
||||||
|
else if (argc > 1)
|
||||||
|
snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s",
|
||||||
|
argv[0], argv[1]);
|
||||||
|
else
|
||||||
|
snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
|
||||||
|
return wpa_ctrl_command(ctrl, buf);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
|
||||||
|
char *addr, size_t addr_len)
|
||||||
|
{
|
||||||
|
char buf[4096], *pos;
|
||||||
|
size_t len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ctrl_conn == NULL) {
|
||||||
|
printf("Not connected to hostapd - command dropped.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
len = sizeof(buf) - 1;
|
||||||
|
ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
|
||||||
|
hostapd_cli_msg_cb);
|
||||||
|
if (ret == -2) {
|
||||||
|
printf("'%s' command timed out.\n", cmd);
|
||||||
|
return -2;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
printf("'%s' command failed.\n", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[len] = '\0';
|
||||||
|
if (memcmp(buf, "FAIL", 4) == 0)
|
||||||
|
return -1;
|
||||||
|
printf("%s", buf);
|
||||||
|
|
||||||
|
pos = buf;
|
||||||
|
while (*pos != '\0' && *pos != '\n')
|
||||||
|
pos++;
|
||||||
|
*pos = '\0';
|
||||||
|
os_strlcpy(addr, buf, addr_len);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char addr[32], cmd[64];
|
||||||
|
|
||||||
|
if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
|
||||||
|
return 0;
|
||||||
|
do {
|
||||||
|
snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
|
||||||
|
} while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
printf("%s", commands_help);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
printf("%s\n\n%s\n", hostapd_cli_version, hostapd_cli_full_license);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
hostapd_cli_quit = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char cmd[256];
|
||||||
|
if (argc != 1) {
|
||||||
|
printf("Invalid LEVEL command: needs one argument (debug "
|
||||||
|
"level)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
|
||||||
|
return wpa_ctrl_command(ctrl, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl)
|
||||||
|
{
|
||||||
|
struct dirent *dent;
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
dir = opendir(ctrl_iface_dir);
|
||||||
|
if (dir == NULL) {
|
||||||
|
printf("Control interface directory '%s' could not be "
|
||||||
|
"openned.\n", ctrl_iface_dir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Available interfaces:\n");
|
||||||
|
while ((dent = readdir(dir))) {
|
||||||
|
if (strcmp(dent->d_name, ".") == 0 ||
|
||||||
|
strcmp(dent->d_name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
printf("%s\n", dent->d_name);
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
if (argc < 1) {
|
||||||
|
hostapd_cli_list_interfaces(ctrl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hostapd_cli_close_connection();
|
||||||
|
free(ctrl_ifname);
|
||||||
|
ctrl_ifname = strdup(argv[0]);
|
||||||
|
|
||||||
|
if (hostapd_cli_open_connection(ctrl_ifname)) {
|
||||||
|
printf("Connected to interface '%s.\n", ctrl_ifname);
|
||||||
|
if (wpa_ctrl_attach(ctrl_conn) == 0) {
|
||||||
|
hostapd_cli_attached = 1;
|
||||||
|
} else {
|
||||||
|
printf("Warning: Failed to attach to "
|
||||||
|
"hostapd.\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Could not connect to interface '%s' - re-trying\n",
|
||||||
|
ctrl_ifname);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct hostapd_cli_cmd {
|
||||||
|
const char *cmd;
|
||||||
|
int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct hostapd_cli_cmd hostapd_cli_commands[] = {
|
||||||
|
{ "ping", hostapd_cli_cmd_ping },
|
||||||
|
{ "mib", hostapd_cli_cmd_mib },
|
||||||
|
{ "sta", hostapd_cli_cmd_sta },
|
||||||
|
{ "all_sta", hostapd_cli_cmd_all_sta },
|
||||||
|
{ "new_sta", hostapd_cli_cmd_new_sta },
|
||||||
|
{ "deauthenticate", hostapd_cli_cmd_deauthenticate },
|
||||||
|
{ "disassociate", hostapd_cli_cmd_disassociate },
|
||||||
|
#ifdef CONFIG_IEEE80211W
|
||||||
|
{ "sa_query", hostapd_cli_cmd_sa_query },
|
||||||
|
#endif /* CONFIG_IEEE80211W */
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
{ "wps_pin", hostapd_cli_cmd_wps_pin },
|
||||||
|
{ "wps_pbc", hostapd_cli_cmd_wps_pbc },
|
||||||
|
#ifdef CONFIG_WPS_OOB
|
||||||
|
{ "wps_oob", hostapd_cli_cmd_wps_oob },
|
||||||
|
#endif /* CONFIG_WPS_OOB */
|
||||||
|
{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
|
{ "help", hostapd_cli_cmd_help },
|
||||||
|
{ "interface", hostapd_cli_cmd_interface },
|
||||||
|
{ "level", hostapd_cli_cmd_level },
|
||||||
|
{ "license", hostapd_cli_cmd_license },
|
||||||
|
{ "quit", hostapd_cli_cmd_quit },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct hostapd_cli_cmd *cmd, *match = NULL;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
cmd = hostapd_cli_commands;
|
||||||
|
while (cmd->cmd) {
|
||||||
|
if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
|
||||||
|
match = cmd;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
cmd++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 1) {
|
||||||
|
printf("Ambiguous command '%s'; possible commands:", argv[0]);
|
||||||
|
cmd = hostapd_cli_commands;
|
||||||
|
while (cmd->cmd) {
|
||||||
|
if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
|
||||||
|
0) {
|
||||||
|
printf(" %s", cmd->cmd);
|
||||||
|
}
|
||||||
|
cmd++;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
} else if (count == 0) {
|
||||||
|
printf("Unknown command '%s'\n", argv[0]);
|
||||||
|
} else {
|
||||||
|
match->handler(ctrl, argc - 1, &argv[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
|
||||||
|
int action_monitor)
|
||||||
|
{
|
||||||
|
int first = 1;
|
||||||
|
if (ctrl_conn == NULL)
|
||||||
|
return;
|
||||||
|
while (wpa_ctrl_pending(ctrl)) {
|
||||||
|
char buf[256];
|
||||||
|
size_t len = sizeof(buf) - 1;
|
||||||
|
if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
|
||||||
|
buf[len] = '\0';
|
||||||
|
if (action_monitor)
|
||||||
|
hostapd_cli_action_process(buf, len);
|
||||||
|
else {
|
||||||
|
if (in_read && first)
|
||||||
|
printf("\n");
|
||||||
|
first = 0;
|
||||||
|
printf("%s\n", buf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Could not read pending message.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_interactive(void)
|
||||||
|
{
|
||||||
|
const int max_args = 10;
|
||||||
|
char cmd[256], *res, *argv[max_args], *pos;
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
printf("\nInteractive mode\n\n");
|
||||||
|
|
||||||
|
do {
|
||||||
|
hostapd_cli_recv_pending(ctrl_conn, 0, 0);
|
||||||
|
printf("> ");
|
||||||
|
alarm(ping_interval);
|
||||||
|
res = fgets(cmd, sizeof(cmd), stdin);
|
||||||
|
alarm(0);
|
||||||
|
if (res == NULL)
|
||||||
|
break;
|
||||||
|
pos = cmd;
|
||||||
|
while (*pos != '\0') {
|
||||||
|
if (*pos == '\n') {
|
||||||
|
*pos = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
argc = 0;
|
||||||
|
pos = cmd;
|
||||||
|
for (;;) {
|
||||||
|
while (*pos == ' ')
|
||||||
|
pos++;
|
||||||
|
if (*pos == '\0')
|
||||||
|
break;
|
||||||
|
argv[argc] = pos;
|
||||||
|
argc++;
|
||||||
|
if (argc == max_args)
|
||||||
|
break;
|
||||||
|
while (*pos != '\0' && *pos != ' ')
|
||||||
|
pos++;
|
||||||
|
if (*pos == ' ')
|
||||||
|
*pos++ = '\0';
|
||||||
|
}
|
||||||
|
if (argc)
|
||||||
|
wpa_request(ctrl_conn, argc, argv);
|
||||||
|
} while (!hostapd_cli_quit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_cleanup(void)
|
||||||
|
{
|
||||||
|
hostapd_cli_close_connection();
|
||||||
|
if (pid_file)
|
||||||
|
os_daemonize_terminate(pid_file);
|
||||||
|
|
||||||
|
os_program_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_terminate(int sig)
|
||||||
|
{
|
||||||
|
hostapd_cli_cleanup();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_alarm(int sig)
|
||||||
|
{
|
||||||
|
if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
|
||||||
|
printf("Connection to hostapd lost - trying to reconnect\n");
|
||||||
|
hostapd_cli_close_connection();
|
||||||
|
}
|
||||||
|
if (!ctrl_conn) {
|
||||||
|
ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
|
||||||
|
if (ctrl_conn) {
|
||||||
|
printf("Connection to hostapd re-established\n");
|
||||||
|
if (wpa_ctrl_attach(ctrl_conn) == 0) {
|
||||||
|
hostapd_cli_attached = 1;
|
||||||
|
} else {
|
||||||
|
printf("Warning: Failed to attach to "
|
||||||
|
"hostapd.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctrl_conn)
|
||||||
|
hostapd_cli_recv_pending(ctrl_conn, 1, 0);
|
||||||
|
alarm(ping_interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_cli_action(struct wpa_ctrl *ctrl)
|
||||||
|
{
|
||||||
|
fd_set rfds;
|
||||||
|
int fd, res;
|
||||||
|
struct timeval tv;
|
||||||
|
char buf[256];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
fd = wpa_ctrl_get_fd(ctrl);
|
||||||
|
|
||||||
|
while (!hostapd_cli_quit) {
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(fd, &rfds);
|
||||||
|
tv.tv_sec = ping_interval;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
res = select(fd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if (res < 0 && errno != EINTR) {
|
||||||
|
perror("select");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_ISSET(fd, &rfds))
|
||||||
|
hostapd_cli_recv_pending(ctrl, 0, 1);
|
||||||
|
else {
|
||||||
|
len = sizeof(buf) - 1;
|
||||||
|
if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
|
||||||
|
hostapd_cli_action_process) < 0 ||
|
||||||
|
len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
|
||||||
|
printf("hostapd did not reply to PING "
|
||||||
|
"command - exiting\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int interactive;
|
||||||
|
int warning_displayed = 0;
|
||||||
|
int c;
|
||||||
|
int daemonize = 0;
|
||||||
|
|
||||||
|
if (os_program_init())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c = getopt(argc, argv, "a:BhG:i:p:v");
|
||||||
|
if (c < 0)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 'a':
|
||||||
|
action_file = optarg;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
daemonize = 1;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
ping_interval = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
usage();
|
||||||
|
return 0;
|
||||||
|
case 'v':
|
||||||
|
printf("%s\n", hostapd_cli_version);
|
||||||
|
return 0;
|
||||||
|
case 'i':
|
||||||
|
os_free(ctrl_ifname);
|
||||||
|
ctrl_ifname = os_strdup(optarg);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
ctrl_iface_dir = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interactive = (argc == optind) && (action_file == NULL);
|
||||||
|
|
||||||
|
if (interactive) {
|
||||||
|
printf("%s\n\n%s\n\n", hostapd_cli_version,
|
||||||
|
hostapd_cli_license);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (ctrl_ifname == NULL) {
|
||||||
|
struct dirent *dent;
|
||||||
|
DIR *dir = opendir(ctrl_iface_dir);
|
||||||
|
if (dir) {
|
||||||
|
while ((dent = readdir(dir))) {
|
||||||
|
if (os_strcmp(dent->d_name, ".") == 0
|
||||||
|
||
|
||||||
|
os_strcmp(dent->d_name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
printf("Selected interface '%s'\n",
|
||||||
|
dent->d_name);
|
||||||
|
ctrl_ifname = os_strdup(dent->d_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
|
||||||
|
if (ctrl_conn) {
|
||||||
|
if (warning_displayed)
|
||||||
|
printf("Connection established.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interactive) {
|
||||||
|
perror("Failed to connect to hostapd - "
|
||||||
|
"wpa_ctrl_open");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!warning_displayed) {
|
||||||
|
printf("Could not connect to hostapd - re-trying\n");
|
||||||
|
warning_displayed = 1;
|
||||||
|
}
|
||||||
|
os_sleep(1, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGINT, hostapd_cli_terminate);
|
||||||
|
signal(SIGTERM, hostapd_cli_terminate);
|
||||||
|
signal(SIGALRM, hostapd_cli_alarm);
|
||||||
|
|
||||||
|
if (interactive || action_file) {
|
||||||
|
if (wpa_ctrl_attach(ctrl_conn) == 0) {
|
||||||
|
hostapd_cli_attached = 1;
|
||||||
|
} else {
|
||||||
|
printf("Warning: Failed to attach to hostapd.\n");
|
||||||
|
if (action_file)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (daemonize && os_daemonize(pid_file))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (interactive)
|
||||||
|
hostapd_cli_interactive();
|
||||||
|
else if (action_file)
|
||||||
|
hostapd_cli_action(ctrl_conn);
|
||||||
|
else
|
||||||
|
wpa_request(ctrl_conn, argc - optind, &argv[optind]);
|
||||||
|
|
||||||
|
os_free(ctrl_ifname);
|
||||||
|
hostapd_cli_cleanup();
|
||||||
|
return 0;
|
||||||
|
}
|
9
hostapd/logwatch/README
Normal file
9
hostapd/logwatch/README
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Logwatch is a utility for analyzing system logs and provide a human
|
||||||
|
readable summary. This directory has a configuration file and a log
|
||||||
|
analyzer script for parsing hostapd system log entries for logwatch.
|
||||||
|
These files can be installed by copying them to following locations:
|
||||||
|
|
||||||
|
/etc/log.d/conf/services/hostapd.conf
|
||||||
|
/etc/log.d/scripts/services/hostapd
|
||||||
|
|
||||||
|
More information about logwatch is available from http://www.logwatch.org/
|
65
hostapd/logwatch/hostapd
Executable file
65
hostapd/logwatch/hostapd
Executable file
@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
#
|
||||||
|
# Logwatch script for hostapd
|
||||||
|
#
|
||||||
|
# Copyright 2005 Henrik Brix Andersen <brix@gentoo.org>
|
||||||
|
# Distributed under the terms of the GNU General Public License v2
|
||||||
|
# Alternatively, this file may be distributed under the terms of the BSD License
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
my $debug = $ENV{'LOGWATCH_DEBUG'} || 0;
|
||||||
|
my $detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
|
||||||
|
my $debugcounter = 1;
|
||||||
|
|
||||||
|
my %hostapd;
|
||||||
|
my @unmatched;
|
||||||
|
|
||||||
|
if ($debug >= 5) {
|
||||||
|
print STDERR "\n\nDEBUG: Inside HOSTAPD Filter\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
while (defined(my $line = <STDIN>)) {
|
||||||
|
if ($debug >= 5) {
|
||||||
|
print STDERR "DEBUG($debugcounter): $line";
|
||||||
|
$debugcounter++;
|
||||||
|
}
|
||||||
|
chomp($line);
|
||||||
|
|
||||||
|
if (my ($iface,$mac,$layer,$details) = ($line =~ /(.*?): STA (.*?) (.*?): (.*?)$/i)) {
|
||||||
|
unless ($detail == 10) {
|
||||||
|
# collapse association events
|
||||||
|
$details =~ s/^(associated) .*$/$1/i;
|
||||||
|
}
|
||||||
|
$hostapd{$iface}->{$mac}->{$layer}->{$details}++;
|
||||||
|
} else {
|
||||||
|
push @unmatched, "$line\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keys %hostapd) {
|
||||||
|
foreach my $iface (sort keys %hostapd) {
|
||||||
|
print "Interface $iface:\n";
|
||||||
|
foreach my $mac (sort keys %{$hostapd{$iface}}) {
|
||||||
|
print " Client MAC Address $mac:\n";
|
||||||
|
foreach my $layer (sort keys %{$hostapd{$iface}->{$mac}}) {
|
||||||
|
print " $layer:\n";
|
||||||
|
foreach my $details (sort keys %{$hostapd{$iface}->{$mac}->{$layer}}) {
|
||||||
|
print " $details";
|
||||||
|
my $count = $hostapd{$iface}->{$mac}->{$layer}->{$details};
|
||||||
|
if ($count > 1) {
|
||||||
|
print ": " . $count . " Times";
|
||||||
|
}
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($#unmatched >= 0) {
|
||||||
|
print "\n**Unmatched Entries**\n";
|
||||||
|
print @unmatched;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
10
hostapd/logwatch/hostapd.conf
Normal file
10
hostapd/logwatch/hostapd.conf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Logwatch configuration for hostapd
|
||||||
|
#
|
||||||
|
# Copyright 2005 Henrik Brix Andersen <brix@gentoo.org>
|
||||||
|
# Distributed under the terms of the GNU General Public License v2
|
||||||
|
# Alternatively, this file may be distributed under the terms of the BSD License
|
||||||
|
|
||||||
|
Title = "hostapd"
|
||||||
|
LogFile = messages
|
||||||
|
*OnlyService = hostapd
|
||||||
|
*RemoveHeaders
|
565
hostapd/main.c
Normal file
565
hostapd/main.c
Normal file
@ -0,0 +1,565 @@
|
|||||||
|
/*
|
||||||
|
* hostapd / main()
|
||||||
|
* Copyright (c) 2002-2010, 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 "utils/includes.h"
|
||||||
|
#ifndef CONFIG_NATIVE_WINDOWS
|
||||||
|
#include <syslog.h>
|
||||||
|
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||||
|
|
||||||
|
#include "utils/common.h"
|
||||||
|
#include "utils/eloop.h"
|
||||||
|
#include "crypto/tls.h"
|
||||||
|
#include "common/version.h"
|
||||||
|
#include "drivers/driver.h"
|
||||||
|
#include "eap_server/eap.h"
|
||||||
|
#include "eap_server/tncs.h"
|
||||||
|
#include "ap/hostapd.h"
|
||||||
|
#include "ap/ap_config.h"
|
||||||
|
#include "config_file.h"
|
||||||
|
#include "eap_register.h"
|
||||||
|
#include "dump_state.h"
|
||||||
|
#include "ctrl_iface.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern int wpa_debug_level;
|
||||||
|
extern int wpa_debug_show_keys;
|
||||||
|
extern int wpa_debug_timestamp;
|
||||||
|
|
||||||
|
|
||||||
|
struct hapd_interfaces {
|
||||||
|
size_t count;
|
||||||
|
struct hostapd_iface **iface;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
|
||||||
|
int (*cb)(struct hostapd_iface *iface,
|
||||||
|
void *ctx), void *ctx)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (i = 0; i < interfaces->count; i++) {
|
||||||
|
ret = cb(interfaces->iface[i], ctx);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CONFIG_NO_HOSTAPD_LOGGER
|
||||||
|
static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
|
||||||
|
int level, const char *txt, size_t len)
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd = ctx;
|
||||||
|
char *format, *module_str;
|
||||||
|
int maxlen;
|
||||||
|
int conf_syslog_level, conf_stdout_level;
|
||||||
|
unsigned int conf_syslog, conf_stdout;
|
||||||
|
|
||||||
|
maxlen = len + 100;
|
||||||
|
format = os_malloc(maxlen);
|
||||||
|
if (!format)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (hapd && hapd->conf) {
|
||||||
|
conf_syslog_level = hapd->conf->logger_syslog_level;
|
||||||
|
conf_stdout_level = hapd->conf->logger_stdout_level;
|
||||||
|
conf_syslog = hapd->conf->logger_syslog;
|
||||||
|
conf_stdout = hapd->conf->logger_stdout;
|
||||||
|
} else {
|
||||||
|
conf_syslog_level = conf_stdout_level = 0;
|
||||||
|
conf_syslog = conf_stdout = (unsigned int) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (module) {
|
||||||
|
case HOSTAPD_MODULE_IEEE80211:
|
||||||
|
module_str = "IEEE 802.11";
|
||||||
|
break;
|
||||||
|
case HOSTAPD_MODULE_IEEE8021X:
|
||||||
|
module_str = "IEEE 802.1X";
|
||||||
|
break;
|
||||||
|
case HOSTAPD_MODULE_RADIUS:
|
||||||
|
module_str = "RADIUS";
|
||||||
|
break;
|
||||||
|
case HOSTAPD_MODULE_WPA:
|
||||||
|
module_str = "WPA";
|
||||||
|
break;
|
||||||
|
case HOSTAPD_MODULE_DRIVER:
|
||||||
|
module_str = "DRIVER";
|
||||||
|
break;
|
||||||
|
case HOSTAPD_MODULE_IAPP:
|
||||||
|
module_str = "IAPP";
|
||||||
|
break;
|
||||||
|
case HOSTAPD_MODULE_MLME:
|
||||||
|
module_str = "MLME";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
module_str = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hapd && hapd->conf && addr)
|
||||||
|
os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
|
||||||
|
hapd->conf->iface, MAC2STR(addr),
|
||||||
|
module_str ? " " : "", module_str, txt);
|
||||||
|
else if (hapd && hapd->conf)
|
||||||
|
os_snprintf(format, maxlen, "%s:%s%s %s",
|
||||||
|
hapd->conf->iface, module_str ? " " : "",
|
||||||
|
module_str, txt);
|
||||||
|
else if (addr)
|
||||||
|
os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
|
||||||
|
MAC2STR(addr), module_str ? " " : "",
|
||||||
|
module_str, txt);
|
||||||
|
else
|
||||||
|
os_snprintf(format, maxlen, "%s%s%s",
|
||||||
|
module_str, module_str ? ": " : "", txt);
|
||||||
|
|
||||||
|
if ((conf_stdout & module) && level >= conf_stdout_level) {
|
||||||
|
wpa_debug_print_timestamp();
|
||||||
|
printf("%s\n", format);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_NATIVE_WINDOWS
|
||||||
|
if ((conf_syslog & module) && level >= conf_syslog_level) {
|
||||||
|
int priority;
|
||||||
|
switch (level) {
|
||||||
|
case HOSTAPD_LEVEL_DEBUG_VERBOSE:
|
||||||
|
case HOSTAPD_LEVEL_DEBUG:
|
||||||
|
priority = LOG_DEBUG;
|
||||||
|
break;
|
||||||
|
case HOSTAPD_LEVEL_INFO:
|
||||||
|
priority = LOG_INFO;
|
||||||
|
break;
|
||||||
|
case HOSTAPD_LEVEL_NOTICE:
|
||||||
|
priority = LOG_NOTICE;
|
||||||
|
break;
|
||||||
|
case HOSTAPD_LEVEL_WARNING:
|
||||||
|
priority = LOG_WARNING;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
priority = LOG_INFO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
syslog(priority, "%s", format);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||||
|
|
||||||
|
os_free(format);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hostapd_init - Allocate and initialize per-interface data
|
||||||
|
* @config_file: Path to the configuration file
|
||||||
|
* Returns: Pointer to the allocated interface data or %NULL on failure
|
||||||
|
*
|
||||||
|
* This function is used to allocate main data structures for per-interface
|
||||||
|
* data. The allocated data buffer will be freed by calling
|
||||||
|
* hostapd_cleanup_iface().
|
||||||
|
*/
|
||||||
|
static struct hostapd_iface * hostapd_init(const char *config_file)
|
||||||
|
{
|
||||||
|
struct hostapd_iface *hapd_iface = NULL;
|
||||||
|
struct hostapd_config *conf = NULL;
|
||||||
|
struct hostapd_data *hapd;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
hapd_iface = os_zalloc(sizeof(*hapd_iface));
|
||||||
|
if (hapd_iface == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
hapd_iface->reload_config = hostapd_reload_config;
|
||||||
|
hapd_iface->config_read_cb = hostapd_config_read;
|
||||||
|
hapd_iface->config_fname = os_strdup(config_file);
|
||||||
|
if (hapd_iface->config_fname == NULL)
|
||||||
|
goto fail;
|
||||||
|
hapd_iface->ctrl_iface_init = hostapd_ctrl_iface_init;
|
||||||
|
hapd_iface->ctrl_iface_deinit = hostapd_ctrl_iface_deinit;
|
||||||
|
hapd_iface->for_each_interface = hostapd_for_each_interface;
|
||||||
|
|
||||||
|
conf = hostapd_config_read(hapd_iface->config_fname);
|
||||||
|
if (conf == NULL)
|
||||||
|
goto fail;
|
||||||
|
hapd_iface->conf = conf;
|
||||||
|
|
||||||
|
hapd_iface->num_bss = conf->num_bss;
|
||||||
|
hapd_iface->bss = os_zalloc(conf->num_bss *
|
||||||
|
sizeof(struct hostapd_data *));
|
||||||
|
if (hapd_iface->bss == NULL)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
for (i = 0; i < conf->num_bss; i++) {
|
||||||
|
hapd = hapd_iface->bss[i] =
|
||||||
|
hostapd_alloc_bss_data(hapd_iface, conf,
|
||||||
|
&conf->bss[i]);
|
||||||
|
if (hapd == NULL)
|
||||||
|
goto fail;
|
||||||
|
hapd->msg_ctx = hapd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hapd_iface;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (conf)
|
||||||
|
hostapd_config_free(conf);
|
||||||
|
if (hapd_iface) {
|
||||||
|
os_free(hapd_iface->config_fname);
|
||||||
|
os_free(hapd_iface->bss);
|
||||||
|
os_free(hapd_iface);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_driver_init(struct hostapd_iface *iface)
|
||||||
|
{
|
||||||
|
struct wpa_init_params params;
|
||||||
|
size_t i;
|
||||||
|
struct hostapd_data *hapd = iface->bss[0];
|
||||||
|
struct hostapd_bss_config *conf = hapd->conf;
|
||||||
|
u8 *b = conf->bssid;
|
||||||
|
|
||||||
|
if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the driver interface */
|
||||||
|
if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
|
||||||
|
b = NULL;
|
||||||
|
|
||||||
|
os_memset(¶ms, 0, sizeof(params));
|
||||||
|
params.bssid = b;
|
||||||
|
params.ifname = hapd->conf->iface;
|
||||||
|
params.ssid = (const u8 *) hapd->conf->ssid.ssid;
|
||||||
|
params.ssid_len = hapd->conf->ssid.ssid_len;
|
||||||
|
params.test_socket = hapd->conf->test_socket;
|
||||||
|
params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
|
||||||
|
|
||||||
|
params.num_bridge = hapd->iface->num_bss;
|
||||||
|
params.bridge = os_zalloc(hapd->iface->num_bss * sizeof(char *));
|
||||||
|
if (params.bridge == NULL)
|
||||||
|
return -1;
|
||||||
|
for (i = 0; i < hapd->iface->num_bss; i++) {
|
||||||
|
struct hostapd_data *bss = hapd->iface->bss[i];
|
||||||
|
if (bss->conf->bridge[0])
|
||||||
|
params.bridge[i] = bss->conf->bridge;
|
||||||
|
}
|
||||||
|
|
||||||
|
params.own_addr = hapd->own_addr;
|
||||||
|
|
||||||
|
hapd->drv_priv = hapd->driver->hapd_init(hapd, ¶ms);
|
||||||
|
os_free(params.bridge);
|
||||||
|
if (hapd->drv_priv == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "%s driver initialization failed.",
|
||||||
|
hapd->driver->name);
|
||||||
|
hapd->driver = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_interface_deinit_free(struct hostapd_iface *iface)
|
||||||
|
{
|
||||||
|
const struct wpa_driver_ops *driver;
|
||||||
|
void *drv_priv;
|
||||||
|
if (iface == NULL)
|
||||||
|
return;
|
||||||
|
driver = iface->bss[0]->driver;
|
||||||
|
drv_priv = iface->bss[0]->drv_priv;
|
||||||
|
hostapd_interface_deinit(iface);
|
||||||
|
if (driver && driver->hapd_deinit)
|
||||||
|
driver->hapd_deinit(drv_priv);
|
||||||
|
hostapd_interface_free(iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct hostapd_iface *
|
||||||
|
hostapd_interface_init(struct hapd_interfaces *interfaces,
|
||||||
|
const char *config_fname, int debug)
|
||||||
|
{
|
||||||
|
struct hostapd_iface *iface;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
|
||||||
|
iface = hostapd_init(config_fname);
|
||||||
|
if (!iface)
|
||||||
|
return NULL;
|
||||||
|
iface->interfaces = interfaces;
|
||||||
|
|
||||||
|
for (k = 0; k < debug; k++) {
|
||||||
|
if (iface->bss[0]->conf->logger_stdout_level > 0)
|
||||||
|
iface->bss[0]->conf->logger_stdout_level--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostapd_driver_init(iface) ||
|
||||||
|
hostapd_setup_interface(iface)) {
|
||||||
|
hostapd_interface_deinit_free(iface);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle_term - SIGINT and SIGTERM handler to terminate hostapd process
|
||||||
|
*/
|
||||||
|
static void handle_term(int sig, void *signal_ctx)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
|
||||||
|
eloop_terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CONFIG_NATIVE_WINDOWS
|
||||||
|
|
||||||
|
static int handle_reload_iface(struct hostapd_iface *iface, void *ctx)
|
||||||
|
{
|
||||||
|
if (hostapd_reload_config(iface) < 0) {
|
||||||
|
wpa_printf(MSG_WARNING, "Failed to read new configuration "
|
||||||
|
"file - continuing with old.");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle_reload - SIGHUP handler to reload configuration
|
||||||
|
*/
|
||||||
|
static void handle_reload(int sig, void *signal_ctx)
|
||||||
|
{
|
||||||
|
struct hapd_interfaces *interfaces = signal_ctx;
|
||||||
|
wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
|
||||||
|
sig);
|
||||||
|
hostapd_for_each_interface(interfaces, handle_reload_iface, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_dump_state(int sig, void *signal_ctx)
|
||||||
|
{
|
||||||
|
#ifdef HOSTAPD_DUMP_STATE
|
||||||
|
struct hapd_interfaces *interfaces = signal_ctx;
|
||||||
|
hostapd_for_each_interface(interfaces, handle_dump_state_iface, NULL);
|
||||||
|
#endif /* HOSTAPD_DUMP_STATE */
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_global_init(struct hapd_interfaces *interfaces)
|
||||||
|
{
|
||||||
|
hostapd_logger_register_cb(hostapd_logger_cb);
|
||||||
|
|
||||||
|
if (eap_server_register_methods()) {
|
||||||
|
wpa_printf(MSG_ERROR, "Failed to register EAP methods");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eloop_init()) {
|
||||||
|
wpa_printf(MSG_ERROR, "Failed to initialize event loop");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_NATIVE_WINDOWS
|
||||||
|
eloop_register_signal(SIGHUP, handle_reload, interfaces);
|
||||||
|
eloop_register_signal(SIGUSR1, handle_dump_state, interfaces);
|
||||||
|
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||||
|
eloop_register_signal_terminate(handle_term, interfaces);
|
||||||
|
|
||||||
|
#ifndef CONFIG_NATIVE_WINDOWS
|
||||||
|
openlog("hostapd", 0, LOG_DAEMON);
|
||||||
|
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_global_deinit(const char *pid_file)
|
||||||
|
{
|
||||||
|
#ifdef EAP_SERVER_TNC
|
||||||
|
tncs_global_deinit();
|
||||||
|
#endif /* EAP_SERVER_TNC */
|
||||||
|
|
||||||
|
eloop_destroy();
|
||||||
|
|
||||||
|
#ifndef CONFIG_NATIVE_WINDOWS
|
||||||
|
closelog();
|
||||||
|
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||||
|
|
||||||
|
eap_server_unregister_methods();
|
||||||
|
|
||||||
|
os_daemonize_terminate(pid_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
|
||||||
|
const char *pid_file)
|
||||||
|
{
|
||||||
|
#ifdef EAP_SERVER_TNC
|
||||||
|
int tnc = 0;
|
||||||
|
size_t i, k;
|
||||||
|
|
||||||
|
for (i = 0; !tnc && i < ifaces->count; i++) {
|
||||||
|
for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
|
||||||
|
if (ifaces->iface[i]->bss[0]->conf->tnc) {
|
||||||
|
tnc++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tnc && tncs_global_init() < 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* EAP_SERVER_TNC */
|
||||||
|
|
||||||
|
if (daemonize && os_daemonize(pid_file)) {
|
||||||
|
perror("daemon");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eloop_run();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void show_version(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"hostapd v" VERSION_STR "\n"
|
||||||
|
"User space daemon for IEEE 802.11 AP management,\n"
|
||||||
|
"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
|
||||||
|
"Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi> "
|
||||||
|
"and contributors\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
show_version();
|
||||||
|
fprintf(stderr,
|
||||||
|
"\n"
|
||||||
|
"usage: hostapd [-hdBKtv] [-P <PID file>] "
|
||||||
|
"<configuration file(s)>\n"
|
||||||
|
"\n"
|
||||||
|
"options:\n"
|
||||||
|
" -h show this usage\n"
|
||||||
|
" -d show more debug messages (-dd for even more)\n"
|
||||||
|
" -B run daemon in the background\n"
|
||||||
|
" -P PID file\n"
|
||||||
|
" -K include key data in debug messages\n"
|
||||||
|
" -t include timestamps in some debug messages\n"
|
||||||
|
" -v show hostapd version\n");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct hapd_interfaces interfaces;
|
||||||
|
int ret = 1;
|
||||||
|
size_t i;
|
||||||
|
int c, debug = 0, daemonize = 0;
|
||||||
|
char *pid_file = NULL;
|
||||||
|
|
||||||
|
if (os_program_init())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
c = getopt(argc, argv, "BdhKP:tv");
|
||||||
|
if (c < 0)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 'h':
|
||||||
|
usage();
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
debug++;
|
||||||
|
if (wpa_debug_level > 0)
|
||||||
|
wpa_debug_level--;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
daemonize++;
|
||||||
|
break;
|
||||||
|
case 'K':
|
||||||
|
wpa_debug_show_keys++;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
os_free(pid_file);
|
||||||
|
pid_file = os_rel2abs_path(optarg);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
wpa_debug_timestamp++;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
show_version();
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind == argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
interfaces.count = argc - optind;
|
||||||
|
interfaces.iface = os_malloc(interfaces.count *
|
||||||
|
sizeof(struct hostapd_iface *));
|
||||||
|
if (interfaces.iface == NULL) {
|
||||||
|
wpa_printf(MSG_ERROR, "malloc failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostapd_global_init(&interfaces))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Initialize interfaces */
|
||||||
|
for (i = 0; i < interfaces.count; i++) {
|
||||||
|
interfaces.iface[i] = hostapd_interface_init(&interfaces,
|
||||||
|
argv[optind + i],
|
||||||
|
debug);
|
||||||
|
if (!interfaces.iface[i])
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostapd_global_run(&interfaces, daemonize, pid_file))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* Deinitialize all interfaces */
|
||||||
|
for (i = 0; i < interfaces.count; i++)
|
||||||
|
hostapd_interface_deinit_free(interfaces.iface[i]);
|
||||||
|
os_free(interfaces.iface);
|
||||||
|
|
||||||
|
hostapd_global_deinit(pid_file);
|
||||||
|
os_free(pid_file);
|
||||||
|
|
||||||
|
os_program_deinit();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
53
hostapd/nt_password_hash.c
Normal file
53
hostapd/nt_password_hash.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* hostapd - Plaintext password to NtPasswordHash
|
||||||
|
* Copyright (c) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "crypto/ms_funcs.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
unsigned char password_hash[16];
|
||||||
|
size_t i;
|
||||||
|
char *password, buf[64], *pos;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
password = argv[1];
|
||||||
|
else {
|
||||||
|
if (fgets(buf, sizeof(buf), stdin) == NULL) {
|
||||||
|
printf("Failed to read password\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
pos = buf;
|
||||||
|
while (*pos != '\0') {
|
||||||
|
if (*pos == '\r' || *pos == '\n') {
|
||||||
|
*pos = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
password = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nt_password_hash((u8 *) password, strlen(password), password_hash))
|
||||||
|
return -1;
|
||||||
|
for (i = 0; i < sizeof(password_hash); i++)
|
||||||
|
printf("%02x", password_hash[i]);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
40
hostapd/wired.conf
Normal file
40
hostapd/wired.conf
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
##### hostapd configuration file ##############################################
|
||||||
|
# Empty lines and lines starting with # are ignored
|
||||||
|
|
||||||
|
# Example configuration file for wired authenticator. See hostapd.conf for
|
||||||
|
# more details.
|
||||||
|
|
||||||
|
interface=eth0
|
||||||
|
driver=wired
|
||||||
|
logger_stdout=-1
|
||||||
|
logger_stdout_level=1
|
||||||
|
debug=2
|
||||||
|
dump_file=/tmp/hostapd.dump
|
||||||
|
|
||||||
|
ieee8021x=1
|
||||||
|
eap_reauth_period=3600
|
||||||
|
|
||||||
|
use_pae_group_addr=1
|
||||||
|
|
||||||
|
|
||||||
|
##### RADIUS 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=radius
|
||||||
|
|
||||||
|
# RADIUS accounting server
|
||||||
|
acct_server_addr=127.0.0.1
|
||||||
|
acct_server_port=1813
|
||||||
|
acct_server_shared_secret=radius
|
Loading…
Reference in New Issue
Block a user