aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Leffler <sam@FreeBSD.org>2009-03-01 22:10:07 +0000
committerSam Leffler <sam@FreeBSD.org>2009-03-01 22:10:07 +0000
commitb2cbddbd4361766d55c5f9dae81f71f44577bb6a (patch)
tree372b16f9e6ccba7284b53135005cc85cc6545185
parent514fff2b7c1f2e25e5c0611b598797f32aff1042 (diff)
parent22188e6ab4f02f981de3b9f228a40b1e8f98e6a1 (diff)
downloadsrc-b2cbddbd4361766d55c5f9dae81f71f44577bb6a.tar.gz
src-b2cbddbd4361766d55c5f9dae81f71f44577bb6a.zip
import wpa_supplicant+hostapd 0.6.8vendor/wpa/0.6.8
Notes
Notes: svn path=/vendor/wpa/dist/; revision=189251 svn path=/vendor/wpa/0.6.8/; revision=189252; tag=vendor/wpa/0.6.8
-rw-r--r--COPYING (renamed from contrib/hostapd/COPYING)0
-rw-r--r--README19
-rw-r--r--contrib/hostapd/FREEBSD-Xlist17
-rw-r--r--contrib/hostapd/FREEBSD-upgrade24
-rw-r--r--contrib/hostapd/Makefile444
-rw-r--r--contrib/hostapd/aes_wrap.h44
-rw-r--r--contrib/hostapd/config.c1994
-rw-r--r--contrib/hostapd/developer.txt219
-rw-r--r--contrib/hostapd/eap.h115
-rw-r--r--contrib/hostapd/eap_peap.c731
-rw-r--r--contrib/hostapd/eap_tls_common.c301
-rw-r--r--contrib/hostapd/eap_tls_common.h61
-rw-r--r--contrib/hostapd/eap_tlv.c252
-rw-r--r--contrib/hostapd/eapol_version.patch129
-rw-r--r--contrib/hostapd/hostapd.accept5
-rw-r--r--contrib/hostapd/hostapd_ctrl.c188
-rw-r--r--contrib/hostapd/hostapd_ctrl.h18
-rw-r--r--contrib/hostapd/hw_features.c429
-rw-r--r--contrib/hostapd/ieee802_11.h333
-rw-r--r--contrib/hostapd/madwifi.conf278
-rw-r--r--contrib/hostapd/reconfig.c714
-rw-r--r--contrib/hostapd/wpa.c3781
-rw-r--r--contrib/hostapd/wpa.h186
-rw-r--r--hostapd/.gitignore7
-rw-r--r--hostapd/ChangeLog (renamed from contrib/hostapd/ChangeLog)180
-rw-r--r--hostapd/Makefile602
-rw-r--r--hostapd/README (renamed from contrib/hostapd/README)6
-rw-r--r--hostapd/README-WPS232
-rw-r--r--hostapd/accounting.c (renamed from contrib/hostapd/accounting.c)109
-rw-r--r--hostapd/accounting.h (renamed from contrib/hostapd/accounting.h)1
-rw-r--r--hostapd/ap.h (renamed from contrib/hostapd/ap.h)30
-rw-r--r--hostapd/ap_list.c (renamed from contrib/hostapd/ap_list.c)98
-rw-r--r--hostapd/ap_list.h (renamed from contrib/hostapd/ap_list.h)9
-rw-r--r--hostapd/beacon.c (renamed from contrib/hostapd/beacon.c)276
-rw-r--r--hostapd/beacon.h (renamed from contrib/hostapd/beacon.h)0
-rw-r--r--hostapd/config.c2617
-rw-r--r--hostapd/config.h (renamed from contrib/hostapd/config.h)141
-rw-r--r--hostapd/ctrl_iface.c (renamed from contrib/hostapd/ctrl_iface.c)157
-rw-r--r--hostapd/ctrl_iface.h (renamed from contrib/hostapd/ctrl_iface.h)2
-rw-r--r--hostapd/defconfig (renamed from contrib/hostapd/defconfig)58
-rw-r--r--hostapd/doc/.gitignore4
-rw-r--r--hostapd/doc/code_structure.doxygen (renamed from contrib/hostapd/doc/code_structure.doxygen)0
-rw-r--r--hostapd/doc/ctrl_iface.doxygen (renamed from contrib/hostapd/doc/ctrl_iface.doxygen)0
-rw-r--r--hostapd/doc/doxygen.fast (renamed from contrib/hostapd/doc/doxygen.fast)29
-rw-r--r--hostapd/doc/doxygen.full (renamed from contrib/hostapd/doc/doxygen.full)28
-rw-r--r--hostapd/doc/driver_wrapper.doxygen (renamed from contrib/hostapd/doc/driver_wrapper.doxygen)0
-rw-r--r--hostapd/doc/eap.doxygen (renamed from contrib/hostapd/doc/eap.doxygen)0
-rw-r--r--hostapd/doc/hostapd.fig (renamed from contrib/hostapd/doc/hostapd.fig)0
-rwxr-xr-xhostapd/doc/kerneldoc2doxygen.pl (renamed from contrib/hostapd/doc/kerneldoc2doxygen.pl)0
-rw-r--r--hostapd/doc/mainpage.doxygen (renamed from contrib/hostapd/doc/mainpage.doxygen)0
-rw-r--r--hostapd/doc/porting.doxygen (renamed from contrib/hostapd/doc/porting.doxygen)0
-rw-r--r--hostapd/driver.h (renamed from contrib/hostapd/driver.h)314
-rw-r--r--hostapd/driver_bsd.c838
-rw-r--r--hostapd/driver_hostap.c1279
-rw-r--r--hostapd/driver_madwifi.c1483
-rw-r--r--hostapd/driver_nl80211.c2696
-rw-r--r--hostapd/driver_none.c62
-rw-r--r--hostapd/driver_prism54.c1091
-rw-r--r--hostapd/driver_test.c (renamed from contrib/hostapd/driver_test.c)423
-rw-r--r--hostapd/driver_wired.c372
-rw-r--r--hostapd/drivers.c71
-rw-r--r--hostapd/eap_testing.txt77
-rw-r--r--hostapd/eapol_sm.c (renamed from contrib/hostapd/eapol_sm.c)678
-rw-r--r--hostapd/eapol_sm.h (renamed from contrib/hostapd/eapol_sm.h)118
-rw-r--r--hostapd/hostap_common.h (renamed from contrib/hostapd/hostap_common.h)4
-rw-r--r--hostapd/hostapd.8 (renamed from contrib/hostapd/hostapd.8)0
-rw-r--r--hostapd/hostapd.accept6
-rw-r--r--hostapd/hostapd.c (renamed from contrib/hostapd/hostapd.c)1235
-rw-r--r--hostapd/hostapd.conf (renamed from contrib/hostapd/hostapd.conf)379
-rw-r--r--hostapd/hostapd.deny (renamed from contrib/hostapd/hostapd.deny)0
-rw-r--r--hostapd/hostapd.eap_user (renamed from contrib/hostapd/hostapd.eap_user)23
-rw-r--r--hostapd/hostapd.h (renamed from contrib/hostapd/hostapd.h)101
-rw-r--r--hostapd/hostapd.radius_clients (renamed from contrib/hostapd/hostapd.radius_clients)0
-rw-r--r--hostapd/hostapd.sim_db (renamed from contrib/hostapd/hostapd.sim_db)0
-rw-r--r--hostapd/hostapd.vlan (renamed from contrib/hostapd/hostapd.vlan)0
-rw-r--r--hostapd/hostapd.wpa_psk (renamed from contrib/hostapd/hostapd.wpa_psk)0
-rw-r--r--hostapd/hostapd_cli.1 (renamed from contrib/hostapd/hostapd_cli.1)0
-rw-r--r--hostapd/hostapd_cli.c (renamed from contrib/hostapd/hostapd_cli.c)73
-rw-r--r--hostapd/hw_features.c487
-rw-r--r--hostapd/hw_features.h (renamed from contrib/hostapd/hw_features.h)13
-rw-r--r--hostapd/iapp.c (renamed from contrib/hostapd/iapp.c)49
-rw-r--r--hostapd/iapp.h (renamed from contrib/hostapd/iapp.h)0
-rw-r--r--hostapd/ieee802_11.c (renamed from contrib/hostapd/ieee802_11.c)1246
-rw-r--r--hostapd/ieee802_11.h56
-rw-r--r--hostapd/ieee802_11_auth.c (renamed from contrib/hostapd/ieee802_11_auth.c)184
-rw-r--r--hostapd/ieee802_11_auth.h (renamed from contrib/hostapd/ieee802_11_auth.h)0
-rw-r--r--hostapd/ieee802_1x.c (renamed from contrib/hostapd/ieee802_1x.c)1302
-rw-r--r--hostapd/ieee802_1x.h (renamed from contrib/hostapd/ieee802_1x.h)28
-rw-r--r--hostapd/logwatch/README (renamed from contrib/hostapd/logwatch/README)0
-rwxr-xr-xhostapd/logwatch/hostapd (renamed from contrib/hostapd/logwatch/hostapd)0
-rw-r--r--hostapd/logwatch/hostapd.conf (renamed from contrib/hostapd/logwatch/hostapd.conf)0
-rw-r--r--hostapd/mlme.c (renamed from contrib/hostapd/mlme.c)12
-rw-r--r--hostapd/mlme.h (renamed from contrib/hostapd/mlme.h)0
-rw-r--r--hostapd/nt_password_hash.c52
-rw-r--r--hostapd/peerkey.c402
-rw-r--r--hostapd/pmksa_cache.c (renamed from contrib/hostapd/pmksa_cache.c)185
-rw-r--r--hostapd/pmksa_cache.h (renamed from contrib/hostapd/pmksa_cache.h)14
-rw-r--r--hostapd/preauth.c (renamed from contrib/hostapd/preauth.c)73
-rw-r--r--hostapd/preauth.h (renamed from contrib/hostapd/preauth.h)0
-rw-r--r--hostapd/prism54.h177
-rw-r--r--hostapd/priv_netlink.h71
-rw-r--r--hostapd/radiotap.c287
-rw-r--r--hostapd/radiotap.h242
-rw-r--r--hostapd/radiotap_iter.h41
-rw-r--r--hostapd/sta_info.c (renamed from contrib/hostapd/sta_info.c)238
-rw-r--r--hostapd/sta_info.h (renamed from contrib/hostapd/sta_info.h)5
-rw-r--r--hostapd/vlan_init.c (renamed from contrib/hostapd/vlan_init.c)101
-rw-r--r--hostapd/vlan_init.h (renamed from contrib/hostapd/vlan_init.h)0
-rw-r--r--hostapd/wired.conf (renamed from contrib/hostapd/wired.conf)0
-rw-r--r--hostapd/wme.c (renamed from contrib/hostapd/wme.c)38
-rw-r--r--hostapd/wme.h (renamed from contrib/hostapd/wme.h)21
-rw-r--r--hostapd/wpa.c2447
-rw-r--r--hostapd/wpa.h284
-rw-r--r--hostapd/wpa_auth_i.h221
-rw-r--r--hostapd/wpa_auth_ie.c864
-rw-r--r--hostapd/wpa_auth_ie.h54
-rw-r--r--hostapd/wpa_ft.c1499
-rw-r--r--hostapd/wps_hostapd.c998
-rw-r--r--hostapd/wps_hostapd.h48
-rw-r--r--patches/openssl-0.9.8-tls-extensions.patch429
-rw-r--r--patches/openssl-0.9.8d-tls-extensions.patch429
-rw-r--r--patches/openssl-0.9.8e-tls-extensions.patch353
-rw-r--r--patches/openssl-0.9.8g-tls-extensions.patch330
-rw-r--r--patches/openssl-0.9.8h-tls-extensions.patch344
-rw-r--r--patches/openssl-0.9.8i-tls-extensions.patch404
-rw-r--r--patches/openssl-0.9.9-session-ticket.patch374
-rw-r--r--src/Makefile11
-rw-r--r--src/common/.gitignore1
-rw-r--r--src/common/Makefile9
-rw-r--r--src/common/defs.h (renamed from contrib/hostapd/defs.h)65
-rw-r--r--src/common/eapol_common.h (renamed from contrib/hostapd/wpa_common.h)23
-rw-r--r--src/common/ieee802_11_common.c252
-rw-r--r--src/common/ieee802_11_common.h74
-rw-r--r--src/common/ieee802_11_defs.h588
-rw-r--r--src/common/nl80211_copy.h909
-rw-r--r--src/common/privsep_commands.h78
-rw-r--r--src/common/version.h (renamed from contrib/hostapd/version.h)2
-rw-r--r--src/common/wireless_copy.h1099
-rw-r--r--src/common/wpa_common.c570
-rw-r--r--src/common/wpa_common.h335
-rw-r--r--src/common/wpa_ctrl.c (renamed from contrib/hostapd/wpa_ctrl.c)64
-rw-r--r--src/common/wpa_ctrl.h (renamed from contrib/hostapd/wpa_ctrl.h)28
-rw-r--r--src/crypto/.gitignore1
-rw-r--r--src/crypto/Makefile9
-rw-r--r--src/crypto/aes.c (renamed from contrib/hostapd/aes.c)24
-rw-r--r--src/crypto/aes.h (renamed from contrib/hostapd/aes.h)0
-rw-r--r--src/crypto/aes_wrap.c (renamed from contrib/hostapd/aes_wrap.c)58
-rw-r--r--src/crypto/aes_wrap.h48
-rw-r--r--src/crypto/crypto.h (renamed from contrib/hostapd/crypto.h)58
-rw-r--r--src/crypto/crypto_cryptoapi.c801
-rw-r--r--src/crypto/crypto_gnutls.c313
-rw-r--r--src/crypto/crypto_internal.c835
-rw-r--r--src/crypto/crypto_libtomcrypt.c736
-rw-r--r--src/crypto/crypto_none.c28
-rw-r--r--src/crypto/crypto_openssl.c (renamed from contrib/hostapd/crypto.c)157
-rw-r--r--src/crypto/des.c (renamed from contrib/hostapd/des.c)3
-rw-r--r--src/crypto/dh_groups.c620
-rw-r--r--src/crypto/dh_groups.h32
-rw-r--r--src/crypto/md4.c (renamed from contrib/hostapd/md4.c)0
-rw-r--r--src/crypto/md5.c (renamed from contrib/hostapd/md5.c)0
-rw-r--r--src/crypto/md5.h (renamed from contrib/hostapd/md5.h)0
-rw-r--r--src/crypto/ms_funcs.c (renamed from contrib/hostapd/ms_funcs.c)38
-rw-r--r--src/crypto/ms_funcs.h (renamed from contrib/hostapd/ms_funcs.h)9
-rw-r--r--src/crypto/rc4.c (renamed from contrib/hostapd/rc4.c)0
-rw-r--r--src/crypto/rc4.h (renamed from contrib/hostapd/rc4.h)0
-rw-r--r--src/crypto/sha1.c (renamed from contrib/hostapd/sha1.c)41
-rw-r--r--src/crypto/sha1.h (renamed from contrib/hostapd/sha1.h)5
-rw-r--r--src/crypto/sha256.c (renamed from contrib/hostapd/sha256.c)31
-rw-r--r--src/crypto/sha256.h (renamed from contrib/hostapd/sha256.h)0
-rw-r--r--src/crypto/tls.h (renamed from contrib/hostapd/tls.h)113
-rw-r--r--src/crypto/tls_gnutls.c (renamed from contrib/hostapd/tls_gnutls.c)35
-rw-r--r--src/crypto/tls_internal.c569
-rw-r--r--src/crypto/tls_none.c (renamed from contrib/hostapd/tls_none.c)7
-rw-r--r--src/crypto/tls_openssl.c (renamed from contrib/hostapd/tls_openssl.c)549
-rw-r--r--src/crypto/tls_schannel.c789
-rw-r--r--src/drivers/.gitignore1
-rw-r--r--src/drivers/Apple80211.h156
-rw-r--r--src/drivers/Makefile9
-rw-r--r--src/drivers/MobileApple80211.c189
-rw-r--r--src/drivers/MobileApple80211.h43
-rw-r--r--src/drivers/driver.h1325
-rw-r--r--src/drivers/driver_atmel.c506
-rw-r--r--src/drivers/driver_broadcom.c604
-rw-r--r--src/drivers/driver_bsd.c800
-rw-r--r--src/drivers/driver_hostap.c513
-rw-r--r--src/drivers/driver_hostap.h153
-rw-r--r--src/drivers/driver_iphone.m466
-rw-r--r--src/drivers/driver_ipw.c463
-rw-r--r--src/drivers/driver_madwifi.c597
-rw-r--r--src/drivers/driver_ndis.c3126
-rw-r--r--src/drivers/driver_ndis.h64
-rw-r--r--src/drivers/driver_ndis_.c105
-rw-r--r--src/drivers/driver_ndiswrapper.c366
-rw-r--r--src/drivers/driver_nl80211.c2752
-rw-r--r--src/drivers/driver_osx.m432
-rw-r--r--src/drivers/driver_prism54.c381
-rw-r--r--src/drivers/driver_privsep.c820
-rw-r--r--src/drivers/driver_ps3.c186
-rw-r--r--src/drivers/driver_ralink.c1505
-rw-r--r--src/drivers/driver_ralink.h382
-rw-r--r--src/drivers/driver_roboswitch.c444
-rw-r--r--src/drivers/driver_test.c1230
-rw-r--r--src/drivers/driver_wext.c2349
-rw-r--r--src/drivers/driver_wext.h82
-rw-r--r--src/drivers/driver_wired.c277
-rw-r--r--src/drivers/drivers.c139
-rw-r--r--src/drivers/ndis_events.c808
-rw-r--r--src/drivers/priv_netlink.h104
-rw-r--r--src/drivers/radiotap.c287
-rw-r--r--src/drivers/radiotap.h242
-rw-r--r--src/drivers/radiotap_iter.h41
-rw-r--r--src/drivers/scan_helpers.c182
-rw-r--r--src/eap_common/.gitignore1
-rw-r--r--src/eap_common/Makefile9
-rw-r--r--src/eap_common/chap.c (renamed from contrib/hostapd/ieee802_11h.c)31
-rw-r--r--src/eap_common/chap.h (renamed from contrib/hostapd/ieee802_11h.h)18
-rw-r--r--src/eap_common/eap_common.c184
-rw-r--r--src/eap_common/eap_common.h28
-rw-r--r--src/eap_common/eap_defs.h (renamed from contrib/hostapd/eap_defs.h)26
-rw-r--r--src/eap_common/eap_fast_common.c304
-rw-r--r--src/eap_common/eap_fast_common.h117
-rw-r--r--src/eap_common/eap_gpsk_common.c (renamed from contrib/hostapd/eap_gpsk_common.c)9
-rw-r--r--src/eap_common/eap_gpsk_common.h (renamed from contrib/hostapd/eap_gpsk_common.h)0
-rw-r--r--src/eap_common/eap_ikev2_common.c132
-rw-r--r--src/eap_common/eap_ikev2_common.h42
-rw-r--r--src/eap_common/eap_pax_common.c (renamed from contrib/hostapd/eap_pax_common.c)0
-rw-r--r--src/eap_common/eap_pax_common.h (renamed from contrib/hostapd/eap_pax_common.h)6
-rw-r--r--src/eap_common/eap_peap_common.c88
-rw-r--r--src/eap_common/eap_peap_common.h22
-rw-r--r--src/eap_common/eap_psk_common.c (renamed from contrib/hostapd/eap_psk_common.c)30
-rw-r--r--src/eap_common/eap_psk_common.h (renamed from contrib/hostapd/eap_psk_common.h)33
-rw-r--r--src/eap_common/eap_sake_common.c (renamed from contrib/hostapd/eap_sake_common.c)15
-rw-r--r--src/eap_common/eap_sake_common.h (renamed from contrib/hostapd/eap_sake_common.h)8
-rw-r--r--src/eap_common/eap_sim_common.c (renamed from contrib/hostapd/eap_sim_common.c)525
-rw-r--r--src/eap_common/eap_sim_common.h (renamed from contrib/hostapd/eap_sim_common.h)81
-rw-r--r--src/eap_common/eap_tlv_common.h119
-rw-r--r--src/eap_common/eap_ttls.h (renamed from contrib/hostapd/eap_ttls.h)18
-rw-r--r--src/eap_common/eap_wsc_common.c39
-rw-r--r--src/eap_common/eap_wsc_common.h33
-rw-r--r--src/eap_common/ikev2_common.c796
-rw-r--r--src/eap_common/ikev2_common.h344
-rw-r--r--src/eap_peer/.gitignore1
-rw-r--r--src/eap_peer/Makefile12
-rw-r--r--src/eap_peer/eap.c2075
-rw-r--r--src/eap_peer/eap.h291
-rw-r--r--src/eap_peer/eap_aka.c1391
-rw-r--r--src/eap_peer/eap_config.h660
-rw-r--r--src/eap_peer/eap_fast.c1715
-rw-r--r--src/eap_peer/eap_fast_pac.c921
-rw-r--r--src/eap_peer/eap_fast_pac.h56
-rw-r--r--src/eap_peer/eap_gpsk.c737
-rw-r--r--src/eap_peer/eap_gtc.c151
-rw-r--r--src/eap_peer/eap_i.h355
-rw-r--r--src/eap_peer/eap_ikev2.c506
-rw-r--r--src/eap_peer/eap_leap.c403
-rw-r--r--src/eap_peer/eap_md5.c120
-rw-r--r--src/eap_peer/eap_methods.c528
-rw-r--r--src/eap_peer/eap_methods.h87
-rw-r--r--src/eap_peer/eap_mschapv2.c877
-rw-r--r--src/eap_peer/eap_otp.c107
-rw-r--r--src/eap_peer/eap_pax.c532
-rw-r--r--src/eap_peer/eap_peap.c1288
-rw-r--r--src/eap_peer/eap_psk.c482
-rw-r--r--src/eap_peer/eap_sake.c499
-rw-r--r--src/eap_peer/eap_sim.c1104
-rw-r--r--src/eap_peer/eap_tls.c289
-rw-r--r--src/eap_peer/eap_tls_common.c1050
-rw-r--r--src/eap_peer/eap_tls_common.h139
-rw-r--r--src/eap_peer/eap_tnc.c428
-rw-r--r--src/eap_peer/eap_ttls.c1983
-rw-r--r--src/eap_peer/eap_vendor_test.c195
-rw-r--r--src/eap_peer/eap_wsc.c453
-rw-r--r--src/eap_peer/ikev2.c1303
-rw-r--r--src/eap_peer/ikev2.h65
-rw-r--r--src/eap_peer/mschapv2.c119
-rw-r--r--src/eap_peer/mschapv2.h34
-rw-r--r--src/eap_peer/tncc.c1368
-rw-r--r--src/eap_peer/tncc.h42
-rw-r--r--src/eap_server/.gitignore1
-rw-r--r--src/eap_server/Makefile9
-rw-r--r--src/eap_server/eap.c (renamed from contrib/hostapd/eap.c)800
-rw-r--r--src/eap_server/eap.h122
-rw-r--r--src/eap_server/eap_aka.c (renamed from contrib/hostapd/eap_aka.c)646
-rw-r--r--src/eap_server/eap_fast.c1596
-rw-r--r--src/eap_server/eap_gpsk.c (renamed from contrib/hostapd/eap_gpsk.c)168
-rw-r--r--src/eap_server/eap_gtc.c (renamed from contrib/hostapd/eap_gtc.c)120
-rw-r--r--src/eap_server/eap_i.h (renamed from contrib/hostapd/eap_i.h)80
-rw-r--r--src/eap_server/eap_identity.c (renamed from contrib/hostapd/eap_identity.c)39
-rw-r--r--src/eap_server/eap_ikev2.c538
-rw-r--r--src/eap_server/eap_md5.c (renamed from contrib/hostapd/eap_md5.c)70
-rw-r--r--src/eap_server/eap_methods.c (renamed from contrib/hostapd/eap_methods.c)55
-rw-r--r--src/eap_server/eap_methods.h (renamed from contrib/hostapd/eap_methods.h)26
-rw-r--r--src/eap_server/eap_mschapv2.c (renamed from contrib/hostapd/eap_mschapv2.c)209
-rw-r--r--src/eap_server/eap_pax.c (renamed from contrib/hostapd/eap_pax.c)187
-rw-r--r--src/eap_server/eap_peap.c1421
-rw-r--r--src/eap_server/eap_psk.c (renamed from contrib/hostapd/eap_psk.c)233
-rw-r--r--src/eap_server/eap_sake.c (renamed from contrib/hostapd/eap_sake.c)187
-rw-r--r--src/eap_server/eap_sim.c (renamed from contrib/hostapd/eap_sim.c)244
-rw-r--r--src/eap_server/eap_sim_db.c (renamed from contrib/hostapd/eap_sim_db.c)300
-rw-r--r--src/eap_server/eap_sim_db.h (renamed from contrib/hostapd/eap_sim_db.h)12
-rw-r--r--src/eap_server/eap_tls.c (renamed from contrib/hostapd/eap_tls.c)204
-rw-r--r--src/eap_server/eap_tls_common.c410
-rw-r--r--src/eap_server/eap_tls_common.h64
-rw-r--r--src/eap_server/eap_tnc.c536
-rw-r--r--src/eap_server/eap_ttls.c (renamed from contrib/hostapd/eap_ttls.c)614
-rw-r--r--src/eap_server/eap_vendor_test.c (renamed from contrib/hostapd/eap_vendor_test.c)78
-rw-r--r--src/eap_server/eap_wsc.c498
-rw-r--r--src/eap_server/ikev2.c1205
-rw-r--r--src/eap_server/ikev2.h67
-rw-r--r--src/eap_server/tncs.c1272
-rw-r--r--src/eap_server/tncs.h49
-rw-r--r--src/eapol_supp/.gitignore1
-rw-r--r--src/eapol_supp/Makefile9
-rw-r--r--src/eapol_supp/eapol_supp_sm.c1871
-rw-r--r--src/eapol_supp/eapol_supp_sm.h342
-rw-r--r--src/hlr_auc_gw/.gitignore1
-rw-r--r--src/hlr_auc_gw/Makefile9
-rw-r--r--src/hlr_auc_gw/hlr_auc_gw.c (renamed from contrib/hostapd/hlr_auc_gw.c)242
-rw-r--r--src/hlr_auc_gw/hlr_auc_gw.milenage_db (renamed from contrib/hostapd/hlr_auc_gw.milenage_db)4
-rw-r--r--src/hlr_auc_gw/milenage.c (renamed from contrib/hostapd/milenage.c)177
-rw-r--r--src/hlr_auc_gw/milenage.h (renamed from contrib/hostapd/milenage.h)9
-rw-r--r--src/l2_packet/.gitignore1
-rw-r--r--src/l2_packet/Makefile9
-rw-r--r--src/l2_packet/l2_packet.h (renamed from contrib/hostapd/l2_packet.h)13
-rw-r--r--src/l2_packet/l2_packet_freebsd.c285
-rw-r--r--src/l2_packet/l2_packet_linux.c199
-rw-r--r--src/l2_packet/l2_packet_ndis.c516
-rw-r--r--src/l2_packet/l2_packet_none.c (renamed from contrib/hostapd/l2_packet_none.c)2
-rw-r--r--src/l2_packet/l2_packet_pcap.c386
-rw-r--r--src/l2_packet/l2_packet_privsep.c267
-rw-r--r--src/l2_packet/l2_packet_winpcap.c341
-rw-r--r--src/radius/.gitignore1
-rw-r--r--src/radius/Makefile9
-rw-r--r--src/radius/radius.c (renamed from contrib/hostapd/radius.c)136
-rw-r--r--src/radius/radius.h (renamed from contrib/hostapd/radius.h)21
-rw-r--r--src/radius/radius_client.c (renamed from contrib/hostapd/radius_client.c)84
-rw-r--r--src/radius/radius_client.h (renamed from contrib/hostapd/radius_client.h)7
-rw-r--r--src/radius/radius_server.c (renamed from contrib/hostapd/radius_server.c)491
-rw-r--r--src/radius/radius_server.h (renamed from contrib/hostapd/radius_server.h)19
-rw-r--r--src/rsn_supp/.gitignore1
-rw-r--r--src/rsn_supp/Makefile9
-rw-r--r--src/rsn_supp/peerkey.c1182
-rw-r--r--src/rsn_supp/peerkey.h87
-rw-r--r--src/rsn_supp/pmksa_cache.c511
-rw-r--r--src/rsn_supp/pmksa_cache.h126
-rw-r--r--src/rsn_supp/preauth.c529
-rw-r--r--src/rsn_supp/preauth.h78
-rw-r--r--src/rsn_supp/wpa.c2387
-rw-r--r--src/rsn_supp/wpa.h320
-rw-r--r--src/rsn_supp/wpa_ft.c871
-rw-r--r--src/rsn_supp/wpa_i.h245
-rw-r--r--src/rsn_supp/wpa_ie.c536
-rw-r--r--src/rsn_supp/wpa_ie.h52
-rw-r--r--src/tls/.gitignore1
-rw-r--r--src/tls/Makefile9
-rw-r--r--src/tls/asn1.c209
-rw-r--r--src/tls/asn1.h71
-rw-r--r--src/tls/asn1_test.c210
-rw-r--r--src/tls/bignum.c230
-rw-r--r--src/tls/bignum.h38
-rw-r--r--src/tls/libtommath.c3381
-rw-r--r--src/tls/rsa.c359
-rw-r--r--src/tls/rsa.h29
-rw-r--r--src/tls/tlsv1_client.c660
-rw-r--r--src/tls/tlsv1_client.h59
-rw-r--r--src/tls/tlsv1_client_i.h87
-rw-r--r--src/tls/tlsv1_client_read.c976
-rw-r--r--src/tls/tlsv1_client_write.c802
-rw-r--r--src/tls/tlsv1_common.c241
-rw-r--r--src/tls/tlsv1_common.h216
-rw-r--r--src/tls/tlsv1_cred.c422
-rw-r--r--src/tls/tlsv1_cred.h46
-rw-r--r--src/tls/tlsv1_record.c409
-rw-r--r--src/tls/tlsv1_record.h74
-rw-r--r--src/tls/tlsv1_server.c596
-rw-r--r--src/tls/tlsv1_server.h54
-rw-r--r--src/tls/tlsv1_server_i.h77
-rw-r--r--src/tls/tlsv1_server_read.c1142
-rw-r--r--src/tls/tlsv1_server_write.c796
-rw-r--r--src/tls/x509v3.c1724
-rw-r--r--src/tls/x509v3.h154
-rw-r--r--src/utils/.gitignore1
-rw-r--r--src/utils/Makefile9
-rw-r--r--src/utils/base64.c187
-rw-r--r--src/utils/base64.h23
-rw-r--r--src/utils/build_config.h (renamed from contrib/hostapd/build_config.h)45
-rw-r--r--src/utils/common.c (renamed from contrib/hostapd/common.c)290
-rw-r--r--src/utils/common.h (renamed from contrib/hostapd/common.h)470
-rw-r--r--src/utils/eloop.c (renamed from contrib/hostapd/eloop.c)50
-rw-r--r--src/utils/eloop.h (renamed from contrib/hostapd/eloop.h)13
-rw-r--r--src/utils/eloop_none.c (renamed from contrib/hostapd/eloop_none.c)20
-rw-r--r--src/utils/eloop_win.c (renamed from contrib/hostapd/eloop_win.c)22
-rw-r--r--src/utils/includes.h (renamed from contrib/hostapd/includes.h)4
-rw-r--r--src/utils/ip_addr.c83
-rw-r--r--src/utils/ip_addr.h (renamed from contrib/hostapd/config_types.h)15
-rw-r--r--src/utils/os.h (renamed from contrib/hostapd/os.h)13
-rw-r--r--src/utils/os_internal.c (renamed from contrib/hostapd/os_internal.c)25
-rw-r--r--src/utils/os_none.c (renamed from contrib/hostapd/os_none.c)6
-rw-r--r--src/utils/os_unix.c (renamed from contrib/hostapd/os_unix.c)75
-rw-r--r--src/utils/os_win32.c222
-rw-r--r--src/utils/pcsc_funcs.c1238
-rw-r--r--src/utils/pcsc_funcs.h68
-rw-r--r--src/utils/state_machine.h (renamed from contrib/hostapd/state_machine.h)6
-rw-r--r--src/utils/uuid.c107
-rw-r--r--src/utils/uuid.h25
-rw-r--r--src/utils/wpa_debug.c326
-rw-r--r--src/utils/wpa_debug.h223
-rw-r--r--src/utils/wpabuf.c212
-rw-r--r--src/utils/wpabuf.h156
-rw-r--r--src/wps/.gitignore1
-rw-r--r--src/wps/Makefile9
-rw-r--r--src/wps/httpread.c858
-rw-r--r--src/wps/httpread.h123
-rw-r--r--src/wps/wps.c335
-rw-r--r--src/wps/wps.h518
-rw-r--r--src/wps/wps_attr_build.c254
-rw-r--r--src/wps/wps_attr_parse.c429
-rw-r--r--src/wps/wps_attr_process.c323
-rw-r--r--src/wps/wps_common.c337
-rw-r--r--src/wps/wps_defs.h297
-rw-r--r--src/wps/wps_dev_attr.c390
-rw-r--r--src/wps/wps_dev_attr.h33
-rw-r--r--src/wps/wps_enrollee.c1174
-rw-r--r--src/wps/wps_i.h248
-rw-r--r--src/wps/wps_registrar.c2448
-rw-r--r--src/wps/wps_upnp.c1056
-rw-r--r--src/wps/wps_upnp.h67
-rw-r--r--src/wps/wps_upnp_event.c534
-rw-r--r--src/wps/wps_upnp_i.h193
-rw-r--r--src/wps/wps_upnp_ssdp.c886
-rw-r--r--src/wps/wps_upnp_web.c1964
-rw-r--r--wpa_supplicant/.gitignore8
-rw-r--r--wpa_supplicant/ChangeLog1173
-rw-r--r--wpa_supplicant/Makefile1246
-rw-r--r--wpa_supplicant/README1028
-rw-r--r--wpa_supplicant/README-WPS184
-rw-r--r--wpa_supplicant/README-Windows.txt450
-rw-r--r--wpa_supplicant/blacklist.c133
-rw-r--r--wpa_supplicant/blacklist.h30
-rw-r--r--wpa_supplicant/config.c1978
-rw-r--r--wpa_supplicant/config.h392
-rw-r--r--wpa_supplicant/config_file.c942
-rw-r--r--wpa_supplicant/config_none.c57
-rw-r--r--wpa_supplicant/config_ssid.h347
-rw-r--r--wpa_supplicant/config_winreg.c980
-rw-r--r--wpa_supplicant/ctrl_iface.c1875
-rw-r--r--wpa_supplicant/ctrl_iface.h159
-rw-r--r--wpa_supplicant/ctrl_iface_dbus.c1115
-rw-r--r--wpa_supplicant/ctrl_iface_dbus.h156
-rw-r--r--wpa_supplicant/ctrl_iface_dbus_handlers.c1410
-rw-r--r--wpa_supplicant/ctrl_iface_dbus_handlers.h86
-rw-r--r--wpa_supplicant/ctrl_iface_named_pipe.c835
-rw-r--r--wpa_supplicant/ctrl_iface_udp.c561
-rw-r--r--wpa_supplicant/ctrl_iface_unix.c699
-rw-r--r--wpa_supplicant/dbus-wpa_supplicant.conf16
-rw-r--r--wpa_supplicant/dbus-wpa_supplicant.service4
-rw-r--r--wpa_supplicant/dbus_dict_helpers.c976
-rw-r--r--wpa_supplicant/dbus_dict_helpers.h135
-rw-r--r--wpa_supplicant/defconfig382
-rw-r--r--wpa_supplicant/doc/.gitignore4
-rw-r--r--wpa_supplicant/doc/code_structure.doxygen322
-rw-r--r--wpa_supplicant/doc/ctrl_iface.doxygen481
-rw-r--r--wpa_supplicant/doc/docbook/.gitignore6
-rw-r--r--wpa_supplicant/doc/docbook/Makefile27
-rw-r--r--wpa_supplicant/doc/docbook/manpage.links0
-rw-r--r--wpa_supplicant/doc/docbook/manpage.refs4
-rw-r--r--wpa_supplicant/doc/docbook/wpa_background.884
-rw-r--r--wpa_supplicant/doc/docbook/wpa_background.sgml101
-rw-r--r--wpa_supplicant/doc/docbook/wpa_cli.8210
-rw-r--r--wpa_supplicant/doc/docbook/wpa_cli.sgml339
-rw-r--r--wpa_supplicant/doc/docbook/wpa_gui.851
-rw-r--r--wpa_supplicant/doc/docbook/wpa_gui.sgml85
-rw-r--r--wpa_supplicant/doc/docbook/wpa_passphrase.840
-rw-r--r--wpa_supplicant/doc/docbook/wpa_passphrase.sgml73
-rw-r--r--wpa_supplicant/doc/docbook/wpa_priv.8120
-rw-r--r--wpa_supplicant/doc/docbook/wpa_priv.sgml148
-rw-r--r--wpa_supplicant/doc/docbook/wpa_supplicant.8571
-rw-r--r--wpa_supplicant/doc/docbook/wpa_supplicant.conf.5225
-rw-r--r--wpa_supplicant/doc/docbook/wpa_supplicant.conf.sgml239
-rw-r--r--wpa_supplicant/doc/docbook/wpa_supplicant.sgml818
-rw-r--r--wpa_supplicant/doc/doxygen.fast239
-rw-r--r--wpa_supplicant/doc/doxygen.full239
-rw-r--r--wpa_supplicant/doc/driver_wrapper.doxygen180
-rw-r--r--wpa_supplicant/doc/eap.doxygen87
-rwxr-xr-xwpa_supplicant/doc/kerneldoc2doxygen.pl134
-rw-r--r--wpa_supplicant/doc/mainpage.doxygen56
-rw-r--r--wpa_supplicant/doc/porting.doxygen208
-rw-r--r--wpa_supplicant/doc/testing_tools.doxygen295
-rw-r--r--wpa_supplicant/doc/wpa_supplicant.fig247
-rw-r--r--wpa_supplicant/eap_testing.txt392
-rw-r--r--wpa_supplicant/eapol_test.c1216
-rw-r--r--wpa_supplicant/events.c1116
-rw-r--r--wpa_supplicant/examples/ieee8021x.conf13
-rw-r--r--wpa_supplicant/examples/openCryptoki.conf41
-rw-r--r--wpa_supplicant/examples/plaintext.conf8
-rw-r--r--wpa_supplicant/examples/wep.conf11
-rw-r--r--wpa_supplicant/examples/wpa-psk-tkip.conf12
-rw-r--r--wpa_supplicant/examples/wpa2-eap-ccmp.conf15
-rwxr-xr-xwpa_supplicant/examples/wpas-test.py91
-rw-r--r--wpa_supplicant/main.c264
-rw-r--r--wpa_supplicant/main_none.c46
-rw-r--r--wpa_supplicant/main_symbian.cpp48
-rw-r--r--wpa_supplicant/main_winmain.c84
-rw-r--r--wpa_supplicant/main_winsvc.c464
-rw-r--r--wpa_supplicant/mlme.c2994
-rw-r--r--wpa_supplicant/mlme.h132
-rw-r--r--wpa_supplicant/nmake.mak228
-rw-r--r--wpa_supplicant/preauth_test.c375
-rw-r--r--wpa_supplicant/scan.c263
-rw-r--r--wpa_supplicant/symbian/README.symbian24
-rw-r--r--wpa_supplicant/symbian/bld.inf8
-rw-r--r--wpa_supplicant/symbian/wpa_supplicant.mmp38
-rw-r--r--wpa_supplicant/tests/link_test.c83
-rw-r--r--wpa_supplicant/tests/test_aes.c307
-rw-r--r--wpa_supplicant/tests/test_eap_sim_common.c53
-rw-r--r--wpa_supplicant/tests/test_md4.c99
-rw-r--r--wpa_supplicant/tests/test_md5.c99
-rw-r--r--wpa_supplicant/tests/test_ms_funcs.c119
-rw-r--r--wpa_supplicant/tests/test_sha1.c347
-rw-r--r--wpa_supplicant/tests/test_sha256.c331
-rw-r--r--wpa_supplicant/tests/test_wpa.c394
-rw-r--r--wpa_supplicant/tests/test_x509v3.c69
-rwxr-xr-xwpa_supplicant/tests/test_x509v3_nist.sh144
-rwxr-xr-xwpa_supplicant/tests/test_x509v3_nist2.sh165
-rw-r--r--wpa_supplicant/todo.txt92
-rwxr-xr-xwpa_supplicant/vs2005/eapol_test/eapol_test.vcproj425
-rwxr-xr-xwpa_supplicant/vs2005/win_if_list/win_if_list.vcproj203
-rwxr-xr-xwpa_supplicant/vs2005/wpa_cli/wpa_cli.vcproj215
-rwxr-xr-xwpa_supplicant/vs2005/wpa_passphrase/wpa_passphrase.vcproj220
-rwxr-xr-xwpa_supplicant/vs2005/wpa_supplicant.sln52
-rwxr-xr-xwpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj421
-rwxr-xr-xwpa_supplicant/vs2005/wpasvc/wpasvc.vcproj421
-rwxr-xr-xwpa_supplicant/win_example.reg42
-rw-r--r--wpa_supplicant/win_if_list.c179
-rw-r--r--wpa_supplicant/wpa_cli.c1921
-rw-r--r--wpa_supplicant/wpa_gui-qt4/.gitignore6
-rw-r--r--wpa_supplicant/wpa_gui-qt4/addinterface.cpp245
-rw-r--r--wpa_supplicant/wpa_gui-qt4/addinterface.h45
-rw-r--r--wpa_supplicant/wpa_gui-qt4/eventhistory.cpp130
-rw-r--r--wpa_supplicant/wpa_gui-qt4/eventhistory.h63
-rw-r--r--wpa_supplicant/wpa_gui-qt4/eventhistory.ui61
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons.qrc5
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/Makefile27
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/README7
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons/wpa_gui.svg256
-rw-r--r--wpa_supplicant/wpa_gui-qt4/icons_png.qrc5
-rw-r--r--wpa_supplicant/wpa_gui-qt4/main.cpp66
-rw-r--r--wpa_supplicant/wpa_gui-qt4/networkconfig.cpp823
-rw-r--r--wpa_supplicant/wpa_gui-qt4/networkconfig.h61
-rw-r--r--wpa_supplicant/wpa_gui-qt4/networkconfig.ui425
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresults.cpp144
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresults.h46
-rw-r--r--wpa_supplicant/wpa_gui-qt4/scanresults.ui94
-rw-r--r--wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp100
-rw-r--r--wpa_supplicant/wpa_gui-qt4/userdatarequest.h46
-rw-r--r--wpa_supplicant/wpa_gui-qt4/userdatarequest.ui109
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop10
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpa_gui.pro62
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpagui.cpp1699
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpagui.h145
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpagui.ui517
-rw-r--r--wpa_supplicant/wpa_gui-qt4/wpamsg.h41
-rw-r--r--wpa_supplicant/wpa_gui/.gitignore5
-rw-r--r--wpa_supplicant/wpa_gui/eventhistory.ui125
-rw-r--r--wpa_supplicant/wpa_gui/eventhistory.ui.h41
-rw-r--r--wpa_supplicant/wpa_gui/main.cpp30
-rw-r--r--wpa_supplicant/wpa_gui/networkconfig.ui475
-rw-r--r--wpa_supplicant/wpa_gui/networkconfig.ui.h552
-rw-r--r--wpa_supplicant/wpa_gui/scanresults.ui179
-rw-r--r--wpa_supplicant/wpa_gui/scanresults.ui.h101
-rwxr-xr-xwpa_supplicant/wpa_gui/setup-mingw-cross-compiling11
-rw-r--r--wpa_supplicant/wpa_gui/userdatarequest.ui163
-rw-r--r--wpa_supplicant/wpa_gui/userdatarequest.ui.h72
-rw-r--r--wpa_supplicant/wpa_gui/wpa_gui.pro50
-rw-r--r--wpa_supplicant/wpa_gui/wpagui.ui471
-rw-r--r--wpa_supplicant/wpa_gui/wpagui.ui.h730
-rw-r--r--wpa_supplicant/wpa_gui/wpamsg.h34
-rw-r--r--wpa_supplicant/wpa_passphrase.c73
-rw-r--r--wpa_supplicant/wpa_priv.c1220
-rw-r--r--wpa_supplicant/wpa_supplicant.c2170
-rw-r--r--wpa_supplicant/wpa_supplicant.conf840
-rw-r--r--wpa_supplicant/wpa_supplicant.nsi108
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h763
-rw-r--r--wpa_supplicant/wpas_glue.c642
-rw-r--r--wpa_supplicant/wpas_glue.h23
-rw-r--r--wpa_supplicant/wps_supplicant.c770
-rw-r--r--wpa_supplicant/wps_supplicant.h95
587 files changed, 187752 insertions, 16595 deletions
diff --git a/contrib/hostapd/COPYING b/COPYING
index 14f5453722a8..14f5453722a8 100644
--- a/contrib/hostapd/COPYING
+++ b/COPYING
diff --git a/README b/README
new file mode 100644
index 000000000000..9c6be85d9ea3
--- /dev/null
+++ b/README
@@ -0,0 +1,19 @@
+wpa_supplicant and hostapd v0.6.x
+---------------------------------
+
+Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> and contributors
+All Rights Reserved.
+
+These program is dual-licensed under both the GPL version 2 and BSD
+license. Either license may be used at your option.
+
+
+This package may include either wpa_supplicant, hostapd, or both. See
+README file respective subdirectories (wpa_supplicant/README or
+hostapd/README) for more details.
+
+Source code files have been moved around in v0.6.x releases and
+compared to earlier releases, the programs are now build by first
+going to a subdirectory (wpa_supplicant or hostapd) and creating
+build configuration (.config) and running 'make' there (for
+Linux/BSD/cygwin builds).
diff --git a/contrib/hostapd/FREEBSD-Xlist b/contrib/hostapd/FREEBSD-Xlist
deleted file mode 100644
index 1f544522a1b5..000000000000
--- a/contrib/hostapd/FREEBSD-Xlist
+++ /dev/null
@@ -1,17 +0,0 @@
-$FreeBSD$
-.cvsignore
-driver.c
-driver_bsd.c
-driver_devicescape.c
-driver_madwifi.c
-driver_prism54.c
-l2_packet_freebsd.c
-l2_packet_linux.c
-l2_packet_ndis.c
-l2_packet_pcap.c
-l2_packet_winpcap.c
-nt_password_hash.c
-os_win32.c
-prism54.h
-priv_netlink.h
-wireless_copy.h
diff --git a/contrib/hostapd/FREEBSD-upgrade b/contrib/hostapd/FREEBSD-upgrade
deleted file mode 100644
index 08922051fe55..000000000000
--- a/contrib/hostapd/FREEBSD-upgrade
+++ /dev/null
@@ -1,24 +0,0 @@
-$FreeBSD$
-
-WPA/802.1x Authenticator
- originals can be found at: http://hostap.epitest.fi/releases/
-
-
-For the import files and directories were pruned by:
-
- tar -X FREEBSD-Xlist -zxf hostapd-0.5.8.tar.gz
-
-then imported by:
-
- cvs import -m 'Import of hostapd 0.5.8' \
- src/contrib/hostapd MALINEN v0_5_8
-
-To make local changes to hostapd, simply patch and commit to the
-main branch (aka HEAD). Never make local changes on the vendor
-(MALINEN) branch.
-
-All local changes should be submitted to Jouni Malinen for inclusion in
-the next vendor release.
-
-sam@FreeBSD.org
-7-July-2007
diff --git a/contrib/hostapd/Makefile b/contrib/hostapd/Makefile
deleted file mode 100644
index 4fadede02057..000000000000
--- a/contrib/hostapd/Makefile
+++ /dev/null
@@ -1,444 +0,0 @@
-CC=gcc
-DIR_WPA_SUPPLICANT=.
-
-ifndef CFLAGS
-CFLAGS = -MMD -O2 -Wall -g
-endif
-
-# 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
-
-# Include directories for CVS version
-CFLAGS += -I. -I../utils -I$(DIR_WPA_SUPPLICANT)
-
-# 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 = hostapd.o eloop.o ieee802_1x.o eapol_sm.o radius.o md5.o rc4.o md4.o \
- common.o ieee802_11.o config.o ieee802_11_auth.o accounting.o \
- sta_info.o radius_client.o sha1.o wpa.o aes_wrap.o ctrl_iface.o \
- driver_conf.o os_$(CONFIG_OS).o preauth.o pmksa_cache.o beacon.o \
- hw_features.o wme.o ap_list.o reconfig.o \
- mlme.o vlan_init.o ieee802_11h.o
-
-HOBJS=hlr_auc_gw.o common.o os_$(CONFIG_OS).o milenage.o aes_wrap.o
-
-CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
-
-ifdef CONFIG_IAPP
-CFLAGS += -DCONFIG_IAPP
-OBJS += iapp.o
-endif
-
-ifdef CONFIG_RSN_PREAUTH
-CFLAGS += -DCONFIG_RSN_PREAUTH
-CONFIG_L2_PACKET=y
-endif
-
-ifdef CONFIG_PEERKEY
-CFLAGS += -DCONFIG_PEERKEY
-endif
-
-ifdef CONFIG_IEEE80211W
-CFLAGS += -DCONFIG_IEEE80211W
-NEED_SHA256=y
-endif
-
-ifdef CONFIG_DRIVER_HOSTAP
-CFLAGS += -DCONFIG_DRIVER_HOSTAP
-OBJS += driver.o
-endif
-
-ifdef CONFIG_DRIVER_WIRED
-CFLAGS += -DCONFIG_DRIVER_WIRED
-OBJS += driver_wired.o
-endif
-
-ifdef CONFIG_DRIVER_MADWIFI
-CFLAGS += -DCONFIG_DRIVER_MADWIFI
-OBJS += driver_madwifi.o
-CONFIG_L2_PACKET=y
-endif
-
-ifdef CONFIG_DRIVER_PRISM54
-CFLAGS += -DCONFIG_DRIVER_PRISM54
-OBJS += driver_prism54.o
-endif
-
-ifdef CONFIG_DRIVER_DEVICESCAPE
-CFLAGS += -DCONFIG_DRIVER_DEVICESCAPE
-OBJS += driver_devicescape.o
-endif
-
-ifdef CONFIG_DRIVER_BSD
-CFLAGS += -DCONFIG_DRIVER_BSD
-OBJS += driver_bsd.o
-CONFIG_L2_PACKET=y
-CONFIG_DNET_PCAP=y
-CONFIG_L2_FREEBSD=y
-endif
-
-ifdef CONFIG_DRIVER_TEST
-CFLAGS += -DCONFIG_DRIVER_TEST
-OBJS += driver_test.o
-endif
-
-ifdef CONFIG_L2_PACKET
-ifdef CONFIG_DNET_PCAP
-ifdef CONFIG_L2_FREEBSD
-LIBS += -lpcap
-OBJS += $(DIR_WPA_SUPPLICANT)/l2_packet_freebsd.o
-else
-LIBS += -ldnet -lpcap
-OBJS += $(DIR_WPA_SUPPLICANT)/l2_packet_pcap.o
-endif
-else
-OBJS += $(DIR_WPA_SUPPLICANT)/l2_packet_linux.o
-endif
-endif
-
-
-ifdef CONFIG_EAP_MD5
-CFLAGS += -DEAP_MD5
-OBJS += eap_md5.o
-endif
-
-ifdef CONFIG_EAP_TLS
-CFLAGS += -DEAP_TLS
-OBJS += eap_tls.o
-TLS_FUNCS=y
-endif
-
-ifdef CONFIG_EAP_PEAP
-CFLAGS += -DEAP_PEAP
-OBJS += eap_peap.o
-TLS_FUNCS=y
-CONFIG_EAP_TLV=y
-CONFIG_EAP_MSCHAPV2=y
-endif
-
-ifdef CONFIG_EAP_TTLS
-CFLAGS += -DEAP_TTLS
-OBJS += eap_ttls.o
-TLS_FUNCS=y
-endif
-
-ifdef CONFIG_EAP_MSCHAPV2
-CFLAGS += -DEAP_MSCHAPv2
-OBJS += eap_mschapv2.o
-MS_FUNCS=y
-endif
-
-ifdef CONFIG_EAP_GTC
-CFLAGS += -DEAP_GTC
-OBJS += eap_gtc.o
-endif
-
-ifdef CONFIG_EAP_SIM
-CFLAGS += -DEAP_SIM
-OBJS += eap_sim.o
-CONFIG_EAP_SIM_COMMON=y
-endif
-
-ifdef CONFIG_EAP_AKA
-CFLAGS += -DEAP_AKA
-OBJS += eap_aka.o
-CONFIG_EAP_SIM_COMMON=y
-endif
-
-ifdef CONFIG_EAP_SIM_COMMON
-OBJS += $(DIR_WPA_SUPPLICANT)/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 += eap_sim_db.o
-endif
-
-ifdef CONFIG_EAP_PAX
-CFLAGS += -DEAP_PAX
-OBJS += eap_pax.o $(DIR_WPA_SUPPLICANT)/eap_pax_common.o
-endif
-
-ifdef CONFIG_EAP_PSK
-CFLAGS += -DEAP_PSK
-OBJS += eap_psk.o $(DIR_WPA_SUPPLICANT)/eap_psk_common.o
-endif
-
-ifdef CONFIG_EAP_SAKE
-CFLAGS += -DEAP_SAKE
-OBJS += eap_sake.o $(DIR_WPA_SUPPLICANT)/eap_sake_common.o
-endif
-
-ifdef CONFIG_EAP_GPSK
-CFLAGS += -DEAP_GPSK
-OBJS += eap_gpsk.o $(DIR_WPA_SUPPLICANT)/eap_gpsk_common.o
-ifdef CONFIG_EAP_GPSK_SHA256
-CFLAGS += -DEAP_GPSK_SHA256
-NEED_SHA256=y
-endif
-endif
-
-ifdef CONFIG_EAP_VENDOR_TEST
-CFLAGS += -DEAP_VENDOR_TEST
-OBJS += eap_vendor_test.o
-endif
-
-ifdef CONFIG_EAP_TLV
-CFLAGS += -DEAP_TLV
-OBJS += eap_tlv.o
-endif
-
-ifdef CONFIG_EAP
-CFLAGS += -DEAP_SERVER
-OBJS += eap.o eap_methods.o eap_identity.o
-endif
-
-ifndef CONFIG_TLS
-CONFIG_TLS=openssl
-endif
-
-ifdef TLS_FUNCS
-# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
-CFLAGS += -DEAP_TLS_FUNCS
-OBJS += eap_tls_common.o
-ifeq ($(CONFIG_TLS), openssl)
-OBJS += $(DIR_WPA_SUPPLICANT)/tls_openssl.o
-LIBS += -lssl -lcrypto
-LIBS_p += -lcrypto
-LIBS_h += -lcrypto
-endif
-ifeq ($(CONFIG_TLS), gnutls)
-OBJS += $(DIR_WPA_SUPPLICANT)/tls_gnutls.o
-LIBS += -lgnutls -lgcrypt -lgpg-error
-LIBS_p += -lgcrypt
-LIBS_h += -lgcrypt
-endif
-ifdef CONFIG_GNUTLS_EXTRA
-CFLAGS += -DCONFIG_GNUTLS_EXTRA
-LIBS += -lgnutls-extra
-endif
-NEED_CRYPTO=y
-else
-OBJS += $(DIR_WPA_SUPPLICANT)/tls_none.o
-endif
-
-ifdef CONFIG_PKCS12
-CFLAGS += -DPKCS12_FUNCS
-endif
-
-ifdef MS_FUNCS
-OBJS += $(DIR_WPA_SUPPLICANT)/ms_funcs.o
-NEED_CRYPTO=y
-endif
-
-ifdef NEED_CRYPTO
-ifndef TLS_FUNCS
-ifeq ($(CONFIG_TLS), openssl)
-LIBS += -lcrypto
-LIBS_p += -lcrypto
-LIBS_h += -lcrypto
-endif
-ifeq ($(CONFIG_TLS), gnutls)
-LIBS += -lgcrypt
-LIBS_p += -lgcrypt
-LIBS_h += -lgcrypt
-endif
-endif
-ifeq ($(CONFIG_TLS), openssl)
-OBJS += $(DIR_WPA_SUPPLICANT)/crypto.o
-OBJS_p += $(DIR_WPA_SUPPLICANT)/crypto.o
-HOBJS += $(DIR_WPA_SUPPLICANT)/crypto.o
-CONFIG_INTERNAL_SHA256=y
-endif
-ifeq ($(CONFIG_TLS), gnutls)
-OBJS += $(DIR_WPA_SUPPLICANT)/crypto_gnutls.o
-OBJS_p += $(DIR_WPA_SUPPLICANT)/crypto_gnutls.o
-HOBJS += $(DIR_WPA_SUPPLICANT)/crypto_gnutls.o
-CONFIG_INTERNAL_SHA256=y
-endif
-else
-CONFIG_INTERNAL_AES=y
-CONFIG_INTERNAL_SHA1=y
-CONFIG_INTERNAL_MD5=y
-CONFIG_INTERNAL_SHA256=y
-endif
-
-ifdef CONFIG_INTERNAL_AES
-CFLAGS += -DINTERNAL_AES
-endif
-ifdef CONFIG_INTERNAL_SHA1
-CFLAGS += -DINTERNAL_SHA1
-endif
-ifdef CONFIG_INTERNAL_SHA256
-CFLAGS += -DINTERNAL_SHA256
-endif
-ifdef CONFIG_INTERNAL_MD5
-CFLAGS += -DINTERNAL_MD5
-endif
-ifdef CONFIG_INTERNAL_MD4
-CFLAGS += -DINTERNAL_MD4
-endif
-
-ifdef NEED_SHA256
-OBJS += sha256.o
-endif
-
-ifdef CONFIG_RADIUS_SERVER
-CFLAGS += -DRADIUS_SERVER
-OBJS += 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
-
-ALL=hostapd hostapd_cli
-
-all: verify_config $(ALL)
-
-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 $$i /usr/local/bin/$$i; done
-
-hostapd: $(OBJS)
- $(CC) -o hostapd $(OBJS) $(LIBS)
-
-driver_conf.c: Makefile .config
- rm -f driver_conf.c
- echo '/* THIS FILE AUTOMATICALLY GENERATED, DO NOT EDIT! */' \
- > driver_conf.c
- echo '#include "includes.h"' >> driver_conf.c
- echo '#include "hostapd.h"' >> driver_conf.c
- echo '#include "driver.h"' >> driver_conf.c
-ifdef CONFIG_DRIVER_HOSTAP
- echo "void hostap_driver_register(void);" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_WIRED
- echo "void wired_driver_register(void);" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_MADWIFI
- echo "void madwifi_driver_register(void);" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_PRISM54
- echo "void prism54_driver_register(void);" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_DEVICESCAPE
- echo "void devicescape_driver_register(void);" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_BSD
- echo "void bsd_driver_register(void);" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_TEST
- echo "void test_driver_register(void);" >> driver_conf.c
-endif
- echo 'void register_drivers(void) {' >> driver_conf.c
-ifdef CONFIG_DRIVER_HOSTAP
- echo "hostap_driver_register();" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_WIRED
- echo "wired_driver_register();" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_MADWIFI
- echo "madwifi_driver_register();" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_PRISM54
- echo "prism54_driver_register();" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_DEVICESCAPE
- echo "devicescape_driver_register();" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_BSD
- echo "bsd_driver_register();" >> driver_conf.c
-endif
-ifdef CONFIG_DRIVER_TEST
- echo "test_driver_register();" >> driver_conf.c
-endif
- echo '}' >> driver_conf.c
-
-hostapd_cli: hostapd_cli.o $(DIR_WPA_SUPPLICANT)/wpa_ctrl.o
- $(CC) -o hostapd_cli hostapd_cli.o $(DIR_WPA_SUPPLICANT)/wpa_ctrl.o
-
-NOBJS = nt_password_hash.o $(DIR_WPA_SUPPLICANT)/ms_funcs.o sha1.o rc4.o md5.o
-NOBJS += $(DIR_WPA_SUPPLICANT)/crypto.o os_$(CONFIG_OS).o
-ifdef TLS_FUNCS
-LIBS_n += -lcrypto
-endif
-
-nt_password_hash: $(NOBJS)
- $(CC) -o nt_password_hash $(NOBJS) $(LIBS_n)
-
-hlr_auc_gw: $(HOBJS)
- $(CC) -o hlr_auc_gw $(HOBJS) $(LIBS_h)
-
-clean:
- rm -f core *~ *.o hostapd hostapd_cli nt_password_hash hlr_auc_gw
- rm -f *.d driver_conf.c
-
-%.eps: %.fig
- fig2dev -L eps $*.fig $*.eps
-
-%.png: %.fig
- fig2dev -L png -m 3 $*.fig | pngtopnm | pnmscale 0.4 | pnmtopng \
- > $*.png
-
-docs-pics: doc/hostapd.png doc/hostapd.eps
-
-docs: docs-pics
- doxygen doc/doxygen.full
- $(MAKE) -C doc/latex
- cp doc/latex/refman.pdf hostapd-devel.pdf
-
-docs-fast: docs-pics
- doxygen doc/doxygen.fast
-
-clean-docs:
- rm -rf doc/latex doc/html
- rm -f doc/hosta.d{eps,png} hostapd-devel.pdf
-
-TEST_SRC_MILENAGE = milenage.c aes_wrap.c common.c os_$(CONFIG_OS).c
-test-milenage: $(TEST_SRC_MILENAGE)
- $(CC) -o test-milenage -Wall -Werror $(TEST_SRC_MILENAGE) \
- -DTEST_MAIN_MILENAGE -I. -I../wpa_supplicant -DINTERNAL_AES
- ./test-milenage
- rm test-milenage
-
--include $(OBJS:%.o=%.d)
diff --git a/contrib/hostapd/aes_wrap.h b/contrib/hostapd/aes_wrap.h
deleted file mode 100644
index 5eb4342a5bf9..000000000000
--- a/contrib/hostapd/aes_wrap.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * AES-based functions
- *
- * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
- * - One-Key CBC MAC (OMAC1) hash with AES-128
- * - AES-128 CTR mode encryption
- * - AES-128 EAX mode encryption/decryption
- * - AES-128 CBC
- *
- * Copyright (c) 2003-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.
- */
-
-#ifndef AES_WRAP_H
-#define AES_WRAP_H
-
-int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher);
-int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain);
-int omac1_aes_128_vector(const u8 *key, size_t num_elem,
- const u8 *addr[], const size_t *len, u8 *mac);
-int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac);
-int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
-int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
- u8 *data, size_t data_len);
-int aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
- const u8 *hdr, size_t hdr_len,
- u8 *data, size_t data_len, u8 *tag);
-int aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
- const u8 *hdr, size_t hdr_len,
- u8 *data, size_t data_len, const u8 *tag);
-int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data,
- size_t data_len);
-int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
- size_t data_len);
-
-#endif /* AES_WRAP_H */
diff --git a/contrib/hostapd/config.c b/contrib/hostapd/config.c
deleted file mode 100644
index d1b2ba3fa5e0..000000000000
--- a/contrib/hostapd/config.c
+++ /dev/null
@@ -1,1994 +0,0 @@
-/*
- * hostapd / Configuration file
- * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-#ifndef CONFIG_NATIVE_WINDOWS
-#include <grp.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-#include "hostapd.h"
-#include "driver.h"
-#include "sha1.h"
-#include "eap.h"
-#include "radius_client.h"
-#include "wpa_common.h"
-
-
-#define MAX_STA_COUNT 2007
-
-
-static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
- const char *fname)
-{
- FILE *f;
- char buf[128], *pos, *pos2;
- int line = 0, vlan_id;
- struct hostapd_vlan *vlan;
-
- f = fopen(fname, "r");
- if (!f) {
- printf("VLAN file '%s' not readable.\n", fname);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- if (buf[0] == '*') {
- vlan_id = VLAN_ID_WILDCARD;
- pos = buf + 1;
- } else {
- vlan_id = strtol(buf, &pos, 10);
- if (buf == pos || vlan_id < 1 ||
- vlan_id > MAX_VLAN_ID) {
- printf("Invalid VLAN ID at line %d in '%s'\n",
- line, fname);
- fclose(f);
- return -1;
- }
- }
-
- while (*pos == ' ' || *pos == '\t')
- pos++;
- pos2 = pos;
- while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0')
- pos2++;
- *pos2 = '\0';
- if (*pos == '\0' || strlen(pos) > IFNAMSIZ) {
- printf("Invalid VLAN ifname at line %d in '%s'\n",
- line, fname);
- fclose(f);
- return -1;
- }
-
- vlan = malloc(sizeof(*vlan));
- if (vlan == NULL) {
- printf("Out of memory while reading VLAN interfaces "
- "from '%s'\n", fname);
- fclose(f);
- return -1;
- }
-
- memset(vlan, 0, sizeof(*vlan));
- vlan->vlan_id = vlan_id;
- strncpy(vlan->ifname, pos, sizeof(vlan->ifname));
- if (bss->vlan_tail)
- bss->vlan_tail->next = vlan;
- else
- bss->vlan = vlan;
- bss->vlan_tail = vlan;
- }
-
- fclose(f);
-
- return 0;
-}
-
-
-static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
-{
- struct hostapd_vlan *vlan, *prev;
-
- vlan = bss->vlan;
- prev = NULL;
- while (vlan) {
- prev = vlan;
- vlan = vlan->next;
- free(prev);
- }
-
- bss->vlan = NULL;
-}
-
-
-/* convert floats with one decimal place to value*10 int, i.e.,
- * "1.5" will return 15 */
-static int hostapd_config_read_int10(const char *value)
-{
- int i, d;
- char *pos;
-
- i = atoi(value);
- pos = strchr(value, '.');
- d = 0;
- if (pos) {
- pos++;
- if (*pos >= '0' && *pos <= '9')
- d = *pos - '0';
- }
-
- return i * 10 + d;
-}
-
-
-static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
-{
- bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
- bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
- bss->logger_syslog = (unsigned int) -1;
- bss->logger_stdout = (unsigned int) -1;
-
- bss->auth_algs = HOSTAPD_AUTH_OPEN | HOSTAPD_AUTH_SHARED_KEY;
-
- bss->wep_rekeying_period = 300;
- /* use key0 in individual key and key1 in broadcast key */
- bss->broadcast_key_idx_min = 1;
- bss->broadcast_key_idx_max = 2;
- bss->eap_reauth_period = 3600;
-
- bss->wpa_group_rekey = 600;
- bss->wpa_gmk_rekey = 86400;
- bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
- bss->wpa_pairwise = WPA_CIPHER_TKIP;
- bss->wpa_group = WPA_CIPHER_TKIP;
-
- bss->max_num_sta = MAX_STA_COUNT;
-
- bss->dtim_period = 2;
-
- bss->radius_server_auth_port = 1812;
- bss->ap_max_inactivity = AP_MAX_INACTIVITY;
- bss->eapol_version = EAPOL_VERSION;
-}
-
-
-static struct hostapd_config * hostapd_config_defaults(void)
-{
- struct hostapd_config *conf;
- struct hostapd_bss_config *bss;
- int i;
- const int aCWmin = 15, aCWmax = 1024;
- const struct hostapd_wme_ac_params ac_bk =
- { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
- const struct hostapd_wme_ac_params ac_be =
- { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
- const struct hostapd_wme_ac_params ac_vi = /* video traffic */
- { aCWmin >> 1, aCWmin, 2, 3000 / 32, 1 };
- const struct hostapd_wme_ac_params ac_vo = /* voice traffic */
- { aCWmin >> 2, aCWmin >> 1, 2, 1500 / 32, 1 };
-
- conf = wpa_zalloc(sizeof(*conf));
- bss = wpa_zalloc(sizeof(*bss));
- if (conf == NULL || bss == NULL) {
- printf("Failed to allocate memory for configuration data.\n");
- free(conf);
- free(bss);
- return NULL;
- }
-
- /* set default driver based on configuration */
- conf->driver = driver_lookup("default");
- if (conf->driver == NULL) {
- printf("No default driver registered!\n");
- free(conf);
- free(bss);
- return NULL;
- }
-
- bss->radius = wpa_zalloc(sizeof(*bss->radius));
- if (bss->radius == NULL) {
- free(conf);
- free(bss);
- return NULL;
- }
-
- hostapd_config_defaults_bss(bss);
-
- conf->num_bss = 1;
- conf->bss = bss;
-
- conf->beacon_int = 100;
- conf->rts_threshold = -1; /* use driver default: 2347 */
- conf->fragm_threshold = -1; /* user driver default: 2346 */
- conf->send_probe_response = 1;
- conf->bridge_packets = INTERNAL_BRIDGE_DO_NOT_CONTROL;
-
- memcpy(conf->country, "US ", 3);
-
- for (i = 0; i < NUM_TX_QUEUES; i++)
- conf->tx_queue[i].aifs = -1; /* use hw default */
-
- conf->wme_ac_params[0] = ac_be;
- conf->wme_ac_params[1] = ac_bk;
- conf->wme_ac_params[2] = ac_vi;
- conf->wme_ac_params[3] = ac_vo;
-
- return conf;
-}
-
-
-static int hostapd_parse_ip_addr(const char *txt, struct hostapd_ip_addr *addr)
-{
- if (inet_aton(txt, &addr->u.v4)) {
- addr->af = AF_INET;
- return 0;
- }
-
-#ifdef CONFIG_IPV6
- if (inet_pton(AF_INET6, txt, &addr->u.v6) > 0) {
- addr->af = AF_INET6;
- return 0;
- }
-#endif /* CONFIG_IPV6 */
-
- return -1;
-}
-
-
-int hostapd_mac_comp(const void *a, const void *b)
-{
- return memcmp(a, b, sizeof(macaddr));
-}
-
-
-int hostapd_mac_comp_empty(const void *a)
-{
- macaddr empty = { 0 };
- return memcmp(a, empty, sizeof(macaddr));
-}
-
-
-static int hostapd_config_read_maclist(const char *fname, macaddr **acl,
- int *num)
-{
- FILE *f;
- char buf[128], *pos;
- int line = 0;
- u8 addr[ETH_ALEN];
- macaddr *newacl;
-
- if (!fname)
- return 0;
-
- f = fopen(fname, "r");
- if (!f) {
- printf("MAC list file '%s' not found.\n", fname);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- if (hwaddr_aton(buf, addr)) {
- printf("Invalid MAC address '%s' at line %d in '%s'\n",
- buf, line, fname);
- fclose(f);
- return -1;
- }
-
- newacl = (macaddr *) realloc(*acl, (*num + 1) * ETH_ALEN);
- if (newacl == NULL) {
- printf("MAC list reallocation failed\n");
- fclose(f);
- return -1;
- }
-
- *acl = newacl;
- memcpy((*acl)[*num], addr, ETH_ALEN);
- (*num)++;
- }
-
- fclose(f);
-
- qsort(*acl, *num, sizeof(macaddr), hostapd_mac_comp);
-
- return 0;
-}
-
-
-static int hostapd_config_read_wpa_psk(const char *fname,
- struct hostapd_ssid *ssid)
-{
- FILE *f;
- char buf[128], *pos;
- int line = 0, ret = 0, len, ok;
- u8 addr[ETH_ALEN];
- struct hostapd_wpa_psk *psk;
-
- if (!fname)
- return 0;
-
- f = fopen(fname, "r");
- if (!f) {
- printf("WPA PSK file '%s' not found.\n", fname);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- if (hwaddr_aton(buf, addr)) {
- printf("Invalid MAC address '%s' on line %d in '%s'\n",
- buf, line, fname);
- ret = -1;
- break;
- }
-
- psk = wpa_zalloc(sizeof(*psk));
- if (psk == NULL) {
- printf("WPA PSK allocation failed\n");
- ret = -1;
- break;
- }
- if (memcmp(addr, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
- psk->group = 1;
- else
- memcpy(psk->addr, addr, ETH_ALEN);
-
- pos = buf + 17;
- if (pos == '\0') {
- printf("No PSK on line %d in '%s'\n", line, fname);
- free(psk);
- ret = -1;
- break;
- }
- pos++;
-
- ok = 0;
- len = strlen(pos);
- if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
- ok = 1;
- else if (len >= 8 && len < 64) {
- pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
- 4096, psk->psk, PMK_LEN);
- ok = 1;
- }
- if (!ok) {
- printf("Invalid PSK '%s' on line %d in '%s'\n",
- pos, line, fname);
- free(psk);
- ret = -1;
- break;
- }
-
- psk->next = ssid->wpa_psk;
- ssid->wpa_psk = psk;
- }
-
- fclose(f);
-
- return ret;
-}
-
-
-int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
-{
- struct hostapd_ssid *ssid = &conf->ssid;
-
- if (ssid->wpa_passphrase != NULL) {
- if (ssid->wpa_psk != NULL) {
- printf("Warning: both WPA PSK and passphrase set. "
- "Using passphrase.\n");
- free(ssid->wpa_psk);
- }
- ssid->wpa_psk = wpa_zalloc(sizeof(struct hostapd_wpa_psk));
- if (ssid->wpa_psk == NULL) {
- printf("Unable to alloc space for PSK\n");
- return -1;
- }
- wpa_hexdump_ascii(MSG_DEBUG, "SSID",
- (u8 *) ssid->ssid, ssid->ssid_len);
- wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",
- (u8 *) ssid->wpa_passphrase,
- strlen(ssid->wpa_passphrase));
- pbkdf2_sha1(ssid->wpa_passphrase,
- ssid->ssid, ssid->ssid_len,
- 4096, ssid->wpa_psk->psk, PMK_LEN);
- wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",
- ssid->wpa_psk->psk, PMK_LEN);
- ssid->wpa_psk->group = 1;
-
- memset(ssid->wpa_passphrase, 0,
- strlen(ssid->wpa_passphrase));
- free(ssid->wpa_passphrase);
- ssid->wpa_passphrase = NULL;
- }
-
- if (ssid->wpa_psk_file) {
- if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file,
- &conf->ssid))
- return -1;
- free(ssid->wpa_psk_file);
- ssid->wpa_psk_file = NULL;
- }
-
- return 0;
-}
-
-
-#ifdef EAP_SERVER
-static int hostapd_config_read_eap_user(const char *fname,
- struct hostapd_bss_config *conf)
-{
- FILE *f;
- char buf[512], *pos, *start, *pos2;
- int line = 0, ret = 0, num_methods;
- struct hostapd_eap_user *user, *tail = NULL;
-
- if (!fname)
- return 0;
-
- f = fopen(fname, "r");
- if (!f) {
- printf("EAP user file '%s' not found.\n", fname);
- return -1;
- }
-
- /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
- while (fgets(buf, sizeof(buf), f)) {
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- user = NULL;
-
- if (buf[0] != '"' && buf[0] != '*') {
- printf("Invalid EAP identity (no \" in start) on "
- "line %d in '%s'\n", line, fname);
- goto failed;
- }
-
- user = wpa_zalloc(sizeof(*user));
- if (user == NULL) {
- printf("EAP user allocation failed\n");
- goto failed;
- }
- user->force_version = -1;
-
- if (buf[0] == '*') {
- pos = buf;
- } else {
- pos = buf + 1;
- start = pos;
- while (*pos != '"' && *pos != '\0')
- pos++;
- if (*pos == '\0') {
- printf("Invalid EAP identity (no \" in end) on"
- " line %d in '%s'\n", line, fname);
- goto failed;
- }
-
- user->identity = malloc(pos - start);
- if (user->identity == NULL) {
- printf("Failed to allocate memory for EAP "
- "identity\n");
- goto failed;
- }
- memcpy(user->identity, start, pos - start);
- user->identity_len = pos - start;
-
- if (pos[0] == '"' && pos[1] == '*') {
- user->wildcard_prefix = 1;
- pos++;
- }
- }
- pos++;
- while (*pos == ' ' || *pos == '\t')
- pos++;
-
- if (*pos == '\0') {
- printf("No EAP method on line %d in '%s'\n",
- line, fname);
- goto failed;
- }
-
- start = pos;
- while (*pos != ' ' && *pos != '\t' && *pos != '\0')
- pos++;
- if (*pos == '\0') {
- pos = NULL;
- } else {
- *pos = '\0';
- pos++;
- }
- num_methods = 0;
- while (*start) {
- char *pos3 = strchr(start, ',');
- if (pos3) {
- *pos3++ = '\0';
- }
- user->methods[num_methods].method =
- eap_get_type(start, &user->methods[num_methods]
- .vendor);
- if (user->methods[num_methods].vendor ==
- EAP_VENDOR_IETF &&
- user->methods[num_methods].method == EAP_TYPE_NONE)
- {
- printf("Unsupported EAP type '%s' on line %d "
- "in '%s'\n", start, line, fname);
- goto failed;
- }
-
- num_methods++;
- if (num_methods >= EAP_USER_MAX_METHODS)
- break;
- if (pos3 == NULL)
- break;
- start = pos3;
- }
- if (num_methods == 0) {
- printf("No EAP types configured on line %d in '%s'\n",
- line, fname);
- goto failed;
- }
-
- if (pos == NULL)
- goto done;
-
- while (*pos == ' ' || *pos == '\t')
- pos++;
- if (*pos == '\0')
- goto done;
-
- if (strncmp(pos, "[ver=0]", 7) == 0) {
- user->force_version = 0;
- goto done;
- }
-
- if (strncmp(pos, "[ver=1]", 7) == 0) {
- user->force_version = 1;
- goto done;
- }
-
- if (strncmp(pos, "[2]", 3) == 0) {
- user->phase2 = 1;
- goto done;
- }
-
- if (*pos == '"') {
- pos++;
- start = pos;
- while (*pos != '"' && *pos != '\0')
- pos++;
- if (*pos == '\0') {
- printf("Invalid EAP password (no \" in end) "
- "on line %d in '%s'\n", line, fname);
- goto failed;
- }
-
- user->password = malloc(pos - start);
- if (user->password == NULL) {
- printf("Failed to allocate memory for EAP "
- "password\n");
- goto failed;
- }
- memcpy(user->password, start, pos - start);
- user->password_len = pos - start;
-
- pos++;
- } else if (strncmp(pos, "hash:", 5) == 0) {
- pos += 5;
- pos2 = pos;
- while (*pos2 != '\0' && *pos2 != ' ' &&
- *pos2 != '\t' && *pos2 != '#')
- pos2++;
- if (pos2 - pos != 32) {
- printf("Invalid password hash on line %d in "
- "'%s'\n", line, fname);
- goto failed;
- }
- user->password = malloc(16);
- if (user->password == NULL) {
- printf("Failed to allocate memory for EAP "
- "password hash\n");
- goto failed;
- }
- if (hexstr2bin(pos, user->password, 16) < 0) {
- printf("Invalid hash password on line %d in "
- "'%s'\n", line, fname);
- goto failed;
- }
- user->password_len = 16;
- user->password_hash = 1;
- pos = pos2;
- } else {
- pos2 = pos;
- while (*pos2 != '\0' && *pos2 != ' ' &&
- *pos2 != '\t' && *pos2 != '#')
- pos2++;
- if ((pos2 - pos) & 1) {
- printf("Invalid hex password on line %d in "
- "'%s'\n", line, fname);
- goto failed;
- }
- user->password = malloc((pos2 - pos) / 2);
- if (user->password == NULL) {
- printf("Failed to allocate memory for EAP "
- "password\n");
- goto failed;
- }
- if (hexstr2bin(pos, user->password,
- (pos2 - pos) / 2) < 0) {
- printf("Invalid hex password on line %d in "
- "'%s'\n", line, fname);
- goto failed;
- }
- user->password_len = (pos2 - pos) / 2;
- pos = pos2;
- }
-
- while (*pos == ' ' || *pos == '\t')
- pos++;
- if (strncmp(pos, "[2]", 3) == 0) {
- user->phase2 = 1;
- }
-
- done:
- if (tail == NULL) {
- tail = conf->eap_user = user;
- } else {
- tail->next = user;
- tail = user;
- }
- continue;
-
- failed:
- if (user) {
- free(user->password);
- free(user->identity);
- free(user);
- }
- ret = -1;
- break;
- }
-
- fclose(f);
-
- return ret;
-}
-#endif /* EAP_SERVER */
-
-
-static int
-hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
- int *num_server, const char *val, int def_port,
- struct hostapd_radius_server **curr_serv)
-{
- struct hostapd_radius_server *nserv;
- int ret;
- static int server_index = 1;
-
- nserv = realloc(*server, (*num_server + 1) * sizeof(*nserv));
- if (nserv == NULL)
- return -1;
-
- *server = nserv;
- nserv = &nserv[*num_server];
- (*num_server)++;
- (*curr_serv) = nserv;
-
- memset(nserv, 0, sizeof(*nserv));
- nserv->port = def_port;
- ret = hostapd_parse_ip_addr(val, &nserv->addr);
- nserv->index = server_index++;
-
- return ret;
-}
-
-
-static int hostapd_config_parse_key_mgmt(int line, const char *value)
-{
- int val = 0, last;
- char *start, *end, *buf;
-
- buf = strdup(value);
- if (buf == NULL)
- return -1;
- start = buf;
-
- while (start != '\0') {
- while (*start == ' ' || *start == '\t')
- start++;
- if (*start == '\0')
- break;
- end = start;
- while (*end != ' ' && *end != '\t' && *end != '\0')
- end++;
- last = *end == '\0';
- *end = '\0';
- if (strcmp(start, "WPA-PSK") == 0)
- val |= WPA_KEY_MGMT_PSK;
- else if (strcmp(start, "WPA-EAP") == 0)
- val |= WPA_KEY_MGMT_IEEE8021X;
- else {
- printf("Line %d: invalid key_mgmt '%s'\n",
- line, start);
- free(buf);
- return -1;
- }
-
- if (last)
- break;
- start = end + 1;
- }
-
- free(buf);
- if (val == 0) {
- printf("Line %d: no key_mgmt values configured.\n", line);
- return -1;
- }
-
- return val;
-}
-
-
-static int hostapd_config_parse_cipher(int line, const char *value)
-{
- int val = 0, last;
- char *start, *end, *buf;
-
- buf = strdup(value);
- if (buf == NULL)
- return -1;
- start = buf;
-
- while (start != '\0') {
- while (*start == ' ' || *start == '\t')
- start++;
- if (*start == '\0')
- break;
- end = start;
- while (*end != ' ' && *end != '\t' && *end != '\0')
- end++;
- last = *end == '\0';
- *end = '\0';
- if (strcmp(start, "CCMP") == 0)
- val |= WPA_CIPHER_CCMP;
- else if (strcmp(start, "TKIP") == 0)
- val |= WPA_CIPHER_TKIP;
- else if (strcmp(start, "WEP104") == 0)
- val |= WPA_CIPHER_WEP104;
- else if (strcmp(start, "WEP40") == 0)
- val |= WPA_CIPHER_WEP40;
- else if (strcmp(start, "NONE") == 0)
- val |= WPA_CIPHER_NONE;
- else {
- printf("Line %d: invalid cipher '%s'.", line, start);
- free(buf);
- return -1;
- }
-
- if (last)
- break;
- start = end + 1;
- }
- free(buf);
-
- if (val == 0) {
- printf("Line %d: no cipher values configured.", line);
- return -1;
- }
- return val;
-}
-
-
-static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
- struct hostapd_config *conf)
-{
- if (bss->ieee802_1x && !bss->eap_server &&
- !bss->radius->auth_servers) {
- printf("Invalid IEEE 802.1X configuration (no EAP "
- "authenticator configured).\n");
- return -1;
- }
-
- if (bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
- bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
- bss->ssid.wpa_psk_file == NULL) {
- printf("WPA-PSK enabled, but PSK or passphrase is not "
- "configured.\n");
- return -1;
- }
-
- if (hostapd_mac_comp_empty(bss->bssid) != 0) {
- size_t i;
-
- for (i = 0; i < conf->num_bss; i++) {
- if ((&conf->bss[i] != bss) &&
- (hostapd_mac_comp(conf->bss[i].bssid,
- bss->bssid) == 0)) {
- printf("Duplicate BSSID " MACSTR
- " on interface '%s' and '%s'.\n",
- MAC2STR(bss->bssid),
- conf->bss[i].iface, bss->iface);
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-
-static int hostapd_config_check(struct hostapd_config *conf)
-{
- size_t i;
-
- for (i = 0; i < conf->num_bss; i++) {
- if (hostapd_config_check_bss(&conf->bss[i], conf))
- return -1;
- }
-
- return 0;
-}
-
-
-static int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
- char *val)
-{
- size_t len = strlen(val);
-
- if (keyidx < 0 || keyidx > 3 || wep->key[keyidx] != NULL)
- return -1;
-
- if (val[0] == '"') {
- if (len < 2 || val[len - 1] != '"')
- return -1;
- len -= 2;
- wep->key[keyidx] = malloc(len);
- if (wep->key[keyidx] == NULL)
- return -1;
- memcpy(wep->key[keyidx], val + 1, len);
- wep->len[keyidx] = len;
- } else {
- if (len & 1)
- return -1;
- len /= 2;
- wep->key[keyidx] = malloc(len);
- if (wep->key[keyidx] == NULL)
- return -1;
- wep->len[keyidx] = len;
- if (hexstr2bin(val, wep->key[keyidx], len) < 0)
- return -1;
- }
-
- wep->keys_set++;
-
- return 0;
-}
-
-
-static int hostapd_parse_rates(int **rate_list, char *val)
-{
- int *list;
- int count;
- char *pos, *end;
-
- free(*rate_list);
- *rate_list = NULL;
-
- pos = val;
- count = 0;
- while (*pos != '\0') {
- if (*pos == ' ')
- count++;
- pos++;
- }
-
- list = malloc(sizeof(int) * (count + 2));
- if (list == NULL)
- return -1;
- pos = val;
- count = 0;
- while (*pos != '\0') {
- end = strchr(pos, ' ');
- if (end)
- *end = '\0';
-
- list[count++] = atoi(pos);
- if (!end)
- break;
- pos = end + 1;
- }
- list[count] = -1;
-
- *rate_list = list;
- return 0;
-}
-
-
-static int hostapd_config_bss(struct hostapd_config *conf, const char *ifname)
-{
- struct hostapd_bss_config *bss;
-
- if (*ifname == '\0')
- return -1;
-
- bss = realloc(conf->bss, (conf->num_bss + 1) *
- sizeof(struct hostapd_bss_config));
- if (bss == NULL) {
- printf("Failed to allocate memory for multi-BSS entry\n");
- return -1;
- }
- conf->bss = bss;
-
- bss = &(conf->bss[conf->num_bss]);
- memset(bss, 0, sizeof(*bss));
- bss->radius = wpa_zalloc(sizeof(*bss->radius));
- if (bss->radius == NULL) {
- printf("Failed to allocate memory for multi-BSS RADIUS "
- "data\n");
- return -1;
- }
-
- conf->num_bss++;
- conf->last_bss = bss;
-
- hostapd_config_defaults_bss(bss);
- snprintf(bss->iface, sizeof(bss->iface), "%s", ifname);
- memcpy(bss->ssid.vlan, bss->iface, IFNAMSIZ + 1);
-
- return 0;
-}
-
-
-static int valid_cw(int cw)
-{
- return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
- cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023);
-}
-
-
-enum {
- IEEE80211_TX_QUEUE_DATA0 = 0, /* used for EDCA AC_VO data */
- IEEE80211_TX_QUEUE_DATA1 = 1, /* used for EDCA AC_VI data */
- IEEE80211_TX_QUEUE_DATA2 = 2, /* used for EDCA AC_BE data */
- IEEE80211_TX_QUEUE_DATA3 = 3, /* used for EDCA AC_BK data */
- IEEE80211_TX_QUEUE_DATA4 = 4,
- IEEE80211_TX_QUEUE_AFTER_BEACON = 6,
- IEEE80211_TX_QUEUE_BEACON = 7
-};
-
-static int hostapd_config_tx_queue(struct hostapd_config *conf, char *name,
- char *val)
-{
- int num;
- char *pos;
- struct hostapd_tx_queue_params *queue;
-
- /* skip 'tx_queue_' prefix */
- pos = name + 9;
- if (strncmp(pos, "data", 4) == 0 &&
- pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
- num = pos[4] - '0';
- pos += 6;
- } else if (strncmp(pos, "after_beacon_", 13) == 0) {
- num = IEEE80211_TX_QUEUE_AFTER_BEACON;
- pos += 13;
- } else if (strncmp(pos, "beacon_", 7) == 0) {
- num = IEEE80211_TX_QUEUE_BEACON;
- pos += 7;
- } else {
- printf("Unknown tx_queue name '%s'\n", pos);
- return -1;
- }
-
- queue = &conf->tx_queue[num];
-
- if (strcmp(pos, "aifs") == 0) {
- queue->aifs = atoi(val);
- if (queue->aifs < 0 || queue->aifs > 255) {
- printf("Invalid AIFS value %d\n", queue->aifs);
- return -1;
- }
- } else if (strcmp(pos, "cwmin") == 0) {
- queue->cwmin = atoi(val);
- if (!valid_cw(queue->cwmin)) {
- printf("Invalid cwMin value %d\n", queue->cwmin);
- return -1;
- }
- } else if (strcmp(pos, "cwmax") == 0) {
- queue->cwmax = atoi(val);
- if (!valid_cw(queue->cwmax)) {
- printf("Invalid cwMax value %d\n", queue->cwmax);
- return -1;
- }
- } else if (strcmp(pos, "burst") == 0) {
- queue->burst = hostapd_config_read_int10(val);
- } else {
- printf("Unknown tx_queue field '%s'\n", pos);
- return -1;
- }
-
- queue->configured = 1;
-
- return 0;
-}
-
-
-static int hostapd_config_wme_ac(struct hostapd_config *conf, char *name,
- char *val)
-{
- int num, v;
- char *pos;
- struct hostapd_wme_ac_params *ac;
-
- /* skip 'wme_ac_' prefix */
- pos = name + 7;
- if (strncmp(pos, "be_", 3) == 0) {
- num = 0;
- pos += 3;
- } else if (strncmp(pos, "bk_", 3) == 0) {
- num = 1;
- pos += 3;
- } else if (strncmp(pos, "vi_", 3) == 0) {
- num = 2;
- pos += 3;
- } else if (strncmp(pos, "vo_", 3) == 0) {
- num = 3;
- pos += 3;
- } else {
- printf("Unknown wme name '%s'\n", pos);
- return -1;
- }
-
- ac = &conf->wme_ac_params[num];
-
- if (strcmp(pos, "aifs") == 0) {
- v = atoi(val);
- if (v < 1 || v > 255) {
- printf("Invalid AIFS value %d\n", v);
- return -1;
- }
- ac->aifs = v;
- } else if (strcmp(pos, "cwmin") == 0) {
- v = atoi(val);
- if (v < 0 || v > 12) {
- printf("Invalid cwMin value %d\n", v);
- return -1;
- }
- ac->cwmin = v;
- } else if (strcmp(pos, "cwmax") == 0) {
- v = atoi(val);
- if (v < 0 || v > 12) {
- printf("Invalid cwMax value %d\n", v);
- return -1;
- }
- ac->cwmax = v;
- } else if (strcmp(pos, "txop_limit") == 0) {
- v = atoi(val);
- if (v < 0 || v > 0xffff) {
- printf("Invalid txop value %d\n", v);
- return -1;
- }
- ac->txopLimit = v;
- } else if (strcmp(pos, "acm") == 0) {
- v = atoi(val);
- if (v < 0 || v > 1) {
- printf("Invalid acm value %d\n", v);
- return -1;
- }
- ac->admission_control_mandatory = v;
- } else {
- printf("Unknown wme_ac_ field '%s'\n", pos);
- return -1;
- }
-
- return 0;
-}
-
-
-struct hostapd_config * hostapd_config_read(const char *fname)
-{
- struct hostapd_config *conf;
- struct hostapd_bss_config *bss;
- FILE *f;
- char buf[256], *pos;
- int line = 0;
- int errors = 0;
- size_t i;
-
- f = fopen(fname, "r");
- if (f == NULL) {
- printf("Could not open configuration file '%s' for reading.\n",
- fname);
- return NULL;
- }
-
- conf = hostapd_config_defaults();
- if (conf == NULL) {
- fclose(f);
- return NULL;
- }
- bss = conf->last_bss = conf->bss;
-
- while (fgets(buf, sizeof(buf), f)) {
- bss = conf->last_bss;
- line++;
-
- if (buf[0] == '#')
- continue;
- pos = buf;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- if (buf[0] == '\0')
- continue;
-
- pos = strchr(buf, '=');
- if (pos == NULL) {
- printf("Line %d: invalid line '%s'\n", line, buf);
- errors++;
- continue;
- }
- *pos = '\0';
- pos++;
-
- if (strcmp(buf, "interface") == 0) {
- snprintf(conf->bss[0].iface,
- sizeof(conf->bss[0].iface), "%s", pos);
- } else if (strcmp(buf, "bridge") == 0) {
- snprintf(bss->bridge, sizeof(bss->bridge), "%s", pos);
- } else if (strcmp(buf, "driver") == 0) {
- conf->driver = driver_lookup(pos);
- if (conf->driver == NULL) {
- printf("Line %d: invalid/unknown driver "
- "'%s'\n", line, pos);
- errors++;
- }
- } else if (strcmp(buf, "debug") == 0) {
- bss->debug = atoi(pos);
- } else if (strcmp(buf, "logger_syslog_level") == 0) {
- bss->logger_syslog_level = atoi(pos);
- } else if (strcmp(buf, "logger_stdout_level") == 0) {
- bss->logger_stdout_level = atoi(pos);
- } else if (strcmp(buf, "logger_syslog") == 0) {
- bss->logger_syslog = atoi(pos);
- } else if (strcmp(buf, "logger_stdout") == 0) {
- bss->logger_stdout = atoi(pos);
- } else if (strcmp(buf, "dump_file") == 0) {
- bss->dump_log_name = strdup(pos);
- } else if (strcmp(buf, "ssid") == 0) {
- bss->ssid.ssid_len = strlen(pos);
- if (bss->ssid.ssid_len > HOSTAPD_MAX_SSID_LEN ||
- bss->ssid.ssid_len < 1) {
- printf("Line %d: invalid SSID '%s'\n", line,
- pos);
- errors++;
- } else {
- memcpy(bss->ssid.ssid, pos,
- bss->ssid.ssid_len);
- bss->ssid.ssid[bss->ssid.ssid_len] = '\0';
- bss->ssid.ssid_set = 1;
- }
- } else if (strcmp(buf, "macaddr_acl") == 0) {
- bss->macaddr_acl = atoi(pos);
- if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
- bss->macaddr_acl != DENY_UNLESS_ACCEPTED &&
- bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
- printf("Line %d: unknown macaddr_acl %d\n",
- line, bss->macaddr_acl);
- }
- } else if (strcmp(buf, "accept_mac_file") == 0) {
- if (hostapd_config_read_maclist(pos, &bss->accept_mac,
- &bss->num_accept_mac))
- {
- printf("Line %d: Failed to read "
- "accept_mac_file '%s'\n",
- line, pos);
- errors++;
- }
- } else if (strcmp(buf, "deny_mac_file") == 0) {
- if (hostapd_config_read_maclist(pos, &bss->deny_mac,
- &bss->num_deny_mac))
- {
- printf("Line %d: Failed to read "
- "deny_mac_file '%s'\n",
- line, pos);
- errors++;
- }
- } else if (strcmp(buf, "ap_max_inactivity") == 0) {
- bss->ap_max_inactivity = atoi(pos);
- } else if (strcmp(buf, "country_code") == 0) {
- memcpy(conf->country, pos, 2);
- /* FIX: make this configurable */
- conf->country[2] = ' ';
- } else if (strcmp(buf, "ieee80211d") == 0) {
- conf->ieee80211d = atoi(pos);
- } else if (strcmp(buf, "ieee80211h") == 0) {
- conf->ieee80211h = atoi(pos);
- } else if (strcmp(buf, "assoc_ap_addr") == 0) {
- if (hwaddr_aton(pos, bss->assoc_ap_addr)) {
- printf("Line %d: invalid MAC address '%s'\n",
- line, pos);
- errors++;
- }
- bss->assoc_ap = 1;
- } else if (strcmp(buf, "ieee8021x") == 0) {
- bss->ieee802_1x = atoi(pos);
- } else if (strcmp(buf, "eapol_version") == 0) {
- bss->eapol_version = atoi(pos);
- if (bss->eapol_version < 1 ||
- bss->eapol_version > 2) {
- printf("Line %d: invalid EAPOL "
- "version (%d): '%s'.\n",
- line, bss->eapol_version, pos);
- errors++;
- } else
- wpa_printf(MSG_DEBUG, "eapol_version=%d",
- bss->eapol_version);
-#ifdef EAP_SERVER
- } else if (strcmp(buf, "eap_authenticator") == 0) {
- bss->eap_server = atoi(pos);
- printf("Line %d: obsolete eap_authenticator used; "
- "this has been renamed to eap_server\n", line);
- } else if (strcmp(buf, "eap_server") == 0) {
- bss->eap_server = atoi(pos);
- } else if (strcmp(buf, "eap_user_file") == 0) {
- if (hostapd_config_read_eap_user(pos, bss))
- errors++;
- } else if (strcmp(buf, "ca_cert") == 0) {
- free(bss->ca_cert);
- bss->ca_cert = strdup(pos);
- } else if (strcmp(buf, "server_cert") == 0) {
- free(bss->server_cert);
- bss->server_cert = strdup(pos);
- } else if (strcmp(buf, "private_key") == 0) {
- free(bss->private_key);
- bss->private_key = strdup(pos);
- } else if (strcmp(buf, "private_key_passwd") == 0) {
- free(bss->private_key_passwd);
- bss->private_key_passwd = strdup(pos);
- } else if (strcmp(buf, "check_crl") == 0) {
- bss->check_crl = atoi(pos);
-#ifdef EAP_SIM
- } else if (strcmp(buf, "eap_sim_db") == 0) {
- free(bss->eap_sim_db);
- bss->eap_sim_db = strdup(pos);
-#endif /* EAP_SIM */
-#endif /* EAP_SERVER */
- } else if (strcmp(buf, "eap_message") == 0) {
- char *term;
- bss->eap_req_id_text = strdup(pos);
- if (bss->eap_req_id_text == NULL) {
- printf("Line %d: Failed to allocate memory "
- "for eap_req_id_text\n", line);
- errors++;
- continue;
- }
- bss->eap_req_id_text_len =
- strlen(bss->eap_req_id_text);
- term = strstr(bss->eap_req_id_text, "\\0");
- if (term) {
- *term++ = '\0';
- memmove(term, term + 1,
- bss->eap_req_id_text_len -
- (term - bss->eap_req_id_text) - 1);
- bss->eap_req_id_text_len--;
- }
- } else if (strcmp(buf, "wep_key_len_broadcast") == 0) {
- bss->default_wep_key_len = atoi(pos);
- if (bss->default_wep_key_len > 13) {
- printf("Line %d: invalid WEP key len %lu "
- "(= %lu bits)\n", line,
- (unsigned long)
- bss->default_wep_key_len,
- (unsigned long)
- bss->default_wep_key_len * 8);
- errors++;
- }
- } else if (strcmp(buf, "wep_key_len_unicast") == 0) {
- bss->individual_wep_key_len = atoi(pos);
- if (bss->individual_wep_key_len < 0 ||
- bss->individual_wep_key_len > 13) {
- printf("Line %d: invalid WEP key len %d "
- "(= %d bits)\n", line,
- bss->individual_wep_key_len,
- bss->individual_wep_key_len * 8);
- errors++;
- }
- } else if (strcmp(buf, "wep_rekey_period") == 0) {
- bss->wep_rekeying_period = atoi(pos);
- if (bss->wep_rekeying_period < 0) {
- printf("Line %d: invalid period %d\n",
- line, bss->wep_rekeying_period);
- errors++;
- }
- } else if (strcmp(buf, "eap_reauth_period") == 0) {
- bss->eap_reauth_period = atoi(pos);
- if (bss->eap_reauth_period < 0) {
- printf("Line %d: invalid period %d\n",
- line, bss->eap_reauth_period);
- errors++;
- }
- } else if (strcmp(buf, "eapol_key_index_workaround") == 0) {
- bss->eapol_key_index_workaround = atoi(pos);
-#ifdef CONFIG_IAPP
- } else if (strcmp(buf, "iapp_interface") == 0) {
- bss->ieee802_11f = 1;
- snprintf(bss->iapp_iface, sizeof(bss->iapp_iface),
- "%s", pos);
-#endif /* CONFIG_IAPP */
- } else if (strcmp(buf, "own_ip_addr") == 0) {
- if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
- printf("Line %d: invalid IP address '%s'\n",
- line, pos);
- errors++;
- }
- } else if (strcmp(buf, "nas_identifier") == 0) {
- bss->nas_identifier = strdup(pos);
- } else if (strcmp(buf, "auth_server_addr") == 0) {
- if (hostapd_config_read_radius_addr(
- &bss->radius->auth_servers,
- &bss->radius->num_auth_servers, pos, 1812,
- &bss->radius->auth_server)) {
- printf("Line %d: invalid IP address '%s'\n",
- line, pos);
- errors++;
- }
- } else if (bss->radius->auth_server &&
- strcmp(buf, "auth_server_port") == 0) {
- bss->radius->auth_server->port = atoi(pos);
- } else if (bss->radius->auth_server &&
- strcmp(buf, "auth_server_shared_secret") == 0) {
- int len = strlen(pos);
- if (len == 0) {
- /* RFC 2865, Ch. 3 */
- printf("Line %d: empty shared secret is not "
- "allowed.\n", line);
- errors++;
- }
- bss->radius->auth_server->shared_secret =
- (u8 *) strdup(pos);
- bss->radius->auth_server->shared_secret_len = len;
- } else if (strcmp(buf, "acct_server_addr") == 0) {
- if (hostapd_config_read_radius_addr(
- &bss->radius->acct_servers,
- &bss->radius->num_acct_servers, pos, 1813,
- &bss->radius->acct_server)) {
- printf("Line %d: invalid IP address '%s'\n",
- line, pos);
- errors++;
- }
- } else if (bss->radius->acct_server &&
- strcmp(buf, "acct_server_port") == 0) {
- bss->radius->acct_server->port = atoi(pos);
- } else if (bss->radius->acct_server &&
- strcmp(buf, "acct_server_shared_secret") == 0) {
- int len = strlen(pos);
- if (len == 0) {
- /* RFC 2865, Ch. 3 */
- printf("Line %d: empty shared secret is not "
- "allowed.\n", line);
- errors++;
- }
- bss->radius->acct_server->shared_secret =
- (u8 *) strdup(pos);
- bss->radius->acct_server->shared_secret_len = len;
- } else if (strcmp(buf, "radius_retry_primary_interval") == 0) {
- bss->radius->retry_primary_interval = atoi(pos);
- } else if (strcmp(buf, "radius_acct_interim_interval") == 0) {
- bss->radius->acct_interim_interval = atoi(pos);
- } else if (strcmp(buf, "auth_algs") == 0) {
- bss->auth_algs = atoi(pos);
- if (bss->auth_algs == 0) {
- printf("Line %d: no authentication algorithms "
- "allowed\n",
- line);
- errors++;
- }
- } else if (strcmp(buf, "max_num_sta") == 0) {
- bss->max_num_sta = atoi(pos);
- if (bss->max_num_sta < 0 ||
- bss->max_num_sta > MAX_STA_COUNT) {
- printf("Line %d: Invalid max_num_sta=%d; "
- "allowed range 0..%d\n", line,
- bss->max_num_sta, MAX_STA_COUNT);
- errors++;
- }
- } else if (strcmp(buf, "wpa") == 0) {
- bss->wpa = atoi(pos);
- } else if (strcmp(buf, "wpa_group_rekey") == 0) {
- bss->wpa_group_rekey = atoi(pos);
- } else if (strcmp(buf, "wpa_strict_rekey") == 0) {
- bss->wpa_strict_rekey = atoi(pos);
- } else if (strcmp(buf, "wpa_gmk_rekey") == 0) {
- bss->wpa_gmk_rekey = atoi(pos);
- } else if (strcmp(buf, "wpa_passphrase") == 0) {
- int len = strlen(pos);
- if (len < 8 || len > 63) {
- printf("Line %d: invalid WPA passphrase length"
- " %d (expected 8..63)\n", line, len);
- errors++;
- } else {
- free(bss->ssid.wpa_passphrase);
- bss->ssid.wpa_passphrase = strdup(pos);
- }
- } else if (strcmp(buf, "wpa_psk") == 0) {
- free(bss->ssid.wpa_psk);
- bss->ssid.wpa_psk =
- wpa_zalloc(sizeof(struct hostapd_wpa_psk));
- if (bss->ssid.wpa_psk == NULL)
- errors++;
- else if (hexstr2bin(pos, bss->ssid.wpa_psk->psk,
- PMK_LEN) ||
- pos[PMK_LEN * 2] != '\0') {
- printf("Line %d: Invalid PSK '%s'.\n", line,
- pos);
- errors++;
- } else {
- bss->ssid.wpa_psk->group = 1;
- }
- } else if (strcmp(buf, "wpa_psk_file") == 0) {
- free(bss->ssid.wpa_psk_file);
- bss->ssid.wpa_psk_file = strdup(pos);
- if (!bss->ssid.wpa_psk_file) {
- printf("Line %d: allocation failed\n", line);
- errors++;
- }
- } else if (strcmp(buf, "wpa_key_mgmt") == 0) {
- bss->wpa_key_mgmt =
- hostapd_config_parse_key_mgmt(line, pos);
- if (bss->wpa_key_mgmt == -1)
- errors++;
- } else if (strcmp(buf, "wpa_pairwise") == 0) {
- bss->wpa_pairwise =
- hostapd_config_parse_cipher(line, pos);
- if (bss->wpa_pairwise == -1 ||
- bss->wpa_pairwise == 0)
- errors++;
- else if (bss->wpa_pairwise &
- (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
- WPA_CIPHER_WEP104)) {
- printf("Line %d: unsupported pairwise "
- "cipher suite '%s'\n",
- bss->wpa_pairwise, pos);
- errors++;
- } else {
- if (bss->wpa_pairwise & WPA_CIPHER_TKIP)
- bss->wpa_group = WPA_CIPHER_TKIP;
- else
- bss->wpa_group = WPA_CIPHER_CCMP;
- }
-#ifdef CONFIG_RSN_PREAUTH
- } else if (strcmp(buf, "rsn_preauth") == 0) {
- bss->rsn_preauth = atoi(pos);
- } else if (strcmp(buf, "rsn_preauth_interfaces") == 0) {
- bss->rsn_preauth_interfaces = strdup(pos);
-#endif /* CONFIG_RSN_PREAUTH */
-#ifdef CONFIG_PEERKEY
- } else if (strcmp(buf, "peerkey") == 0) {
- bss->peerkey = atoi(pos);
-#endif /* CONFIG_PEERKEY */
- } else if (strcmp(buf, "ctrl_interface") == 0) {
- free(bss->ctrl_interface);
- bss->ctrl_interface = strdup(pos);
- } else if (strcmp(buf, "ctrl_interface_group") == 0) {
-#ifndef CONFIG_NATIVE_WINDOWS
- struct group *grp;
- char *endp;
- const char *group = pos;
-
- grp = getgrnam(group);
- if (grp) {
- bss->ctrl_interface_gid = grp->gr_gid;
- bss->ctrl_interface_gid_set = 1;
- wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
- " (from group name '%s')",
- bss->ctrl_interface_gid, group);
- continue;
- }
-
- /* Group name not found - try to parse this as gid */
- bss->ctrl_interface_gid = strtol(group, &endp, 10);
- if (*group == '\0' || *endp != '\0') {
- wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
- "'%s'", line, group);
- errors++;
- continue;
- }
- bss->ctrl_interface_gid_set = 1;
- wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
- bss->ctrl_interface_gid);
-#endif /* CONFIG_NATIVE_WINDOWS */
-#ifdef RADIUS_SERVER
- } else if (strcmp(buf, "radius_server_clients") == 0) {
- free(bss->radius_server_clients);
- bss->radius_server_clients = strdup(pos);
- } else if (strcmp(buf, "radius_server_auth_port") == 0) {
- bss->radius_server_auth_port = atoi(pos);
- } else if (strcmp(buf, "radius_server_ipv6") == 0) {
- bss->radius_server_ipv6 = atoi(pos);
-#endif /* RADIUS_SERVER */
- } else if (strcmp(buf, "test_socket") == 0) {
- free(bss->test_socket);
- bss->test_socket = strdup(pos);
- } else if (strcmp(buf, "use_pae_group_addr") == 0) {
- bss->use_pae_group_addr = atoi(pos);
- } else if (strcmp(buf, "hw_mode") == 0) {
- if (strcmp(pos, "a") == 0)
- conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
- else if (strcmp(pos, "b") == 0)
- conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
- else if (strcmp(pos, "g") == 0)
- conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
- else {
- printf("Line %d: unknown hw_mode '%s'\n",
- line, pos);
- errors++;
- }
- } else if (strcmp(buf, "channel") == 0) {
- conf->channel = atoi(pos);
- } else if (strcmp(buf, "beacon_int") == 0) {
- int val = atoi(pos);
- /* MIB defines range as 1..65535, but very small values
- * cause problems with the current implementation.
- * Since it is unlikely that this small numbers are
- * useful in real life scenarios, do not allow beacon
- * period to be set below 15 TU. */
- if (val < 15 || val > 65535) {
- printf("Line %d: invalid beacon_int %d "
- "(expected 15..65535)\n",
- line, val);
- errors++;
- } else
- conf->beacon_int = val;
- } else if (strcmp(buf, "dtim_period") == 0) {
- bss->dtim_period = atoi(pos);
- if (bss->dtim_period < 1 || bss->dtim_period > 255) {
- printf("Line %d: invalid dtim_period %d\n",
- line, bss->dtim_period);
- errors++;
- }
- } else if (strcmp(buf, "rts_threshold") == 0) {
- conf->rts_threshold = atoi(pos);
- if (conf->rts_threshold < 0 ||
- conf->rts_threshold > 2347) {
- printf("Line %d: invalid rts_threshold %d\n",
- line, conf->rts_threshold);
- errors++;
- }
- } else if (strcmp(buf, "fragm_threshold") == 0) {
- conf->fragm_threshold = atoi(pos);
- if (conf->fragm_threshold < 256 ||
- conf->fragm_threshold > 2346) {
- printf("Line %d: invalid fragm_threshold %d\n",
- line, conf->fragm_threshold);
- errors++;
- }
- } else if (strcmp(buf, "send_probe_response") == 0) {
- int val = atoi(pos);
- if (val != 0 && val != 1) {
- printf("Line %d: invalid send_probe_response "
- "%d (expected 0 or 1)\n", line, val);
- } else
- conf->send_probe_response = val;
- } else if (strcmp(buf, "supported_rates") == 0) {
- if (hostapd_parse_rates(&conf->supported_rates, pos)) {
- printf("Line %d: invalid rate list\n", line);
- errors++;
- }
- } else if (strcmp(buf, "basic_rates") == 0) {
- if (hostapd_parse_rates(&conf->basic_rates, pos)) {
- printf("Line %d: invalid rate list\n", line);
- errors++;
- }
- } else if (strcmp(buf, "ignore_broadcast_ssid") == 0) {
- bss->ignore_broadcast_ssid = atoi(pos);
- } else if (strcmp(buf, "bridge_packets") == 0) {
- conf->bridge_packets = atoi(pos);
- } else if (strcmp(buf, "wep_default_key") == 0) {
- bss->ssid.wep.idx = atoi(pos);
- if (bss->ssid.wep.idx > 3) {
- printf("Invalid wep_default_key index %d\n",
- bss->ssid.wep.idx);
- errors++;
- }
- } else if (strcmp(buf, "wep_key0") == 0 ||
- strcmp(buf, "wep_key1") == 0 ||
- strcmp(buf, "wep_key2") == 0 ||
- strcmp(buf, "wep_key3") == 0) {
- if (hostapd_config_read_wep(&bss->ssid.wep,
- buf[7] - '0', pos)) {
- printf("Line %d: invalid WEP key '%s'\n",
- line, buf);
- errors++;
- }
- } else if (strcmp(buf, "dynamic_vlan") == 0) {
- bss->ssid.dynamic_vlan = atoi(pos);
- } else if (strcmp(buf, "vlan_file") == 0) {
- if (hostapd_config_read_vlan_file(bss, pos)) {
- printf("Line %d: failed to read VLAN file "
- "'%s'\n", line, pos);
- errors++;
- }
-#ifdef CONFIG_FULL_DYNAMIC_VLAN
- } else if (strcmp(buf, "vlan_tagged_interface") == 0) {
- bss->ssid.vlan_tagged_interface = strdup(pos);
-#endif /* CONFIG_FULL_DYNAMIC_VLAN */
- } else if (strcmp(buf, "passive_scan_interval") == 0) {
- conf->passive_scan_interval = atoi(pos);
- } else if (strcmp(buf, "passive_scan_listen") == 0) {
- conf->passive_scan_listen = atoi(pos);
- } else if (strcmp(buf, "passive_scan_mode") == 0) {
- conf->passive_scan_mode = atoi(pos);
- } else if (strcmp(buf, "ap_table_max_size") == 0) {
- conf->ap_table_max_size = atoi(pos);
- } else if (strcmp(buf, "ap_table_expiration_time") == 0) {
- conf->ap_table_expiration_time = atoi(pos);
- } else if (strncmp(buf, "tx_queue_", 9) == 0) {
- if (hostapd_config_tx_queue(conf, buf, pos)) {
- printf("Line %d: invalid TX queue item\n",
- line);
- errors++;
- }
- } else if (strcmp(buf, "wme_enabled") == 0) {
- bss->wme_enabled = atoi(pos);
- } else if (strncmp(buf, "wme_ac_", 7) == 0) {
- if (hostapd_config_wme_ac(conf, buf, pos)) {
- printf("Line %d: invalid wme ac item\n",
- line);
- errors++;
- }
- } else if (strcmp(buf, "bss") == 0) {
- if (hostapd_config_bss(conf, pos)) {
- printf("Line %d: invalid bss item\n", line);
- errors++;
- }
- } else if (strcmp(buf, "bssid") == 0) {
- if (bss == conf->bss) {
- printf("Line %d: bssid item not allowed "
- "for the default interface\n", line);
- errors++;
- } else if (hwaddr_aton(pos, bss->bssid)) {
- printf("Line %d: invalid bssid item\n", line);
- errors++;
- }
-#ifdef CONFIG_IEEE80211W
- } else if (strcmp(buf, "ieee80211w") == 0) {
- bss->ieee80211w = atoi(pos);
-#endif /* CONFIG_IEEE80211W */
- } else {
- printf("Line %d: unknown configuration item '%s'\n",
- line, buf);
- errors++;
- }
- }
-
- fclose(f);
-
- if (bss->individual_wep_key_len == 0) {
- /* individual keys are not use; can use key idx0 for broadcast
- * keys */
- bss->broadcast_key_idx_min = 0;
- }
-
- for (i = 0; i < conf->num_bss; i++) {
- bss = &conf->bss[i];
-
- bss->radius->auth_server = bss->radius->auth_servers;
- bss->radius->acct_server = bss->radius->acct_servers;
-
- if (bss->wpa && bss->ieee802_1x) {
- bss->ssid.security_policy = SECURITY_WPA;
- } else if (bss->wpa) {
- bss->ssid.security_policy = SECURITY_WPA_PSK;
- } else if (bss->ieee802_1x) {
- bss->ssid.security_policy = SECURITY_IEEE_802_1X;
- bss->ssid.wep.default_len = bss->default_wep_key_len;
- } else if (bss->ssid.wep.keys_set)
- bss->ssid.security_policy = SECURITY_STATIC_WEP;
- else
- bss->ssid.security_policy = SECURITY_PLAINTEXT;
- }
-
- if (hostapd_config_check(conf))
- errors++;
-
- if (errors) {
- printf("%d errors found in configuration file '%s'\n",
- errors, fname);
- hostapd_config_free(conf);
- conf = NULL;
- }
-
- return conf;
-}
-
-
-int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b)
-{
- int i;
-
- if (a->idx != b->idx || a->default_len != b->default_len)
- return 1;
- for (i = 0; i < NUM_WEP_KEYS; i++)
- if (a->len[i] != b->len[i] ||
- memcmp(a->key[i], b->key[i], a->len[i]) != 0)
- return 1;
- return 0;
-}
-
-
-static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
- int num_servers)
-{
- int i;
-
- for (i = 0; i < num_servers; i++) {
- free(servers[i].shared_secret);
- }
- free(servers);
-}
-
-
-static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
-{
- free(user->identity);
- free(user->password);
- free(user);
-}
-
-
-static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
-{
- int i;
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- free(keys->key[i]);
- keys->key[i] = NULL;
- }
-}
-
-
-static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
-{
- struct hostapd_wpa_psk *psk, *prev;
- struct hostapd_eap_user *user, *prev_user;
-
- if (conf == NULL)
- return;
-
- psk = conf->ssid.wpa_psk;
- while (psk) {
- prev = psk;
- psk = psk->next;
- free(prev);
- }
-
- free(conf->ssid.wpa_passphrase);
- free(conf->ssid.wpa_psk_file);
-#ifdef CONFIG_FULL_DYNAMIC_VLAN
- free(conf->ssid.vlan_tagged_interface);
-#endif /* CONFIG_FULL_DYNAMIC_VLAN */
-
- user = conf->eap_user;
- while (user) {
- prev_user = user;
- user = user->next;
- hostapd_config_free_eap_user(prev_user);
- }
-
- free(conf->dump_log_name);
- free(conf->eap_req_id_text);
- free(conf->accept_mac);
- free(conf->deny_mac);
- free(conf->nas_identifier);
- hostapd_config_free_radius(conf->radius->auth_servers,
- conf->radius->num_auth_servers);
- hostapd_config_free_radius(conf->radius->acct_servers,
- conf->radius->num_acct_servers);
- free(conf->rsn_preauth_interfaces);
- free(conf->ctrl_interface);
- free(conf->ca_cert);
- free(conf->server_cert);
- free(conf->private_key);
- free(conf->private_key_passwd);
- free(conf->eap_sim_db);
- free(conf->radius_server_clients);
- free(conf->test_socket);
- free(conf->radius);
- hostapd_config_free_vlan(conf);
- if (conf->ssid.dyn_vlan_keys) {
- struct hostapd_ssid *ssid = &conf->ssid;
- size_t i;
- for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
- if (ssid->dyn_vlan_keys[i] == NULL)
- continue;
- hostapd_config_free_wep(ssid->dyn_vlan_keys[i]);
- free(ssid->dyn_vlan_keys[i]);
- }
- free(ssid->dyn_vlan_keys);
- ssid->dyn_vlan_keys = NULL;
- }
-}
-
-
-void hostapd_config_free(struct hostapd_config *conf)
-{
- size_t i;
-
- if (conf == NULL)
- return;
-
- for (i = 0; i < conf->num_bss; i++)
- hostapd_config_free_bss(&conf->bss[i]);
- free(conf->bss);
-
- free(conf);
-}
-
-
-/* Perform a binary search for given MAC address from a pre-sorted list.
- * Returns 1 if address is in the list or 0 if not. */
-int hostapd_maclist_found(macaddr *list, int num_entries, const u8 *addr)
-{
- int start, end, middle, res;
-
- start = 0;
- end = num_entries - 1;
-
- while (start <= end) {
- middle = (start + end) / 2;
- res = memcmp(list[middle], addr, ETH_ALEN);
- if (res == 0)
- return 1;
- if (res < 0)
- start = middle + 1;
- else
- end = middle - 1;
- }
-
- return 0;
-}
-
-
-int hostapd_rate_found(int *list, int rate)
-{
- int i;
-
- if (list == NULL)
- return 0;
-
- for (i = 0; list[i] >= 0; i++)
- if (list[i] == rate)
- return 1;
-
- return 0;
-}
-
-
-const char * hostapd_get_vlan_id_ifname(struct hostapd_vlan *vlan, int vlan_id)
-{
- struct hostapd_vlan *v = vlan;
- while (v) {
- if (v->vlan_id == vlan_id || v->vlan_id == VLAN_ID_WILDCARD)
- return v->ifname;
- v = v->next;
- }
- return NULL;
-}
-
-
-const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
- const u8 *addr, const u8 *prev_psk)
-{
- struct hostapd_wpa_psk *psk;
- int next_ok = prev_psk == NULL;
-
- for (psk = conf->ssid.wpa_psk; psk != NULL; psk = psk->next) {
- if (next_ok &&
- (psk->group || memcmp(psk->addr, addr, ETH_ALEN) == 0))
- return psk->psk;
-
- if (psk->psk == prev_psk)
- next_ok = 1;
- }
-
- return NULL;
-}
-
-
-const struct hostapd_eap_user *
-hostapd_get_eap_user(const struct hostapd_bss_config *conf, const u8 *identity,
- size_t identity_len, int phase2)
-{
- struct hostapd_eap_user *user = conf->eap_user;
-
- while (user) {
- if (!phase2 && user->identity == NULL) {
- /* Wildcard match */
- break;
- }
-
- if (!phase2 && user->wildcard_prefix &&
- identity_len >= user->identity_len &&
- memcmp(user->identity, identity, user->identity_len) == 0)
- {
- /* Wildcard prefix match */
- break;
- }
-
- if (user->phase2 == !!phase2 &&
- user->identity_len == identity_len &&
- memcmp(user->identity, identity, identity_len) == 0)
- break;
- user = user->next;
- }
-
- return user;
-}
diff --git a/contrib/hostapd/developer.txt b/contrib/hostapd/developer.txt
deleted file mode 100644
index e1d316341390..000000000000
--- a/contrib/hostapd/developer.txt
+++ /dev/null
@@ -1,219 +0,0 @@
-Developer notes for hostapd
-===========================
-
-hostapd daemon setup, operations, and shutdown
-----------------------------------------------
-
-Files: hostapd.[ch]
-
-Externally called functions:
- hostapd_new_assoc_sta() is called when a station associates with the AP
-
-Event loop functions:
- handle_term() is called on SIGINT and SIGTERM to terminate hostapd process
- handle_reload() is called on SIGHUP to reload configuration
- handle_dump_state() is called on SIGUSR1 to dump station state data to a
- text file
- hostapd_rotate_wep() is called to periodically change WEP keys
-
-
-Configuration parsing
----------------------
-
-Configuration file parsing and data structure definition.
-
-Files: config.[ch]
-
-Externally called functions:
- hostapd_config_read() is called to read and parse a configuration file;
- allocates and returns configuration data structure
- hostapd_config_free() is called to free configuration data structure
- hostapd_maclist_found() is called to check whether a given address is found
- in a list of MAC addresses
-
-
-Kernel driver access
---------------------
-
-Helper functions for configuring the Host AP kernel driver and
-accessing data from it.
-
-Files: driver.[ch]
-
-
-IEEE 802.11 frame handling (netdevice wlan#ap)
-----------------------------------------------
-
-Receive all incoming IEEE 802.11 frames from the kernel driver via
-wlan#ap interface.
-
-Files: receive.c
-
-Externally called functions:
- hostapd_init_sockets() is called to initialize sockets for receiving and
- sending IEEE 802.11 frames via wlan#ap interface
-
-Event loop functions:
- handle_read() is called for each incoming packet from wlan#ap net device
-
-
-Station table
--------------
-
-Files: sta_info.[ch], ap.h
-
-Event loop functions:
- ap_handle_timer() is called to check station activity and to remove
- inactive stations
-
-
-IEEE 802.11 management
-----------------------
-
-IEEE 802.11 management frame sending and processing (mainly,
-authentication and association). IEEE 802.11 station functionality
-(authenticate and associate with another AP as an station).
-
-Files: ieee802_11.[ch]
-
-Externally called functions:
- ieee802_11_mgmt() is called for each received IEEE 802.11 management frame
- (from handle_frame() in hostapd.c)
- ieee802_11_mgmt_cb() is called for each received TX callback of IEEE 802.11
- management frame (from handle_tx_callback() in hostapd.c)
- ieee802_11_send_deauth() is called to send deauthentication frame
- ieee802_11_send_disassoc() is called to send disassociation frame
- ieee802_11_parse_elems() is used to parse information elements in
- IEEE 802.11 management frames
-
-Event loop functions:
- ieee802_11_sta_authenticate() called to retry authentication (with another
- AP)
- ieee802_11_sta_associate() called to retry association (with another AP)
-
-
-IEEE 802.11 authentication
---------------------------
-
-Access control list for IEEE 802.11 authentication. Uses staticly
-configured ACL from configuration files or an external RADIUS
-server. Results from external RADIUS queries are cached to allow
-faster authentication frame processing.
-
-Files: ieee802_11_auth.[ch]
-
-Externally called functions:
- hostapd_acl_init() called once during hostapd startup
- hostapd_acl_deinit() called once during hostapd shutdown
- hostapd_acl_recv_radius() called by IEEE 802.1X code for incoming RADIUS
- Authentication messages (returns 0 if message was processed)
- hostapd_allowed_address() called to check whether a specified station can be
- authenticated
-
-Event loop functions:
- hostapd_acl_expire() is called to expire ACL cache entries
-
-
-IEEE 802.1X Authenticator
--------------------------
-
-Files: ieee802_1x.[ch]
-
-
-Externally called functions:
- ieee802_1x_receive() is called for each incoming EAPOL frame from the
- wireless interface
- ieee802_1x_new_station() is called to start IEEE 802.1X authentication when
- a new station completes IEEE 802.11 association
-
-Event loop functions:
- ieee802_1x_receive_auth() called for each incoming RADIUS Authentication
- message
-
-
-EAPOL state machine
--------------------
-
-IEEE 802.1X state machine for EAPOL.
-
-Files: eapol_sm.[ch]
-
-Externally called functions:
- eapol_sm_step() is called to advance EAPOL state machines after any change
- that could affect their state
-
-Event loop functions:
- eapol_port_timers_tick() called once per second to advance Port Timers state
- machine
-
-
-IEEE 802.11f (IAPP)
--------------------
-
-Files: iapp.[ch]
-
-Externally called functions:
- iapp_new_station() is called to start accounting session when a new station
- completes IEEE 802.11 association or IEEE 802.1X authentication
-
-Event loop functions:
- iapp_receive_udp() is called for incoming IAPP frames over UDP
-
-
-Per station accounting
-----------------------
-
-Send RADIUS Accounting start and stop messages to a RADIUS Accounting
-server. Process incoming RADIUS Accounting messages.
-
-Files: accounting.[ch]
-
-Externally called functions:
- accounting_init() called once during hostapd startup
- accounting_deinit() called once during hostapd shutdown
- accounting_sta_start() called when a station starts new session
- accounting_sta_stop() called when a station session is terminated
-
-Event loop functions:
- accounting_receive() called for each incoming RADIUS Accounting message
- accounting_list_timer() called to retransmit accounting messages and to
- remove expired entries
-
-
-RADIUS messages
----------------
-
-RADIUS message generation and parsing functions.
-
-Files: radius.[ch]
-
-
-Event loop
-----------
-
-Event loop for registering timeout calls, signal handlers, and socket
-read events.
-
-Files: eloop.[ch]
-
-
-RC4
----
-
-RC4 encryption
-
-Files: rc4.[ch]
-
-
-MD5
----
-
-MD5 hash and HMAC-MD5.
-
-Files: md5.[ch]
-
-
-Miscellaneous helper functions
-------------------------------
-
-Files: common.[ch]
diff --git a/contrib/hostapd/eap.h b/contrib/hostapd/eap.h
deleted file mode 100644
index 137719189dfa..000000000000
--- a/contrib/hostapd/eap.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * hostapd / EAP Standalone Authenticator state machine (RFC 4137)
- * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef EAP_H
-#define EAP_H
-
-#include "defs.h"
-#include "eap_defs.h"
-#include "eap_methods.h"
-
-struct eap_sm;
-
-#define EAP_MAX_METHODS 8
-struct eap_user {
- struct {
- int vendor;
- u32 method;
- } methods[EAP_MAX_METHODS];
- u8 *password;
- size_t password_len;
- int password_hash; /* whether password is hashed with
- * nt_password_hash() */
- int phase2;
- int force_version;
-};
-
-enum eapol_bool_var {
- EAPOL_eapSuccess, EAPOL_eapRestart, EAPOL_eapFail, EAPOL_eapResp,
- EAPOL_eapReq, EAPOL_eapNoReq, EAPOL_portEnabled, EAPOL_eapTimeout
-};
-
-struct eapol_callbacks {
- Boolean (*get_bool)(void *ctx, enum eapol_bool_var variable);
- void (*set_bool)(void *ctx, enum eapol_bool_var variable,
- Boolean value);
- void (*set_eapReqData)(void *ctx, const u8 *eapReqData,
- size_t eapReqDataLen);
- void (*set_eapKeyData)(void *ctx, const u8 *eapKeyData,
- size_t eapKeyDataLen);
- int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
- int phase2, struct eap_user *user);
- const char * (*get_eap_req_id_text)(void *ctx, size_t *len);
-};
-
-struct eap_config {
- void *ssl_ctx;
- void *eap_sim_db_priv;
- Boolean backend_auth;
-};
-
-
-#ifdef EAP_SERVER
-
-struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
- struct eap_config *eap_conf);
-void eap_sm_deinit(struct eap_sm *sm);
-int eap_sm_step(struct eap_sm *sm);
-void eap_set_eapRespData(struct eap_sm *sm, const u8 *eapRespData,
- size_t eapRespDataLen);
-void eap_sm_notify_cached(struct eap_sm *sm);
-void eap_sm_pending_cb(struct eap_sm *sm);
-int eap_sm_method_pending(struct eap_sm *sm);
-
-#else /* EAP_SERVER */
-
-static inline struct eap_sm * eap_sm_init(void *eapol_ctx,
- struct eapol_callbacks *eapol_cb,
- struct eap_config *eap_conf)
-{
- return NULL;
-}
-
-static inline void eap_sm_deinit(struct eap_sm *sm)
-{
-}
-
-static inline int eap_sm_step(struct eap_sm *sm)
-{
- return 0;
-}
-
-
-static inline void eap_set_eapRespData(struct eap_sm *sm,
- const u8 *eapRespData,
- size_t eapRespDataLen)
-{
-}
-
-static inline void eap_sm_notify_cached(struct eap_sm *sm)
-{
-}
-
-static inline void eap_sm_pending_cb(struct eap_sm *sm)
-{
-}
-
-static inline int eap_sm_method_pending(struct eap_sm *sm)
-{
- return 0;
-}
-
-#endif /* EAP_SERVER */
-
-#endif /* EAP_H */
diff --git a/contrib/hostapd/eap_peap.c b/contrib/hostapd/eap_peap.c
deleted file mode 100644
index 6ea1f618a1d8..000000000000
--- a/contrib/hostapd/eap_peap.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * hostapd / EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-07.txt)
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "hostapd.h"
-#include "common.h"
-#include "eap_i.h"
-#include "eap_tls_common.h"
-#include "tls.h"
-
-
-/* Maximum supported PEAP version
- * 0 = Microsoft's PEAP version 0; draft-kamath-pppext-peapv0-00.txt
- * 1 = draft-josefsson-ppext-eap-tls-eap-05.txt
- * 2 = draft-josefsson-ppext-eap-tls-eap-07.txt
- */
-#define EAP_PEAP_VERSION 1
-
-
-static void eap_peap_reset(struct eap_sm *sm, void *priv);
-
-
-struct eap_peap_data {
- struct eap_ssl_data ssl;
- enum {
- START, PHASE1, PHASE2_START, PHASE2_ID, PHASE2_METHOD,
- PHASE2_TLV, SUCCESS_REQ, FAILURE_REQ, SUCCESS, FAILURE
- } state;
-
- int peap_version;
- const struct eap_method *phase2_method;
- void *phase2_priv;
- int force_version;
-};
-
-
-static const char * eap_peap_state_txt(int state)
-{
- switch (state) {
- case START:
- return "START";
- case PHASE1:
- return "PHASE1";
- case PHASE2_START:
- return "PHASE2_START";
- case PHASE2_ID:
- return "PHASE2_ID";
- case PHASE2_METHOD:
- return "PHASE2_METHOD";
- case PHASE2_TLV:
- return "PHASE2_TLV";
- case SUCCESS_REQ:
- return "SUCCESS_REQ";
- case FAILURE_REQ:
- return "FAILURE_REQ";
- case SUCCESS:
- return "SUCCESS";
- case FAILURE:
- return "FAILURE";
- default:
- return "Unknown?!";
- }
-}
-
-
-static void eap_peap_state(struct eap_peap_data *data, int state)
-{
- wpa_printf(MSG_DEBUG, "EAP-PEAP: %s -> %s",
- eap_peap_state_txt(data->state),
- eap_peap_state_txt(state));
- data->state = state;
-}
-
-
-static EapType eap_peap_req_success(struct eap_sm *sm,
- struct eap_peap_data *data)
-{
- if (data->state == FAILURE || data->state == FAILURE_REQ) {
- eap_peap_state(data, FAILURE);
- return EAP_TYPE_NONE;
- }
-
- if (data->peap_version == 0) {
- sm->tlv_request = TLV_REQ_SUCCESS;
- eap_peap_state(data, PHASE2_TLV);
- return EAP_TYPE_TLV;
- } else {
- eap_peap_state(data, SUCCESS_REQ);
- return EAP_TYPE_NONE;
- }
-}
-
-
-static EapType eap_peap_req_failure(struct eap_sm *sm,
- struct eap_peap_data *data)
-{
- if (data->state == FAILURE || data->state == FAILURE_REQ ||
- data->state == SUCCESS_REQ ||
- (data->phase2_method &&
- data->phase2_method->method == EAP_TYPE_TLV)) {
- eap_peap_state(data, FAILURE);
- return EAP_TYPE_NONE;
- }
-
- if (data->peap_version == 0) {
- sm->tlv_request = TLV_REQ_FAILURE;
- eap_peap_state(data, PHASE2_TLV);
- return EAP_TYPE_TLV;
- } else {
- eap_peap_state(data, FAILURE_REQ);
- return EAP_TYPE_NONE;
- }
-}
-
-
-static void * eap_peap_init(struct eap_sm *sm)
-{
- struct eap_peap_data *data;
-
- data = wpa_zalloc(sizeof(*data));
- if (data == NULL)
- return NULL;
- data->peap_version = EAP_PEAP_VERSION;
- data->force_version = -1;
- if (sm->user && sm->user->force_version >= 0) {
- data->force_version = sm->user->force_version;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: forcing version %d",
- data->force_version);
- data->peap_version = data->force_version;
- }
- data->state = START;
-
- if (eap_tls_ssl_init(sm, &data->ssl, 0)) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Failed to initialize SSL.");
- eap_peap_reset(sm, data);
- return NULL;
- }
-
- return data;
-}
-
-
-static void eap_peap_reset(struct eap_sm *sm, void *priv)
-{
- struct eap_peap_data *data = priv;
- if (data == NULL)
- return;
- if (data->phase2_priv && data->phase2_method)
- data->phase2_method->reset(sm, data->phase2_priv);
- eap_tls_ssl_deinit(sm, &data->ssl);
- free(data);
-}
-
-
-static u8 * eap_peap_build_start(struct eap_sm *sm, struct eap_peap_data *data,
- int id, size_t *reqDataLen)
-{
- struct eap_hdr *req;
- u8 *pos;
-
- *reqDataLen = sizeof(*req) + 2;
- req = malloc(*reqDataLen);
- if (req == NULL) {
- wpa_printf(MSG_ERROR, "EAP-PEAP: Failed to allocate memory for"
- " request");
- eap_peap_state(data, FAILURE);
- return NULL;
- }
-
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
- req->length = htons(*reqDataLen);
- pos = (u8 *) (req + 1);
- *pos++ = EAP_TYPE_PEAP;
- *pos = EAP_TLS_FLAGS_START | data->peap_version;
-
- eap_peap_state(data, PHASE1);
-
- return (u8 *) req;
-}
-
-
-static u8 * eap_peap_build_req(struct eap_sm *sm, struct eap_peap_data *data,
- int id, size_t *reqDataLen)
-{
- int res;
- u8 *req;
-
- res = eap_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_PEAP,
- data->peap_version, id, &req,
- reqDataLen);
-
- if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase1 done, starting "
- "Phase2");
- eap_peap_state(data, PHASE2_START);
- }
-
- if (res == 1)
- return eap_tls_build_ack(reqDataLen, id, EAP_TYPE_PEAP,
- data->peap_version);
- return req;
-}
-
-
-static u8 * eap_peap_encrypt(struct eap_sm *sm, struct eap_peap_data *data,
- int id, u8 *plain, size_t plain_len,
- size_t *out_len)
-{
- int res;
- u8 *pos;
- struct eap_hdr *req;
-
- /* TODO: add support for fragmentation, if needed. This will need to
- * add TLS Message Length field, if the frame is fragmented. */
- req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
- if (req == NULL)
- return NULL;
-
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
-
- pos = (u8 *) (req + 1);
- *pos++ = EAP_TYPE_PEAP;
- *pos++ = data->peap_version;
-
- res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
- plain, plain_len,
- pos, data->ssl.tls_out_limit);
- if (res < 0) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Failed to encrypt Phase 2 "
- "data");
- free(req);
- return NULL;
- }
-
- *out_len = sizeof(struct eap_hdr) + 2 + res;
- req->length = host_to_be16(*out_len);
- return (u8 *) req;
-}
-
-
-static u8 * eap_peap_build_phase2_req(struct eap_sm *sm,
- struct eap_peap_data *data,
- int id, size_t *reqDataLen)
-{
- u8 *req, *buf, *encr_req;
- size_t req_len;
-
- buf = req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
- &req_len);
- if (req == NULL)
- return NULL;
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
- req, req_len);
-
- if (data->peap_version == 0 &&
- data->phase2_method->method != EAP_TYPE_TLV) {
- req += sizeof(struct eap_hdr);
- req_len -= sizeof(struct eap_hdr);
- }
-
- encr_req = eap_peap_encrypt(sm, data, id, req, req_len, reqDataLen);
- free(buf);
-
- return encr_req;
-}
-
-
-static u8 * eap_peap_build_phase2_term(struct eap_sm *sm,
- struct eap_peap_data *data,
- int id, size_t *reqDataLen, int success)
-{
- u8 *encr_req;
- size_t req_len;
- struct eap_hdr *hdr;
-
- req_len = sizeof(*hdr);
- hdr = wpa_zalloc(req_len);
- if (hdr == NULL)
- return NULL;
-
- hdr->code = success ? EAP_CODE_SUCCESS : EAP_CODE_FAILURE;
- hdr->identifier = id;
- hdr->length = htons(req_len);
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
- (u8 *) hdr, req_len);
-
- encr_req = eap_peap_encrypt(sm, data, id, (u8 *) hdr, req_len,
- reqDataLen);
- free(hdr);
-
- return encr_req;
-}
-
-
-static u8 * eap_peap_buildReq(struct eap_sm *sm, void *priv, int id,
- size_t *reqDataLen)
-{
- struct eap_peap_data *data = priv;
-
- switch (data->state) {
- case START:
- return eap_peap_build_start(sm, data, id, reqDataLen);
- case PHASE1:
- return eap_peap_build_req(sm, data, id, reqDataLen);
- case PHASE2_ID:
- case PHASE2_METHOD:
- case PHASE2_TLV:
- return eap_peap_build_phase2_req(sm, data, id, reqDataLen);
- case SUCCESS_REQ:
- return eap_peap_build_phase2_term(sm, data, id, reqDataLen, 1);
- case FAILURE_REQ:
- return eap_peap_build_phase2_term(sm, data, id, reqDataLen, 0);
- default:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d",
- __func__, data->state);
- return NULL;
- }
-}
-
-
-static Boolean eap_peap_check(struct eap_sm *sm, void *priv,
- u8 *respData, size_t respDataLen)
-{
- struct eap_hdr *resp;
- u8 *pos;
-
- resp = (struct eap_hdr *) respData;
- pos = (u8 *) (resp + 1);
- if (respDataLen < sizeof(*resp) + 2 || *pos != EAP_TYPE_PEAP ||
- (ntohs(resp->length)) > respDataLen) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Invalid frame");
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static int eap_peap_phase2_init(struct eap_sm *sm, struct eap_peap_data *data,
- EapType eap_type)
-{
- if (data->phase2_priv && data->phase2_method) {
- data->phase2_method->reset(sm, data->phase2_priv);
- data->phase2_method = NULL;
- data->phase2_priv = NULL;
- }
- data->phase2_method = eap_sm_get_eap_methods(EAP_VENDOR_IETF,
- eap_type);
- if (!data->phase2_method)
- return -1;
-
- sm->init_phase2 = 1;
- data->phase2_priv = data->phase2_method->init(sm);
- sm->init_phase2 = 0;
- return 0;
-}
-
-
-static void eap_peap_process_phase2_response(struct eap_sm *sm,
- struct eap_peap_data *data,
- u8 *in_data, size_t in_len)
-{
- u8 next_type = EAP_TYPE_NONE;
- struct eap_hdr *hdr;
- u8 *pos;
- size_t left;
-
- if (data->phase2_priv == NULL) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - Phase2 not "
- "initialized?!", __func__);
- return;
- }
-
- hdr = (struct eap_hdr *) in_data;
- pos = (u8 *) (hdr + 1);
-
- if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
- left = in_len - sizeof(*hdr);
- wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Phase2 type Nak'ed; "
- "allowed types", pos + 1, left - 1);
- eap_sm_process_nak(sm, pos + 1, left - 1);
- if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
- sm->user->methods[sm->user_eap_method_index].method !=
- EAP_TYPE_NONE) {
- next_type = sm->user->methods[
- sm->user_eap_method_index++].method;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d",
- next_type);
- } else {
- next_type = eap_peap_req_failure(sm, data);
- }
- eap_peap_phase2_init(sm, data, next_type);
- return;
- }
-
- if (data->phase2_method->check(sm, data->phase2_priv, in_data,
- in_len)) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 check() asked to "
- "ignore the packet");
- return;
- }
-
- data->phase2_method->process(sm, data->phase2_priv, in_data, in_len);
-
- if (!data->phase2_method->isDone(sm, data->phase2_priv))
- return;
-
-
- if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method failed");
- next_type = eap_peap_req_failure(sm, data);
- eap_peap_phase2_init(sm, data, next_type);
- return;
- }
-
- switch (data->state) {
- case PHASE2_ID:
- if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
- wpa_hexdump_ascii(MSG_DEBUG, "EAP_PEAP: Phase2 "
- "Identity not found in the user "
- "database",
- sm->identity, sm->identity_len);
- next_type = eap_peap_req_failure(sm, data);
- break;
- }
-
- eap_peap_state(data, PHASE2_METHOD);
- next_type = sm->user->methods[0].method;
- sm->user_eap_method_index = 1;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type);
- break;
- case PHASE2_METHOD:
- next_type = eap_peap_req_success(sm, data);
- break;
- case PHASE2_TLV:
- if (sm->tlv_request == TLV_REQ_SUCCESS ||
- data->state == SUCCESS_REQ) {
- eap_peap_state(data, SUCCESS);
- } else {
- eap_peap_state(data, FAILURE);
- }
- break;
- case FAILURE:
- break;
- default:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d",
- __func__, data->state);
- break;
- }
-
- eap_peap_phase2_init(sm, data, next_type);
-}
-
-
-static void eap_peap_process_phase2(struct eap_sm *sm,
- struct eap_peap_data *data,
- struct eap_hdr *resp,
- u8 *in_data, size_t in_len)
-{
- u8 *in_decrypted;
- int len_decrypted, len, res;
- struct eap_hdr *hdr;
- size_t buf_len;
-
- wpa_printf(MSG_DEBUG, "EAP-PEAP: received %lu bytes encrypted data for"
- " Phase 2", (unsigned long) in_len);
-
- res = eap_tls_data_reassemble(sm, &data->ssl, &in_data, &in_len);
- if (res < 0 || res == 1)
- return;
-
- buf_len = in_len;
- if (data->ssl.tls_in_total > buf_len)
- buf_len = data->ssl.tls_in_total;
- in_decrypted = malloc(buf_len);
- if (in_decrypted == NULL) {
- free(data->ssl.tls_in);
- data->ssl.tls_in = NULL;
- data->ssl.tls_in_len = 0;
- wpa_printf(MSG_WARNING, "EAP-PEAP: failed to allocate memory "
- "for decryption");
- return;
- }
-
- len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
- in_data, in_len,
- in_decrypted, buf_len);
- free(data->ssl.tls_in);
- data->ssl.tls_in = NULL;
- data->ssl.tls_in_len = 0;
- if (len_decrypted < 0) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Failed to decrypt Phase 2 "
- "data");
- free(in_decrypted);
- eap_peap_state(data, FAILURE);
- return;
- }
-
- wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP",
- in_decrypted, len_decrypted);
-
- hdr = (struct eap_hdr *) in_decrypted;
-
- if (data->peap_version == 0 && data->state != PHASE2_TLV) {
- struct eap_hdr *nhdr = malloc(sizeof(struct eap_hdr) +
- len_decrypted);
- if (nhdr == NULL) {
- free(in_decrypted);
- return;
- }
- memcpy((u8 *) (nhdr + 1), in_decrypted, len_decrypted);
- free(in_decrypted);
- nhdr->code = resp->code;
- nhdr->identifier = resp->identifier;
- nhdr->length = host_to_be16(sizeof(struct eap_hdr) +
- len_decrypted);
-
- len_decrypted += sizeof(struct eap_hdr);
- in_decrypted = (u8 *) nhdr;
- }
- hdr = (struct eap_hdr *) in_decrypted;
- if (len_decrypted < (int) sizeof(*hdr)) {
- free(in_decrypted);
- wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
- "EAP frame (len=%d)", len_decrypted);
- eap_peap_req_failure(sm, data);
- return;
- }
- len = be_to_host16(hdr->length);
- if (len > len_decrypted) {
- free(in_decrypted);
- wpa_printf(MSG_INFO, "EAP-PEAP: Length mismatch in "
- "Phase 2 EAP frame (len=%d hdr->length=%d)",
- len_decrypted, len);
- eap_peap_req_failure(sm, data);
- return;
- }
- wpa_printf(MSG_DEBUG, "EAP-PEAP: received Phase 2: code=%d "
- "identifier=%d length=%d", hdr->code, hdr->identifier, len);
- switch (hdr->code) {
- case EAP_CODE_RESPONSE:
- eap_peap_process_phase2_response(sm, data, (u8 *) hdr, len);
- break;
- case EAP_CODE_SUCCESS:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Success");
- if (data->state == SUCCESS_REQ) {
- eap_peap_state(data, SUCCESS);
- }
- break;
- case EAP_CODE_FAILURE:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Failure");
- eap_peap_state(data, FAILURE);
- break;
- default:
- wpa_printf(MSG_INFO, "EAP-PEAP: Unexpected code=%d in "
- "Phase 2 EAP header", hdr->code);
- break;
- }
-
- free(in_decrypted);
- }
-
-
-static void eap_peap_process(struct eap_sm *sm, void *priv,
- u8 *respData, size_t respDataLen)
-{
- struct eap_peap_data *data = priv;
- struct eap_hdr *resp;
- u8 *pos, flags;
- int left;
- unsigned int tls_msg_len;
- int peer_version;
-
- resp = (struct eap_hdr *) respData;
- pos = (u8 *) (resp + 1);
- pos++;
- flags = *pos++;
- left = htons(resp->length) - sizeof(struct eap_hdr) - 2;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Received packet(len=%lu) - "
- "Flags 0x%02x", (unsigned long) respDataLen, flags);
- peer_version = flags & EAP_PEAP_VERSION_MASK;
- if (data->force_version >= 0 && peer_version != data->force_version) {
- wpa_printf(MSG_INFO, "EAP-PEAP: peer did not select the forced"
- " version (forced=%d peer=%d) - reject",
- data->force_version, peer_version);
- eap_peap_state(data, FAILURE);
- return;
- }
- if (peer_version < data->peap_version) {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: peer ver=%d, own ver=%d; "
- "use version %d",
- peer_version, data->peap_version, peer_version);
- data->peap_version = peer_version;
- }
- if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
- if (left < 4) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Short frame with TLS "
- "length");
- eap_peap_state(data, FAILURE);
- return;
- }
- tls_msg_len = (pos[0] << 24) | (pos[1] << 16) | (pos[2] << 8) |
- pos[3];
- wpa_printf(MSG_DEBUG, "EAP-PEAP: TLS Message Length: %d",
- tls_msg_len);
- if (data->ssl.tls_in_left == 0) {
- data->ssl.tls_in_total = tls_msg_len;
- data->ssl.tls_in_left = tls_msg_len;
- free(data->ssl.tls_in);
- data->ssl.tls_in = NULL;
- data->ssl.tls_in_len = 0;
- }
- pos += 4;
- left -= 4;
- }
-
- switch (data->state) {
- case PHASE1:
- if (eap_tls_process_helper(sm, &data->ssl, pos, left) < 0) {
- wpa_printf(MSG_INFO, "EAP-PEAP: TLS processing "
- "failed");
- eap_peap_state(data, FAILURE);
- }
- break;
- case PHASE2_START:
- eap_peap_state(data, PHASE2_ID);
- eap_peap_phase2_init(sm, data, EAP_TYPE_IDENTITY);
- break;
- case PHASE2_ID:
- case PHASE2_METHOD:
- case PHASE2_TLV:
- eap_peap_process_phase2(sm, data, resp, pos, left);
- break;
- case SUCCESS_REQ:
- eap_peap_state(data, SUCCESS);
- break;
- case FAILURE_REQ:
- eap_peap_state(data, FAILURE);
- break;
- default:
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Unexpected state %d in %s",
- data->state, __func__);
- break;
- }
-
- if (tls_connection_get_write_alerts(sm->ssl_ctx, data->ssl.conn) > 1) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Locally detected fatal error "
- "in TLS processing");
- eap_peap_state(data, FAILURE);
- }
-}
-
-
-static Boolean eap_peap_isDone(struct eap_sm *sm, void *priv)
-{
- struct eap_peap_data *data = priv;
- return data->state == SUCCESS || data->state == FAILURE;
-}
-
-
-static u8 * eap_peap_getKey(struct eap_sm *sm, void *priv, size_t *len)
-{
- struct eap_peap_data *data = priv;
- u8 *eapKeyData;
-
- if (data->state != SUCCESS)
- return NULL;
-
- /* TODO: PEAPv1 - different label in some cases */
- eapKeyData = eap_tls_derive_key(sm, &data->ssl,
- "client EAP encryption",
- EAP_TLS_KEY_LEN);
- if (eapKeyData) {
- *len = EAP_TLS_KEY_LEN;
- wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Derived key",
- eapKeyData, EAP_TLS_KEY_LEN);
- } else {
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Failed to derive key");
- }
-
- return eapKeyData;
-}
-
-
-static Boolean eap_peap_isSuccess(struct eap_sm *sm, void *priv)
-{
- struct eap_peap_data *data = priv;
- return data->state == SUCCESS;
-}
-
-
-int eap_server_peap_register(void)
-{
- struct eap_method *eap;
- int ret;
-
- eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
- EAP_VENDOR_IETF, EAP_TYPE_PEAP, "PEAP");
- if (eap == NULL)
- return -1;
-
- eap->init = eap_peap_init;
- eap->reset = eap_peap_reset;
- eap->buildReq = eap_peap_buildReq;
- eap->check = eap_peap_check;
- eap->process = eap_peap_process;
- eap->isDone = eap_peap_isDone;
- eap->getKey = eap_peap_getKey;
- eap->isSuccess = eap_peap_isSuccess;
-
- ret = eap_server_method_register(eap);
- if (ret)
- eap_server_method_free(eap);
- return ret;
-}
diff --git a/contrib/hostapd/eap_tls_common.c b/contrib/hostapd/eap_tls_common.c
deleted file mode 100644
index ce61729bc944..000000000000
--- a/contrib/hostapd/eap_tls_common.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * hostapd / EAP-TLS/PEAP/TTLS common functions
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "hostapd.h"
-#include "common.h"
-#include "eap_i.h"
-#include "eap_tls_common.h"
-#include "sha1.h"
-#include "tls.h"
-
-
-int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
- int verify_peer)
-{
- data->eap = sm;
- data->phase2 = sm->init_phase2;
-
- data->conn = tls_connection_init(sm->ssl_ctx);
- if (data->conn == NULL) {
- wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
- "connection");
- return -1;
- }
-
- if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer)) {
- wpa_printf(MSG_INFO, "SSL: Failed to configure verification "
- "of TLS peer certificate");
- tls_connection_deinit(sm->ssl_ctx, data->conn);
- data->conn = NULL;
- return -1;
- }
-
- /* TODO: make this configurable */
- data->tls_out_limit = 1398;
- if (data->phase2) {
- /* Limit the fragment size in the inner TLS authentication
- * since the outer authentication with EAP-PEAP does not yet
- * support fragmentation */
- if (data->tls_out_limit > 100)
- data->tls_out_limit -= 100;
- }
- return 0;
-}
-
-
-void eap_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
-{
- tls_connection_deinit(sm->ssl_ctx, data->conn);
- free(data->tls_in);
- free(data->tls_out);
-}
-
-
-u8 * eap_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- char *label, size_t len)
-{
- struct tls_keys keys;
- u8 *rnd = NULL, *out;
-
- out = malloc(len);
- if (out == NULL)
- return NULL;
-
- if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
- 0)
- return out;
-
- if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
- goto fail;
-
- if (keys.client_random == NULL || keys.server_random == NULL ||
- keys.master_key == NULL)
- goto fail;
-
- rnd = malloc(keys.client_random_len + keys.server_random_len);
- if (rnd == NULL)
- goto fail;
- memcpy(rnd, keys.client_random, keys.client_random_len);
- memcpy(rnd + keys.client_random_len, keys.server_random,
- keys.server_random_len);
-
- if (tls_prf(keys.master_key, keys.master_key_len,
- label, rnd, keys.client_random_len +
- keys.server_random_len, out, len))
- goto fail;
-
- free(rnd);
- return out;
-
-fail:
- free(out);
- free(rnd);
- return NULL;
-}
-
-
-int eap_tls_data_reassemble(struct eap_sm *sm, struct eap_ssl_data *data,
- u8 **in_data, size_t *in_len)
-{
- u8 *buf;
-
- if (data->tls_in_left > *in_len || data->tls_in) {
- if (*in_len == 0) {
- wpa_printf(MSG_INFO, "SSL: Empty fragment when trying "
- "to reassemble");
- return -1;
- }
- if (data->tls_in_len + *in_len > 65536) {
- /* Limit length to avoid rogue peers from causing large
- * memory allocations. */
- free(data->tls_in);
- data->tls_in = NULL;
- data->tls_in_len = 0;
- wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size"
- " over 64 kB)");
- return -1;
- }
- buf = realloc(data->tls_in, data->tls_in_len + *in_len);
- if (buf == NULL) {
- free(data->tls_in);
- data->tls_in = NULL;
- data->tls_in_len = 0;
- wpa_printf(MSG_INFO, "SSL: Could not allocate memory "
- "for TLS data");
- return -1;
- }
- memcpy(buf + data->tls_in_len, *in_data, *in_len);
- data->tls_in = buf;
- data->tls_in_len += *in_len;
- if (*in_len > data->tls_in_left) {
- wpa_printf(MSG_INFO, "SSL: more data than TLS message "
- "length indicated");
- data->tls_in_left = 0;
- return -1;
- }
- data->tls_in_left -= *in_len;
- if (data->tls_in_left > 0) {
- wpa_printf(MSG_DEBUG, "SSL: Need %lu bytes more input "
- "data", (unsigned long) data->tls_in_left);
- return 1;
- }
-
- *in_data = data->tls_in;
- *in_len = data->tls_in_len;
- } else
- data->tls_in_left = 0;
-
- return 0;
-}
-
-
-int eap_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
- u8 *in_data, size_t in_len)
-{
- WPA_ASSERT(data->tls_out_len == 0 || in_len == 0);
-
- if (data->tls_out_len == 0) {
- /* No more data to send out - expect to receive more data from
- * the peer. */
- int res = eap_tls_data_reassemble(sm, data, &in_data, &in_len);
- if (res < 0 || res == 1) {
- wpa_printf(MSG_DEBUG, "SSL: data reassembly failed");
- return res;
- }
- /* Full TLS message reassembled - continue handshake processing
- */
- if (data->tls_out) {
- /* This should not happen.. */
- wpa_printf(MSG_INFO, "SSL: eap_tls_process_helper - "
- "pending tls_out data even though "
- "tls_out_len = 0");
- free(data->tls_out);
- WPA_ASSERT(data->tls_out == NULL);
- }
- data->tls_out = tls_connection_server_handshake(
- sm->ssl_ctx, data->conn, in_data, in_len,
- &data->tls_out_len);
-
- /* Clear reassembled input data (if the buffer was needed). */
- data->tls_in_left = data->tls_in_total = data->tls_in_len = 0;
- free(data->tls_in);
- data->tls_in = NULL;
- }
-
- if (data->tls_out == NULL) {
- wpa_printf(MSG_DEBUG, "SSL: failed to generate output data");
- data->tls_out_len = 0;
- return -1;
- }
- if (data->tls_out_len == 0) {
- /* TLS negotiation should now be complete since all other cases
- * needing more that should have been catched above based on
- * the TLS Message Length field. */
- wpa_printf(MSG_DEBUG, "SSL: No data to be sent out");
- free(data->tls_out);
- data->tls_out = NULL;
-
- if (tls_connection_get_read_alerts(sm->ssl_ctx, data->conn)) {
- wpa_printf(MSG_DEBUG, "SSL: Remote end sent a fatal "
- "alert - abort handshake");
- return -1;
- }
-
- return 1;
- }
-
- wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total "
- "%lu bytes)",
- (unsigned long) data->tls_out_len - data->tls_out_pos,
- (unsigned long) data->tls_out_len);
-
- return 0;
-}
-
-
-int eap_tls_buildReq_helper(struct eap_sm *sm, struct eap_ssl_data *data,
- int eap_type, int peap_version, u8 id,
- u8 **out_data, size_t *out_len)
-{
- size_t len;
- u8 *pos, *flags;
- struct eap_hdr *req;
-
- *out_len = 0;
-
- req = malloc(sizeof(struct eap_hdr) + 2 + 4 + data->tls_out_limit);
- if (req == NULL) {
- *out_data = NULL;
- return -1;
- }
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
- pos = (u8 *) (req + 1);
- *pos++ = eap_type;
- flags = pos++;
- *flags = peap_version;
- if (data->tls_out_pos == 0 &&
- data->tls_out_len > data->tls_out_limit) {
- *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
- *pos++ = (data->tls_out_len >> 24) & 0xff;
- *pos++ = (data->tls_out_len >> 16) & 0xff;
- *pos++ = (data->tls_out_len >> 8) & 0xff;
- *pos++ = data->tls_out_len & 0xff;
- }
-
- len = data->tls_out_len - data->tls_out_pos;
- if (len > data->tls_out_limit) {
- *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS;
- len = data->tls_out_limit;
- wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments "
- "will follow", (unsigned long) len);
- }
- memcpy(pos, &data->tls_out[data->tls_out_pos], len);
- data->tls_out_pos += len;
- *out_len = (pos - (u8 *) req) + len;
- req->length = htons(*out_len);
- *out_data = (u8 *) req;
-
- if (!(*flags & EAP_TLS_FLAGS_MORE_FRAGMENTS)) {
- data->tls_out_len = 0;
- data->tls_out_pos = 0;
- free(data->tls_out);
- data->tls_out = NULL;
- }
-
- return 0;
-}
-
-
-u8 * eap_tls_build_ack(size_t *reqDataLen, u8 id, int eap_type,
- int peap_version)
-{
- struct eap_hdr *req;
- u8 *pos;
-
- *reqDataLen = sizeof(struct eap_hdr) + 2;
- req = malloc(*reqDataLen);
- if (req == NULL)
- return NULL;
- wpa_printf(MSG_DEBUG, "SSL: Building ACK");
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
- req->length = htons(*reqDataLen);
- pos = (u8 *) (req + 1);
- *pos++ = eap_type; /* Type */
- *pos = peap_version; /* Flags */
- return (u8 *) req;
-}
diff --git a/contrib/hostapd/eap_tls_common.h b/contrib/hostapd/eap_tls_common.h
deleted file mode 100644
index 6c9d69603ed0..000000000000
--- a/contrib/hostapd/eap_tls_common.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * hostapd / EAP-TLS/PEAP/TTLS common functions
- * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef EAP_TLS_COMMON_H
-#define EAP_TLS_COMMON_H
-
-struct eap_ssl_data {
- struct tls_connection *conn;
-
- u8 *tls_out;
- size_t tls_out_len;
- size_t tls_out_pos;
- size_t tls_out_limit;
- u8 *tls_in;
- size_t tls_in_len;
- size_t tls_in_left;
- size_t tls_in_total;
-
- int phase2;
-
- struct eap_sm *eap;
-};
-
-
-/* EAP TLS Flags */
-#define EAP_TLS_FLAGS_LENGTH_INCLUDED 0x80
-#define EAP_TLS_FLAGS_MORE_FRAGMENTS 0x40
-#define EAP_TLS_FLAGS_START 0x20
-#define EAP_PEAP_VERSION_MASK 0x07
-
- /* could be up to 128 bytes, but only the first 64 bytes are used */
-#define EAP_TLS_KEY_LEN 64
-
-
-int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
- int verify_peer);
-void eap_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
-u8 * eap_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
- char *label, size_t len);
-int eap_tls_data_reassemble(struct eap_sm *sm, struct eap_ssl_data *data,
- u8 **in_data, size_t *in_len);
-int eap_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
- u8 *in_data, size_t in_len);
-int eap_tls_buildReq_helper(struct eap_sm *sm, struct eap_ssl_data *data,
- int eap_type, int peap_version, u8 id,
- u8 **out_data, size_t *out_len);
-u8 * eap_tls_build_ack(size_t *reqDataLen, u8 id, int eap_type,
- int peap_version);
-
-#endif /* EAP_TLS_COMMON_H */
diff --git a/contrib/hostapd/eap_tlv.c b/contrib/hostapd/eap_tlv.c
deleted file mode 100644
index b48e1861c57d..000000000000
--- a/contrib/hostapd/eap_tlv.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * hostapd / EAP-TLV (draft-josefsson-pppext-eap-tls-eap-07.txt)
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "hostapd.h"
-#include "common.h"
-#include "eap_i.h"
-
-
-/* EAP-TLV TLVs (draft-josefsson-ppext-eap-tls-eap-07.txt) */
-#define EAP_TLV_RESULT_TLV 3 /* Acknowledged Result */
-#define EAP_TLV_NAK_TLV 4
-#define EAP_TLV_CRYPTO_BINDING_TLV 5
-#define EAP_TLV_CONNECTION_BINDING_TLV 6
-#define EAP_TLV_VENDOR_SPECIFIC_TLV 7
-#define EAP_TLV_URI_TLV 8
-#define EAP_TLV_EAP_PAYLOAD_TLV 9
-#define EAP_TLV_INTERMEDIATE_RESULT_TLV 10
-
-#define EAP_TLV_RESULT_SUCCESS 1
-#define EAP_TLV_RESULT_FAILURE 2
-
-
-struct eap_tlv_data {
- enum { CONTINUE, SUCCESS, FAILURE } state;
-};
-
-
-static void * eap_tlv_init(struct eap_sm *sm)
-{
- struct eap_tlv_data *data;
-
- data = wpa_zalloc(sizeof(*data));
- if (data == NULL)
- return NULL;
- data->state = CONTINUE;
-
- return data;
-}
-
-
-static void eap_tlv_reset(struct eap_sm *sm, void *priv)
-{
- struct eap_tlv_data *data = priv;
- free(data);
-}
-
-
-static u8 * eap_tlv_buildReq(struct eap_sm *sm, void *priv, int id,
- size_t *reqDataLen)
-{
- struct eap_hdr *req;
- u8 *pos;
- u16 status;
-
- if (sm->tlv_request == TLV_REQ_SUCCESS) {
- status = EAP_TLV_RESULT_SUCCESS;
- } else {
- status = EAP_TLV_RESULT_FAILURE;
- }
-
- *reqDataLen = sizeof(struct eap_hdr) + 1 + 6;
- req = malloc(*reqDataLen);
- if (req == NULL)
- return NULL;
-
- req->code = EAP_CODE_REQUEST;
- req->identifier = id;
- req->length = host_to_be16(*reqDataLen);
- pos = (u8 *) (req + 1);
- *pos++ = EAP_TYPE_TLV;
- *pos++ = 0x80; /* Mandatory */
- *pos++ = EAP_TLV_RESULT_TLV;
- /* Length */
- *pos++ = 0;
- *pos++ = 2;
- /* Status */
- *pos++ = status >> 8;
- *pos++ = status & 0xff;
-
- return (u8 *) req;
-}
-
-
-static Boolean eap_tlv_check(struct eap_sm *sm, void *priv,
- u8 *respData, size_t respDataLen)
-{
- struct eap_hdr *resp;
- u8 *pos;
-
- resp = (struct eap_hdr *) respData;
- pos = (u8 *) (resp + 1);
- if (respDataLen < sizeof(*resp) + 1 || *pos != EAP_TYPE_TLV ||
- (ntohs(resp->length)) > respDataLen) {
- wpa_printf(MSG_INFO, "EAP-TLV: Invalid frame");
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static void eap_tlv_process(struct eap_sm *sm, void *priv,
- u8 *respData, size_t respDataLen)
-{
- struct eap_tlv_data *data = priv;
- struct eap_hdr *resp;
- u8 *pos;
- size_t left;
- u8 *result_tlv = NULL;
- size_t result_tlv_len = 0;
- int tlv_type, mandatory, tlv_len;
-
- resp = (struct eap_hdr *) respData;
- pos = (u8 *) (resp + 1);
-
- /* Parse TLVs */
- left = be_to_host16(resp->length) - sizeof(struct eap_hdr) - 1;
- pos = (u8 *) (resp + 1);
- pos++;
- wpa_hexdump(MSG_DEBUG, "EAP-TLV: Received TLVs", pos, left);
- while (left >= 4) {
- mandatory = !!(pos[0] & 0x80);
- tlv_type = pos[0] & 0x3f;
- tlv_type = (tlv_type << 8) | pos[1];
- tlv_len = ((int) pos[2] << 8) | pos[3];
- pos += 4;
- left -= 4;
- if ((size_t) tlv_len > left) {
- wpa_printf(MSG_DEBUG, "EAP-TLV: TLV underrun "
- "(tlv_len=%d left=%lu)", tlv_len,
- (unsigned long) left);
- data->state = FAILURE;
- return;
- }
- switch (tlv_type) {
- case EAP_TLV_RESULT_TLV:
- result_tlv = pos;
- result_tlv_len = tlv_len;
- break;
- default:
- wpa_printf(MSG_DEBUG, "EAP-TLV: Unsupported TLV Type "
- "%d%s", tlv_type,
- mandatory ? " (mandatory)" : "");
- if (mandatory) {
- data->state = FAILURE;
- return;
- }
- /* Ignore this TLV, but process other TLVs */
- break;
- }
-
- pos += tlv_len;
- left -= tlv_len;
- }
- if (left) {
- wpa_printf(MSG_DEBUG, "EAP-TLV: Last TLV too short in "
- "Request (left=%lu)", (unsigned long) left);
- data->state = FAILURE;
- return;
- }
-
- /* Process supported TLVs */
- if (result_tlv) {
- int status;
- const char *requested;
-
- wpa_hexdump(MSG_DEBUG, "EAP-TLV: Result TLV",
- result_tlv, result_tlv_len);
- if (result_tlv_len < 2) {
- wpa_printf(MSG_INFO, "EAP-TLV: Too short Result TLV "
- "(len=%lu)",
- (unsigned long) result_tlv_len);
- data->state = FAILURE;
- return;
- }
- requested = sm->tlv_request == TLV_REQ_SUCCESS ? "Success" :
- "Failure";
- status = ((int) result_tlv[0] << 8) | result_tlv[1];
- if (status == EAP_TLV_RESULT_SUCCESS) {
- wpa_printf(MSG_INFO, "EAP-TLV: TLV Result - Success "
- "- requested %s", requested);
- if (sm->tlv_request == TLV_REQ_SUCCESS)
- data->state = SUCCESS;
- else
- data->state = FAILURE;
-
- } else if (status == EAP_TLV_RESULT_FAILURE) {
- wpa_printf(MSG_INFO, "EAP-TLV: TLV Result - Failure - "
- "requested %s", requested);
- if (sm->tlv_request == TLV_REQ_FAILURE)
- data->state = SUCCESS;
- else
- data->state = FAILURE;
- } else {
- wpa_printf(MSG_INFO, "EAP-TLV: Unknown TLV Result "
- "Status %d", status);
- data->state = FAILURE;
- }
- }
-}
-
-
-static Boolean eap_tlv_isDone(struct eap_sm *sm, void *priv)
-{
- struct eap_tlv_data *data = priv;
- return data->state != CONTINUE;
-}
-
-
-static Boolean eap_tlv_isSuccess(struct eap_sm *sm, void *priv)
-{
- struct eap_tlv_data *data = priv;
- return data->state == SUCCESS;
-}
-
-
-int eap_server_tlv_register(void)
-{
- struct eap_method *eap;
- int ret;
-
- eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
- EAP_VENDOR_IETF, EAP_TYPE_TLV, "TLV");
- if (eap == NULL)
- return -1;
-
- eap->init = eap_tlv_init;
- eap->reset = eap_tlv_reset;
- eap->buildReq = eap_tlv_buildReq;
- eap->check = eap_tlv_check;
- eap->process = eap_tlv_process;
- eap->isDone = eap_tlv_isDone;
- eap->isSuccess = eap_tlv_isSuccess;
-
- ret = eap_server_method_register(eap);
- if (ret)
- eap_server_method_free(eap);
- return ret;
-}
diff --git a/contrib/hostapd/eapol_version.patch b/contrib/hostapd/eapol_version.patch
deleted file mode 100644
index c02e3677d0e6..000000000000
--- a/contrib/hostapd/eapol_version.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-? eapol_version.patch
-Index: config.c
-===================================================================
-RCS file: /home/ncvs/src/contrib/hostapd/config.c,v
-retrieving revision 1.1.1.3
-diff -u -r1.1.1.3 config.c
---- config.c 7 Mar 2006 05:46:42 -0000 1.1.1.3
-+++ config.c 27 Mar 2006 05:28:09 -0000
-@@ -29,6 +29,7 @@
- #include "sha1.h"
- #include "eap.h"
- #include "radius_client.h"
-+#include "ieee802_1x.h" /* XXX for EAPOL_VERSION */
-
-
- static struct hostapd_config *hostapd_config_defaults(void)
-@@ -60,6 +61,7 @@
- conf->logger_stdout = (unsigned int) -1;
-
- conf->auth_algs = HOSTAPD_AUTH_OPEN | HOSTAPD_AUTH_SHARED_KEY;
-+ conf->eapol_version = EAPOL_VERSION; /* NB: default version */
-
- conf->wpa_group_rekey = 600;
- conf->wpa_gmk_rekey = 86400;
-@@ -855,6 +857,17 @@
- }
- } else if (strcmp(buf, "eapol_key_index_workaround") == 0) {
- conf->eapol_key_index_workaround = atoi(pos);
-+ } else if (strcmp(buf, "eapol_version") == 0) {
-+ conf->eapol_version = atoi(pos);
-+ if (conf->eapol_version < 1 ||
-+ conf->eapol_version > 2) {
-+ printf("Line %d: invalid EAPOL "
-+ "version (%d): '%s'.\n",
-+ line, conf->eapol_version, pos);
-+ errors++;
-+ } else
-+ wpa_printf(MSG_DEBUG, "eapol_version=%d",
-+ conf->eapol_version);
- #ifdef CONFIG_IAPP
- } else if (strcmp(buf, "iapp_interface") == 0) {
- conf->ieee802_11f = 1;
-Index: config.h
-===================================================================
-RCS file: /home/ncvs/src/contrib/hostapd/config.h,v
-retrieving revision 1.1.1.2
-diff -u -r1.1.1.2 config.h
---- config.h 7 Mar 2006 05:46:42 -0000 1.1.1.2
-+++ config.h 27 Mar 2006 05:28:09 -0000
-@@ -73,6 +73,7 @@
- * EAP Request-Identity */
- size_t eap_req_id_text_len;
- int eapol_key_index_workaround;
-+ int eapol_version;
-
- size_t default_wep_key_len;
- int individual_wep_key_len;
-Index: hostapd.conf
-===================================================================
-RCS file: /home/ncvs/src/contrib/hostapd/hostapd.conf,v
-retrieving revision 1.1.1.2
-diff -u -r1.1.1.2 hostapd.conf
---- hostapd.conf 7 Mar 2006 05:46:50 -0000 1.1.1.2
-+++ hostapd.conf 27 Mar 2006 05:28:09 -0000
-@@ -106,6 +106,14 @@
- # Require IEEE 802.1X authorization
- #ieee8021x=1
-
-+# IEEE 802.1X/EAPOL version
-+# hostapd is implemented based on IEEE Std 802.1X-2004 which defines EAPOL
-+# version 2. However, there are some clients that do not handle
-+# the new version number correctly (they seem to drop the frames completely).
-+# In order to make hostapd interoperate with these clients, the version number
-+# can be set to the older version (1) with this configuration value.
-+#eapol_version=2
-+
- # Optional displayable message sent with EAP Request-Identity. The first \0
- # in this string will be converted to ASCII-0 (nul). This can be used to
- # separate network info (comma separated list of attribute=value pairs); see,
-Index: ieee802_1x.c
-===================================================================
-RCS file: /home/ncvs/src/contrib/hostapd/ieee802_1x.c,v
-retrieving revision 1.4
-diff -u -r1.4 ieee802_1x.c
---- ieee802_1x.c 7 Mar 2006 05:51:52 -0000 1.4
-+++ ieee802_1x.c 27 Mar 2006 05:28:10 -0000
-@@ -76,7 +76,7 @@
- #endif
-
- xhdr = (struct ieee802_1x_hdr *) buf;
-- xhdr->version = EAPOL_VERSION;
-+ xhdr->version = hapd->conf->eapol_version;
- xhdr->type = type;
- xhdr->length = htons(datalen);
-
-@@ -324,7 +324,7 @@
-
- /* This header is needed here for HMAC-MD5, but it will be regenerated
- * in ieee802_1x_send() */
-- hdr->version = EAPOL_VERSION;
-+ hdr->version = hapd->conf->eapol_version;
- hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
- hdr->length = htons(len);
- hmac_md5(sm->eapol_key_sign, sm->eapol_key_sign_len,
-@@ -1665,7 +1665,7 @@
- "dot1xPaePortInitialize=%d\n"
- "dot1xPaePortReauthenticate=FALSE\n",
- sta->aid,
-- EAPOL_VERSION,
-+ hapd->conf->eapol_version,
- sm->initialize);
-
- /* dot1xAuthConfigTable */
-Index: wpa.c
-===================================================================
-RCS file: /home/ncvs/src/contrib/hostapd/wpa.c,v
-retrieving revision 1.4
-diff -u -r1.4 wpa.c
---- wpa.c 7 Mar 2006 05:51:52 -0000 1.4
-+++ wpa.c 27 Mar 2006 05:28:12 -0000
-@@ -1855,7 +1855,7 @@
- if (hdr == NULL)
- return;
- memset(hdr, 0, len);
-- hdr->version = EAPOL_VERSION;
-+ hdr->version = hapd->conf->eapol_version;
- hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
- hdr->length = htons(len - sizeof(*hdr));
- key = (struct wpa_eapol_key *) (hdr + 1);
diff --git a/contrib/hostapd/hostapd.accept b/contrib/hostapd/hostapd.accept
deleted file mode 100644
index 57122b663449..000000000000
--- a/contrib/hostapd/hostapd.accept
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of MAC addresses that are allowed to authenticate (IEEE 802.11)
-# with the AP.
-00:11:22:33:44:55
-00:66:77:88:99:aa
-00:00:22:33:44:55
diff --git a/contrib/hostapd/hostapd_ctrl.c b/contrib/hostapd/hostapd_ctrl.c
deleted file mode 100644
index 55b690451b50..000000000000
--- a/contrib/hostapd/hostapd_ctrl.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * hostapd - hostapd control interface library
- * Copyright (c) 2004, Jouni Malinen <jkmaline@cc.hut.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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/un.h>
-
-#include "hostapd_ctrl.h"
-
-
-struct hostapd_ctrl {
- int s;
- struct sockaddr_un local;
- struct sockaddr_un dest;
-};
-
-
-struct hostapd_ctrl * hostapd_ctrl_open(const char *ctrl_path)
-{
- struct hostapd_ctrl *ctrl;
- static int counter = 0;
-
- ctrl = malloc(sizeof(*ctrl));
- if (ctrl == NULL)
- return NULL;
- memset(ctrl, 0, sizeof(*ctrl));
-
- ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (ctrl->s < 0) {
- free(ctrl);
- return NULL;
- }
-
- ctrl->local.sun_family = AF_UNIX;
- snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
- "/tmp/hostapd_ctrl_%d-%d", getpid(), counter++);
- if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
- sizeof(ctrl->local.sun_family) +
- strlen(ctrl->local.sun_path)) < 0) {
- close(ctrl->s);
- free(ctrl);
- return NULL;
- }
-
- ctrl->dest.sun_family = AF_UNIX;
- strncpy(ctrl->dest.sun_path, ctrl_path, sizeof(ctrl->dest.sun_path));
- if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
- sizeof(ctrl->dest.sun_family) +
- strlen(ctrl->dest.sun_path)) < 0) {
- close(ctrl->s);
- unlink(ctrl->local.sun_path);
- free(ctrl);
- return NULL;
- }
-
- return ctrl;
-}
-
-
-void hostapd_ctrl_close(struct hostapd_ctrl *ctrl)
-{
- unlink(ctrl->local.sun_path);
- close(ctrl->s);
- free(ctrl);
-}
-
-
-int hostapd_ctrl_request(struct hostapd_ctrl *ctrl, char *cmd, size_t cmd_len,
- char *reply, size_t *reply_len,
- void (*msg_cb)(char *msg, size_t len))
-{
- struct timeval tv;
- int res;
- fd_set rfds;
-
- if (send(ctrl->s, cmd, cmd_len, 0) < 0)
- return -1;
-
- for (;;) {
- tv.tv_sec = 2;
- tv.tv_usec = 0;
- FD_ZERO(&rfds);
- FD_SET(ctrl->s, &rfds);
- res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
- if (FD_ISSET(ctrl->s, &rfds)) {
- res = recv(ctrl->s, reply, *reply_len, 0);
- if (res < 0)
- return res;
- if (res > 0 && reply[0] == '<') {
- /* This is an unsolicited message from
- * wpa_supplicant, not the reply to the
- * request. Use msg_cb to report this to the
- * caller. */
- if (msg_cb) {
- /* Make sure the message is nul
- * terminated. */
- if (res == *reply_len)
- res = (*reply_len) - 1;
- reply[res] = '\0';
- msg_cb(reply, res);
- }
- continue;
- }
- *reply_len = res;
- break;
- } else {
- return -2;
- }
- }
- return 0;
-}
-
-
-static int hostapd_ctrl_attach_helper(struct hostapd_ctrl *ctrl, int attach)
-{
- char buf[10];
- int ret;
- size_t len = 10;
-
- ret = hostapd_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6,
- buf, &len, NULL);
- if (ret < 0)
- return ret;
- if (len == 3 && memcmp(buf, "OK\n", 3) == 0)
- return 0;
- return -1;
-}
-
-
-int hostapd_ctrl_attach(struct hostapd_ctrl *ctrl)
-{
- return hostapd_ctrl_attach_helper(ctrl, 1);
-}
-
-
-int hostapd_ctrl_detach(struct hostapd_ctrl *ctrl)
-{
- return hostapd_ctrl_attach_helper(ctrl, 0);
-}
-
-
-int hostapd_ctrl_recv(struct hostapd_ctrl *ctrl, char *reply,
- size_t *reply_len)
-{
- int res;
-
- res = recv(ctrl->s, reply, *reply_len, 0);
- if (res < 0)
- return res;
- *reply_len = res;
- return 0;
-}
-
-
-int hostapd_ctrl_pending(struct hostapd_ctrl *ctrl)
-{
- struct timeval tv;
- int res;
- fd_set rfds;
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- FD_ZERO(&rfds);
- FD_SET(ctrl->s, &rfds);
- res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
- return FD_ISSET(ctrl->s, &rfds);
-}
-
-
-int hostapd_ctrl_get_fd(struct hostapd_ctrl *ctrl)
-{
- return ctrl->s;
-}
diff --git a/contrib/hostapd/hostapd_ctrl.h b/contrib/hostapd/hostapd_ctrl.h
deleted file mode 100644
index 7ba221e19fc1..000000000000
--- a/contrib/hostapd/hostapd_ctrl.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef HOSTAPD_CTRL_H
-#define HOSTAPD_CTRL_H
-
-struct hostapd_ctrl;
-
-struct hostapd_ctrl * hostapd_ctrl_open(const char *ctrl_path);
-void hostapd_ctrl_close(struct hostapd_ctrl *ctrl);
-int hostapd_ctrl_request(struct hostapd_ctrl *ctrl, char *cmd, size_t cmd_len,
- char *reply, size_t *reply_len,
- void (*msg_cb)(char *msg, size_t len));
-int hostapd_ctrl_attach(struct hostapd_ctrl *ctrl);
-int hostapd_ctrl_detach(struct hostapd_ctrl *ctrl);
-int hostapd_ctrl_recv(struct hostapd_ctrl *ctrl, char *reply,
- size_t *reply_len);
-int hostapd_ctrl_pending(struct hostapd_ctrl *ctrl);
-int hostapd_ctrl_get_fd(struct hostapd_ctrl *ctrl);
-
-#endif /* HOSTAPD_CTRL_H */
diff --git a/contrib/hostapd/hw_features.c b/contrib/hostapd/hw_features.c
deleted file mode 100644
index 484959f63cc5..000000000000
--- a/contrib/hostapd/hw_features.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * hostapd / Hardware feature query and different modes
- * Copyright 2002-2003, Instant802 Networks, Inc.
- * Copyright 2005-2006, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "hostapd.h"
-#include "hw_features.h"
-#include "driver.h"
-#include "config.h"
-#include "ieee802_11.h"
-#include "eloop.h"
-
-
-void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
- size_t num_hw_features)
-{
- size_t i;
-
- if (hw_features == NULL)
- return;
-
- for (i = 0; i < num_hw_features; i++) {
- free(hw_features[i].channels);
- free(hw_features[i].rates);
- }
-
- free(hw_features);
-}
-
-
-int hostapd_get_hw_features(struct hostapd_iface *iface)
-{
- struct hostapd_data *hapd = iface->bss[0];
- int ret = 0, i, j;
- u16 num_modes, flags;
- struct hostapd_hw_modes *modes;
-
- modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags);
- if (modes == NULL) {
- hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_DEBUG,
- "Fetching hardware channel/rate support not "
- "supported.");
- return -1;
- }
-
- iface->hw_flags = flags;
-
- hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
- iface->hw_features = modes;
- iface->num_hw_features = num_modes;
-
- for (i = 0; i < num_modes; i++) {
- struct hostapd_hw_modes *feature = &modes[i];
- /* set flag for channels we can use in current regulatory
- * domain */
- for (j = 0; j < feature->num_channels; j++) {
- /* TODO: add regulatory domain lookup */
- unsigned char power_level = 0;
- unsigned char antenna_max = 0;
-
- if ((feature->mode == HOSTAPD_MODE_IEEE80211G ||
- feature->mode == HOSTAPD_MODE_IEEE80211B) &&
- feature->channels[j].chan >= 1 &&
- feature->channels[j].chan <= 11) {
- power_level = 20;
- feature->channels[j].flag |=
- HOSTAPD_CHAN_W_SCAN;
- } else
- feature->channels[j].flag &=
- ~HOSTAPD_CHAN_W_SCAN;
-
- hostapd_set_channel_flag(hapd, feature->mode,
- feature->channels[j].chan,
- feature->channels[j].flag,
- power_level,
- antenna_max);
- }
- }
-
- return ret;
-}
-
-
-static int hostapd_prepare_rates(struct hostapd_data *hapd,
- struct hostapd_hw_modes *mode)
-{
- int i, num_basic_rates = 0;
- int basic_rates_a[] = { 60, 120, 240, -1 };
- int basic_rates_b[] = { 10, 20, -1 };
- int basic_rates_g[] = { 10, 20, 55, 110, -1 };
- int *basic_rates;
-
- if (hapd->iconf->basic_rates)
- basic_rates = hapd->iconf->basic_rates;
- else switch (mode->mode) {
- case HOSTAPD_MODE_IEEE80211A:
- basic_rates = basic_rates_a;
- break;
- case HOSTAPD_MODE_IEEE80211B:
- basic_rates = basic_rates_b;
- break;
- case HOSTAPD_MODE_IEEE80211G:
- basic_rates = basic_rates_g;
- break;
- default:
- return -1;
- }
-
- if (hostapd_set_rate_sets(hapd, hapd->iconf->supported_rates,
- basic_rates, mode->mode)) {
- printf("Failed to update rate sets in kernel module\n");
- }
-
- free(hapd->iface->current_rates);
- hapd->iface->num_rates = 0;
-
- hapd->iface->current_rates =
- malloc(mode->num_rates * sizeof(struct hostapd_rate_data));
- if (!hapd->iface->current_rates) {
- printf("Failed to allocate memory for rate table.\n");
- return -1;
- }
-
- for (i = 0; i < mode->num_rates; i++) {
- struct hostapd_rate_data *rate;
-
- if (hapd->iconf->supported_rates &&
- !hostapd_rate_found(hapd->iconf->supported_rates,
- mode->rates[i].rate))
- continue;
-
- rate = &hapd->iface->current_rates[hapd->iface->num_rates];
- memcpy(rate, &mode->rates[i],
- sizeof(struct hostapd_rate_data));
- if (hostapd_rate_found(basic_rates, rate->rate)) {
- rate->flags |= HOSTAPD_RATE_BASIC;
- num_basic_rates++;
- } else
- rate->flags &= ~HOSTAPD_RATE_BASIC;
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "RATE[%d] rate=%d flags=0x%x\n",
- hapd->iface->num_rates, rate->rate, rate->flags);
- hapd->iface->num_rates++;
- }
-
- if (hapd->iface->num_rates == 0 || num_basic_rates == 0) {
- printf("No rates remaining in supported/basic rate sets "
- "(%d,%d).\n", hapd->iface->num_rates, num_basic_rates);
- return -1;
- }
-
- return 0;
-}
-
-
-static void select_hw_mode_start(void *eloop_data, void *user_ctx);
-static void select_hw_mode2_handler(void *eloop_data, void *user_ctx);
-
-/**
- * select_hw_mode_finalize - Finish select HW mode & call the callback
- * @iface: Pointer to interface data.
- * @status: Status of the select HW mode (0 on success; -1 on failure).
- * Returns: 0 on success; -1 on failure (e.g., was not in progress).
- */
-static int select_hw_mode_finalize(struct hostapd_iface *iface, int status)
-{
- hostapd_iface_cb cb;
-
- if (!iface->hw_mode_sel_cb)
- return -1;
-
- eloop_cancel_timeout(select_hw_mode_start, iface, NULL);
- eloop_cancel_timeout(select_hw_mode2_handler, iface, NULL);
-
- cb = iface->hw_mode_sel_cb;
-
- iface->hw_mode_sel_cb = NULL;
-
- cb(iface, status);
-
- return 0;
-}
-
-
-/**
- * select_hw_mode2 - Select the hardware mode (part 2)
- * @iface: Pointer to interface data.
- * @status: Status of auto chanel selection.
- *
- * Setup the rates and passive scanning based on the configuration.
- */
-static void select_hw_mode2(struct hostapd_iface *iface, int status)
-{
- int ret = status;
- if (ret)
- goto fail;
-
- if (iface->current_mode == NULL) {
- hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_WARNING,
- "Hardware does not support configured channel");
- ret = -1;
- goto fail;
- }
-
- if (hostapd_prepare_rates(iface->bss[0], iface->current_mode)) {
- printf("Failed to prepare rates table.\n");
- hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_WARNING,
- "Failed to prepare rates table.");
- ret = -1;
- goto fail;
- }
-
- ret = hostapd_passive_scan(iface->bss[0], 0,
- iface->conf->passive_scan_mode,
- iface->conf->passive_scan_interval,
- iface->conf->passive_scan_listen,
- NULL, NULL);
- if (ret) {
- printf("Could not set passive scanning: %s\n", strerror(ret));
- ret = 0;
- }
-
-fail:
- select_hw_mode_finalize(iface, ret);
-}
-
-
-/**
- * select_hw_mode2_handler - Calls select_hw_mode2 when auto chan isn't used
- * @eloop_data: Stores the struct hostapd_iface * for the interface.
- * @user_ctx: Unused.
- */
-static void select_hw_mode2_handler(void *eloop_data, void *user_ctx)
-{
- struct hostapd_iface *iface = eloop_data;
-
- select_hw_mode2(iface, 0);
-}
-
-
-/**
- * select_hw_mode1 - Select the hardware mode (part 1)
- * @iface: Pointer to interface data.
- * Returns: 0 on success; -1 on failure.
- *
- * Setup the hardware mode and channel based on the configuration.
- * Schedules select_hw_mode2() to be called immediately or after automatic
- * channel selection takes place.
- */
-static int select_hw_mode1(struct hostapd_iface *iface)
-{
- int i, j, ok;
-
- if (iface->num_hw_features < 1)
- return -1;
-
- iface->current_mode = NULL;
- for (i = 0; i < iface->num_hw_features; i++) {
- struct hostapd_hw_modes *mode = &iface->hw_features[i];
- if (mode->mode == (int) iface->conf->hw_mode) {
- iface->current_mode = mode;
- break;
- }
- }
-
- if (iface->current_mode == NULL) {
- printf("Hardware does not support configured mode\n");
- hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_WARNING,
- "Hardware does not support configured mode "
- "(%d)", (int) iface->conf->hw_mode);
- return -1;
- }
-
- ok = 0;
- for (j = 0; j < iface->current_mode->num_channels; j++) {
- struct hostapd_channel_data *chan =
- &iface->current_mode->channels[j];
- if ((chan->flag & HOSTAPD_CHAN_W_SCAN) &&
- (chan->chan == iface->conf->channel)) {
- ok = 1;
- break;
- }
- }
- if (ok == 0 && iface->conf->channel != 0) {
- hostapd_logger(iface->bss[0], NULL,
- HOSTAPD_MODULE_IEEE80211,
- HOSTAPD_LEVEL_WARNING,
- "Configured channel (%d) not found from the "
- "channel list of current mode (%d) %s",
- iface->conf->channel,
- iface->current_mode->mode,
- hostapd_hw_mode_txt(iface->current_mode->mode));
- iface->current_mode = NULL;
- }
-
- /*
- * Calls select_hw_mode2() via a handler, so that the function is
- * always executed from eloop.
- */
- eloop_register_timeout(0, 0, select_hw_mode2_handler, iface, NULL);
- return 0;
-}
-
-
-/**
- * select_hw_mode_start - Handler to start select HW mode
- * @eloop_data: Stores the struct hostapd_iface * for the interface.
- * @user_ctx: Unused.
- *
- * An eloop handler is used so that all errors can be processed by the
- * callback without introducing stack recursion.
- */
-static void select_hw_mode_start(void *eloop_data, void *user_ctx)
-{
- struct hostapd_iface *iface = (struct hostapd_iface *)eloop_data;
-
- int ret;
-
- ret = select_hw_mode1(iface);
- if (ret)
- select_hw_mode_finalize(iface, ret);
-}
-
-
-/**
- * hostapd_select_hw_mode_start - Start selection of the hardware mode
- * @iface: Pointer to interface data.
- * @cb: The function to callback when done.
- * Returns: 0 if it starts successfully; cb will be called when done.
- * -1 on failure; cb will not be called.
- *
- * Sets up the hardware mode, channel, rates, and passive scanning
- * based on the configuration.
- */
-int hostapd_select_hw_mode_start(struct hostapd_iface *iface,
- hostapd_iface_cb cb)
-{
- if (iface->hw_mode_sel_cb) {
- wpa_printf(MSG_DEBUG,
- "%s: Hardware mode select already in progress.",
- iface->bss[0]->conf->iface);
- return -1;
- }
-
- iface->hw_mode_sel_cb = cb;
-
- eloop_register_timeout(0, 0, select_hw_mode_start, iface, NULL);
-
- return 0;
-}
-
-
-/**
- * hostapd_auto_chan_select_stop - Stops automatic channel selection
- * @iface: Pointer to interface data.
- * Returns: 0 if successfully stopped;
- * -1 on failure (i.e., was not in progress)
- */
-int hostapd_select_hw_mode_stop(struct hostapd_iface *iface)
-{
- return select_hw_mode_finalize(iface, -1);
-}
-
-
-const char * hostapd_hw_mode_txt(int mode)
-{
- switch (mode) {
- case HOSTAPD_MODE_IEEE80211A:
- return "IEEE 802.11a";
- case HOSTAPD_MODE_IEEE80211B:
- return "IEEE 802.11b";
- case HOSTAPD_MODE_IEEE80211G:
- return "IEEE 802.11g";
- default:
- return "UNKNOWN";
- }
-}
-
-
-int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
-{
- int i;
-
- if (!hapd->iface->current_mode)
- return 0;
-
- for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {
- struct hostapd_channel_data *ch =
- &hapd->iface->current_mode->channels[i];
- if (ch->chan == chan)
- return ch->freq;
- }
-
- return 0;
-}
-
-
-int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
-{
- int i;
-
- if (!hapd->iface->current_mode)
- return 0;
-
- for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {
- struct hostapd_channel_data *ch =
- &hapd->iface->current_mode->channels[i];
- if (ch->freq == freq)
- return ch->chan;
- }
-
- return 0;
-}
diff --git a/contrib/hostapd/ieee802_11.h b/contrib/hostapd/ieee802_11.h
deleted file mode 100644
index 37bd711d0194..000000000000
--- a/contrib/hostapd/ieee802_11.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * hostapd / IEEE 802.11 Management
- * Copyright (c) 2002-2006, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef IEEE802_11_H
-#define IEEE802_11_H
-
-/* IEEE 802.11 defines */
-
-#define WLAN_FC_PVER (BIT(1) | BIT(0))
-#define WLAN_FC_TODS BIT(8)
-#define WLAN_FC_FROMDS BIT(9)
-#define WLAN_FC_MOREFRAG BIT(10)
-#define WLAN_FC_RETRY BIT(11)
-#define WLAN_FC_PWRMGT BIT(12)
-#define WLAN_FC_MOREDATA BIT(13)
-#define WLAN_FC_ISWEP BIT(14)
-#define WLAN_FC_ORDER BIT(15)
-
-#define WLAN_FC_GET_TYPE(fc) (((fc) & (BIT(3) | BIT(2))) >> 2)
-#define WLAN_FC_GET_STYPE(fc) \
- (((fc) & (BIT(7) | BIT(6) | BIT(5) | BIT(4))) >> 4)
-
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & (BIT(3) | BIT(2) | BIT(1) | BIT(0)))
-#define WLAN_GET_SEQ_SEQ(seq) \
- (((seq) & (~(BIT(3) | BIT(2) | BIT(1) | BIT(0)))) >> 4)
-
-#define WLAN_FC_TYPE_MGMT 0
-#define WLAN_FC_TYPE_CTRL 1
-#define WLAN_FC_TYPE_DATA 2
-
-/* management */
-#define WLAN_FC_STYPE_ASSOC_REQ 0
-#define WLAN_FC_STYPE_ASSOC_RESP 1
-#define WLAN_FC_STYPE_REASSOC_REQ 2
-#define WLAN_FC_STYPE_REASSOC_RESP 3
-#define WLAN_FC_STYPE_PROBE_REQ 4
-#define WLAN_FC_STYPE_PROBE_RESP 5
-#define WLAN_FC_STYPE_BEACON 8
-#define WLAN_FC_STYPE_ATIM 9
-#define WLAN_FC_STYPE_DISASSOC 10
-#define WLAN_FC_STYPE_AUTH 11
-#define WLAN_FC_STYPE_DEAUTH 12
-#define WLAN_FC_STYPE_ACTION 13
-
-/* control */
-#define WLAN_FC_STYPE_PSPOLL 10
-#define WLAN_FC_STYPE_RTS 11
-#define WLAN_FC_STYPE_CTS 12
-#define WLAN_FC_STYPE_ACK 13
-#define WLAN_FC_STYPE_CFEND 14
-#define WLAN_FC_STYPE_CFENDACK 15
-
-/* data */
-#define WLAN_FC_STYPE_DATA 0
-#define WLAN_FC_STYPE_DATA_CFACK 1
-#define WLAN_FC_STYPE_DATA_CFPOLL 2
-#define WLAN_FC_STYPE_DATA_CFACKPOLL 3
-#define WLAN_FC_STYPE_NULLFUNC 4
-#define WLAN_FC_STYPE_CFACK 5
-#define WLAN_FC_STYPE_CFPOLL 6
-#define WLAN_FC_STYPE_CFACKPOLL 7
-#define WLAN_FC_STYPE_QOS_DATA 8
-
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-
-#define WLAN_AUTH_CHALLENGE_LEN 128
-
-#define WLAN_CAPABILITY_ESS BIT(0)
-#define WLAN_CAPABILITY_IBSS BIT(1)
-#define WLAN_CAPABILITY_CF_POLLABLE BIT(2)
-#define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3)
-#define WLAN_CAPABILITY_PRIVACY BIT(4)
-#define WLAN_CAPABILITY_SHORT_PREAMBLE BIT(5)
-#define WLAN_CAPABILITY_PBCC BIT(6)
-#define WLAN_CAPABILITY_CHANNEL_AGILITY BIT(7)
-#define WLAN_CAPABILITY_SPECTRUM_MGMT BIT(8)
-#define WLAN_CAPABILITY_SHORT_SLOT_TIME BIT(10)
-#define WLAN_CAPABILITY_DSSS_OFDM BIT(13)
-
-/* Status codes */
-#define WLAN_STATUS_SUCCESS 0
-#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
-#define WLAN_STATUS_CAPS_UNSUPPORTED 10
-#define WLAN_STATUS_REASSOC_NO_ASSOC 11
-#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
-#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
-#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
-#define WLAN_STATUS_CHALLENGE_FAIL 15
-#define WLAN_STATUS_AUTH_TIMEOUT 16
-#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
-#define WLAN_STATUS_ASSOC_DENIED_RATES 18
-/* IEEE 802.11b */
-#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
-#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
-#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
-/* IEEE 802.11h */
-#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22
-#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23
-#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24
-/* IEEE 802.11i */
-#define WLAN_STATUS_INVALID_IE 40
-#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41
-#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42
-#define WLAN_STATUS_AKMP_NOT_VALID 43
-#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44
-#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45
-#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46
-
-/* Reason codes */
-#define WLAN_REASON_UNSPECIFIED 1
-#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
-#define WLAN_REASON_DEAUTH_LEAVING 3
-#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
-#define WLAN_REASON_DISASSOC_AP_BUSY 5
-#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
-#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
-#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
-#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
-/* IEEE 802.11i */
-#define WLAN_REASON_INVALID_IE 13
-#define WLAN_REASON_MICHAEL_MIC_FAILURE 14
-#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15
-#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16
-#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17
-#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18
-#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19
-#define WLAN_REASON_AKMP_NOT_VALID 20
-#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21
-#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22
-#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23
-#define WLAN_REASON_CIPHER_SUITE_REJECTED 24
-
-
-/* Information Element IDs */
-#define WLAN_EID_SSID 0
-#define WLAN_EID_SUPP_RATES 1
-#define WLAN_EID_FH_PARAMS 2
-#define WLAN_EID_DS_PARAMS 3
-#define WLAN_EID_CF_PARAMS 4
-#define WLAN_EID_TIM 5
-#define WLAN_EID_IBSS_PARAMS 6
-#define WLAN_EID_COUNTRY 7
-#define WLAN_EID_CHALLENGE 16
-/* EIDs defined by IEEE 802.11h - START */
-#define WLAN_EID_PWR_CONSTRAINT 32
-#define WLAN_EID_PWR_CAPABILITY 33
-#define WLAN_EID_TPC_REQUEST 34
-#define WLAN_EID_TPC_REPORT 35
-#define WLAN_EID_SUPPORTED_CHANNELS 36
-#define WLAN_EID_CHANNEL_SWITCH 37
-#define WLAN_EID_MEASURE_REQUEST 38
-#define WLAN_EID_MEASURE_REPORT 39
-#define WLAN_EID_QUITE 40
-#define WLAN_EID_IBSS_DFS 41
-/* EIDs defined by IEEE 802.11h - END */
-#define WLAN_EID_ERP_INFO 42
-#define WLAN_EID_RSN 48
-#define WLAN_EID_EXT_SUPP_RATES 50
-#define WLAN_EID_GENERIC 221
-#define WLAN_EID_VENDOR_SPECIFIC 221
-
-
-struct ieee80211_mgmt {
- u16 frame_control;
- u16 duration;
- u8 da[6];
- u8 sa[6];
- u8 bssid[6];
- u16 seq_ctrl;
- union {
- struct {
- u16 auth_alg;
- u16 auth_transaction;
- u16 status_code;
- /* possibly followed by Challenge text */
- u8 variable[0];
- } __attribute__ ((packed)) auth;
- struct {
- u16 reason_code;
- } __attribute__ ((packed)) deauth;
- struct {
- u16 capab_info;
- u16 listen_interval;
- /* followed by SSID and Supported rates */
- u8 variable[0];
- } __attribute__ ((packed)) assoc_req;
- struct {
- u16 capab_info;
- u16 status_code;
- u16 aid;
- /* followed by Supported rates */
- u8 variable[0];
- } __attribute__ ((packed)) assoc_resp, reassoc_resp;
- struct {
- u16 capab_info;
- u16 listen_interval;
- u8 current_ap[6];
- /* followed by SSID and Supported rates */
- u8 variable[0];
- } __attribute__ ((packed)) reassoc_req;
- struct {
- u16 reason_code;
- } __attribute__ ((packed)) disassoc;
- struct {
- /* only variable items: SSID, Supported rates */
- u8 variable[0];
- } __attribute__ ((packed)) probe_req;
- struct {
- u8 timestamp[8];
- u16 beacon_int;
- u16 capab_info;
- /* followed by some of SSID, Supported rates,
- * FH Params, DS Params, CF Params, IBSS Params */
- u8 variable[0];
- } __attribute__ ((packed)) probe_resp;
- struct {
- u8 timestamp[8];
- u16 beacon_int;
- u16 capab_info;
- /* followed by some of SSID, Supported rates,
- * FH Params, DS Params, CF Params, IBSS Params, TIM */
- u8 variable[0];
- } __attribute__ ((packed)) beacon;
- struct {
- u8 category;
- union {
- struct {
- u8 action_code;
- u8 dialog_token;
- u8 status_code;
- u8 variable[0];
- } __attribute__ ((packed)) wme_action;
- struct{
- u8 action_code;
- u8 element_id;
- u8 length;
- u8 switch_mode;
- u8 new_chan;
- u8 switch_count;
- } __attribute__ ((packed)) chan_switch;
- } u;
- } __attribute__ ((packed)) action;
- } u;
-} __attribute__ ((packed));
-
-
-#define ERP_INFO_NON_ERP_PRESENT BIT(0)
-#define ERP_INFO_USE_PROTECTION BIT(1)
-#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2)
-
-/* Parsed Information Elements */
-struct ieee802_11_elems {
- u8 *ssid;
- u8 ssid_len;
- u8 *supp_rates;
- u8 supp_rates_len;
- u8 *fh_params;
- u8 fh_params_len;
- u8 *ds_params;
- u8 ds_params_len;
- u8 *cf_params;
- u8 cf_params_len;
- u8 *tim;
- u8 tim_len;
- u8 *ibss_params;
- u8 ibss_params_len;
- u8 *challenge;
- u8 challenge_len;
- u8 *erp_info;
- u8 erp_info_len;
- u8 *ext_supp_rates;
- u8 ext_supp_rates_len;
- u8 *wpa_ie;
- u8 wpa_ie_len;
- u8 *rsn_ie;
- u8 rsn_ie_len;
- u8 *wme;
- u8 wme_len;
- u8 *wme_tspec;
- u8 wme_tspec_len;
- u8 *power_cap;
- u8 power_cap_len;
- u8 *supp_channels;
- u8 supp_channels_len;
-};
-
-typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
-
-
-struct hostapd_frame_info {
- u32 phytype;
- u32 channel;
- u32 datarate;
- u32 ssi_signal;
-
- unsigned int passive_scan:1;
-};
-
-
-void ieee802_11_send_deauth(struct hostapd_data *hapd, u8 *addr, u16 reason);
-void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len,
- u16 stype, struct hostapd_frame_info *fi);
-void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len,
- u16 stype, int ok);
-ParseRes ieee802_11_parse_elems(struct hostapd_data *hapd, u8 *start,
- size_t len,
- struct ieee802_11_elems *elems,
- int show_errors);
-void ieee802_11_print_ssid(const u8 *ssid, u8 len);
-void ieee80211_michael_mic_failure(struct hostapd_data *hapd, const u8 *addr,
- int local);
-int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen);
-int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
- char *buf, size_t buflen);
-u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
- int probe);
-u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid);
-u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid);
-
-#endif /* IEEE802_11_H */
diff --git a/contrib/hostapd/madwifi.conf b/contrib/hostapd/madwifi.conf
deleted file mode 100644
index ed3704fcb634..000000000000
--- a/contrib/hostapd/madwifi.conf
+++ /dev/null
@@ -1,278 +0,0 @@
-##### hostapd configuration file ##############################################
-# Empty lines and lines starting with # are ignored
-
-# AP netdevice name (without 'ap' prefix, i.e., wlan0 uses wlan0ap for
-# management frames)
-interface=ath0
-
-# In case of madwifi driver, an additional configuration parameter, bridge,
-# must be used to notify hostapd if the interface is included in a bridge. This
-# parameter is not used with Host AP driver.
-bridge=br0
-
-# Driver interface type (hostap/wired/madwifi; default: hostap)
-driver=madwifi
-
-# hostapd event logger configuration
-#
-# Two output method: syslog and stdout (only usable if not forking to
-# background).
-#
-# Module bitfield (ORed bitfield of modules that will be logged; -1 = all
-# modules):
-# bit 0 (1) = IEEE 802.11
-# bit 1 (2) = IEEE 802.1X
-# bit 2 (4) = RADIUS
-# bit 3 (8) = WPA
-# bit 4 (16) = driver interface
-# bit 5 (32) = IAPP
-#
-# Levels (minimum value for logged events):
-# 0 = verbose debugging
-# 1 = debugging
-# 2 = informational messages
-# 3 = notification
-# 4 = warning
-#
-logger_syslog=-1
-logger_syslog_level=2
-logger_stdout=-1
-logger_stdout_level=2
-
-# Debugging: 0 = no, 1 = minimal, 2 = verbose, 3 = msg dumps, 4 = excessive
-debug=0
-
-# Dump file for state information (on SIGUSR1)
-dump_file=/tmp/hostapd.dump
-
-
-##### IEEE 802.11 related configuration #######################################
-
-# SSID to be used in IEEE 802.11 management frames
-ssid=wpa-test
-
-##### IEEE 802.1X-REV related configuration ###################################
-
-# Require IEEE 802.1X authorization
-#ieee8021x=1
-
-# Optional displayable message sent with EAP Request-Identity. The first \0
-# in this string will be converted to ASCII-0 (nul). This can be used to
-# separate network info (comma separated list of attribute=value pairs); see,
-# e.g., RFC 4284.
-#eap_message=hello
-#eap_message=hello\0networkid=netw,nasid=foo,portid=0,NAIRealms=example.com
-
-# WEP rekeying (disabled if key lengths are not set or are set to 0)
-# Key lengths for default/broadcast and individual/unicast keys:
-# 5 = 40-bit WEP (also known as 64-bit WEP with 40 secret bits)
-# 13 = 104-bit WEP (also known as 128-bit WEP with 104 secret bits)
-#wep_key_len_broadcast=5
-#wep_key_len_unicast=5
-# Rekeying period in seconds. 0 = do not rekey (i.e., set keys only once)
-#wep_rekey_period=300
-
-# EAPOL-Key index workaround (set bit7) for WinXP Supplicant (needed only if
-# only broadcast keys are used)
-eapol_key_index_workaround=0
-
-# EAP reauthentication period in seconds (default: 3600 seconds; 0 = disable
-# reauthentication).
-#eap_reauth_period=3600
-
-
-##### Integrated EAP server ###################################################
-
-# Optionally, hostapd can be configured to use an integrated EAP server
-# to process EAP authentication locally without need for an external RADIUS
-# server. This functionality can be used both as a local authentication server
-# for IEEE 802.1X/EAPOL and as a RADIUS server for other devices.
-
-# Use integrated EAP server instead of external RADIUS authentication
-# server. This is also needed if hostapd is configured to act as a RADIUS
-# authentication server.
-eap_server=0
-
-# Path for EAP server user database
-#eap_user_file=/etc/hostapd.eap_user
-
-# CA certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS
-#ca_cert=/etc/hostapd.ca.pem
-
-# Server certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS
-#server_cert=/etc/hostapd.server.pem
-
-# Private key matching with the server certificate for EAP-TLS/PEAP/TTLS
-# This may point to the same file as server_cert if both certificate and key
-# are included in a single file. PKCS#12 (PFX) file (.p12/.pfx) can also be
-# used by commenting out server_cert and specifying the PFX file as the
-# private_key.
-#private_key=/etc/hostapd.server.prv
-
-# Passphrase for private key
-#private_key_passwd=secret passphrase
-
-# Enable CRL verification.
-# Note: hostapd does not yet support CRL downloading based on CDP. Thus, a
-# valid CRL signed by the CA is required to be included in the ca_cert file.
-# This can be done by using PEM format for CA certificate and CRL and
-# concatenating these into one file. Whenever CRL changes, hostapd needs to be
-# restarted to take the new CRL into use.
-# 0 = do not verify CRLs (default)
-# 1 = check the CRL of the user certificate
-# 2 = check all CRLs in the certificate path
-#check_crl=1
-
-# Configuration data for EAP-SIM database/authentication gateway interface.
-# This is a text string in implementation specific format. The example
-# implementation in eap_sim_db.c uses this as the file name for the GSM
-# authentication triplets.
-#eap_sim_db=/etc/hostapd.sim_db
-
-
-##### IEEE 802.11f - Inter-Access Point Protocol (IAPP) #######################
-
-# Interface to be used for IAPP broadcast packets
-#iapp_interface=eth0
-
-
-##### RADIUS client configuration #############################################
-# for IEEE 802.1X with external Authentication Server, IEEE 802.11
-# authentication with external ACL for MAC addresses, and accounting
-
-# The own IP address of the access point (used as NAS-IP-Address)
-own_ip_addr=127.0.0.1
-
-# Optional NAS-Identifier string for RADIUS messages. When used, this should be
-# a unique to the NAS within the scope of the RADIUS server. For example, a
-# fully qualified domain name can be used here.
-#nas_identifier=ap.example.com
-
-# RADIUS authentication server
-#auth_server_addr=127.0.0.1
-#auth_server_port=1812
-#auth_server_shared_secret=secret
-
-# RADIUS accounting server
-#acct_server_addr=127.0.0.1
-#acct_server_port=1813
-#acct_server_shared_secret=secret
-
-# Secondary RADIUS servers; to be used if primary one does not reply to
-# RADIUS packets. These are optional and there can be more than one secondary
-# server listed.
-#auth_server_addr=127.0.0.2
-#auth_server_port=1812
-#auth_server_shared_secret=secret2
-#
-#acct_server_addr=127.0.0.2
-#acct_server_port=1813
-#acct_server_shared_secret=secret2
-
-# Retry interval for trying to return to the primary RADIUS server (in
-# seconds). RADIUS client code will automatically try to use the next server
-# when the current server is not replying to requests. If this interval is set,
-# primary server will be retried after configured amount of time even if the
-# currently used secondary server is still working.
-#radius_retry_primary_interval=600
-
-
-# Interim accounting update interval
-# If this is set (larger than 0) and acct_server is configured, hostapd will
-# send interim accounting updates every N seconds. Note: if set, this overrides
-# possible Acct-Interim-Interval attribute in Access-Accept message. Thus, this
-# value should not be configured in hostapd.conf, if RADIUS server is used to
-# control the interim interval.
-# This value should not be less 600 (10 minutes) and must not be less than
-# 60 (1 minute).
-#radius_acct_interim_interval=600
-
-
-##### RADIUS authentication server configuration ##############################
-
-# hostapd can be used as a RADIUS authentication server for other hosts. This
-# requires that the integrated EAP authenticator is also enabled and both
-# authentication services are sharing the same configuration.
-
-# File name of the RADIUS clients configuration for the RADIUS server. If this
-# commented out, RADIUS server is disabled.
-#radius_server_clients=/etc/hostapd.radius_clients
-
-# The UDP port number for the RADIUS authentication server
-#radius_server_auth_port=1812
-
-# Use IPv6 with RADIUS server (IPv4 will also be supported using IPv6 API)
-#radius_server_ipv6=1
-
-
-##### WPA/IEEE 802.11i configuration ##########################################
-
-# Enable WPA. Setting this variable configures the AP to require WPA (either
-# WPA-PSK or WPA-RADIUS/EAP based on other configuration). For WPA-PSK, either
-# wpa_psk or wpa_passphrase must be set and wpa_key_mgmt must include WPA-PSK.
-# For WPA-RADIUS/EAP, ieee8021x must be set (but without dynamic WEP keys),
-# RADIUS authentication server must be configured, and WPA-EAP must be included
-# in wpa_key_mgmt.
-# This field is a bit field that can be used to enable WPA (IEEE 802.11i/D3.0)
-# and/or WPA2 (full IEEE 802.11i/RSN):
-# bit0 = WPA
-# bit1 = IEEE 802.11i/RSN (WPA2) (dot11RSNAEnabled)
-#wpa=1
-
-# WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit
-# secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase
-# (8..63 characters) that will be converted to PSK. This conversion uses SSID
-# so the PSK changes when ASCII passphrase is used and the SSID is changed.
-# wpa_psk (dot11RSNAConfigPSKValue)
-# wpa_passphrase (dot11RSNAConfigPSKPassPhrase)
-#wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
-#wpa_passphrase=secret passphrase
-
-# Optionally, WPA PSKs can be read from a separate text file (containing list
-# of (PSK,MAC address) pairs. This allows more than one PSK to be configured.
-# Use absolute path name to make sure that the files can be read on SIGHUP
-# configuration reloads.
-#wpa_psk_file=/etc/hostapd.wpa_psk
-
-# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
-# entries are separated with a space.
-# (dot11RSNAConfigAuthenticationSuitesTable)
-#wpa_key_mgmt=WPA-PSK WPA-EAP
-
-# Set of accepted cipher suites (encryption algorithms) for pairwise keys
-# (unicast packets). This is a space separated list of algorithms:
-# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
-# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
-# Group cipher suite (encryption algorithm for broadcast and multicast frames)
-# is automatically selected based on this configuration. If only CCMP is
-# allowed as the pairwise cipher, group cipher will also be CCMP. Otherwise,
-# TKIP will be used as the group cipher.
-# (dot11RSNAConfigPairwiseCiphersTable)
-#wpa_pairwise=TKIP CCMP
-
-# Time interval for rekeying GTK (broadcast/multicast encryption keys) in
-# seconds. (dot11RSNAConfigGroupRekeyTime)
-#wpa_group_rekey=600
-
-# Rekey GTK when any STA that possesses the current GTK is leaving the BSS.
-# (dot11RSNAConfigGroupRekeyStrict)
-#wpa_strict_rekey=1
-
-# Time interval for rekeying GMK (master key used internally to generate GTKs
-# (in seconds).
-#wpa_gmk_rekey=86400
-
-# Enable IEEE 802.11i/RSN/WPA2 pre-authentication. This is used to speed up
-# roaming be pre-authenticating IEEE 802.1X/EAP part of the full RSN
-# authentication and key handshake before actually associating with a new AP.
-# (dot11RSNAPreauthenticationEnabled)
-#rsn_preauth=1
-#
-# Space separated list of interfaces from which pre-authentication frames are
-# accepted (e.g., 'eth0' or 'eth0 wlan0wds0'. This list should include all
-# interface that are used for connections to other APs. This could include
-# wired interfaces and WDS links. The normal wireless data interface towards
-# associated stations (e.g., wlan0) should not be added, since
-# pre-authentication is only used with APs other than the currently associated
-# one.
-#rsn_preauth_interfaces=eth0
diff --git a/contrib/hostapd/reconfig.c b/contrib/hostapd/reconfig.c
deleted file mode 100644
index a0d61569812b..000000000000
--- a/contrib/hostapd/reconfig.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * hostapd / Configuration reloading
- * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2002-2004, Instant802 Networks, Inc.
- * Copyright (c) 2005-2006, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "hostapd.h"
-#include "beacon.h"
-#include "hw_features.h"
-#include "driver.h"
-#include "sta_info.h"
-#include "radius_client.h"
-#include "ieee802_11.h"
-#include "iapp.h"
-#include "ap_list.h"
-#include "wpa.h"
-#include "vlan_init.h"
-#include "ieee802_11_auth.h"
-#include "ieee802_1x.h"
-#include "accounting.h"
-#include "eloop.h"
-
-
-/**
- * struct hostapd_config_change - Configuration change information
- * This is for two purposes:
- * - Storing configuration information in the hostapd_iface during
- * the asynchronous parts of reconfiguration.
- * - Passing configuration information for per-station reconfiguration.
- */
-struct hostapd_config_change {
- struct hostapd_data *hapd;
- struct hostapd_config *newconf, *oldconf;
- struct hostapd_bss_config *newbss, *oldbss;
- int mac_acl_changed;
- int num_sta_remove; /* number of STAs that need to be removed */
- int beacon_changed;
- struct hostapd_iface *hapd_iface;
- struct hostapd_data **new_hapd, **old_hapd;
- int num_old_hapd;
-};
-
-
-static int hostapd_config_reload_sta(struct hostapd_data *hapd,
- struct sta_info *sta, void *data)
-{
- struct hostapd_config_change *change = data;
- struct hostapd_bss_config *newbss, *oldbss;
- int deauth = 0;
- u8 reason = WLAN_REASON_PREV_AUTH_NOT_VALID;
-
- newbss = change->newbss;
- oldbss = change->oldbss;
- hapd = change->hapd;
-
- if (sta->ssid == &oldbss->ssid) {
- sta->ssid = &newbss->ssid;
-
- if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len ||
- memcmp(newbss->ssid.ssid, oldbss->ssid.ssid,
- newbss->ssid.ssid_len) != 0) {
- /* main SSID was changed - kick STA out */
- deauth++;
- }
- }
- sta->ssid_probe = sta->ssid;
-
- /*
- * If MAC ACL configuration has changed, deauthenticate stations that
- * have been removed from accepted list or have been added to denied
- * list. If external RADIUS server is used for ACL, all stations are
- * deauthenticated and they will need to authenticate again. This
- * limits sudden load on the RADIUS server since the verification will
- * be done over the time needed for the STAs to reauthenticate
- * themselves.
- */
- if (change->mac_acl_changed &&
- (newbss->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH ||
- !hostapd_allowed_address(hapd, sta->addr, NULL, 0, NULL, NULL,
- NULL)))
- deauth++;
-
- if (newbss->ieee802_1x != oldbss->ieee802_1x &&
- sta->ssid == &hapd->conf->ssid)
- deauth++;
-
- if (newbss->wpa != oldbss->wpa)
- deauth++;
-
- if (!newbss->wme_enabled && (sta->flags & WLAN_STA_WME))
- deauth++;
-
- if (newbss->auth_algs != oldbss->auth_algs &&
- ((sta->auth_alg == WLAN_AUTH_OPEN &&
- !(newbss->auth_algs & HOSTAPD_AUTH_OPEN)) ||
- (sta->auth_alg == WLAN_AUTH_SHARED_KEY &&
- !(newbss->auth_algs & HOSTAPD_AUTH_SHARED_KEY))))
- deauth++;
-
- if (change->num_sta_remove > 0) {
- deauth++;
- reason = WLAN_REASON_DISASSOC_AP_BUSY;
- }
-
- if (deauth) {
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "STA " MACSTR
- " deauthenticated during config reloading "
- "(reason=%d)\n", MAC2STR(sta->addr), reason);
- ieee802_11_send_deauth(hapd, sta->addr, reason);
- ap_sta_deauthenticate(hapd, sta, reason);
- change->num_sta_remove--;
- }
-
- return 0;
-}
-
-
-static void hostapd_reconfig_tx_queue_params(struct hostapd_data *hapd,
- struct hostapd_config *newconf,
- struct hostapd_config *oldconf)
-{
- int i;
- struct hostapd_tx_queue_params *o, *n;
-
- for (i = 0; i < NUM_TX_QUEUES; i++) {
- o = &oldconf->tx_queue[i];
- n = &newconf->tx_queue[i];
-
- if (!n->configured)
- continue;
-
- if ((n->aifs != o->aifs || n->cwmin != o->cwmin ||
- n->cwmax != o->cwmax || n->burst != o->burst) &&
- hostapd_set_tx_queue_params(hapd, i, n->aifs, n->cwmin,
- n->cwmax, n->burst))
- printf("Failed to set TX queue parameters for queue %d"
- ".\n", i);
- }
-}
-
-
-static int hostapd_reconfig_wme(struct hostapd_data *hapd,
- struct hostapd_config *newconf,
- struct hostapd_config *oldconf)
-{
- int beacon_changed = 0;
- size_t i;
- struct hostapd_wme_ac_params *o, *n;
-
- for (i = 0; i < sizeof(newconf->wme_ac_params) /
- sizeof(newconf->wme_ac_params[0]); i++) {
- o = &oldconf->wme_ac_params[i];
- n = &newconf->wme_ac_params[i];
- if (n->cwmin != o->cwmin ||
- n->cwmax != o->cwmax ||
- n->aifs != o->aifs ||
- n->txopLimit != o->txopLimit ||
- n->admission_control_mandatory !=
- o->admission_control_mandatory) {
- beacon_changed++;
- hapd->parameter_set_count++;
- }
- }
-
- return beacon_changed;
-}
-
-
-static int rate_array_diff(int *a1, int *a2)
-{
- int i;
-
- if (a1 == NULL && a2 == NULL)
- return 0;
- if (a1 == NULL || a2 == NULL)
- return 1;
-
- i = 0;
- for (;;) {
- if (a1[i] != a2[i])
- return 1;
- if (a1[i] == -1)
- break;
- i++;
- }
-
- return 0;
-}
-
-
-static int hostapd_acl_diff(struct hostapd_bss_config *a,
- struct hostapd_bss_config *b)
-{
- int i;
-
- if (a->macaddr_acl != b->macaddr_acl ||
- a->num_accept_mac != b->num_accept_mac ||
- a->num_deny_mac != b->num_deny_mac)
- return 1;
-
- for (i = 0; i < a->num_accept_mac; i++) {
- if (memcmp(a->accept_mac[i], b->accept_mac[i], ETH_ALEN) != 0)
- return 1;
- }
-
- for (i = 0; i < a->num_deny_mac; i++) {
- if (memcmp(a->deny_mac[i], b->deny_mac[i], ETH_ALEN) != 0)
- return 1;
- }
-
- return 0;
-}
-
-
-/**
- * reload_iface2 - Part 2 of reload_iface
- * @hapd_iface: Pointer to hostapd interface data.
- */
-static void reload_iface2(struct hostapd_iface *hapd_iface)
-{
- struct hostapd_data *hapd = hapd_iface->bss[0];
- struct hostapd_config *newconf = hapd_iface->change->newconf;
- struct hostapd_config *oldconf = hapd_iface->change->oldconf;
- int beacon_changed = hapd_iface->change->beacon_changed;
- hostapd_iface_cb cb = hapd_iface->reload_iface_cb;
-
- if (newconf->preamble != oldconf->preamble) {
- if (hostapd_set_preamble(hapd, hapd->iconf->preamble))
- printf("Could not set preamble for kernel driver\n");
- beacon_changed++;
- }
-
- if (newconf->beacon_int != oldconf->beacon_int) {
- /* Need to change beacon interval if it has changed or if
- * auto channel selection was used. */
- if (hostapd_set_beacon_int(hapd, newconf->beacon_int))
- printf("Could not set beacon interval for kernel "
- "driver\n");
- if (newconf->beacon_int != oldconf->beacon_int)
- beacon_changed++;
- }
-
- if (newconf->cts_protection_type != oldconf->cts_protection_type)
- beacon_changed++;
-
- if (newconf->rts_threshold > -1 &&
- newconf->rts_threshold != oldconf->rts_threshold &&
- hostapd_set_rts(hapd, newconf->rts_threshold))
- printf("Could not set RTS threshold for kernel driver\n");
-
- if (newconf->fragm_threshold > -1 &&
- newconf->fragm_threshold != oldconf->fragm_threshold &&
- hostapd_set_frag(hapd, newconf->fragm_threshold))
- printf("Could not set fragmentation threshold for kernel "
- "driver\n");
-
- hostapd_reconfig_tx_queue_params(hapd, newconf, oldconf);
-
- if (hostapd_reconfig_wme(hapd, newconf, oldconf) > 0)
- beacon_changed++;
-
- ap_list_reconfig(hapd_iface, oldconf);
-
- hapd_iface->change->beacon_changed = beacon_changed;
-
- hapd_iface->reload_iface_cb = NULL;
- cb(hapd_iface, 0);
-}
-
-
-/**
- * reload_iface2_handler - Handler that calls reload_face2
- * @eloop_data: Stores the struct hostapd_iface for the interface.
- * @user_ctx: Unused.
- */
-static void reload_iface2_handler(void *eloop_data, void *user_ctx)
-{
- struct hostapd_iface *hapd_iface = eloop_data;
-
- reload_iface2(hapd_iface);
-}
-
-
-/**
- * reload_hw_mode_done - Callback for after the HW mode is setup
- * @hapd_iface: Pointer to interface data.
- * @status: Status of the HW mode setup.
- */
-static void reload_hw_mode_done(struct hostapd_iface *hapd_iface, int status)
-{
- struct hostapd_data *hapd = hapd_iface->bss[0];
- struct hostapd_config_change *change = hapd_iface->change;
- struct hostapd_config *newconf = change->newconf;
- hostapd_iface_cb cb;
- int freq;
-
- if (status) {
- printf("Failed to select hw_mode.\n");
-
- cb = hapd_iface->reload_iface_cb;
- hapd_iface->reload_iface_cb = NULL;
- cb(hapd_iface, -1);
-
- return;
- }
-
- freq = hostapd_hw_get_freq(hapd, newconf->channel);
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "Mode: %s Channel: %d Frequency: %d MHz\n",
- hostapd_hw_mode_txt(newconf->hw_mode),
- newconf->channel, freq);
-
- if (hostapd_set_freq(hapd, newconf->hw_mode, freq)) {
- printf("Could not set channel %d (%d MHz) for kernel "
- "driver\n", newconf->channel, freq);
- }
-
- change->beacon_changed++;
-
- reload_iface2(hapd_iface);
-}
-
-
-/**
- * hostapd_config_reload_iface_start - Start interface reload
- * @hapd_iface: Pointer to interface data.
- * @cb: The function to callback when done.
- * Returns: 0 if it starts successfully; cb will be called when done.
- * -1 on failure; cb will not be called.
- */
-static int hostapd_config_reload_iface_start(struct hostapd_iface *hapd_iface,
- hostapd_iface_cb cb)
-{
- struct hostapd_config_change *change = hapd_iface->change;
- struct hostapd_config *newconf = change->newconf;
- struct hostapd_config *oldconf = change->oldconf;
- struct hostapd_data *hapd = hapd_iface->bss[0];
-
- if (hapd_iface->reload_iface_cb) {
- wpa_printf(MSG_DEBUG,
- "%s: Interface reload already in progress.",
- hapd_iface->bss[0]->conf->iface);
- return -1;
- }
-
- hapd_iface->reload_iface_cb = cb;
-
- if (newconf->bridge_packets != oldconf->bridge_packets &&
- hapd->iconf->bridge_packets != INTERNAL_BRIDGE_DO_NOT_CONTROL &&
- hostapd_set_internal_bridge(hapd, hapd->iconf->bridge_packets))
- printf("Failed to set bridge_packets for kernel driver\n");
-
- if (newconf->channel != oldconf->channel ||
- newconf->hw_mode != oldconf->hw_mode ||
- rate_array_diff(newconf->supported_rates,
- oldconf->supported_rates) ||
- rate_array_diff(newconf->basic_rates, oldconf->basic_rates)) {
- hostapd_free_stas(hapd);
-
- if (hostapd_get_hw_features(hapd_iface)) {
- printf("Could not read HW feature info from the kernel"
- " driver.\n");
- hapd_iface->reload_iface_cb = NULL;
- return -1;
- }
-
- if (hostapd_select_hw_mode_start(hapd_iface,
- reload_hw_mode_done)) {
- printf("Failed to start select hw_mode.\n");
- hapd_iface->reload_iface_cb = NULL;
- return -1;
- }
-
- return 0;
- }
-
- eloop_register_timeout(0, 0, reload_iface2_handler, hapd_iface, NULL);
- return 0;
-}
-
-
-static void hostapd_reconfig_bss(struct hostapd_data *hapd,
- struct hostapd_bss_config *newbss,
- struct hostapd_bss_config *oldbss,
- struct hostapd_config *oldconf,
- int beacon_changed)
-{
- struct hostapd_config_change change;
- int encr_changed = 0;
- struct radius_client_data *old_radius;
-
- radius_client_flush(hapd->radius, 0);
-
- if (hostapd_set_dtim_period(hapd, newbss->dtim_period))
- printf("Could not set DTIM period for kernel driver\n");
-
- if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len ||
- memcmp(newbss->ssid.ssid, oldbss->ssid.ssid,
- newbss->ssid.ssid_len) != 0) {
- if (hostapd_set_ssid(hapd, (u8 *) newbss->ssid.ssid,
- newbss->ssid.ssid_len))
- printf("Could not set SSID for kernel driver\n");
- beacon_changed++;
- }
-
- if (newbss->ignore_broadcast_ssid != oldbss->ignore_broadcast_ssid)
- beacon_changed++;
-
- if (hostapd_wep_key_cmp(&newbss->ssid.wep, &oldbss->ssid.wep)) {
- encr_changed++;
- beacon_changed++;
- }
-
- vlan_reconfig(hapd, oldconf, oldbss);
-
- if (beacon_changed) {
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Updating beacon frame "
- "information\n");
- ieee802_11_set_beacon(hapd);
- }
-
- change.hapd = hapd;
- change.oldconf = oldconf;
- change.newconf = hapd->iconf;
- change.oldbss = oldbss;
- change.newbss = newbss;
- change.mac_acl_changed = hostapd_acl_diff(newbss, oldbss);
- if (newbss->max_num_sta != oldbss->max_num_sta &&
- newbss->max_num_sta < hapd->num_sta) {
- change.num_sta_remove = hapd->num_sta - newbss->max_num_sta;
- } else
- change.num_sta_remove = 0;
- ap_for_each_sta(hapd, hostapd_config_reload_sta, &change);
-
- old_radius = hapd->radius;
- hapd->radius = radius_client_reconfig(hapd->radius, hapd,
- oldbss->radius, newbss->radius);
- hapd->radius_client_reconfigured = old_radius != hapd->radius ||
- hostapd_ip_diff(&newbss->own_ip_addr, &oldbss->own_ip_addr);
-
- ieee802_1x_reconfig(hapd, oldconf, oldbss);
- iapp_reconfig(hapd, oldconf, oldbss);
-
- hostapd_acl_reconfig(hapd, oldconf);
- accounting_reconfig(hapd, oldconf);
-}
-
-
-/**
- * config_reload2 - Part 2 of configuration reloading
- * @hapd_iface:
- */
-static void config_reload2(struct hostapd_iface *hapd_iface, int status)
-{
- struct hostapd_config_change *change = hapd_iface->change;
- struct hostapd_data *hapd = change->hapd;
- struct hostapd_config *newconf = change->newconf;
- struct hostapd_config *oldconf = change->oldconf;
- int beacon_changed = change->beacon_changed;
- struct hostapd_data **new_hapd = change->new_hapd;
- struct hostapd_data **old_hapd = change->old_hapd;
- int num_old_hapd = change->num_old_hapd;
- size_t i, j, max_bss, same_bssid;
- struct hostapd_bss_config *newbss, *oldbss;
- u8 *prev_addr;
- hostapd_iface_cb cb;
-
- free(change);
- hapd_iface->change = NULL;
-
- if (status) {
- printf("Failed to setup new interface config\n");
-
- cb = hapd_iface->config_reload_cb;
- hapd_iface->config_reload_cb = NULL;
-
- /* Invalid configuration - cleanup and terminate hostapd */
- hapd_iface->bss = old_hapd;
- hapd_iface->num_bss = num_old_hapd;
- hapd_iface->conf = hapd->iconf = oldconf;
- hapd->conf = &oldconf->bss[0];
- hostapd_config_free(newconf);
- free(new_hapd);
-
- cb(hapd_iface, -2);
-
- return;
- }
-
- /*
- * If any BSSes have been removed, added, or had their BSSIDs changed,
- * completely remove and reinitialize such BSSes and all the BSSes
- * following them since their BSSID might have changed.
- */
- max_bss = oldconf->num_bss;
- if (max_bss > newconf->num_bss)
- max_bss = newconf->num_bss;
-
- for (i = 0; i < max_bss; i++) {
- if (strcmp(oldconf->bss[i].iface, newconf->bss[i].iface) != 0
- || hostapd_mac_comp(oldconf->bss[i].bssid,
- newconf->bss[i].bssid) != 0)
- break;
- }
- same_bssid = i;
-
- for (i = 0; i < oldconf->num_bss; i++) {
- oldbss = &oldconf->bss[i];
- newbss = NULL;
- for (j = 0; j < newconf->num_bss; j++) {
- if (strcmp(oldbss->iface, newconf->bss[j].iface) == 0)
- {
- newbss = &newconf->bss[j];
- break;
- }
- }
-
- if (newbss && i < same_bssid) {
- hapd = hapd_iface->bss[j] = old_hapd[i];
- hapd->iconf = newconf;
- hapd->conf = newbss;
- hostapd_reconfig_bss(hapd, newbss, oldbss, oldconf,
- beacon_changed);
- } else {
- hapd = old_hapd[i];
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "Removing BSS (ifname %s)\n",
- hapd->conf->iface);
- hostapd_free_stas(hapd);
- /* Send broadcast deauthentication for this BSS, but do
- * not clear all STAs from the driver since other BSSes
- * may have STA entries. The driver will remove all STA
- * entries for this BSS anyway when the interface is
- * being removed. */
-#if 0
- hostapd_deauth_all_stas(hapd);
- hostapd_cleanup(hapd);
-#endif
-
- free(hapd);
- }
- }
-
-
- prev_addr = hapd_iface->bss[0]->own_addr;
- hapd = hapd_iface->bss[0];
- for (j = 0; j < newconf->num_bss; j++) {
- if (hapd_iface->bss[j] != NULL) {
- prev_addr = hapd_iface->bss[j]->own_addr;
- continue;
- }
-
- newbss = &newconf->bss[j];
-
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Reconfiguration: adding "
- "new BSS (ifname=%s)\n", newbss->iface);
-
-#if 0
- hapd = hapd_iface->bss[j] =
- hostapd_alloc_bss_data(hapd_iface, newconf, newbss);
-#endif
- if (hapd == NULL) {
- printf("Failed to initialize new BSS\n");
- /* FIX: This one is somewhat hard to recover
- * from.. Would need to remove this BSS from
- * conf and BSS list. */
- exit(1);
- }
- hapd->driver = hapd_iface->bss[0]->driver;
- hapd->iface = hapd_iface;
- hapd->iconf = newconf;
- hapd->conf = newbss;
-
- memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
- if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
- prev_addr = hapd->own_addr;
-
-#if 0
- if (hostapd_setup_bss(hapd, j == 0)) {
- printf("Failed to setup new BSS\n");
- /* FIX */
- exit(1);
- }
-#endif
-
- }
-
- free(old_hapd);
- hostapd_config_free(oldconf);
-
- cb = hapd_iface->config_reload_cb;
- hapd_iface->config_reload_cb = NULL;
-
- cb(hapd_iface, 0);
-}
-
-
-/**
- * hostapd_config_reload_start - Start reconfiguration of an interface
- * @hapd_iface: Pointer to hostapd interface data
- * @cb: Function to be called back when done.
- * The status indicates:
- * 0 = success, new configuration in use;
- * -1 = failed to update configuraiton, old configuration in use;
- * -2 = failed to update configuration and failed to recover; caller
- * should cleanup and terminate hostapd
- * Returns:
- * 0 = reconfiguration started;
- * -1 = failed to update configuration, old configuration in use;
- * -2 = failed to update configuration and failed to recover; caller
- * should cleanup and terminate hostapd
- */
-int hostapd_config_reload_start(struct hostapd_iface *hapd_iface,
- hostapd_iface_cb cb)
-{
- struct hostapd_config *newconf, *oldconf;
- struct hostapd_config_change *change;
- struct hostapd_data *hapd = NULL;
- struct hostapd_data **old_hapd, **new_hapd;
- int num_old_hapd;
-
- if (hapd_iface->config_reload_cb) {
- wpa_printf(MSG_DEBUG, "%s: Config reload already in progress.",
- hapd_iface->bss[0]->conf->iface);
- return -1;
- }
-
- newconf = hostapd_config_read(hapd_iface->config_fname);
- if (newconf == NULL) {
- printf("Failed to read new configuration file - continuing "
- "with old.\n");
- return -1;
- }
-
- if (strcmp(newconf->bss[0].iface, hapd_iface->conf->bss[0].iface) !=
- 0) {
- printf("Interface name changing is not allowed in "
- "configuration reloading (%s -> %s).\n",
- hapd_iface->conf->bss[0].iface, newconf->bss[0].iface);
- hostapd_config_free(newconf);
- return -1;
- }
-
- new_hapd = wpa_zalloc(newconf->num_bss *
- sizeof(struct hostapd_data *));
- if (new_hapd == NULL) {
- hostapd_config_free(newconf);
- return -1;
- }
- old_hapd = hapd_iface->bss;
- num_old_hapd = hapd_iface->num_bss;
-
- hapd_iface->bss = new_hapd;
- hapd_iface->num_bss = newconf->num_bss;
- /*
- * First BSS remains the same since interface name changing was
- * prohibited above. Now, this is only used in
- * hostapd_config_reload_iface() and following loop will anyway set
- * this again.
- */
- hapd = hapd_iface->bss[0] = old_hapd[0];
-
- oldconf = hapd_iface->conf;
- hapd->iconf = hapd_iface->conf = newconf;
- hapd->conf = &newconf->bss[0];
-
- change = wpa_zalloc(sizeof(struct hostapd_config_change));
- if (change == NULL) {
- hostapd_config_free(newconf);
- return -1;
- }
-
- change->hapd = hapd;
- change->newconf = newconf;
- change->oldconf = oldconf;
- change->beacon_changed = 0;
- change->hapd_iface = hapd_iface;
- change->new_hapd = new_hapd;
- change->old_hapd = old_hapd;
- change->num_old_hapd = num_old_hapd;
-
- hapd_iface->config_reload_cb = cb;
- hapd_iface->change = change;
- if (hostapd_config_reload_iface_start(hapd_iface, config_reload2)) {
- printf("Failed to start setup of new interface config\n");
-
- hapd_iface->config_reload_cb = NULL;
- free(change);
- hapd_iface->change = NULL;
-
- /* Invalid configuration - cleanup and terminate hostapd */
- hapd_iface->bss = old_hapd;
- hapd_iface->num_bss = num_old_hapd;
- hapd_iface->conf = hapd->iconf = oldconf;
- hapd->conf = &oldconf->bss[0];
- hostapd_config_free(newconf);
- free(new_hapd);
- return -2;
- }
-
- return 0;
-}
diff --git a/contrib/hostapd/wpa.c b/contrib/hostapd/wpa.c
deleted file mode 100644
index b92cb2fbac63..000000000000
--- a/contrib/hostapd/wpa.c
+++ /dev/null
@@ -1,3781 +0,0 @@
-/*
- * hostapd - IEEE 802.11i-2004 / WPA Authenticator
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#ifndef CONFIG_NATIVE_WINDOWS
-
-#include "hostapd.h"
-#include "eapol_sm.h"
-#include "wpa.h"
-#include "wme.h"
-#include "sha1.h"
-#include "md5.h"
-#include "rc4.h"
-#include "aes_wrap.h"
-#include "crypto.h"
-#include "eloop.h"
-#include "ieee802_11.h"
-#include "pmksa_cache.h"
-#include "state_machine.h"
-
-#define STATE_MACHINE_DATA struct wpa_state_machine
-#define STATE_MACHINE_DEBUG_PREFIX "WPA"
-#define STATE_MACHINE_ADDR sm->addr
-
-
-#define RSN_NUM_REPLAY_COUNTERS_1 0
-#define RSN_NUM_REPLAY_COUNTERS_2 1
-#define RSN_NUM_REPLAY_COUNTERS_4 2
-#define RSN_NUM_REPLAY_COUNTERS_16 3
-
-
-struct wpa_group;
-
-struct wpa_stsl_negotiation {
- struct wpa_stsl_negotiation *next;
- u8 initiator[ETH_ALEN];
- u8 peer[ETH_ALEN];
-};
-
-
-struct wpa_state_machine {
- struct wpa_authenticator *wpa_auth;
- struct wpa_group *group;
-
- u8 addr[ETH_ALEN];
-
- enum {
- WPA_PTK_INITIALIZE, WPA_PTK_DISCONNECT, WPA_PTK_DISCONNECTED,
- WPA_PTK_AUTHENTICATION, WPA_PTK_AUTHENTICATION2,
- WPA_PTK_INITPMK, WPA_PTK_INITPSK, WPA_PTK_PTKSTART,
- WPA_PTK_PTKCALCNEGOTIATING, WPA_PTK_PTKCALCNEGOTIATING2,
- WPA_PTK_PTKINITNEGOTIATING, WPA_PTK_PTKINITDONE
- } wpa_ptk_state;
-
- enum {
- WPA_PTK_GROUP_IDLE = 0,
- WPA_PTK_GROUP_REKEYNEGOTIATING,
- WPA_PTK_GROUP_REKEYESTABLISHED,
- WPA_PTK_GROUP_KEYERROR
- } wpa_ptk_group_state;
-
- Boolean Init;
- Boolean DeauthenticationRequest;
- Boolean AuthenticationRequest;
- Boolean ReAuthenticationRequest;
- Boolean Disconnect;
- int TimeoutCtr;
- int GTimeoutCtr;
- Boolean TimeoutEvt;
- Boolean EAPOLKeyReceived;
- Boolean EAPOLKeyPairwise;
- Boolean EAPOLKeyRequest;
- Boolean MICVerified;
- Boolean GUpdateStationKeys;
- u8 ANonce[WPA_NONCE_LEN];
- u8 SNonce[WPA_NONCE_LEN];
- u8 PMK[WPA_PMK_LEN];
- struct wpa_ptk PTK;
- Boolean PTK_valid;
- Boolean pairwise_set;
- int keycount;
- Boolean Pair;
- u8 key_replay_counter[WPA_REPLAY_COUNTER_LEN];
- Boolean key_replay_counter_valid;
- Boolean PInitAKeys; /* WPA only, not in IEEE 802.11i */
- Boolean PTKRequest; /* not in IEEE 802.11i state machine */
- Boolean has_GTK;
-
- u8 *last_rx_eapol_key; /* starting from IEEE 802.1X header */
- size_t last_rx_eapol_key_len;
-
- unsigned int changed:1;
- unsigned int in_step_loop:1;
- unsigned int pending_deinit:1;
- unsigned int started:1;
- unsigned int mgmt_frame_prot:1;
-
- u8 req_replay_counter[WPA_REPLAY_COUNTER_LEN];
- int req_replay_counter_used;
-
- u8 *wpa_ie;
- size_t wpa_ie_len;
-
- enum {
- WPA_VERSION_NO_WPA = 0 /* WPA not used */,
- WPA_VERSION_WPA = 1 /* WPA / IEEE 802.11i/D3.0 */,
- WPA_VERSION_WPA2 = 2 /* WPA2 / IEEE 802.11i */
- } wpa;
- int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */
- int wpa_key_mgmt; /* the selected WPA_KEY_MGMT_* */
- struct rsn_pmksa_cache_entry *pmksa;
-
- u32 dot11RSNAStatsTKIPLocalMICFailures;
- u32 dot11RSNAStatsTKIPRemoteMICFailures;
-};
-
-
-/* per group key state machine data */
-struct wpa_group {
- struct wpa_group *next;
- int vlan_id;
-
- Boolean GInit;
- int GKeyDoneStations;
- Boolean GTKReKey;
- int GTK_len;
- int GN, GM;
- Boolean GTKAuthenticator;
- u8 Counter[WPA_NONCE_LEN];
-
- enum {
- WPA_GROUP_GTK_INIT = 0,
- WPA_GROUP_SETKEYS, WPA_GROUP_SETKEYSDONE
- } wpa_group_state;
-
- u8 GMK[WPA_GMK_LEN];
- u8 GTK[2][WPA_GTK_MAX_LEN];
- u8 GNonce[WPA_NONCE_LEN];
- Boolean changed;
-#ifdef CONFIG_IEEE80211W
- u8 DGTK[WPA_DGTK_LEN];
- u8 IGTK[2][WPA_IGTK_LEN];
-#endif /* CONFIG_IEEE80211W */
-};
-
-
-/* per authenticator data */
-struct wpa_authenticator {
- struct wpa_group *group;
-
- unsigned int dot11RSNAStatsTKIPRemoteMICFailures;
- u8 dot11RSNAAuthenticationSuiteSelected[4];
- u8 dot11RSNAPairwiseCipherSelected[4];
- u8 dot11RSNAGroupCipherSelected[4];
- u8 dot11RSNAPMKIDUsed[PMKID_LEN];
- u8 dot11RSNAAuthenticationSuiteRequested[4]; /* FIX: update */
- u8 dot11RSNAPairwiseCipherRequested[4]; /* FIX: update */
- u8 dot11RSNAGroupCipherRequested[4]; /* FIX: update */
- unsigned int dot11RSNATKIPCounterMeasuresInvoked;
- unsigned int dot11RSNA4WayHandshakeFailures;
-
- struct wpa_stsl_negotiation *stsl_negotiations;
-
- struct wpa_auth_config conf;
- struct wpa_auth_callbacks cb;
-
- u8 *wpa_ie;
- size_t wpa_ie_len;
-
- u8 addr[ETH_ALEN];
-
- struct rsn_pmksa_cache *pmksa;
-};
-
-
-static void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx);
-static void wpa_sm_step(struct wpa_state_machine *sm);
-static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len);
-static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx);
-static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
- struct wpa_group *group);
-static int wpa_stsl_remove(struct wpa_authenticator *wpa_auth,
- struct wpa_stsl_negotiation *neg);
-static void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm, int key_info,
- const u8 *key_rsc, const u8 *nonce,
- const u8 *kde, size_t kde_len,
- int keyidx, int encr, int force_version);
-
-/* Default timeouts are 100 ms, but this seems to be a bit too fast for most
- * WPA Supplicants, so use a bit longer timeout. */
-static const u32 dot11RSNAConfigGroupUpdateTimeOut = 1000; /* ms */
-static const u32 dot11RSNAConfigGroupUpdateCount = 3;
-static const u32 dot11RSNAConfigPairwiseUpdateTimeOut = 1000; /* ms */
-static const u32 dot11RSNAConfigPairwiseUpdateCount = 3;
-
-/* TODO: make these configurable */
-static const int dot11RSNAConfigPMKLifetime = 43200;
-static const int dot11RSNAConfigPMKReauthThreshold = 70;
-static const int dot11RSNAConfigSATimeout = 60;
-
-
-static const int WPA_SELECTOR_LEN = 4;
-static const u8 WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
-static const u16 WPA_VERSION = 1;
-static const u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 };
-static const u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 };
-static const u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 };
-static const u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 };
-static const u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 };
-static const u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 };
-static const u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 };
-static const u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };
-#ifdef CONFIG_IEEE80211W
-static const u8 RSN_CIPHER_SUITE_AES_128_CMAC[] = { 0x00, 0x0f, 0xac, 6 };
-#endif /* CONFIG_IEEE80211W */
-
-static const int RSN_SELECTOR_LEN = 4;
-static const u16 RSN_VERSION = 1;
-static const u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 };
-static const u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 };
-static const u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 };
-static const u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 };
-static const u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 };
-static const u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 };
-static const u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 };
-static const u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 };
-
-/* EAPOL-Key Key Data Encapsulation
- * GroupKey and PeerKey require encryption, otherwise, encryption is optional.
- */
-static const u8 RSN_KEY_DATA_GROUPKEY[] = { 0x00, 0x0f, 0xac, 1 };
-#if 0
-static const u8 RSN_KEY_DATA_STAKEY[] = { 0x00, 0x0f, 0xac, 2 };
-#endif
-static const u8 RSN_KEY_DATA_MAC_ADDR[] = { 0x00, 0x0f, 0xac, 3 };
-static const u8 RSN_KEY_DATA_PMKID[] = { 0x00, 0x0f, 0xac, 4 };
-#ifdef CONFIG_PEERKEY
-static const u8 RSN_KEY_DATA_SMK[] = { 0x00, 0x0f, 0xac, 5 };
-static const u8 RSN_KEY_DATA_NONCE[] = { 0x00, 0x0f, 0xac, 6 };
-static const u8 RSN_KEY_DATA_LIFETIME[] = { 0x00, 0x0f, 0xac, 7 };
-static const u8 RSN_KEY_DATA_ERROR[] = { 0x00, 0x0f, 0xac, 8 };
-#endif /* CONFIG_PEERKEY */
-#ifdef CONFIG_IEEE80211W
-/* FIX: IEEE 802.11w/D1.0 is using subtypes 5 and 6 for these, but they were
- * already taken by 802.11ma (PeerKey). Need to update the values here once
- * IEEE 802.11w fixes these. */
-static const u8 RSN_KEY_DATA_DHV[] = { 0x00, 0x0f, 0xac, 9 };
-static const u8 RSN_KEY_DATA_IGTK[] = { 0x00, 0x0f, 0xac, 10 };
-#endif /* CONFIG_IEEE80211W */
-
-#ifdef CONFIG_PEERKEY
-enum {
- STK_MUI_4WAY_STA_AP = 1,
- STK_MUI_4WAY_STAT_STA = 2,
- STK_MUI_GTK = 3,
- STK_MUI_SMK = 4
-};
-
-enum {
- STK_ERR_STA_NR = 1,
- STK_ERR_STA_NRSN = 2,
- STK_ERR_CPHR_NS = 3,
- STK_ERR_NO_STSL = 4
-};
-#endif /* CONFIG_PEERKEY */
-
-#define GENERIC_INFO_ELEM 0xdd
-#define RSN_INFO_ELEM 0x30
-
-#ifdef _MSC_VER
-#pragma pack(push, 1)
-#endif /* _MSC_VER */
-
-/* WPA IE version 1
- * 00-50-f2:1 (OUI:OUI type)
- * 0x01 0x00 (version; little endian)
- * (all following fields are optional:)
- * Group Suite Selector (4 octets) (default: TKIP)
- * Pairwise Suite Count (2 octets, little endian) (default: 1)
- * Pairwise Suite List (4 * n octets) (default: TKIP)
- * Authenticated Key Management Suite Count (2 octets, little endian)
- * (default: 1)
- * Authenticated Key Management Suite List (4 * n octets)
- * (default: unspec 802.1X)
- * WPA Capabilities (2 octets, little endian) (default: 0)
- */
-
-struct wpa_ie_hdr {
- u8 elem_id;
- u8 len;
- u8 oui[3];
- u8 oui_type;
- u16 version;
-} STRUCT_PACKED;
-
-
-/* RSN IE version 1
- * 0x01 0x00 (version; little endian)
- * (all following fields are optional:)
- * Group Suite Selector (4 octets) (default: CCMP)
- * Pairwise Suite Count (2 octets, little endian) (default: 1)
- * Pairwise Suite List (4 * n octets) (default: CCMP)
- * Authenticated Key Management Suite Count (2 octets, little endian)
- * (default: 1)
- * Authenticated Key Management Suite List (4 * n octets)
- * (default: unspec 802.1X)
- * RSN Capabilities (2 octets, little endian) (default: 0)
- * PMKID Count (2 octets) (default: 0)
- * PMKID List (16 * n octets)
- * Management Group Cipher Suite (4 octets) (default: AES-128-CMAC)
- */
-
-struct rsn_ie_hdr {
- u8 elem_id; /* WLAN_EID_RSN */
- u8 len;
- u16 version;
-} STRUCT_PACKED;
-
-
-struct rsn_error_kde {
- u16 mui;
- u16 error_type;
-} STRUCT_PACKED;
-
-
-#ifdef CONFIG_IEEE80211W
-struct wpa_dhv_kde {
- u8 dhv[WPA_DHV_LEN];
-} STRUCT_PACKED;
-
-struct wpa_igtk_kde {
- u8 keyid[2];
- u8 pn[6];
- u8 igtk[WPA_IGTK_LEN];
-} STRUCT_PACKED;
-#endif /* CONFIG_IEEE80211W */
-
-#ifdef _MSC_VER
-#pragma pack(pop)
-#endif /* _MSC_VER */
-
-
-static inline void wpa_auth_mic_failure_report(
- struct wpa_authenticator *wpa_auth, const u8 *addr)
-{
- if (wpa_auth->cb.mic_failure_report)
- wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);
-}
-
-
-static inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth,
- const u8 *addr, wpa_eapol_variable var,
- int value)
-{
- if (wpa_auth->cb.set_eapol)
- wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value);
-}
-
-
-static inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth,
- const u8 *addr, wpa_eapol_variable var)
-{
- if (wpa_auth->cb.get_eapol == NULL)
- return -1;
- return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var);
-}
-
-
-static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
- const u8 *addr, const u8 *prev_psk)
-{
- if (wpa_auth->cb.get_psk == NULL)
- return NULL;
- return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, prev_psk);
-}
-
-
-static inline int wpa_auth_get_pmk(struct wpa_authenticator *wpa_auth,
- const u8 *addr, u8 *pmk, size_t *len)
-{
- if (wpa_auth->cb.get_pmk == NULL)
- return -1;
- return wpa_auth->cb.get_pmk(wpa_auth->cb.ctx, addr, pmk, len);
-}
-
-
-static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
- int vlan_id,
- const char *alg, const u8 *addr, int idx,
- u8 *key, size_t key_len)
-{
- if (wpa_auth->cb.set_key == NULL)
- return -1;
- return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx,
- key, key_len);
-}
-
-
-static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
- const u8 *addr, int idx, u8 *seq)
-{
- if (wpa_auth->cb.get_seqnum == NULL)
- return -1;
- return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq);
-}
-
-
-static inline int wpa_auth_get_seqnum_igtk(struct wpa_authenticator *wpa_auth,
- const u8 *addr, int idx, u8 *seq)
-{
- if (wpa_auth->cb.get_seqnum_igtk == NULL)
- return -1;
- return wpa_auth->cb.get_seqnum_igtk(wpa_auth->cb.ctx, addr, idx, seq);
-}
-
-
-static inline int
-wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,
- const u8 *data, size_t data_len, int encrypt)
-{
- if (wpa_auth->cb.send_eapol == NULL)
- return -1;
- return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len,
- encrypt);
-}
-
-
-static inline int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth,
- int (*cb)(struct wpa_state_machine *sm,
- void *ctx),
- void *cb_ctx)
-{
- if (wpa_auth->cb.for_each_sta == NULL)
- return 0;
- return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx);
-}
-
-
-static void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr,
- logger_level level, const char *txt)
-{
- if (wpa_auth->cb.logger == NULL)
- return;
- wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt);
-}
-
-
-static void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth,
- const u8 *addr, logger_level level,
- const char *fmt, ...)
-{
- char *format;
- int maxlen;
- va_list ap;
-
- if (wpa_auth->cb.logger == NULL)
- return;
-
- maxlen = strlen(fmt) + 100;
- format = malloc(maxlen);
- if (!format)
- return;
-
- va_start(ap, fmt);
- vsnprintf(format, maxlen, fmt, ap);
- va_end(ap);
-
- wpa_auth_logger(wpa_auth, addr, level, format);
-
- free(format);
-}
-
-
-static int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len)
-{
- struct wpa_ie_hdr *hdr;
- int num_suites;
- u8 *pos, *count;
-
- hdr = (struct wpa_ie_hdr *) buf;
- hdr->elem_id = WLAN_EID_GENERIC;
- memcpy(&hdr->oui, WPA_OUI_TYPE, WPA_SELECTOR_LEN);
- hdr->version = host_to_le16(WPA_VERSION);
- pos = (u8 *) (hdr + 1);
-
- if (conf->wpa_group == WPA_CIPHER_CCMP) {
- memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
- } else if (conf->wpa_group == WPA_CIPHER_TKIP) {
- memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
- } else if (conf->wpa_group == WPA_CIPHER_WEP104) {
- memcpy(pos, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN);
- } else if (conf->wpa_group == WPA_CIPHER_WEP40) {
- memcpy(pos, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN);
- } else {
- wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
- conf->wpa_group);
- return -1;
- }
- pos += WPA_SELECTOR_LEN;
-
- num_suites = 0;
- count = pos;
- pos += 2;
-
- if (conf->wpa_pairwise & WPA_CIPHER_CCMP) {
- memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);
- pos += WPA_SELECTOR_LEN;
- num_suites++;
- }
- if (conf->wpa_pairwise & WPA_CIPHER_TKIP) {
- memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);
- pos += WPA_SELECTOR_LEN;
- num_suites++;
- }
- if (conf->wpa_pairwise & WPA_CIPHER_NONE) {
- memcpy(pos, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN);
- pos += WPA_SELECTOR_LEN;
- num_suites++;
- }
-
- if (num_suites == 0) {
- wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
- conf->wpa_pairwise);
- return -1;
- }
- *count++ = num_suites & 0xff;
- *count = (num_suites >> 8) & 0xff;
-
- num_suites = 0;
- count = pos;
- pos += 2;
-
- if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
- memcpy(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN);
- pos += WPA_SELECTOR_LEN;
- num_suites++;
- }
- if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
- memcpy(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X,
- WPA_SELECTOR_LEN);
- pos += WPA_SELECTOR_LEN;
- num_suites++;
- }
-
- if (num_suites == 0) {
- wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
- conf->wpa_key_mgmt);
- return -1;
- }
- *count++ = num_suites & 0xff;
- *count = (num_suites >> 8) & 0xff;
-
- /* WPA Capabilities; use defaults, so no need to include it */
-
- hdr->len = (pos - buf) - 2;
-
- return pos - buf;
-}
-
-
-static int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len)
-{
- struct rsn_ie_hdr *hdr;
- int num_suites;
- u8 *pos, *count;
- u16 capab;
-
- hdr = (struct rsn_ie_hdr *) buf;
- hdr->elem_id = WLAN_EID_RSN;
- pos = (u8 *) &hdr->version;
- *pos++ = RSN_VERSION & 0xff;
- *pos++ = RSN_VERSION >> 8;
- pos = (u8 *) (hdr + 1);
-
- if (conf->wpa_group == WPA_CIPHER_CCMP) {
- memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
- } else if (conf->wpa_group == WPA_CIPHER_TKIP) {
- memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
- } else if (conf->wpa_group == WPA_CIPHER_WEP104) {
- memcpy(pos, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN);
- } else if (conf->wpa_group == WPA_CIPHER_WEP40) {
- memcpy(pos, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN);
- } else {
- wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
- conf->wpa_group);
- return -1;
- }
- pos += RSN_SELECTOR_LEN;
-
- num_suites = 0;
- count = pos;
- pos += 2;
-
- if (conf->wpa_pairwise & WPA_CIPHER_CCMP) {
- memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);
- pos += RSN_SELECTOR_LEN;
- num_suites++;
- }
- if (conf->wpa_pairwise & WPA_CIPHER_TKIP) {
- memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);
- pos += RSN_SELECTOR_LEN;
- num_suites++;
- }
- if (conf->wpa_pairwise & WPA_CIPHER_NONE) {
- memcpy(pos, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN);
- pos += RSN_SELECTOR_LEN;
- num_suites++;
- }
-
- if (num_suites == 0) {
- wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
- conf->wpa_pairwise);
- return -1;
- }
- *count++ = num_suites & 0xff;
- *count = (num_suites >> 8) & 0xff;
-
- num_suites = 0;
- count = pos;
- pos += 2;
-
- if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
- memcpy(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN);
- pos += RSN_SELECTOR_LEN;
- num_suites++;
- }
- if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
- memcpy(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X,
- RSN_SELECTOR_LEN);
- pos += RSN_SELECTOR_LEN;
- num_suites++;
- }
-
- if (num_suites == 0) {
- wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
- conf->wpa_key_mgmt);
- return -1;
- }
- *count++ = num_suites & 0xff;
- *count = (num_suites >> 8) & 0xff;
-
- /* RSN Capabilities */
- capab = 0;
- if (conf->rsn_preauth)
- capab |= WPA_CAPABILITY_PREAUTH;
- if (conf->peerkey)
- capab |= WPA_CAPABILITY_PEERKEY_ENABLED;
- if (conf->wme_enabled) {
- /* 4 PTKSA replay counters when using WME */
- capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
- }
-#ifdef CONFIG_IEEE80211W
- if (conf->ieee80211w != WPA_NO_IEEE80211W)
- capab |= WPA_CAPABILITY_MGMT_FRAME_PROTECTION;
-#endif /* CONFIG_IEEE80211W */
- *pos++ = capab & 0xff;
- *pos++ = capab >> 8;
-
-#ifdef CONFIG_IEEE80211W
- if (conf->ieee80211w != WPA_NO_IEEE80211W) {
- if (pos + 2 + 4 > buf + len)
- return -1;
- /* PMKID Count */
- WPA_PUT_LE16(pos, 0);
- pos += 2;
-
- /* Management Group Cipher Suite */
- memcpy(pos, RSN_CIPHER_SUITE_AES_128_CMAC, RSN_SELECTOR_LEN);
- pos += RSN_SELECTOR_LEN;
- }
-#endif /* CONFIG_IEEE80211W */
-
- hdr->len = (pos - buf) - 2;
-
- return pos - buf;
-}
-
-
-static int wpa_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
-{
- u8 *pos, buf[100];
- int res;
-
- pos = buf;
-
- if (wpa_auth->conf.wpa & HOSTAPD_WPA_VERSION_WPA2) {
- res = wpa_write_rsn_ie(&wpa_auth->conf,
- pos, buf + sizeof(buf) - pos);
- if (res < 0)
- return res;
- pos += res;
- }
- if (wpa_auth->conf.wpa & HOSTAPD_WPA_VERSION_WPA) {
- res = wpa_write_wpa_ie(&wpa_auth->conf,
- pos, buf + sizeof(buf) - pos);
- if (res < 0)
- return res;
- pos += res;
- }
-
- free(wpa_auth->wpa_ie);
- wpa_auth->wpa_ie = malloc(pos - buf);
- if (wpa_auth->wpa_ie == NULL)
- return -1;
- memcpy(wpa_auth->wpa_ie, buf, pos - buf);
- wpa_auth->wpa_ie_len = pos - buf;
-
- return 0;
-}
-
-
-static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,
- const u8 *addr)
-{
- if (wpa_auth->cb.disconnect == NULL)
- return;
- wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr,
- WLAN_REASON_PREV_AUTH_NOT_VALID);
-}
-
-
-static void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_authenticator *wpa_auth = eloop_ctx;
-
- if (hostapd_get_rand(wpa_auth->group->GMK, WPA_GMK_LEN)) {
- wpa_printf(MSG_ERROR, "Failed to get random data for WPA "
- "initialization.");
- } else {
- wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "GMK rekeyd");
- }
-
- if (wpa_auth->conf.wpa_gmk_rekey) {
- eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0,
- wpa_rekey_gmk, wpa_auth, NULL);
- }
-}
-
-
-static void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_authenticator *wpa_auth = eloop_ctx;
- struct wpa_group *group;
-
- wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK");
- for (group = wpa_auth->group; group; group = group->next) {
- group->GTKReKey = TRUE;
- do {
- group->changed = FALSE;
- wpa_group_sm_step(wpa_auth, group);
- } while (group->changed);
- }
-
- if (wpa_auth->conf.wpa_group_rekey) {
- eloop_register_timeout(wpa_auth->conf.wpa_group_rekey,
- 0, wpa_rekey_gtk, wpa_auth, NULL);
- }
-}
-
-
-static int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx)
-{
- if (sm->pmksa == ctx)
- sm->pmksa = NULL;
- return 0;
-}
-
-
-static void wpa_auth_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
- void *ctx)
-{
- struct wpa_authenticator *wpa_auth = ctx;
- wpa_auth_for_each_sta(wpa_auth, wpa_auth_pmksa_clear_cb, entry);
-}
-
-
-static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,
- int vlan_id)
-{
- struct wpa_group *group;
- u8 buf[ETH_ALEN + 8 + sizeof(group)];
- u8 rkey[32];
-
- group = wpa_zalloc(sizeof(struct wpa_group));
- if (group == NULL)
- return NULL;
-
- group->GTKAuthenticator = TRUE;
- group->vlan_id = vlan_id;
-
- switch (wpa_auth->conf.wpa_group) {
- case WPA_CIPHER_CCMP:
- group->GTK_len = 16;
- break;
- case WPA_CIPHER_TKIP:
- group->GTK_len = 32;
- break;
- case WPA_CIPHER_WEP104:
- group->GTK_len = 13;
- break;
- case WPA_CIPHER_WEP40:
- group->GTK_len = 5;
- break;
- }
-
- /* Counter = PRF-256(Random number, "Init Counter",
- * Local MAC Address || Time)
- */
- memcpy(buf, wpa_auth->addr, ETH_ALEN);
- wpa_get_ntp_timestamp(buf + ETH_ALEN);
- memcpy(buf + ETH_ALEN + 8, &group, sizeof(group));
- if (hostapd_get_rand(rkey, sizeof(rkey)) ||
- hostapd_get_rand(group->GMK, WPA_GMK_LEN)) {
- wpa_printf(MSG_ERROR, "Failed to get random data for WPA "
- "initialization.");
- free(group);
- return NULL;
- }
-
- sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf),
- group->Counter, WPA_NONCE_LEN);
-
- group->GInit = TRUE;
- wpa_group_sm_step(wpa_auth, group);
- group->GInit = FALSE;
- wpa_group_sm_step(wpa_auth, group);
-
- return group;
-}
-
-
-/**
- * wpa_init - Initialize WPA authenticator
- * @addr: Authenticator address
- * @conf: Configuration for WPA authenticator
- * Returns: Pointer to WPA authenticator data or %NULL on failure
- */
-struct wpa_authenticator * wpa_init(const u8 *addr,
- struct wpa_auth_config *conf,
- struct wpa_auth_callbacks *cb)
-{
- struct wpa_authenticator *wpa_auth;
-
- wpa_auth = wpa_zalloc(sizeof(struct wpa_authenticator));
- if (wpa_auth == NULL)
- return NULL;
- memcpy(wpa_auth->addr, addr, ETH_ALEN);
- memcpy(&wpa_auth->conf, conf, sizeof(*conf));
- memcpy(&wpa_auth->cb, cb, sizeof(*cb));
-
- if (wpa_gen_wpa_ie(wpa_auth)) {
- wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
- free(wpa_auth);
- return NULL;
- }
-
- wpa_auth->group = wpa_group_init(wpa_auth, 0);
- if (wpa_auth->group == NULL) {
- free(wpa_auth->wpa_ie);
- free(wpa_auth);
- return NULL;
- }
-
- wpa_auth->pmksa = pmksa_cache_init(wpa_auth_pmksa_free_cb, wpa_auth);
- if (wpa_auth->pmksa == NULL) {
- wpa_printf(MSG_ERROR, "PMKSA cache initialization failed.");
- free(wpa_auth->wpa_ie);
- free(wpa_auth);
- return NULL;
- }
-
- if (wpa_auth->conf.wpa_gmk_rekey) {
- eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0,
- wpa_rekey_gmk, wpa_auth, NULL);
- }
-
- if (wpa_auth->conf.wpa_group_rekey) {
- eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 0,
- wpa_rekey_gtk, wpa_auth, NULL);
- }
-
- return wpa_auth;
-}
-
-
-/**
- * wpa_deinit - Deinitialize WPA authenticator
- * @wpa_auth: Pointer to WPA authenticator data from wpa_init()
- */
-void wpa_deinit(struct wpa_authenticator *wpa_auth)
-{
- struct wpa_group *group, *prev;
-
- eloop_cancel_timeout(wpa_rekey_gmk, wpa_auth, NULL);
- eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);
-
- while (wpa_auth->stsl_negotiations)
- wpa_stsl_remove(wpa_auth, wpa_auth->stsl_negotiations);
-
- pmksa_cache_deinit(wpa_auth->pmksa);
-
- free(wpa_auth->wpa_ie);
-
- group = wpa_auth->group;
- while (group) {
- prev = group;
- group = group->next;
- free(prev);
- }
-
- free(wpa_auth);
-}
-
-
-/**
- * wpa_reconfig - Update WPA authenticator configuration
- * @wpa_auth: Pointer to WPA authenticator data from wpa_init()
- * @conf: Configuration for WPA authenticator
- */
-int wpa_reconfig(struct wpa_authenticator *wpa_auth,
- struct wpa_auth_config *conf)
-{
- if (wpa_auth == NULL)
- return 0;
-
- memcpy(&wpa_auth->conf, conf, sizeof(*conf));
- /*
- * TODO:
- * Disassociate stations if configuration changed
- * Update WPA/RSN IE
- */
- return 0;
-}
-
-
-static int wpa_selector_to_bitfield(u8 *s)
-{
- if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0)
- return WPA_CIPHER_NONE;
- if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0)
- return WPA_CIPHER_WEP40;
- if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0)
- return WPA_CIPHER_TKIP;
- if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0)
- return WPA_CIPHER_CCMP;
- if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0)
- return WPA_CIPHER_WEP104;
- return 0;
-}
-
-
-static int wpa_key_mgmt_to_bitfield(u8 *s)
-{
- if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0)
- return WPA_KEY_MGMT_IEEE8021X;
- if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) ==
- 0)
- return WPA_KEY_MGMT_PSK;
- return 0;
-}
-
-
-static int rsn_selector_to_bitfield(u8 *s)
-{
- if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0)
- return WPA_CIPHER_NONE;
- if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0)
- return WPA_CIPHER_WEP40;
- if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0)
- return WPA_CIPHER_TKIP;
- if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0)
- return WPA_CIPHER_CCMP;
- if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0)
- return WPA_CIPHER_WEP104;
-#ifdef CONFIG_IEEE80211W
- if (memcmp(s, RSN_CIPHER_SUITE_AES_128_CMAC, RSN_SELECTOR_LEN) == 0)
- return WPA_CIPHER_AES_128_CMAC;
-#endif /* CONFIG_IEEE80211W */
- return 0;
-}
-
-
-static int rsn_key_mgmt_to_bitfield(u8 *s)
-{
- if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0)
- return WPA_KEY_MGMT_IEEE8021X;
- if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) ==
- 0)
- return WPA_KEY_MGMT_PSK;
- return 0;
-}
-
-
-static u8 * wpa_add_kde(u8 *pos, const u8 *kde, const u8 *data,
- size_t data_len, const u8 *data2, size_t data2_len)
-{
- *pos++ = GENERIC_INFO_ELEM;
- *pos++ = RSN_SELECTOR_LEN + data_len + data2_len;
- memcpy(pos, kde, RSN_SELECTOR_LEN);
- pos += RSN_SELECTOR_LEN;
- memcpy(pos, data, data_len);
- pos += data_len;
- if (data2) {
- memcpy(pos, data2, data2_len);
- pos += data2_len;
- }
- return pos;
-}
-
-
-struct wpa_ie_data {
- int pairwise_cipher;
- int group_cipher;
- int key_mgmt;
- int capabilities;
- size_t num_pmkid;
- u8 *pmkid;
- int mgmt_group_cipher;
-};
-
-
-static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
- struct wpa_ie_data *data)
-{
- struct wpa_ie_hdr *hdr;
- u8 *pos;
- int left;
- int i, count;
-
- memset(data, 0, sizeof(*data));
- data->pairwise_cipher = WPA_CIPHER_TKIP;
- data->group_cipher = WPA_CIPHER_TKIP;
- data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
- data->mgmt_group_cipher = 0;
-
- if (wpa_ie_len < sizeof(struct wpa_ie_hdr))
- return -1;
-
- hdr = (struct wpa_ie_hdr *) wpa_ie;
-
- if (hdr->elem_id != WLAN_EID_GENERIC ||
- hdr->len != wpa_ie_len - 2 ||
- memcmp(&hdr->oui, WPA_OUI_TYPE, WPA_SELECTOR_LEN) != 0 ||
- le_to_host16(hdr->version) != WPA_VERSION) {
- return -2;
- }
-
- pos = (u8 *) (hdr + 1);
- left = wpa_ie_len - sizeof(*hdr);
-
- if (left >= WPA_SELECTOR_LEN) {
- data->group_cipher = wpa_selector_to_bitfield(pos);
- pos += WPA_SELECTOR_LEN;
- left -= WPA_SELECTOR_LEN;
- } else if (left > 0)
- return -3;
-
- if (left >= 2) {
- data->pairwise_cipher = 0;
- count = pos[0] | (pos[1] << 8);
- pos += 2;
- left -= 2;
- if (count == 0 || left < count * WPA_SELECTOR_LEN)
- return -4;
- for (i = 0; i < count; i++) {
- data->pairwise_cipher |= wpa_selector_to_bitfield(pos);
- pos += WPA_SELECTOR_LEN;
- left -= WPA_SELECTOR_LEN;
- }
- } else if (left == 1)
- return -5;
-
- if (left >= 2) {
- data->key_mgmt = 0;
- count = pos[0] | (pos[1] << 8);
- pos += 2;
- left -= 2;
- if (count == 0 || left < count * WPA_SELECTOR_LEN)
- return -6;
- for (i = 0; i < count; i++) {
- data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
- pos += WPA_SELECTOR_LEN;
- left -= WPA_SELECTOR_LEN;
- }
- } else if (left == 1)
- return -7;
-
- if (left >= 2) {
- data->capabilities = pos[0] | (pos[1] << 8);
- pos += 2;
- left -= 2;
- }
-
- if (left > 0) {
- return -8;
- }
-
- return 0;
-}
-
-
-static int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
- struct wpa_ie_data *data)
-{
- struct rsn_ie_hdr *hdr;
- u8 *pos;
- int left;
- int i, count;
-
- memset(data, 0, sizeof(*data));
- data->pairwise_cipher = WPA_CIPHER_CCMP;
- data->group_cipher = WPA_CIPHER_CCMP;
- data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
-#ifdef CONFIG_IEEE80211W
- data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
-#else /* CONFIG_IEEE80211W */
- data->mgmt_group_cipher = 0;
-#endif /* CONFIG_IEEE80211W */
-
- if (rsn_ie_len < sizeof(struct rsn_ie_hdr))
- return -1;
-
- hdr = (struct rsn_ie_hdr *) rsn_ie;
-
- if (hdr->elem_id != WLAN_EID_RSN ||
- hdr->len != rsn_ie_len - 2 ||
- le_to_host16(hdr->version) != RSN_VERSION) {
- return -2;
- }
-
- pos = (u8 *) (hdr + 1);
- left = rsn_ie_len - sizeof(*hdr);
-
- if (left >= RSN_SELECTOR_LEN) {
- data->group_cipher = rsn_selector_to_bitfield(pos);
- pos += RSN_SELECTOR_LEN;
- left -= RSN_SELECTOR_LEN;
- } else if (left > 0)
- return -3;
-
- if (left >= 2) {
- data->pairwise_cipher = 0;
- count = pos[0] | (pos[1] << 8);
- pos += 2;
- left -= 2;
- if (count == 0 || left < count * RSN_SELECTOR_LEN)
- return -4;
- for (i = 0; i < count; i++) {
- data->pairwise_cipher |= rsn_selector_to_bitfield(pos);
- pos += RSN_SELECTOR_LEN;
- left -= RSN_SELECTOR_LEN;
- }
- } else if (left == 1)
- return -5;
-
- if (left >= 2) {
- data->key_mgmt = 0;
- count = pos[0] | (pos[1] << 8);
- pos += 2;
- left -= 2;
- if (count == 0 || left < count * RSN_SELECTOR_LEN)
- return -6;
- for (i = 0; i < count; i++) {
- data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);
- pos += RSN_SELECTOR_LEN;
- left -= RSN_SELECTOR_LEN;
- }
- } else if (left == 1)
- return -7;
-
- if (left >= 2) {
- data->capabilities = pos[0] | (pos[1] << 8);
- pos += 2;
- left -= 2;
- }
-
- if (left >= 2) {
- data->num_pmkid = pos[0] | (pos[1] << 8);
- pos += 2;
- left -= 2;
- if (left < (int) data->num_pmkid * PMKID_LEN) {
- wpa_printf(MSG_DEBUG, "RSN: too short RSN IE for "
- "PMKIDs (num=%lu, left=%d)",
- (unsigned long) data->num_pmkid, left);
- return -9;
- }
- data->pmkid = pos;
- pos += data->num_pmkid * PMKID_LEN;
- left -= data->num_pmkid * PMKID_LEN;
- }
-
-#ifdef CONFIG_IEEE80211W
- if (left >= 4) {
- data->mgmt_group_cipher = rsn_selector_to_bitfield(pos);
- if (data->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) {
- wpa_printf(MSG_DEBUG, "RSN: Unsupported management "
- "group cipher 0x%x",
- data->mgmt_group_cipher);
- return -10;
- }
- pos += RSN_SELECTOR_LEN;
- left -= RSN_SELECTOR_LEN;
- }
-#endif /* CONFIG_IEEE80211W */
-
- if (left > 0) {
- return -8;
- }
-
- return 0;
-}
-
-
-int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- const u8 *wpa_ie, size_t wpa_ie_len)
-{
- struct wpa_ie_data data;
- int ciphers, key_mgmt, res, version;
- const u8 *selector;
- size_t i;
-
- if (wpa_auth == NULL || sm == NULL)
- return WPA_NOT_ENABLED;
-
- if (wpa_ie == NULL || wpa_ie_len < 1)
- return WPA_INVALID_IE;
-
- if (wpa_ie[0] == WLAN_EID_RSN)
- version = HOSTAPD_WPA_VERSION_WPA2;
- else
- version = HOSTAPD_WPA_VERSION_WPA;
-
- if (version == HOSTAPD_WPA_VERSION_WPA2) {
- res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);
-
- selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
- if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
- selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
- else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
- selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;
- memcpy(wpa_auth->dot11RSNAAuthenticationSuiteSelected,
- selector, RSN_SELECTOR_LEN);
-
- selector = RSN_CIPHER_SUITE_CCMP;
- if (data.pairwise_cipher & WPA_CIPHER_CCMP)
- selector = RSN_CIPHER_SUITE_CCMP;
- else if (data.pairwise_cipher & WPA_CIPHER_TKIP)
- selector = RSN_CIPHER_SUITE_TKIP;
- else if (data.pairwise_cipher & WPA_CIPHER_WEP104)
- selector = RSN_CIPHER_SUITE_WEP104;
- else if (data.pairwise_cipher & WPA_CIPHER_WEP40)
- selector = RSN_CIPHER_SUITE_WEP40;
- else if (data.pairwise_cipher & WPA_CIPHER_NONE)
- selector = RSN_CIPHER_SUITE_NONE;
- memcpy(wpa_auth->dot11RSNAPairwiseCipherSelected,
- selector, RSN_SELECTOR_LEN);
-
- selector = RSN_CIPHER_SUITE_CCMP;
- if (data.group_cipher & WPA_CIPHER_CCMP)
- selector = RSN_CIPHER_SUITE_CCMP;
- else if (data.group_cipher & WPA_CIPHER_TKIP)
- selector = RSN_CIPHER_SUITE_TKIP;
- else if (data.group_cipher & WPA_CIPHER_WEP104)
- selector = RSN_CIPHER_SUITE_WEP104;
- else if (data.group_cipher & WPA_CIPHER_WEP40)
- selector = RSN_CIPHER_SUITE_WEP40;
- else if (data.group_cipher & WPA_CIPHER_NONE)
- selector = RSN_CIPHER_SUITE_NONE;
- memcpy(wpa_auth->dot11RSNAGroupCipherSelected,
- selector, RSN_SELECTOR_LEN);
- } else {
- res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data);
-
- selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
- if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
- selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;
- else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
- selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;
- memcpy(wpa_auth->dot11RSNAAuthenticationSuiteSelected,
- selector, WPA_SELECTOR_LEN);
-
- selector = WPA_CIPHER_SUITE_TKIP;
- if (data.pairwise_cipher & WPA_CIPHER_CCMP)
- selector = WPA_CIPHER_SUITE_CCMP;
- else if (data.pairwise_cipher & WPA_CIPHER_TKIP)
- selector = WPA_CIPHER_SUITE_TKIP;
- else if (data.pairwise_cipher & WPA_CIPHER_WEP104)
- selector = WPA_CIPHER_SUITE_WEP104;
- else if (data.pairwise_cipher & WPA_CIPHER_WEP40)
- selector = WPA_CIPHER_SUITE_WEP40;
- else if (data.pairwise_cipher & WPA_CIPHER_NONE)
- selector = WPA_CIPHER_SUITE_NONE;
- memcpy(wpa_auth->dot11RSNAPairwiseCipherSelected,
- selector, WPA_SELECTOR_LEN);
-
- selector = WPA_CIPHER_SUITE_TKIP;
- if (data.group_cipher & WPA_CIPHER_CCMP)
- selector = WPA_CIPHER_SUITE_CCMP;
- else if (data.group_cipher & WPA_CIPHER_TKIP)
- selector = WPA_CIPHER_SUITE_TKIP;
- else if (data.group_cipher & WPA_CIPHER_WEP104)
- selector = WPA_CIPHER_SUITE_WEP104;
- else if (data.group_cipher & WPA_CIPHER_WEP40)
- selector = WPA_CIPHER_SUITE_WEP40;
- else if (data.group_cipher & WPA_CIPHER_NONE)
- selector = WPA_CIPHER_SUITE_NONE;
- memcpy(wpa_auth->dot11RSNAGroupCipherSelected,
- selector, WPA_SELECTOR_LEN);
- }
- if (res) {
- wpa_printf(MSG_DEBUG, "Failed to parse WPA/RSN IE from "
- MACSTR " (res=%d)", MAC2STR(sm->addr), res);
- wpa_hexdump(MSG_DEBUG, "WPA/RSN IE", wpa_ie, wpa_ie_len);
- return WPA_INVALID_IE;
- }
-
- if (data.group_cipher != wpa_auth->conf.wpa_group) {
- wpa_printf(MSG_DEBUG, "Invalid WPA group cipher (0x%x) from "
- MACSTR, data.group_cipher, MAC2STR(sm->addr));
- return WPA_INVALID_GROUP;
- }
-
- key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt;
- if (!key_mgmt) {
- wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from "
- MACSTR, data.key_mgmt, MAC2STR(sm->addr));
- return WPA_INVALID_AKMP;
- }
- if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
- sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
- else
- sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
-
- ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise;
- if (!ciphers) {
- wpa_printf(MSG_DEBUG, "Invalid WPA pairwise cipher (0x%x) "
- "from " MACSTR,
- data.pairwise_cipher, MAC2STR(sm->addr));
- return WPA_INVALID_PAIRWISE;
- }
-
-#ifdef CONFIG_IEEE80211W
- if (wpa_auth->conf.ieee80211w == WPA_IEEE80211W_REQUIRED) {
- if (!(data.capabilities &
- WPA_CAPABILITY_MGMT_FRAME_PROTECTION)) {
- wpa_printf(MSG_DEBUG, "Management frame protection "
- "required, but client did not enable it");
- return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
- }
-
- if (ciphers & WPA_CIPHER_TKIP) {
- wpa_printf(MSG_DEBUG, "Management frame protection "
- "cannot use TKIP");
- return WPA_MGMT_FRAME_PROTECTION_VIOLATION;
- }
-
- if (data.mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) {
- wpa_printf(MSG_DEBUG, "Unsupported management group "
- "cipher %d", data.mgmt_group_cipher);
- return WPA_INVALID_MGMT_GROUP_CIPHER;
- }
- }
-
- if (wpa_auth->conf.ieee80211w == WPA_NO_IEEE80211W ||
- !(data.capabilities & WPA_CAPABILITY_MGMT_FRAME_PROTECTION))
- sm->mgmt_frame_prot = 0;
- else
- sm->mgmt_frame_prot = 1;
-#endif /* CONFIG_IEEE80211W */
-
- if (ciphers & WPA_CIPHER_CCMP)
- sm->pairwise = WPA_CIPHER_CCMP;
- else
- sm->pairwise = WPA_CIPHER_TKIP;
-
- /* TODO: clear WPA/WPA2 state if STA changes from one to another */
- if (wpa_ie[0] == WLAN_EID_RSN)
- sm->wpa = WPA_VERSION_WPA2;
- else
- sm->wpa = WPA_VERSION_WPA;
-
- for (i = 0; i < data.num_pmkid; i++) {
- wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID",
- &data.pmkid[i * PMKID_LEN], PMKID_LEN);
- sm->pmksa = pmksa_cache_get(wpa_auth->pmksa, sm->addr,
- &data.pmkid[i * PMKID_LEN]);
- if (sm->pmksa) {
- wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "PMKID found from PMKSA cache "
- "eap_type=%d vlan_id=%d",
- sm->pmksa->eap_type_authsrv,
- sm->pmksa->vlan_id);
- memcpy(wpa_auth->dot11RSNAPMKIDUsed,
- sm->pmksa->pmkid, PMKID_LEN);
- break;
- }
- }
-
- if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) {
- free(sm->wpa_ie);
- sm->wpa_ie = malloc(wpa_ie_len);
- if (sm->wpa_ie == NULL)
- return WPA_ALLOC_FAIL;
- }
- memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len);
- sm->wpa_ie_len = wpa_ie_len;
-
- return WPA_IE_OK;
-}
-
-
-struct wpa_eapol_ie_parse {
- const u8 *wpa_ie;
- size_t wpa_ie_len;
- const u8 *rsn_ie;
- size_t rsn_ie_len;
- const u8 *pmkid;
- const u8 *gtk;
- size_t gtk_len;
- const u8 *mac_addr;
- size_t mac_addr_len;
-#ifdef CONFIG_PEERKEY
- const u8 *smk;
- size_t smk_len;
- const u8 *nonce;
- size_t nonce_len;
- const u8 *lifetime;
- size_t lifetime_len;
- const u8 *error;
- size_t error_len;
-#endif /* CONFIG_PEERKEY */
-};
-
-
-/**
- * wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
- * @pos: Pointer to the IE header
- * @end: Pointer to the end of the Key Data buffer
- * @ie: Pointer to parsed IE data
- * Returns: 0 on success, 1 if end mark is found, -1 on failure
- */
-static int wpa_parse_generic(const u8 *pos, const u8 *end,
- struct wpa_eapol_ie_parse *ie)
-{
- if (pos[1] == 0)
- return 1;
-
- if (pos[1] >= 6 &&
- memcmp(pos + 2, WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0 &&
- pos[2 + WPA_SELECTOR_LEN] == 1 &&
- pos[2 + WPA_SELECTOR_LEN + 1] == 0) {
- ie->wpa_ie = pos;
- ie->wpa_ie_len = pos[1] + 2;
- return 0;
- }
-
- if (pos + 1 + RSN_SELECTOR_LEN < end &&
- pos[1] >= RSN_SELECTOR_LEN + PMKID_LEN &&
- memcmp(pos + 2, RSN_KEY_DATA_PMKID, RSN_SELECTOR_LEN) == 0) {
- ie->pmkid = pos + 2 + RSN_SELECTOR_LEN;
- return 0;
- }
-
- if (pos[1] > RSN_SELECTOR_LEN + 2 &&
- memcmp(pos + 2, RSN_KEY_DATA_GROUPKEY, RSN_SELECTOR_LEN) == 0) {
- ie->gtk = pos + 2 + RSN_SELECTOR_LEN;
- ie->gtk_len = pos[1] - RSN_SELECTOR_LEN;
- return 0;
- }
-
- if (pos[1] > RSN_SELECTOR_LEN + 2 &&
- memcmp(pos + 2, RSN_KEY_DATA_MAC_ADDR, RSN_SELECTOR_LEN) == 0) {
- ie->mac_addr = pos + 2 + RSN_SELECTOR_LEN;
- ie->mac_addr_len = pos[1] - RSN_SELECTOR_LEN;
- return 0;
- }
-
-#ifdef CONFIG_PEERKEY
- if (pos[1] > RSN_SELECTOR_LEN + 2 &&
- memcmp(pos + 2, RSN_KEY_DATA_SMK, RSN_SELECTOR_LEN) == 0) {
- ie->smk = pos + 2 + RSN_SELECTOR_LEN;
- ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
- return 0;
- }
-
- if (pos[1] > RSN_SELECTOR_LEN + 2 &&
- memcmp(pos + 2, RSN_KEY_DATA_NONCE, RSN_SELECTOR_LEN) == 0) {
- ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
- ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
- return 0;
- }
-
- if (pos[1] > RSN_SELECTOR_LEN + 2 &&
- memcmp(pos + 2, RSN_KEY_DATA_LIFETIME, RSN_SELECTOR_LEN) == 0) {
- ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
- ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
- return 0;
- }
-
- if (pos[1] > RSN_SELECTOR_LEN + 2 &&
- memcmp(pos + 2, RSN_KEY_DATA_ERROR, RSN_SELECTOR_LEN) == 0) {
- ie->error = pos + 2 + RSN_SELECTOR_LEN;
- ie->error_len = pos[1] - RSN_SELECTOR_LEN;
- return 0;
- }
-#endif /* CONFIG_PEERKEY */
-
- return 0;
-}
-
-
-/**
- * wpa_parse_kde_ies - Parse EAPOL-Key Key Data IEs
- * @buf: Pointer to the Key Data buffer
- * @len: Key Data Length
- * @ie: Pointer to parsed IE data
- * Returns: 0 on success, -1 on failure
- */
-static int wpa_parse_kde_ies(const u8 *buf, size_t len,
- struct wpa_eapol_ie_parse *ie)
-{
- const u8 *pos, *end;
- int ret = 0;
-
- memset(ie, 0, sizeof(*ie));
- for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1]) {
- if (pos[0] == 0xdd &&
- ((pos == buf + len - 1) || pos[1] == 0)) {
- /* Ignore padding */
- break;
- }
- if (pos + 2 + pos[1] > end) {
- wpa_printf(MSG_DEBUG, "WPA: EAPOL-Key Key Data "
- "underflow (ie=%d len=%d)", pos[0], pos[1]);
- ret = -1;
- break;
- }
- if (*pos == RSN_INFO_ELEM) {
- ie->rsn_ie = pos;
- ie->rsn_ie_len = pos[1] + 2;
- } else if (*pos == GENERIC_INFO_ELEM) {
- ret = wpa_parse_generic(pos, end, ie);
- if (ret < 0)
- break;
- if (ret > 0) {
- ret = 0;
- break;
- }
- } else {
- wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key "
- "Key Data IE", pos, 2 + pos[1]);
- }
- }
-
- return ret;
-}
-
-
-struct wpa_state_machine *
-wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr)
-{
- struct wpa_state_machine *sm;
-
- sm = wpa_zalloc(sizeof(struct wpa_state_machine));
- if (sm == NULL)
- return NULL;
- memcpy(sm->addr, addr, ETH_ALEN);
-
- sm->wpa_auth = wpa_auth;
- sm->group = wpa_auth->group;
-
- return sm;
-}
-
-
-void wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm)
-{
- if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)
- return;
-
- if (sm->started) {
- memset(sm->key_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);
- sm->ReAuthenticationRequest = TRUE;
- wpa_sm_step(sm);
- return;
- }
-
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "start authentication");
- sm->started = 1;
-
- sm->Init = TRUE;
- wpa_sm_step(sm);
- sm->Init = FALSE;
- sm->AuthenticationRequest = TRUE;
- wpa_sm_step(sm);
-}
-
-
-static void wpa_free_sta_sm(struct wpa_state_machine *sm)
-{
- free(sm->last_rx_eapol_key);
- free(sm->wpa_ie);
- free(sm);
-}
-
-
-void wpa_auth_sta_deinit(struct wpa_state_machine *sm)
-{
- if (sm == NULL)
- return;
-
- if (sm->wpa_auth->conf.wpa_strict_rekey && sm->has_GTK) {
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "strict rekeying - force GTK rekey since STA "
- "is leaving");
- eloop_cancel_timeout(wpa_rekey_gtk, sm->wpa_auth, NULL);
- eloop_register_timeout(0, 500000, wpa_rekey_gtk, sm->wpa_auth,
- NULL);
- }
-
- eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
- eloop_cancel_timeout(wpa_sm_call_step, sm, NULL);
- if (sm->in_step_loop) {
- /* Must not free state machine while wpa_sm_step() is running.
- * Freeing will be completed in the end of wpa_sm_step(). */
- wpa_printf(MSG_DEBUG, "WPA: Registering pending STA state "
- "machine deinit for " MACSTR, MAC2STR(sm->addr));
- sm->pending_deinit = 1;
- } else
- wpa_free_sta_sm(sm);
-}
-
-
-static void wpa_request_new_ptk(struct wpa_state_machine *sm)
-{
- if (sm == NULL)
- return;
-
- sm->PTKRequest = TRUE;
- sm->PTK_valid = 0;
-}
-
-
-#ifdef CONFIG_PEERKEY
-static void wpa_stsl_step(void *eloop_ctx, void *timeout_ctx)
-{
-#if 0
- struct wpa_authenticator *wpa_auth = eloop_ctx;
- struct wpa_stsl_negotiation *neg = timeout_ctx;
-#endif
-
- /* TODO: ? */
-}
-
-
-struct wpa_stsl_search {
- const u8 *addr;
- struct wpa_state_machine *sm;
-};
-
-
-static int wpa_stsl_select_sta(struct wpa_state_machine *sm, void *ctx)
-{
- struct wpa_stsl_search *search = ctx;
- if (memcmp(search->addr, sm->addr, ETH_ALEN) == 0) {
- search->sm = sm;
- return 1;
- }
- return 0;
-}
-
-
-static void wpa_smk_send_error(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm, const u8 *peer,
- u16 mui, u16 error_type)
-{
- u8 kde[2 + RSN_SELECTOR_LEN + ETH_ALEN +
- 2 + RSN_SELECTOR_LEN + sizeof(struct rsn_error_kde)];
- size_t kde_len;
- u8 *pos;
- struct rsn_error_kde error;
-
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "Sending SMK Error");
-
- kde_len = 2 + RSN_SELECTOR_LEN + sizeof(struct rsn_error_kde);
- pos = kde;
-
- if (peer) {
- pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN,
- NULL, 0);
- kde_len += 2 + RSN_SELECTOR_LEN + ETH_ALEN;
- }
-
- error.mui = host_to_be16(mui);
- error.error_type = host_to_be16(error_type);
- pos = wpa_add_kde(pos, RSN_KEY_DATA_ERROR,
- (u8 *) &error, sizeof(error), NULL, 0);
-
- __wpa_send_eapol(wpa_auth, sm,
- WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_ERROR,
- NULL, NULL, kde, kde_len, 0, 0, 0);
-}
-
-
-static void wpa_smk_m1(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- struct wpa_eapol_key *key)
-{
- struct wpa_eapol_ie_parse kde;
- struct wpa_stsl_search search;
- u8 *buf, *pos;
- size_t buf_len;
-
- if (wpa_parse_kde_ies((const u8 *) (key + 1),
- ntohs(key->key_data_length), &kde) < 0) {
- wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M1");
- return;
- }
-
- if (kde.rsn_ie == NULL || kde.mac_addr == NULL ||
- kde.mac_addr_len < ETH_ALEN) {
- wpa_printf(MSG_INFO, "RSN: No RSN IE or MAC address KDE in "
- "SMK M1");
- return;
- }
-
- /* Initiator = sm->addr; Peer = kde.mac_addr */
-
- search.addr = kde.mac_addr;
- search.sm = NULL;
- if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
- 0 || search.sm == NULL) {
- wpa_printf(MSG_DEBUG, "RSN: SMK handshake with " MACSTR
- " aborted - STA not associated anymore",
- MAC2STR(kde.mac_addr));
- wpa_smk_send_error(wpa_auth, sm, kde.mac_addr, STK_MUI_SMK,
- STK_ERR_STA_NR);
- /* FIX: wpa_stsl_remove(wpa_auth, neg); */
- return;
- }
-
- buf_len = kde.rsn_ie_len + 2 + RSN_SELECTOR_LEN + ETH_ALEN;
- buf = malloc(buf_len);
- if (buf == NULL)
- return;
- /* Initiator RSN IE */
- memcpy(buf, kde.rsn_ie, kde.rsn_ie_len);
- pos = buf + kde.rsn_ie_len;
- /* Initiator MAC Address */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, sm->addr, ETH_ALEN,
- NULL, 0);
-
- /* SMK M2:
- * EAPOL-Key(S=1, M=1, A=1, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
- * MIC=MIC, DataKDs=(RSNIE_I, MAC_I KDE)
- */
-
- wpa_auth_logger(wpa_auth, search.sm->addr, LOGGER_DEBUG,
- "Sending SMK M2");
-
- __wpa_send_eapol(wpa_auth, search.sm,
- WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE,
- NULL, key->key_nonce, buf, buf_len, 0, 0, 0);
-
- free(buf);
-
-}
-
-
-static void wpa_send_smk_m4(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- struct wpa_eapol_key *key,
- struct wpa_eapol_ie_parse *kde,
- const u8 *smk)
-{
- u8 *buf, *pos;
- size_t buf_len;
- u32 lifetime;
-
- /* SMK M4:
- * EAPOL-Key(S=1, M=1, A=0, I=1, K=0, SM=1, KeyRSC=0, Nonce=PNonce,
- * MIC=MIC, DataKDs=(MAC_I KDE, INonce KDE, SMK KDE,
- * Lifetime KDE)
- */
-
- buf_len = 2 + RSN_SELECTOR_LEN + ETH_ALEN +
- 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN +
- 2 + RSN_SELECTOR_LEN + WPA_PMK_LEN + WPA_NONCE_LEN +
- 2 + RSN_SELECTOR_LEN + sizeof(lifetime);
- pos = buf = malloc(buf_len);
- if (buf == NULL)
- return;
-
- /* Initiator MAC Address */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, kde->mac_addr, ETH_ALEN,
- NULL, 0);
-
- /* Initiator Nonce */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_NONCE, kde->nonce, WPA_NONCE_LEN,
- NULL, 0);
-
- /* SMK with PNonce */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_SMK, smk, WPA_PMK_LEN,
- key->key_nonce, WPA_NONCE_LEN);
-
- /* Lifetime */
- lifetime = htonl(43200); /* dot11RSNAConfigSMKLifetime */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
- (u8 *) &lifetime, sizeof(lifetime), NULL, 0);
-
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "Sending SMK M4");
-
- __wpa_send_eapol(wpa_auth, sm,
- WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_INSTALL | WPA_KEY_INFO_SMK_MESSAGE,
- NULL, key->key_nonce, buf, buf_len, 0, 1, 0);
-
- free(buf);
-}
-
-
-static void wpa_send_smk_m5(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- struct wpa_eapol_key *key,
- struct wpa_eapol_ie_parse *kde,
- const u8 *smk, const u8 *peer)
-{
- u8 *buf, *pos;
- size_t buf_len;
- u32 lifetime;
-
- /* SMK M5:
- * EAPOL-Key(S=1, M=1, A=0, I=0, K=0, SM=1, KeyRSC=0, Nonce=INonce,
- * MIC=MIC, DataKDs=(RSNIE_P, MAC_P KDE, PNonce, SMK KDE,
- * Lifetime KDE))
- */
-
- buf_len = kde->rsn_ie_len +
- 2 + RSN_SELECTOR_LEN + ETH_ALEN +
- 2 + RSN_SELECTOR_LEN + WPA_NONCE_LEN +
- 2 + RSN_SELECTOR_LEN + WPA_PMK_LEN + WPA_NONCE_LEN +
- 2 + RSN_SELECTOR_LEN + sizeof(lifetime);
- pos = buf = malloc(buf_len);
- if (buf == NULL)
- return;
-
- /* Peer RSN IE */
- memcpy(buf, kde->rsn_ie, kde->rsn_ie_len);
- pos = buf + kde->rsn_ie_len;
-
- /* Peer MAC Address */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_MAC_ADDR, peer, ETH_ALEN, NULL, 0);
-
- /* PNonce */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_NONCE, key->key_nonce,
- WPA_NONCE_LEN, NULL, 0);
-
- /* SMK and INonce */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_SMK, smk, WPA_PMK_LEN,
- kde->nonce, WPA_NONCE_LEN);
-
- /* Lifetime */
- lifetime = htonl(43200); /* dot11RSNAConfigSMKLifetime */
- pos = wpa_add_kde(pos, RSN_KEY_DATA_LIFETIME,
- (u8 *) &lifetime, sizeof(lifetime), NULL, 0);
-
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "Sending SMK M5");
-
- __wpa_send_eapol(wpa_auth, sm,
- WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_SMK_MESSAGE,
- NULL, kde->nonce, buf, buf_len, 0, 1, 0);
-
- free(buf);
-}
-
-
-static void wpa_smk_m3(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- struct wpa_eapol_key *key)
-{
- struct wpa_eapol_ie_parse kde;
- struct wpa_stsl_search search;
- u8 smk[32], buf[ETH_ALEN + 8 + 2 * WPA_NONCE_LEN], *pos;
-
- if (wpa_parse_kde_ies((const u8 *) (key + 1),
- ntohs(key->key_data_length), &kde) < 0) {
- wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK M3");
- return;
- }
-
- if (kde.rsn_ie == NULL ||
- kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
- kde.nonce == NULL || kde.nonce_len < WPA_NONCE_LEN) {
- wpa_printf(MSG_INFO, "RSN: No RSN IE, MAC address KDE, or "
- "Nonce KDE in SMK M3");
- return;
- }
-
- /* Peer = sm->addr; Initiator = kde.mac_addr;
- * Peer Nonce = key->key_nonce; Initiator Nonce = kde.nonce */
-
- search.addr = kde.mac_addr;
- search.sm = NULL;
- if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
- 0 || search.sm == NULL) {
- wpa_printf(MSG_DEBUG, "RSN: SMK handshake with " MACSTR
- " aborted - STA not associated anymore",
- MAC2STR(kde.mac_addr));
- wpa_smk_send_error(wpa_auth, sm, kde.mac_addr, STK_MUI_SMK,
- STK_ERR_STA_NR);
- /* FIX: wpa_stsl_remove(wpa_auth, neg); */
- return;
- }
-
- if (hostapd_get_rand(smk, WPA_PMK_LEN)) {
- wpa_printf(MSG_DEBUG, "RSN: Failed to generate SMK");
- return;
- }
-
- /* SMK = PRF-256(Random number, "SMK Derivation",
- * AA || Time || INonce || PNonce)
- */
- memcpy(buf, wpa_auth->addr, ETH_ALEN);
- pos = buf + ETH_ALEN;
- wpa_get_ntp_timestamp(pos);
- pos += 8;
- memcpy(pos, kde.nonce, WPA_NONCE_LEN);
- pos += WPA_NONCE_LEN;
- memcpy(pos, key->key_nonce, WPA_NONCE_LEN);
- sha1_prf(smk, WPA_PMK_LEN, "SMK Derivation", buf, sizeof(buf),
- smk, WPA_PMK_LEN);
-
- wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", smk, WPA_PMK_LEN);
-
- wpa_send_smk_m4(wpa_auth, sm, key, &kde, smk);
- wpa_send_smk_m5(wpa_auth, search.sm, key, &kde, smk, sm->addr);
-
- /* Authenticator does not need SMK anymore and it is required to forget
- * it. */
- memset(smk, 0, sizeof(*smk));
-}
-
-
-static void wpa_smk_error(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- struct wpa_eapol_key *key)
-{
- struct wpa_eapol_ie_parse kde;
- struct wpa_stsl_search search;
- struct rsn_error_kde error;
- u16 mui, error_type;
-
- if (wpa_parse_kde_ies((const u8 *) (key + 1),
- ntohs(key->key_data_length), &kde) < 0) {
- wpa_printf(MSG_INFO, "RSN: Failed to parse KDEs in SMK Error");
- return;
- }
-
- if (kde.mac_addr == NULL || kde.mac_addr_len < ETH_ALEN ||
- kde.error == NULL || kde.error_len < sizeof(error)) {
- wpa_printf(MSG_INFO, "RSN: No MAC address or Error KDE in "
- "SMK Error");
- return;
- }
-
- search.addr = kde.mac_addr;
- search.sm = NULL;
- if (wpa_auth_for_each_sta(wpa_auth, wpa_stsl_select_sta, &search) ==
- 0 || search.sm == NULL) {
- wpa_printf(MSG_DEBUG, "RSN: Peer STA " MACSTR " not "
- "associated for SMK Error message from " MACSTR,
- MAC2STR(kde.mac_addr), MAC2STR(sm->addr));
- return;
- }
-
- memcpy(&error, kde.error, sizeof(error));
- mui = be_to_host16(error.mui);
- error_type = be_to_host16(error.error_type);
- wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "STA reported SMK Error: Peer " MACSTR
- " MUI %d Error Type %d",
- MAC2STR(kde.mac_addr), mui, error_type);
-
- wpa_smk_send_error(wpa_auth, search.sm, sm->addr, mui, error_type);
-}
-#endif /* CONFIG_PEERKEY */
-
-
-static int wpa_stsl_remove(struct wpa_authenticator *wpa_auth,
- struct wpa_stsl_negotiation *neg)
-{
-#ifdef CONFIG_PEERKEY
- struct wpa_stsl_negotiation *pos, *prev;
-
- if (wpa_auth == NULL)
- return -1;
- pos = wpa_auth->stsl_negotiations;
- prev = NULL;
- while (pos) {
- if (pos == neg) {
- if (prev)
- prev->next = pos->next;
- else
- wpa_auth->stsl_negotiations = pos->next;
-
- eloop_cancel_timeout(wpa_stsl_step, wpa_auth, pos);
- free(pos);
- return 0;
- }
- prev = pos;
- pos = pos->next;
- }
-#endif /* CONFIG_PEERKEY */
-
- return -1;
-}
-
-
-void wpa_receive(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- u8 *data, size_t data_len)
-{
- struct ieee802_1x_hdr *hdr;
- struct wpa_eapol_key *key;
- u16 key_info, key_data_length;
- enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST,
- SMK_M1, SMK_M3, SMK_ERROR } msg;
- char *msgtxt;
- struct wpa_eapol_ie_parse kde;
-
- if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)
- return;
-
- if (data_len < sizeof(*hdr) + sizeof(*key))
- return;
-
- hdr = (struct ieee802_1x_hdr *) data;
- key = (struct wpa_eapol_key *) (hdr + 1);
- key_info = ntohs(key->key_info);
- key_data_length = ntohs(key->key_data_length);
- if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) {
- wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
- "key_data overflow (%d > %lu)",
- key_data_length,
- (unsigned long) (data_len - sizeof(*hdr) -
- sizeof(*key)));
- return;
- }
-
- /* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys
- * are set */
-
- if ((key_info & (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) ==
- (WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_REQUEST)) {
- if (key_info & WPA_KEY_INFO_ERROR) {
- msg = SMK_ERROR;
- msgtxt = "SMK Error";
- } else {
- msg = SMK_M1;
- msgtxt = "SMK M1";
- }
- } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
- msg = SMK_M3;
- msgtxt = "SMK M3";
- } else if (key_info & WPA_KEY_INFO_REQUEST) {
- msg = REQUEST;
- msgtxt = "Request";
- } else if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) {
- msg = GROUP_2;
- msgtxt = "2/2 Group";
- } else if (key_data_length == 0) {
- msg = PAIRWISE_4;
- msgtxt = "4/4 Pairwise";
- } else {
- msg = PAIRWISE_2;
- msgtxt = "2/4 Pairwise";
- }
-
- if (key_info & WPA_KEY_INFO_REQUEST) {
- if (sm->req_replay_counter_used &&
- memcmp(key->replay_counter, sm->req_replay_counter,
- WPA_REPLAY_COUNTER_LEN) <= 0) {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_WARNING,
- "received EAPOL-Key request with "
- "replayed counter");
- return;
- }
- }
-
- if (!(key_info & WPA_KEY_INFO_REQUEST) &&
- (!sm->key_replay_counter_valid ||
- memcmp(key->replay_counter, sm->key_replay_counter,
- WPA_REPLAY_COUNTER_LEN) != 0)) {
- wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key %s with unexpected "
- "replay counter", msgtxt);
- wpa_hexdump(MSG_DEBUG, "expected replay counter",
- sm->key_replay_counter, WPA_REPLAY_COUNTER_LEN);
- wpa_hexdump(MSG_DEBUG, "received replay counter",
- key->replay_counter, WPA_REPLAY_COUNTER_LEN);
- return;
- }
-
- switch (msg) {
- case PAIRWISE_2:
- if (sm->wpa_ptk_state != WPA_PTK_PTKSTART &&
- sm->wpa_ptk_state != WPA_PTK_PTKCALCNEGOTIATING) {
- wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key msg 2/4 in "
- "invalid state (%d) - dropped",
- sm->wpa_ptk_state);
- return;
- }
- if (sm->wpa_ie == NULL ||
- sm->wpa_ie_len != key_data_length ||
- memcmp(sm->wpa_ie, key + 1, key_data_length) != 0) {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "WPA IE from (Re)AssocReq did not "
- "match with msg 2/4");
- if (sm->wpa_ie) {
- wpa_hexdump(MSG_DEBUG, "WPA IE in AssocReq",
- sm->wpa_ie, sm->wpa_ie_len);
- }
- wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4",
- (u8 *) (key + 1), key_data_length);
- /* MLME-DEAUTHENTICATE.request */
- wpa_sta_disconnect(wpa_auth, sm->addr);
- return;
- }
- break;
- case PAIRWISE_4:
- if (sm->wpa_ptk_state != WPA_PTK_PTKINITNEGOTIATING ||
- !sm->PTK_valid) {
- wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key msg 4/4 in "
- "invalid state (%d) - dropped",
- sm->wpa_ptk_state);
- return;
- }
- break;
- case GROUP_2:
- if (sm->wpa_ptk_group_state != WPA_PTK_GROUP_REKEYNEGOTIATING
- || !sm->PTK_valid) {
- wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key msg 2/2 in "
- "invalid state (%d) - dropped",
- sm->wpa_ptk_group_state);
- return;
- }
- break;
-#ifdef CONFIG_PEERKEY
- case SMK_M1:
- case SMK_M3:
- case SMK_ERROR:
- if (!wpa_auth->conf.peerkey) {
- wpa_printf(MSG_DEBUG, "RSN: SMK M1/M3/Error, but "
- "PeerKey use disabled - ignoring message");
- return;
- }
- if (!sm->PTK_valid) {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key msg SMK in "
- "invalid state - dropped");
- return;
- }
- break;
-#else /* CONFIG_PEERKEY */
- case SMK_M1:
- case SMK_M3:
- case SMK_ERROR:
- return; /* STSL disabled - ignore SMK messages */
-#endif /* CONFIG_PEERKEY */
- case REQUEST:
- break;
- }
-
- wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "received EAPOL-Key frame (%s)", msgtxt);
-
- if (key_info & WPA_KEY_INFO_ACK) {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received invalid EAPOL-Key: Key Ack set");
- return;
- }
-
- if (!(key_info & WPA_KEY_INFO_MIC)) {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received invalid EAPOL-Key: Key MIC not set");
- return;
- }
-
- sm->MICVerified = FALSE;
- if (sm->PTK_valid) {
- if (wpa_verify_key_mic(&sm->PTK, data, data_len)) {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key with invalid MIC");
- return;
- }
- sm->MICVerified = TRUE;
- eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm);
- }
-
- if (key_info & WPA_KEY_INFO_REQUEST) {
- if (sm->MICVerified) {
- sm->req_replay_counter_used = 1;
- memcpy(sm->req_replay_counter, key->replay_counter,
- WPA_REPLAY_COUNTER_LEN);
- } else {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key request with "
- "invalid MIC");
- return;
- }
-
- /*
- * TODO: should decrypt key data field if encryption was used;
- * even though MAC address KDE is not normally encrypted,
- * supplicant is allowed to encrypt it.
- */
- if (msg == SMK_ERROR) {
-#ifdef CONFIG_PEERKEY
- wpa_smk_error(wpa_auth, sm, key);
-#endif /* CONFIG_PEERKEY */
- return;
- } else if (key_info & WPA_KEY_INFO_ERROR) {
- /* Supplicant reported a Michael MIC error */
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key Error Request "
- "(STA detected Michael MIC failure)");
- wpa_auth_mic_failure_report(wpa_auth, sm->addr);
- sm->dot11RSNAStatsTKIPRemoteMICFailures++;
- wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++;
- /* Error report is not a request for a new key
- * handshake, but since Authenticator may do it, let's
- * change the keys now anyway. */
- wpa_request_new_ptk(sm);
- } else if (key_info & WPA_KEY_INFO_KEY_TYPE) {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key Request for new "
- "4-Way Handshake");
- wpa_request_new_ptk(sm);
-#ifdef CONFIG_PEERKEY
- } else if (msg == SMK_M1) {
- wpa_smk_m1(wpa_auth, sm, key);
-#endif /* CONFIG_PEERKEY */
- } else if (key_data_length > 0 &&
- wpa_parse_kde_ies((const u8 *) (key + 1),
- key_data_length, &kde) == 0 &&
- kde.mac_addr) {
- } else {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
- "received EAPOL-Key Request for GTK "
- "rekeying");
- /* FIX: why was this triggering PTK rekeying for the
- * STA that requested Group Key rekeying?? */
- /* wpa_request_new_ptk(sta->wpa_sm); */
- eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);
- wpa_rekey_gtk(wpa_auth, NULL);
- }
- } else {
- /* Do not allow the same key replay counter to be reused. */
- sm->key_replay_counter_valid = FALSE;
- }
-
-#ifdef CONFIG_PEERKEY
- if (msg == SMK_M3) {
- wpa_smk_m3(wpa_auth, sm, key);
- return;
- }
-#endif /* CONFIG_PEERKEY */
-
- free(sm->last_rx_eapol_key);
- sm->last_rx_eapol_key = malloc(data_len);
- if (sm->last_rx_eapol_key == NULL)
- return;
- memcpy(sm->last_rx_eapol_key, data, data_len);
- sm->last_rx_eapol_key_len = data_len;
-
- sm->EAPOLKeyReceived = TRUE;
- sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
- sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST);
- memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN);
- wpa_sm_step(sm);
-}
-
-
-static void wpa_pmk_to_ptk(const u8 *pmk, const u8 *addr1, const u8 *addr2,
- const u8 *nonce1, const u8 *nonce2,
- u8 *ptk, size_t ptk_len)
-{
- u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
-
- /* PTK = PRF-X(PMK, "Pairwise key expansion",
- * Min(AA, SA) || Max(AA, SA) ||
- * Min(ANonce, SNonce) || Max(ANonce, SNonce)) */
-
- if (memcmp(addr1, addr2, ETH_ALEN) < 0) {
- memcpy(data, addr1, ETH_ALEN);
- memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
- } else {
- memcpy(data, addr2, ETH_ALEN);
- memcpy(data + ETH_ALEN, addr1, ETH_ALEN);
- }
-
- if (memcmp(nonce1, nonce2, WPA_NONCE_LEN) < 0) {
- memcpy(data + 2 * ETH_ALEN, nonce1, WPA_NONCE_LEN);
- memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce2,
- WPA_NONCE_LEN);
- } else {
- memcpy(data + 2 * ETH_ALEN, nonce2, WPA_NONCE_LEN);
- memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, nonce1,
- WPA_NONCE_LEN);
- }
-
- sha1_prf(pmk, WPA_PMK_LEN, "Pairwise key expansion",
- data, sizeof(data), ptk, ptk_len);
-
- wpa_hexdump_key(MSG_DEBUG, "PMK", pmk, WPA_PMK_LEN);
- wpa_hexdump_key(MSG_DEBUG, "PTK", ptk, ptk_len);
-}
-
-
-static void wpa_gmk_to_gtk(const u8 *gmk, const u8 *addr, const u8 *gnonce,
- u8 *gtk, size_t gtk_len)
-{
- u8 data[ETH_ALEN + WPA_NONCE_LEN];
-
- /* GTK = PRF-X(GMK, "Group key expansion", AA || GNonce) */
- memcpy(data, addr, ETH_ALEN);
- memcpy(data + ETH_ALEN, gnonce, WPA_NONCE_LEN);
-
- sha1_prf(gmk, WPA_GMK_LEN, "Group key expansion",
- data, sizeof(data), gtk, gtk_len);
-
- wpa_hexdump_key(MSG_DEBUG, "GMK", gmk, WPA_GMK_LEN);
- wpa_hexdump_key(MSG_DEBUG, "GTK", gtk, gtk_len);
-}
-
-
-static void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_authenticator *wpa_auth = eloop_ctx;
- struct wpa_state_machine *sm = timeout_ctx;
-
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout");
- sm->TimeoutEvt = TRUE;
- wpa_sm_step(sm);
-}
-
-
-static int wpa_calc_eapol_key_mic(int ver, u8 *key, u8 *data, size_t len,
- u8 *mic)
-{
- u8 hash[SHA1_MAC_LEN];
-
- switch (ver) {
- case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
- hmac_md5(key, 16, data, len, mic);
- break;
- case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
- hmac_sha1(key, 16, data, len, hash);
- memcpy(mic, hash, MD5_MAC_LEN);
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-
-static void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm, int key_info,
- const u8 *key_rsc, const u8 *nonce,
- const u8 *kde, size_t kde_len,
- int keyidx, int encr, int force_version)
-{
- struct ieee802_1x_hdr *hdr;
- struct wpa_eapol_key *key;
- size_t len;
- int alg;
- int key_data_len, pad_len = 0;
- u8 *buf, *pos;
- int version, pairwise;
-
- len = sizeof(struct ieee802_1x_hdr) + sizeof(struct wpa_eapol_key);
-
- if (force_version)
- version = force_version;
- else if (sm->pairwise == WPA_CIPHER_CCMP)
- version = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
- else
- version = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
-
- pairwise = key_info & WPA_KEY_INFO_KEY_TYPE;
-
- wpa_printf(MSG_DEBUG, "WPA: Send EAPOL(secure=%d mic=%d ack=%d "
- "install=%d pairwise=%d kde_len=%lu keyidx=%d encr=%d)",
- (key_info & WPA_KEY_INFO_SECURE) ? 1 : 0,
- (key_info & WPA_KEY_INFO_MIC) ? 1 : 0,
- (key_info & WPA_KEY_INFO_ACK) ? 1 : 0,
- (key_info & WPA_KEY_INFO_INSTALL) ? 1 : 0,
- pairwise, (unsigned long) kde_len, keyidx, encr);
-
- key_data_len = kde_len;
-
- if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES && encr) {
- pad_len = key_data_len % 8;
- if (pad_len)
- pad_len = 8 - pad_len;
- key_data_len += pad_len + 8;
- }
-
- len += key_data_len;
-
- hdr = wpa_zalloc(len);
- if (hdr == NULL)
- return;
- hdr->version = wpa_auth->conf.eapol_version;
- hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
- hdr->length = htons(len - sizeof(*hdr));
- key = (struct wpa_eapol_key *) (hdr + 1);
-
- key->type = sm->wpa == WPA_VERSION_WPA2 ?
- EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
- key_info |= version;
- if (encr && sm->wpa == WPA_VERSION_WPA2)
- key_info |= WPA_KEY_INFO_ENCR_KEY_DATA;
- if (sm->wpa != WPA_VERSION_WPA2)
- key_info |= keyidx << WPA_KEY_INFO_KEY_INDEX_SHIFT;
- key->key_info = htons(key_info);
-
- alg = pairwise ? sm->pairwise : wpa_auth->conf.wpa_group;
- switch (alg) {
- case WPA_CIPHER_CCMP:
- key->key_length = htons(16);
- break;
- case WPA_CIPHER_TKIP:
- key->key_length = htons(32);
- break;
- case WPA_CIPHER_WEP40:
- key->key_length = htons(5);
- break;
- case WPA_CIPHER_WEP104:
- key->key_length = htons(13);
- break;
- }
- if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
- key->key_length = htons(0);
-
- /* FIX: STSL: what to use as key_replay_counter? */
- inc_byte_array(sm->key_replay_counter, WPA_REPLAY_COUNTER_LEN);
- memcpy(key->replay_counter, sm->key_replay_counter,
- WPA_REPLAY_COUNTER_LEN);
- sm->key_replay_counter_valid = TRUE;
-
- if (nonce)
- memcpy(key->key_nonce, nonce, WPA_NONCE_LEN);
-
- if (key_rsc)
- memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN);
-
- if (kde && !encr) {
- memcpy(key + 1, kde, kde_len);
- key->key_data_length = htons(kde_len);
- } else if (encr && kde) {
- buf = wpa_zalloc(key_data_len);
- if (buf == NULL) {
- free(hdr);
- return;
- }
- pos = buf;
- memcpy(pos, kde, kde_len);
- pos += kde_len;
-
- if (pad_len)
- *pos++ = 0xdd;
-
- wpa_hexdump_key(MSG_DEBUG, "Plaintext EAPOL-Key Key Data",
- buf, key_data_len);
- if (version == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
- aes_wrap(sm->PTK.encr_key, (key_data_len - 8) / 8, buf,
- (u8 *) (key + 1));
- key->key_data_length = htons(key_data_len);
- } else {
- u8 ek[32];
- memcpy(key->key_iv,
- sm->group->Counter + WPA_NONCE_LEN - 16, 16);
- inc_byte_array(sm->group->Counter, WPA_NONCE_LEN);
- memcpy(ek, key->key_iv, 16);
- memcpy(ek + 16, sm->PTK.encr_key, 16);
- memcpy(key + 1, buf, key_data_len);
- rc4_skip(ek, 32, 256, (u8 *) (key + 1), key_data_len);
- key->key_data_length = htons(key_data_len);
- }
- free(buf);
- }
-
- if (key_info & WPA_KEY_INFO_MIC) {
- if (!sm->PTK_valid) {
- wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
- "PTK not valid when sending EAPOL-Key "
- "frame");
- free(hdr);
- return;
- }
- wpa_calc_eapol_key_mic(version,
- sm->PTK.mic_key, (u8 *) hdr, len,
- key->key_mic);
- }
-
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx,
- 1);
- wpa_auth_send_eapol(wpa_auth, sm->addr, (u8 *) hdr, len,
- sm->pairwise_set);
- free(hdr);
-}
-
-
-static void wpa_send_eapol(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm, int key_info,
- const u8 *key_rsc, const u8 *nonce,
- const u8 *kde, size_t kde_len,
- int keyidx, int encr)
-{
- int timeout_ms;
- int pairwise = key_info & WPA_KEY_INFO_KEY_TYPE;
-
- if (sm == NULL)
- return;
-
- __wpa_send_eapol(wpa_auth, sm, key_info, key_rsc, nonce, kde, kde_len,
- keyidx, encr, 0);
-
- timeout_ms = pairwise ? dot11RSNAConfigPairwiseUpdateTimeOut :
- dot11RSNAConfigGroupUpdateTimeOut;
- eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000,
- wpa_send_eapol_timeout, wpa_auth, sm);
-}
-
-
-static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len)
-{
- struct ieee802_1x_hdr *hdr;
- struct wpa_eapol_key *key;
- u16 key_info;
- int ret = 0;
- u8 mic[16];
-
- if (data_len < sizeof(*hdr) + sizeof(*key))
- return -1;
-
- hdr = (struct ieee802_1x_hdr *) data;
- key = (struct wpa_eapol_key *) (hdr + 1);
- key_info = ntohs(key->key_info);
- memcpy(mic, key->key_mic, 16);
- memset(key->key_mic, 0, 16);
- if (wpa_calc_eapol_key_mic(key_info & WPA_KEY_INFO_TYPE_MASK,
- PTK->mic_key, data, data_len, key->key_mic)
- || memcmp(mic, key->key_mic, 16) != 0)
- ret = -1;
- memcpy(key->key_mic, mic, 16);
- return ret;
-}
-
-
-void wpa_remove_ptk(struct wpa_state_machine *sm)
-{
- sm->PTK_valid = FALSE;
- memset(&sm->PTK, 0, sizeof(sm->PTK));
- wpa_auth_set_key(sm->wpa_auth, 0, "none", sm->addr, 0, (u8 *) "", 0);
- sm->pairwise_set = FALSE;
-}
-
-
-void wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event)
-{
- if (sm == NULL)
- return;
-
- wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "event %d notification", event);
-
- switch (event) {
- case WPA_AUTH:
- case WPA_ASSOC:
- break;
- case WPA_DEAUTH:
- case WPA_DISASSOC:
- sm->DeauthenticationRequest = TRUE;
- break;
- case WPA_REAUTH:
- case WPA_REAUTH_EAPOL:
- sm->ReAuthenticationRequest = TRUE;
- break;
- }
-
- sm->PTK_valid = FALSE;
- memset(&sm->PTK, 0, sizeof(sm->PTK));
-
- if (event != WPA_REAUTH_EAPOL)
- wpa_remove_ptk(sm);
-
- wpa_sm_step(sm);
-}
-
-
-static const char * wpa_alg_txt(int alg)
-{
- switch (alg) {
- case WPA_CIPHER_CCMP:
- return "CCMP";
- case WPA_CIPHER_TKIP:
- return "TKIP";
- case WPA_CIPHER_WEP104:
- case WPA_CIPHER_WEP40:
- return "WEP";
- default:
- return "";
- }
-}
-
-
-SM_STATE(WPA_PTK, INITIALIZE)
-{
- SM_ENTRY_MA(WPA_PTK, INITIALIZE, wpa_ptk);
- if (sm->Init) {
- /* Init flag is not cleared here, so avoid busy
- * loop by claiming nothing changed. */
- sm->changed = FALSE;
- }
-
- sm->keycount = 0;
- if (sm->GUpdateStationKeys)
- sm->group->GKeyDoneStations--;
- sm->GUpdateStationKeys = FALSE;
- if (sm->wpa == WPA_VERSION_WPA)
- sm->PInitAKeys = FALSE;
- if (1 /* Unicast cipher supported AND (ESS OR ((IBSS or WDS) and
- * Local AA > Remote AA)) */) {
- sm->Pair = TRUE;
- }
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 0);
- wpa_remove_ptk(sm);
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0);
- sm->TimeoutCtr = 0;
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK) {
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
- WPA_EAPOL_authorized, 0);
- }
-}
-
-
-SM_STATE(WPA_PTK, DISCONNECT)
-{
- SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk);
- sm->Disconnect = FALSE;
- wpa_sta_disconnect(sm->wpa_auth, sm->addr);
-}
-
-
-SM_STATE(WPA_PTK, DISCONNECTED)
-{
- SM_ENTRY_MA(WPA_PTK, DISCONNECTED, wpa_ptk);
- sm->DeauthenticationRequest = FALSE;
-}
-
-
-SM_STATE(WPA_PTK, AUTHENTICATION)
-{
- SM_ENTRY_MA(WPA_PTK, AUTHENTICATION, wpa_ptk);
- memset(&sm->PTK, 0, sizeof(sm->PTK));
- sm->PTK_valid = FALSE;
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portControl_Auto,
- 1);
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portEnabled, 1);
- sm->AuthenticationRequest = FALSE;
-}
-
-
-SM_STATE(WPA_PTK, AUTHENTICATION2)
-{
- SM_ENTRY_MA(WPA_PTK, AUTHENTICATION2, wpa_ptk);
- memcpy(sm->ANonce, sm->group->Counter, WPA_NONCE_LEN);
- inc_byte_array(sm->group->Counter, WPA_NONCE_LEN);
- sm->ReAuthenticationRequest = FALSE;
- /* IEEE 802.11i does not clear TimeoutCtr here, but this is more
- * logical place than INITIALIZE since AUTHENTICATION2 can be
- * re-entered on ReAuthenticationRequest without going through
- * INITIALIZE. */
- sm->TimeoutCtr = 0;
-}
-
-
-SM_STATE(WPA_PTK, INITPMK)
-{
- size_t len = WPA_PMK_LEN;
-
- SM_ENTRY_MA(WPA_PTK, INITPMK, wpa_ptk);
- if (sm->pmksa) {
- wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache");
- memcpy(sm->PMK, sm->pmksa->pmk, WPA_PMK_LEN);
- } else if (wpa_auth_get_pmk(sm->wpa_auth, sm->addr, sm->PMK, &len) ==
- 0) {
- wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine "
- "(len=%lu)", (unsigned long) len);
- } else {
- wpa_printf(MSG_DEBUG, "WPA: Could not get PMK");
- }
-
- sm->req_replay_counter_used = 0;
- /* IEEE 802.11i does not set keyRun to FALSE, but not doing this
- * will break reauthentication since EAPOL state machines may not be
- * get into AUTHENTICATING state that clears keyRun before WPA state
- * machine enters AUTHENTICATION2 state and goes immediately to INITPMK
- * state and takes PMK from the previously used AAA Key. This will
- * eventually fail in 4-Way Handshake because Supplicant uses PMK
- * derived from the new AAA Key. Setting keyRun = FALSE here seems to
- * be good workaround for this issue. */
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyRun, 0);
-}
-
-
-SM_STATE(WPA_PTK, INITPSK)
-{
- const u8 *psk;
- SM_ENTRY_MA(WPA_PTK, INITPSK, wpa_ptk);
- psk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL);
- if (psk)
- memcpy(sm->PMK, psk, WPA_PMK_LEN);
- sm->req_replay_counter_used = 0;
-}
-
-
-SM_STATE(WPA_PTK, PTKSTART)
-{
- u8 buf[2 + RSN_SELECTOR_LEN + PMKID_LEN], *pmkid = NULL;
- size_t pmkid_len = 0;
-
- SM_ENTRY_MA(WPA_PTK, PTKSTART, wpa_ptk);
- sm->PTKRequest = FALSE;
- sm->TimeoutEvt = FALSE;
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "sending 1/4 msg of 4-Way Handshake");
- /*
- * TODO: Could add PMKID even with WPA2-PSK, but only if there is only
- * one possible PSK for this STA.
- */
- if (sm->wpa == WPA_VERSION_WPA2 &&
- sm->wpa_key_mgmt != WPA_KEY_MGMT_PSK) {
- pmkid = buf;
- pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
- pmkid[0] = WLAN_EID_GENERIC;
- pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN;
- memcpy(&pmkid[2], RSN_KEY_DATA_PMKID, RSN_SELECTOR_LEN);
- if (sm->pmksa)
- memcpy(&pmkid[2 + RSN_SELECTOR_LEN], sm->pmksa->pmkid,
- PMKID_LEN);
- else {
- /*
- * Calculate PMKID since no PMKSA cache entry was
- * available with pre-calculated PMKID.
- */
- rsn_pmkid(sm->PMK, WPA_PMK_LEN, sm->wpa_auth->addr,
- sm->addr, &pmkid[2 + RSN_SELECTOR_LEN]);
- }
- }
- wpa_send_eapol(sm->wpa_auth, sm,
- WPA_KEY_INFO_ACK | WPA_KEY_INFO_KEY_TYPE, NULL,
- sm->ANonce, pmkid, pmkid_len, 0, 0);
- sm->TimeoutCtr++;
-}
-
-
-SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
-{
- struct wpa_ptk PTK;
- int ok = 0;
- const u8 *pmk = NULL;
-
- SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
- sm->EAPOLKeyReceived = FALSE;
-
- /* WPA with IEEE 802.1X: use the derived PMK from EAP
- * WPA-PSK: iterate through possible PSKs and select the one matching
- * the packet */
- for (;;) {
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK) {
- pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, pmk);
- if (pmk == NULL)
- break;
- } else
- pmk = sm->PMK;
-
- wpa_pmk_to_ptk(pmk, sm->wpa_auth->addr, sm->addr,
- sm->ANonce, sm->SNonce,
- (u8 *) &PTK, sizeof(PTK));
-
- if (wpa_verify_key_mic(&PTK, sm->last_rx_eapol_key,
- sm->last_rx_eapol_key_len) == 0) {
- ok = 1;
- break;
- }
-
- if (sm->wpa_key_mgmt != WPA_KEY_MGMT_PSK)
- break;
- }
-
- if (!ok) {
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "invalid MIC in msg 2/4 of 4-Way Handshake");
- return;
- }
-
- eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
-
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK) {
- /* PSK may have changed from the previous choice, so update
- * state machine data based on whatever PSK was selected here.
- */
- memcpy(sm->PMK, pmk, WPA_PMK_LEN);
- }
-
- sm->MICVerified = TRUE;
-
- memcpy(&sm->PTK, &PTK, sizeof(PTK));
- sm->PTK_valid = TRUE;
-}
-
-
-SM_STATE(WPA_PTK, PTKCALCNEGOTIATING2)
-{
- SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING2, wpa_ptk);
- sm->TimeoutCtr = 0;
-}
-
-
-#ifdef CONFIG_IEEE80211W
-
-static int ieee80211w_kde_len(struct wpa_state_machine *sm)
-{
- if (sm->mgmt_frame_prot) {
- return 2 + RSN_SELECTOR_LEN + sizeof(struct wpa_dhv_kde) +
- 2 + RSN_SELECTOR_LEN + sizeof(struct wpa_igtk_kde);
- }
-
- return 0;
-}
-
-
-static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
-{
- struct wpa_dhv_kde dhv;
- struct wpa_igtk_kde igtk;
- struct wpa_group *gsm = sm->group;
- u8 mac[32];
- const u8 *addr[3];
- size_t len[3];
-
- if (!sm->mgmt_frame_prot)
- return pos;
-
- addr[0] = sm->wpa_auth->addr;
- len[0] = ETH_ALEN;
- addr[1] = sm->addr;
- len[1] = ETH_ALEN;
- addr[2] = gsm->DGTK;
- len[2] = WPA_DGTK_LEN;
- sha256_vector(3, addr, len, mac);
- memcpy(dhv.dhv, mac, WPA_DHV_LEN);
- wpa_hexdump_key(MSG_DEBUG, "WPA: DHV", dhv.dhv, WPA_DHV_LEN);
- pos = wpa_add_kde(pos, RSN_KEY_DATA_DHV,
- (const u8 *) &dhv, sizeof(dhv), NULL, 0);
-
- igtk.keyid[0] = gsm->GN;
- igtk.keyid[1] = 0;
- if (wpa_auth_get_seqnum_igtk(sm->wpa_auth, NULL, gsm->GN, igtk.pn) < 0)
- memset(igtk.pn, 0, sizeof(igtk.pn));
- memcpy(igtk.igtk, gsm->IGTK[gsm->GN - 1], WPA_IGTK_LEN);
- pos = wpa_add_kde(pos, RSN_KEY_DATA_IGTK,
- (const u8 *) &igtk, sizeof(igtk), NULL, 0);
-
- return pos;
-}
-
-#else /* CONFIG_IEEE80211W */
-
-static int ieee80211w_kde_len(struct wpa_state_machine *sm)
-{
- return 0;
-}
-
-
-static u8 * ieee80211w_kde_add(struct wpa_state_machine *sm, u8 *pos)
-{
- return pos;
-}
-
-#endif /* CONFIG_IEEE80211W */
-
-
-SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
-{
- u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde, *pos;
- size_t gtk_len, kde_len;
- struct wpa_group *gsm = sm->group;
- u8 *wpa_ie;
- int wpa_ie_len, secure, keyidx, encr = 0;
-
- SM_ENTRY_MA(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk);
- sm->TimeoutEvt = FALSE;
- /* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, GTK[GN])
- */
- memset(rsc, 0, WPA_KEY_RSC_LEN);
- wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc);
- wpa_ie = sm->wpa_auth->wpa_ie;
- wpa_ie_len = sm->wpa_auth->wpa_ie_len;
- if (sm->wpa == WPA_VERSION_WPA &&
- (sm->wpa_auth->conf.wpa & HOSTAPD_WPA_VERSION_WPA2) &&
- wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) {
- /* WPA-only STA, remove RSN IE */
- wpa_ie = wpa_ie + wpa_ie[1] + 2;
- wpa_ie_len = wpa_ie[1] + 2;
- }
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "sending 3/4 msg of 4-Way Handshake");
- if (sm->wpa == WPA_VERSION_WPA2) {
- /* WPA2 send GTK in the 4-way handshake */
- secure = 1;
- gtk = gsm->GTK[gsm->GN - 1];
- gtk_len = gsm->GTK_len;
- keyidx = gsm->GN;
- _rsc = rsc;
- encr = 1;
- } else {
- /* WPA does not include GTK in msg 3/4 */
- secure = 0;
- gtk = NULL;
- gtk_len = 0;
- keyidx = 0;
- _rsc = NULL;
- }
-
- kde_len = wpa_ie_len + ieee80211w_kde_len(sm);
- if (gtk)
- kde_len += 2 + RSN_SELECTOR_LEN + 2 + gtk_len;
- kde = malloc(kde_len);
- if (kde == NULL)
- return;
-
- pos = kde;
- memcpy(pos, wpa_ie, wpa_ie_len);
- pos += wpa_ie_len;
- if (gtk) {
- u8 hdr[2];
- hdr[0] = keyidx & 0x03;
- hdr[1] = 0;
- pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
- gtk, gtk_len);
- }
- pos = ieee80211w_kde_add(sm, pos);
-
- wpa_send_eapol(sm->wpa_auth, sm,
- (secure ? WPA_KEY_INFO_SECURE : 0) | WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL |
- WPA_KEY_INFO_KEY_TYPE,
- _rsc, sm->ANonce, kde, pos - kde, keyidx, encr);
- free(kde);
- sm->TimeoutCtr++;
-}
-
-
-SM_STATE(WPA_PTK, PTKINITDONE)
-{
- SM_ENTRY_MA(WPA_PTK, PTKINITDONE, wpa_ptk);
- sm->EAPOLKeyReceived = FALSE;
- if (sm->Pair) {
- char *alg;
- int klen;
- if (sm->pairwise == WPA_CIPHER_TKIP) {
- alg = "TKIP";
- klen = 32;
- } else {
- alg = "CCMP";
- klen = 16;
- }
- if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0,
- sm->PTK.tk1, klen)) {
- wpa_sta_disconnect(sm->wpa_auth, sm->addr);
- return;
- }
- /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
- sm->pairwise_set = TRUE;
-
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK) {
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
- WPA_EAPOL_authorized, 1);
- }
- }
-
- if (0 /* IBSS == TRUE */) {
- sm->keycount++;
- if (sm->keycount == 2) {
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
- WPA_EAPOL_portValid, 1);
- }
- } else {
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid,
- 1);
- }
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyAvailable, 0);
- wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_keyDone, 1);
- if (sm->wpa == WPA_VERSION_WPA)
- sm->PInitAKeys = TRUE;
- else
- sm->has_GTK = TRUE;
- wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO,
- "pairwise key handshake completed (%s)",
- sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
-}
-
-
-SM_STEP(WPA_PTK)
-{
- struct wpa_authenticator *wpa_auth = sm->wpa_auth;
-
- if (sm->Init)
- SM_ENTER(WPA_PTK, INITIALIZE);
- else if (sm->Disconnect
- /* || FIX: dot11RSNAConfigSALifetime timeout */)
- SM_ENTER(WPA_PTK, DISCONNECT);
- else if (sm->DeauthenticationRequest)
- SM_ENTER(WPA_PTK, DISCONNECTED);
- else if (sm->AuthenticationRequest)
- SM_ENTER(WPA_PTK, AUTHENTICATION);
- else if (sm->ReAuthenticationRequest)
- SM_ENTER(WPA_PTK, AUTHENTICATION2);
- else if (sm->PTKRequest)
- SM_ENTER(WPA_PTK, PTKSTART);
- else switch (sm->wpa_ptk_state) {
- case WPA_PTK_INITIALIZE:
- break;
- case WPA_PTK_DISCONNECT:
- SM_ENTER(WPA_PTK, DISCONNECTED);
- break;
- case WPA_PTK_DISCONNECTED:
- SM_ENTER(WPA_PTK, INITIALIZE);
- break;
- case WPA_PTK_AUTHENTICATION:
- SM_ENTER(WPA_PTK, AUTHENTICATION2);
- break;
- case WPA_PTK_AUTHENTICATION2:
- if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_IEEE8021X) &&
- wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
- WPA_EAPOL_keyRun) > 0)
- SM_ENTER(WPA_PTK, INITPMK);
- else if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK)
- /* FIX: && 802.1X::keyRun */)
- SM_ENTER(WPA_PTK, INITPSK);
- break;
- case WPA_PTK_INITPMK:
- if (wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
- WPA_EAPOL_keyAvailable) > 0)
- SM_ENTER(WPA_PTK, PTKSTART);
- else {
- wpa_auth->dot11RSNA4WayHandshakeFailures++;
- SM_ENTER(WPA_PTK, DISCONNECT);
- }
- break;
- case WPA_PTK_INITPSK:
- if (wpa_auth_get_psk(sm->wpa_auth, sm->addr, NULL))
- SM_ENTER(WPA_PTK, PTKSTART);
- else {
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_INFO,
- "no PSK configured for the STA");
- wpa_auth->dot11RSNA4WayHandshakeFailures++;
- SM_ENTER(WPA_PTK, DISCONNECT);
- }
- break;
- case WPA_PTK_PTKSTART:
- if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
- sm->EAPOLKeyPairwise)
- SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);
- else if (sm->TimeoutCtr >
- (int) dot11RSNAConfigPairwiseUpdateCount) {
- wpa_auth->dot11RSNA4WayHandshakeFailures++;
- SM_ENTER(WPA_PTK, DISCONNECT);
- } else if (sm->TimeoutEvt)
- SM_ENTER(WPA_PTK, PTKSTART);
- break;
- case WPA_PTK_PTKCALCNEGOTIATING:
- if (sm->MICVerified)
- SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING2);
- else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
- sm->EAPOLKeyPairwise)
- SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);
- else if (sm->TimeoutEvt)
- SM_ENTER(WPA_PTK, PTKSTART);
- break;
- case WPA_PTK_PTKCALCNEGOTIATING2:
- SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
- break;
- case WPA_PTK_PTKINITNEGOTIATING:
- if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
- sm->EAPOLKeyPairwise && sm->MICVerified)
- SM_ENTER(WPA_PTK, PTKINITDONE);
- else if (sm->TimeoutCtr >
- (int) dot11RSNAConfigPairwiseUpdateCount) {
- wpa_auth->dot11RSNA4WayHandshakeFailures++;
- SM_ENTER(WPA_PTK, DISCONNECT);
- } else if (sm->TimeoutEvt)
- SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
- break;
- case WPA_PTK_PTKINITDONE:
- break;
- }
-}
-
-
-SM_STATE(WPA_PTK_GROUP, IDLE)
-{
- SM_ENTRY_MA(WPA_PTK_GROUP, IDLE, wpa_ptk_group);
- if (sm->Init) {
- /* Init flag is not cleared here, so avoid busy
- * loop by claiming nothing changed. */
- sm->changed = FALSE;
- }
- sm->GTimeoutCtr = 0;
-}
-
-
-SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
-{
- u8 rsc[WPA_KEY_RSC_LEN];
- struct wpa_group *gsm = sm->group;
- u8 *kde, *pos, hdr[2];
- size_t kde_len;
-
- SM_ENTRY_MA(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);
- if (sm->wpa == WPA_VERSION_WPA)
- sm->PInitAKeys = FALSE;
- sm->TimeoutEvt = FALSE;
- /* Send EAPOL(1, 1, 1, !Pair, G, RSC, GNonce, MIC(PTK), GTK[GN]) */
- memset(rsc, 0, WPA_KEY_RSC_LEN);
- if (gsm->wpa_group_state == WPA_GROUP_SETKEYSDONE)
- wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, rsc);
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "sending 1/2 msg of Group Key Handshake");
-
- if (sm->wpa == WPA_VERSION_WPA2) {
- kde_len = 2 + RSN_SELECTOR_LEN + 2 + gsm->GTK_len +
- ieee80211w_kde_len(sm);
- kde = malloc(kde_len);
- if (kde == NULL)
- return;
-
- pos = kde;
- hdr[0] = gsm->GN & 0x03;
- hdr[1] = 0;
- pos = wpa_add_kde(pos, RSN_KEY_DATA_GROUPKEY, hdr, 2,
- gsm->GTK[gsm->GN - 1], gsm->GTK_len);
- pos = ieee80211w_kde_add(sm, pos);
- } else {
- kde = gsm->GTK[gsm->GN - 1];
- pos = kde + gsm->GTK_len;
- }
-
- wpa_send_eapol(sm->wpa_auth, sm,
- WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_ACK |
- (!sm->Pair ? WPA_KEY_INFO_INSTALL : 0),
- rsc, gsm->GNonce, kde, pos - kde, gsm->GN, 1);
- if (sm->wpa == WPA_VERSION_WPA2)
- free(kde);
- sm->GTimeoutCtr++;
-}
-
-
-SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED)
-{
- SM_ENTRY_MA(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group);
- sm->EAPOLKeyReceived = FALSE;
- if (sm->GUpdateStationKeys)
- sm->group->GKeyDoneStations--;
- sm->GUpdateStationKeys = FALSE;
- sm->GTimeoutCtr = 0;
- /* FIX: MLME.SetProtection.Request(TA, Tx_Rx) */
- wpa_auth_vlogger(sm->wpa_auth, sm->addr, LOGGER_INFO,
- "group key handshake completed (%s)",
- sm->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
- sm->has_GTK = TRUE;
-}
-
-
-SM_STATE(WPA_PTK_GROUP, KEYERROR)
-{
- SM_ENTRY_MA(WPA_PTK_GROUP, KEYERROR, wpa_ptk_group);
- if (sm->GUpdateStationKeys)
- sm->group->GKeyDoneStations--;
- sm->GUpdateStationKeys = FALSE;
- sm->Disconnect = TRUE;
-}
-
-
-SM_STEP(WPA_PTK_GROUP)
-{
- if (sm->Init)
- SM_ENTER(WPA_PTK_GROUP, IDLE);
- else switch (sm->wpa_ptk_group_state) {
- case WPA_PTK_GROUP_IDLE:
- if (sm->GUpdateStationKeys ||
- (sm->wpa == WPA_VERSION_WPA && sm->PInitAKeys))
- SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING);
- break;
- case WPA_PTK_GROUP_REKEYNEGOTIATING:
- if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&
- !sm->EAPOLKeyPairwise && sm->MICVerified)
- SM_ENTER(WPA_PTK_GROUP, REKEYESTABLISHED);
- else if (sm->GTimeoutCtr >
- (int) dot11RSNAConfigGroupUpdateCount)
- SM_ENTER(WPA_PTK_GROUP, KEYERROR);
- else if (sm->TimeoutEvt)
- SM_ENTER(WPA_PTK_GROUP, REKEYNEGOTIATING);
- break;
- case WPA_PTK_GROUP_KEYERROR:
- SM_ENTER(WPA_PTK_GROUP, IDLE);
- break;
- case WPA_PTK_GROUP_REKEYESTABLISHED:
- SM_ENTER(WPA_PTK_GROUP, IDLE);
- break;
- }
-}
-
-
-static void wpa_gtk_update(struct wpa_authenticator *wpa_auth,
- struct wpa_group *group)
-{
- /* FIX: is this the correct way of getting GNonce? */
- memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
- inc_byte_array(group->Counter, WPA_NONCE_LEN);
- wpa_gmk_to_gtk(group->GMK, wpa_auth->addr, group->GNonce,
- group->GTK[group->GN - 1], group->GTK_len);
-
-#ifdef CONFIG_IEEE80211W
- if (wpa_auth->conf.ieee80211w != WPA_NO_IEEE80211W) {
- hostapd_get_rand(group->DGTK, WPA_DGTK_LEN);
- wpa_hexdump_key(MSG_DEBUG, "DGTK", group->DGTK, WPA_DGTK_LEN);
- hostapd_get_rand(group->IGTK[group->GN - 1], WPA_IGTK_LEN);
- wpa_hexdump_key(MSG_DEBUG, "IGTK",
- group->IGTK[group->GN - 1], WPA_IGTK_LEN);
- }
-#endif /* CONFIG_IEEE80211W */
-}
-
-
-static void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth,
- struct wpa_group *group)
-{
- wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
- "GTK_INIT (VLAN-ID %d)", group->vlan_id);
- group->changed = FALSE; /* GInit is not cleared here; avoid loop */
- group->wpa_group_state = WPA_GROUP_GTK_INIT;
-
- /* GTK[0..N] = 0 */
- memset(group->GTK, 0, sizeof(group->GTK));
- group->GN = 1;
- group->GM = 2;
- /* GTK[GN] = CalcGTK() */
- wpa_gtk_update(wpa_auth, group);
-}
-
-
-static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx)
-{
- if (sm->wpa_ptk_state != WPA_PTK_PTKINITDONE) {
- wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
- "Not in PTKINITDONE; skip Group Key update");
- return 0;
- }
- sm->group->GKeyDoneStations++;
- sm->GUpdateStationKeys = TRUE;
- wpa_sm_step(sm);
- return 0;
-}
-
-
-static void wpa_group_setkeys(struct wpa_authenticator *wpa_auth,
- struct wpa_group *group)
-{
- int tmp;
-
- wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
- "SETKEYS (VLAN-ID %d)", group->vlan_id);
- group->changed = TRUE;
- group->wpa_group_state = WPA_GROUP_SETKEYS;
- group->GTKReKey = FALSE;
- tmp = group->GM;
- group->GM = group->GN;
- group->GN = tmp;
- /* "GKeyDoneStations = GNoStations" is done in more robust way by
- * counting the STAs that are marked with GUpdateStationKeys instead of
- * including all STAs that could be in not-yet-completed state. */
- wpa_gtk_update(wpa_auth, group);
-
- wpa_auth_for_each_sta(wpa_auth, wpa_group_update_sta, NULL);
- wpa_printf(MSG_DEBUG, "wpa_group_setkeys: GKeyDoneStations=%d",
- group->GKeyDoneStations);
-}
-
-
-static void wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth,
- struct wpa_group *group)
-{
- wpa_printf(MSG_DEBUG, "WPA: group state machine entering state "
- "SETKEYSDONE (VLAN-ID %d)", group->vlan_id);
- group->changed = TRUE;
- group->wpa_group_state = WPA_GROUP_SETKEYSDONE;
- wpa_auth_set_key(wpa_auth, group->vlan_id,
- wpa_alg_txt(wpa_auth->conf.wpa_group),
- NULL, group->GN, group->GTK[group->GN - 1],
- group->GTK_len);
-
-#ifdef CONFIG_IEEE80211W
- if (wpa_auth->conf.ieee80211w != WPA_NO_IEEE80211W) {
- wpa_auth_set_key(wpa_auth, group->vlan_id, "IGTK",
- NULL, group->GN, group->IGTK[group->GN - 1],
- WPA_IGTK_LEN);
- wpa_auth_set_key(wpa_auth, group->vlan_id, "DGTK",
- NULL, 0, group->DGTK, WPA_DGTK_LEN);
- }
-#endif /* CONFIG_IEEE80211W */
-}
-
-
-static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth,
- struct wpa_group *group)
-{
- if (group->GInit) {
- wpa_group_gtk_init(wpa_auth, group);
- } else if (group->wpa_group_state == WPA_GROUP_GTK_INIT &&
- group->GTKAuthenticator) {
- wpa_group_setkeysdone(wpa_auth, group);
- } else if (group->wpa_group_state == WPA_GROUP_SETKEYSDONE &&
- group->GTKReKey) {
- wpa_group_setkeys(wpa_auth, group);
- } else if (group->wpa_group_state == WPA_GROUP_SETKEYS) {
- if (group->GKeyDoneStations == 0)
- wpa_group_setkeysdone(wpa_auth, group);
- else if (group->GTKReKey)
- wpa_group_setkeys(wpa_auth, group);
- }
-}
-
-
-static void wpa_sm_step(struct wpa_state_machine *sm)
-{
- if (sm == NULL)
- return;
-
- if (sm->in_step_loop) {
- /* This should not happen, but if it does, make sure we do not
- * end up freeing the state machine too early by exiting the
- * recursive call. */
- wpa_printf(MSG_ERROR, "WPA: wpa_sm_step() called recursively");
- return;
- }
-
- sm->in_step_loop = 1;
- do {
- if (sm->pending_deinit)
- break;
-
- sm->changed = FALSE;
- sm->wpa_auth->group->changed = FALSE;
-
- SM_STEP_RUN(WPA_PTK);
- if (sm->pending_deinit)
- break;
- SM_STEP_RUN(WPA_PTK_GROUP);
- if (sm->pending_deinit)
- break;
- wpa_group_sm_step(sm->wpa_auth, sm->group);
- } while (sm->changed || sm->wpa_auth->group->changed);
- sm->in_step_loop = 0;
-
- if (sm->pending_deinit) {
- wpa_printf(MSG_DEBUG, "WPA: Completing pending STA state "
- "machine deinit for " MACSTR, MAC2STR(sm->addr));
- wpa_free_sta_sm(sm);
- }
-}
-
-
-static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx)
-{
- struct wpa_state_machine *sm = eloop_ctx;
- wpa_sm_step(sm);
-}
-
-
-void wpa_auth_sm_notify(struct wpa_state_machine *sm)
-{
- if (sm == NULL)
- return;
- eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);
-}
-
-
-void wpa_gtk_rekey(struct wpa_authenticator *wpa_auth)
-{
- int tmp, i;
- struct wpa_group *group;
-
- if (wpa_auth == NULL)
- return;
-
- group = wpa_auth->group;
-
- for (i = 0; i < 2; i++) {
- tmp = group->GM;
- group->GM = group->GN;
- group->GN = tmp;
- wpa_gtk_update(wpa_auth, group);
- }
-}
-
-
-static const char * wpa_bool_txt(int bool)
-{
- return bool ? "TRUE" : "FALSE";
-}
-
-
-static int wpa_cipher_bits(int cipher)
-{
- switch (cipher) {
- case WPA_CIPHER_CCMP:
- return 128;
- case WPA_CIPHER_TKIP:
- return 256;
- case WPA_CIPHER_WEP104:
- return 104;
- case WPA_CIPHER_WEP40:
- return 40;
- default:
- return 0;
- }
-}
-
-
-#define RSN_SUITE "%02x-%02x-%02x-%d"
-#define RSN_SUITE_ARG(s) (s)[0], (s)[1], (s)[2], (s)[3]
-
-int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen)
-{
- int len = 0, ret;
- char pmkid_txt[PMKID_LEN * 2 + 1];
-
- if (wpa_auth == NULL)
- return len;
-
- ret = snprintf(buf + len, buflen - len,
- "dot11RSNAOptionImplemented=TRUE\n"
-#ifdef CONFIG_RSN_PREAUTH
- "dot11RSNAPreauthenticationImplemented=TRUE\n"
-#else /* CONFIG_RSN_PREAUTH */
- "dot11RSNAPreauthenticationImplemented=FALSE\n"
-#endif /* CONFIG_RSN_PREAUTH */
- "dot11RSNAEnabled=%s\n"
- "dot11RSNAPreauthenticationEnabled=%s\n",
- wpa_bool_txt(wpa_auth->conf.wpa &
- HOSTAPD_WPA_VERSION_WPA2),
- wpa_bool_txt(wpa_auth->conf.rsn_preauth));
- if (ret < 0 || (size_t) ret >= buflen - len)
- return len;
- len += ret;
-
- wpa_snprintf_hex(pmkid_txt, sizeof(pmkid_txt),
- wpa_auth->dot11RSNAPMKIDUsed, PMKID_LEN);
-
- ret = snprintf(buf + len, buflen - len,
- "dot11RSNAConfigVersion=%u\n"
- "dot11RSNAConfigPairwiseKeysSupported=9999\n"
- /* FIX: dot11RSNAConfigGroupCipher */
- /* FIX: dot11RSNAConfigGroupRekeyMethod */
- /* FIX: dot11RSNAConfigGroupRekeyTime */
- /* FIX: dot11RSNAConfigGroupRekeyPackets */
- "dot11RSNAConfigGroupRekeyStrict=%u\n"
- "dot11RSNAConfigGroupUpdateCount=%u\n"
- "dot11RSNAConfigPairwiseUpdateCount=%u\n"
- "dot11RSNAConfigGroupCipherSize=%u\n"
- "dot11RSNAConfigPMKLifetime=%u\n"
- "dot11RSNAConfigPMKReauthThreshold=%u\n"
- "dot11RSNAConfigNumberOfPTKSAReplayCounters=0\n"
- "dot11RSNAConfigSATimeout=%u\n"
- "dot11RSNAAuthenticationSuiteSelected=" RSN_SUITE "\n"
- "dot11RSNAPairwiseCipherSelected=" RSN_SUITE "\n"
- "dot11RSNAGroupCipherSelected=" RSN_SUITE "\n"
- "dot11RSNAPMKIDUsed=%s\n"
- "dot11RSNAAuthenticationSuiteRequested=" RSN_SUITE "\n"
- "dot11RSNAPairwiseCipherRequested=" RSN_SUITE "\n"
- "dot11RSNAGroupCipherRequested=" RSN_SUITE "\n"
- "dot11RSNATKIPCounterMeasuresInvoked=%u\n"
- "dot11RSNA4WayHandshakeFailures=%u\n"
- "dot11RSNAConfigNumberOfGTKSAReplayCounters=0\n",
- RSN_VERSION,
- !!wpa_auth->conf.wpa_strict_rekey,
- dot11RSNAConfigGroupUpdateCount,
- dot11RSNAConfigPairwiseUpdateCount,
- wpa_cipher_bits(wpa_auth->conf.wpa_group),
- dot11RSNAConfigPMKLifetime,
- dot11RSNAConfigPMKReauthThreshold,
- dot11RSNAConfigSATimeout,
- RSN_SUITE_ARG(wpa_auth->
- dot11RSNAAuthenticationSuiteSelected),
- RSN_SUITE_ARG(wpa_auth->
- dot11RSNAPairwiseCipherSelected),
- RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherSelected),
- pmkid_txt,
- RSN_SUITE_ARG(wpa_auth->
- dot11RSNAAuthenticationSuiteRequested),
- RSN_SUITE_ARG(wpa_auth->
- dot11RSNAPairwiseCipherRequested),
- RSN_SUITE_ARG(wpa_auth->dot11RSNAGroupCipherRequested),
- wpa_auth->dot11RSNATKIPCounterMeasuresInvoked,
- wpa_auth->dot11RSNA4WayHandshakeFailures);
- if (ret < 0 || (size_t) ret >= buflen - len)
- return len;
- len += ret;
-
- /* TODO: dot11RSNAConfigPairwiseCiphersTable */
- /* TODO: dot11RSNAConfigAuthenticationSuitesTable */
-
- /* Private MIB */
- ret = snprintf(buf + len, buflen - len, "hostapdWPAGroupState=%d\n",
- wpa_auth->group->wpa_group_state);
- if (ret < 0 || (size_t) ret >= buflen - len)
- return len;
- len += ret;
-
- return len;
-}
-
-
-int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen)
-{
- int len = 0, ret;
- u8 not_used[4] = { 0, 0, 0, 0 };
- const u8 *pairwise = not_used;
-
- if (sm == NULL)
- return 0;
-
- /* TODO: FF-FF-FF-FF-FF-FF entry for broadcast/multicast stats */
-
- /* dot11RSNAStatsEntry */
-
- if (sm->wpa == WPA_VERSION_WPA) {
- if (sm->pairwise == WPA_CIPHER_CCMP)
- pairwise = WPA_CIPHER_SUITE_CCMP;
- else if (sm->pairwise == WPA_CIPHER_TKIP)
- pairwise = WPA_CIPHER_SUITE_TKIP;
- else if (sm->pairwise == WPA_CIPHER_WEP104)
- pairwise = WPA_CIPHER_SUITE_WEP104;
- else if (sm->pairwise == WPA_CIPHER_WEP40)
- pairwise = WPA_CIPHER_SUITE_WEP40;
- else if (sm->pairwise == WPA_CIPHER_NONE)
- pairwise = WPA_CIPHER_SUITE_NONE;
- } else if (sm->wpa == WPA_VERSION_WPA2) {
- if (sm->pairwise == WPA_CIPHER_CCMP)
- pairwise = RSN_CIPHER_SUITE_CCMP;
- else if (sm->pairwise == WPA_CIPHER_TKIP)
- pairwise = RSN_CIPHER_SUITE_TKIP;
- else if (sm->pairwise == WPA_CIPHER_WEP104)
- pairwise = RSN_CIPHER_SUITE_WEP104;
- else if (sm->pairwise == WPA_CIPHER_WEP40)
- pairwise = RSN_CIPHER_SUITE_WEP40;
- else if (sm->pairwise == WPA_CIPHER_NONE)
- pairwise = RSN_CIPHER_SUITE_NONE;
- } else
- return 0;
-
- ret = snprintf(buf + len, buflen - len,
- /* TODO: dot11RSNAStatsIndex */
- "dot11RSNAStatsSTAAddress=" MACSTR "\n"
- "dot11RSNAStatsVersion=1\n"
- "dot11RSNAStatsSelectedPairwiseCipher=" RSN_SUITE "\n"
- /* TODO: dot11RSNAStatsTKIPICVErrors */
- "dot11RSNAStatsTKIPLocalMICFailures=%u\n"
- "dot11RSNAStatsTKIPRemoveMICFailures=%u\n"
- /* TODO: dot11RSNAStatsCCMPReplays */
- /* TODO: dot11RSNAStatsCCMPDecryptErrors */
- /* TODO: dot11RSNAStatsTKIPReplays */,
- MAC2STR(sm->addr),
- RSN_SUITE_ARG(pairwise),
- sm->dot11RSNAStatsTKIPLocalMICFailures,
- sm->dot11RSNAStatsTKIPRemoteMICFailures);
- if (ret < 0 || (size_t) ret >= buflen - len)
- return len;
- len += ret;
-
- /* Private MIB */
- ret = snprintf(buf + len, buflen - len,
- "hostapdWPAPTKState=%d\n"
- "hostapdWPAPTKGroupState=%d\n",
- sm->wpa_ptk_state,
- sm->wpa_ptk_group_state);
- if (ret < 0 || (size_t) ret >= buflen - len)
- return len;
- len += ret;
-
- return len;
-}
-
-
-void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth)
-{
- if (wpa_auth)
- wpa_auth->dot11RSNATKIPCounterMeasuresInvoked++;
-}
-
-
-int wpa_auth_pairwise_set(struct wpa_state_machine *sm)
-{
- return sm && sm->pairwise_set;
-}
-
-
-int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm)
-{
- if (sm == NULL)
- return -1;
- return sm->wpa_key_mgmt;
-}
-
-
-int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm)
-{
- if (sm == NULL)
- return 0;
- return sm->wpa;
-}
-
-
-int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
- struct rsn_pmksa_cache_entry *entry)
-{
- if (sm == NULL || sm->pmksa != entry)
- return -1;
- sm->pmksa = NULL;
- return 0;
-}
-
-
-struct rsn_pmksa_cache_entry *
-wpa_auth_sta_get_pmksa(struct wpa_state_machine *sm)
-{
- return sm ? sm->pmksa : NULL;
-}
-
-
-void wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm)
-{
- if (sm)
- sm->dot11RSNAStatsTKIPLocalMICFailures++;
-}
-
-
-const u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth, size_t *len)
-{
- if (wpa_auth == NULL)
- return NULL;
- *len = wpa_auth->wpa_ie_len;
- return wpa_auth->wpa_ie;
-}
-
-
-int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk,
- int session_timeout, struct eapol_state_machine *eapol)
-{
- if (sm == NULL || sm->wpa != WPA_VERSION_WPA2)
- return -1;
-
- if (pmksa_cache_add(sm->wpa_auth->pmksa, pmk, WPA_PMK_LEN,
- sm->wpa_auth->addr, sm->addr, session_timeout,
- eapol))
- return 0;
-
- return -1;
-}
-
-
-int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
- const u8 *pmk, size_t len, const u8 *sta_addr,
- int session_timeout,
- struct eapol_state_machine *eapol)
-{
- if (wpa_auth == NULL)
- return -1;
-
- if (pmksa_cache_add(wpa_auth->pmksa, pmk, len, wpa_auth->addr,
- sta_addr, session_timeout, eapol))
- return 0;
-
- return -1;
-}
-
-
-static struct wpa_group *
-wpa_auth_add_group(struct wpa_authenticator *wpa_auth, int vlan_id)
-{
- struct wpa_group *group;
-
- if (wpa_auth == NULL || wpa_auth->group == NULL)
- return NULL;
-
- wpa_printf(MSG_DEBUG, "WPA: Add group state machine for VLAN-ID %d",
- vlan_id);
- group = wpa_group_init(wpa_auth, vlan_id);
- if (group == NULL)
- return NULL;
-
- group->next = wpa_auth->group->next;
- wpa_auth->group->next = group;
-
- return group;
-}
-
-
-int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id)
-{
- struct wpa_group *group;
-
- if (sm == NULL || sm->wpa_auth == NULL)
- return 0;
-
- group = sm->wpa_auth->group;
- while (group) {
- if (group->vlan_id == vlan_id)
- break;
- group = group->next;
- }
-
- if (group == NULL) {
- group = wpa_auth_add_group(sm->wpa_auth, vlan_id);
- if (group == NULL)
- return -1;
- }
-
- if (sm->group == group)
- return 0;
-
- wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state "
- "machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id);
-
- sm->group = group;
- return 0;
-}
-
-#endif /* CONFIG_NATIVE_WINDOWS */
diff --git a/contrib/hostapd/wpa.h b/contrib/hostapd/wpa.h
deleted file mode 100644
index 633b2c56ab17..000000000000
--- a/contrib/hostapd/wpa.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * hostapd - IEEE 802.11i-2004 / WPA Authenticator
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef WPA_H
-#define WPA_H
-
-#include "wpa_common.h"
-
-#define WPA_PMK_LEN PMK_LEN
-#define WPA_GMK_LEN 32
-#define WPA_GTK_MAX_LEN 32
-#define PMKID_LEN 16
-
-#define WPA_CAPABILITY_PREAUTH BIT(0)
-#define WPA_CAPABILITY_MGMT_FRAME_PROTECTION BIT(6)
-#define WPA_CAPABILITY_PEERKEY_ENABLED BIT(9)
-
-struct wpa_eapol_key {
- u8 type;
- u16 key_info;
- u16 key_length;
- u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
- u8 key_nonce[WPA_NONCE_LEN];
- u8 key_iv[16];
- u8 key_rsc[WPA_KEY_RSC_LEN];
- u8 key_id[8]; /* Reserved */
- u8 key_mic[16];
- u16 key_data_length;
- /* followed by key_data_length bytes of key_data */
-} __attribute__ ((packed));
-
-#define WPA_KEY_INFO_TYPE_MASK (BIT(0) | BIT(1) | BIT(2))
-#define WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 BIT(0)
-#define WPA_KEY_INFO_TYPE_HMAC_SHA1_AES BIT(1)
-#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */
-/* bit4..5 is used in WPA, but is reserved in IEEE 802.11i/RSN */
-#define WPA_KEY_INFO_KEY_INDEX_MASK (BIT(4) | BIT(5))
-#define WPA_KEY_INFO_KEY_INDEX_SHIFT 4
-#define WPA_KEY_INFO_INSTALL BIT(6) /* pairwise */
-#define WPA_KEY_INFO_TXRX BIT(6) /* group */
-#define WPA_KEY_INFO_ACK BIT(7)
-#define WPA_KEY_INFO_MIC BIT(8)
-#define WPA_KEY_INFO_SECURE BIT(9)
-#define WPA_KEY_INFO_ERROR BIT(10)
-#define WPA_KEY_INFO_REQUEST BIT(11)
-#define WPA_KEY_INFO_ENCR_KEY_DATA BIT(12)
-#define WPA_KEY_INFO_SMK_MESSAGE BIT(13)
-
-
-/* per STA state machine data */
-
-struct wpa_ptk {
- u8 mic_key[16]; /* EAPOL-Key MIC Key (MK) */
- u8 encr_key[16]; /* EAPOL-Key Encryption Key (EK) */
- u8 tk1[16]; /* Temporal Key 1 (TK1) */
- union {
- u8 tk2[16]; /* Temporal Key 2 (TK2) */
- struct {
- u8 tx_mic_key[8];
- u8 rx_mic_key[8];
- } auth;
- } u;
-} __attribute__ ((packed));
-
-struct wpa_authenticator;
-struct wpa_state_machine;
-struct rsn_pmksa_cache_entry;
-
-
-struct wpa_auth_config {
- int wpa;
- int wpa_key_mgmt;
- int wpa_pairwise;
- int wpa_group;
- int wpa_group_rekey;
- int wpa_strict_rekey;
- int wpa_gmk_rekey;
- int rsn_preauth;
- int eapol_version;
- int peerkey;
- int wme_enabled;
-#ifdef CONFIG_IEEE80211W
- enum {
- WPA_NO_IEEE80211W = 0,
- WPA_IEEE80211W_OPTIONAL = 1,
- WPA_IEEE80211W_REQUIRED = 2
- } ieee80211w;
-#endif /* CONFIG_IEEE80211W */
-};
-
-typedef enum {
- LOGGER_DEBUG, LOGGER_INFO, LOGGER_WARNING
-} logger_level;
-
-typedef enum {
- WPA_EAPOL_portEnabled, WPA_EAPOL_portValid, WPA_EAPOL_authorized,
- WPA_EAPOL_portControl_Auto, WPA_EAPOL_keyRun, WPA_EAPOL_keyAvailable,
- WPA_EAPOL_keyDone, WPA_EAPOL_inc_EapolFramesTx
-} wpa_eapol_variable;
-
-struct wpa_auth_callbacks {
- void *ctx;
- void (*logger)(void *ctx, const u8 *addr, logger_level level,
- const char *txt);
- void (*disconnect)(void *ctx, const u8 *addr, u16 reason);
- void (*mic_failure_report)(void *ctx, const u8 *addr);
- void (*set_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var,
- int value);
- int (*get_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var);
- const u8 * (*get_psk)(void *ctx, const u8 *addr, const u8 *prev_psk);
- int (*get_pmk)(void *ctx, const u8 *addr, u8 *pmk, size_t *len);
- int (*set_key)(void *ctx, int vlan_id, const char *alg, const u8 *addr,
- int idx, u8 *key, size_t key_len);
- int (*get_seqnum)(void *ctx, const u8 *addr, int idx, u8 *seq);
- int (*get_seqnum_igtk)(void *ctx, const u8 *addr, int idx, u8 *seq);
- int (*send_eapol)(void *ctx, const u8 *addr, const u8 *data,
- size_t data_len, int encrypt);
- int (*for_each_sta)(void *ctx, int (*cb)(struct wpa_state_machine *sm,
- void *ctx), void *cb_ctx);
-};
-
-struct wpa_authenticator * wpa_init(const u8 *addr,
- struct wpa_auth_config *conf,
- struct wpa_auth_callbacks *cb);
-void wpa_deinit(struct wpa_authenticator *wpa_auth);
-int wpa_reconfig(struct wpa_authenticator *wpa_auth,
- struct wpa_auth_config *conf);
-
-enum {
- WPA_IE_OK, WPA_INVALID_IE, WPA_INVALID_GROUP, WPA_INVALID_PAIRWISE,
- WPA_INVALID_AKMP, WPA_NOT_ENABLED, WPA_ALLOC_FAIL,
- WPA_MGMT_FRAME_PROTECTION_VIOLATION, WPA_INVALID_MGMT_GROUP_CIPHER
-};
-
-int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- const u8 *wpa_ie, size_t wpa_ie_len);
-struct wpa_state_machine *
-wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr);
-void wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm);
-void wpa_auth_sta_deinit(struct wpa_state_machine *sm);
-void wpa_receive(struct wpa_authenticator *wpa_auth,
- struct wpa_state_machine *sm,
- u8 *data, size_t data_len);
-typedef enum {
- WPA_AUTH, WPA_ASSOC, WPA_DISASSOC, WPA_DEAUTH, WPA_REAUTH,
- WPA_REAUTH_EAPOL
-} wpa_event;
-void wpa_remove_ptk(struct wpa_state_machine *sm);
-void wpa_auth_sm_event(struct wpa_state_machine *sm, wpa_event event);
-void wpa_auth_sm_notify(struct wpa_state_machine *sm);
-void wpa_gtk_rekey(struct wpa_authenticator *wpa_auth);
-int wpa_get_mib(struct wpa_authenticator *wpa_auth, char *buf, size_t buflen);
-int wpa_get_mib_sta(struct wpa_state_machine *sm, char *buf, size_t buflen);
-void wpa_auth_countermeasures_start(struct wpa_authenticator *wpa_auth);
-int wpa_auth_pairwise_set(struct wpa_state_machine *sm);
-int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm);
-int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm);
-int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm,
- struct rsn_pmksa_cache_entry *entry);
-struct rsn_pmksa_cache_entry *
-wpa_auth_sta_get_pmksa(struct wpa_state_machine *sm);
-void wpa_auth_sta_local_mic_failure_report(struct wpa_state_machine *sm);
-const u8 * wpa_auth_get_wpa_ie(struct wpa_authenticator *wpa_auth,
- size_t *len);
-int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk,
- int session_timeout, struct eapol_state_machine *eapol);
-int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
- const u8 *pmk, size_t len, const u8 *sta_addr,
- int session_timeout,
- struct eapol_state_machine *eapol);
-int wpa_auth_sta_set_vlan(struct wpa_state_machine *sm, int vlan_id);
-
-#endif /* WPA_H */
diff --git a/hostapd/.gitignore b/hostapd/.gitignore
new file mode 100644
index 000000000000..6dd2c2fd35c4
--- /dev/null
+++ b/hostapd/.gitignore
@@ -0,0 +1,7 @@
+*.d
+.config
+driver_conf.c
+hostapd
+hostapd_cli
+hlr_auc_gw
+nt_password_hash
diff --git a/contrib/hostapd/ChangeLog b/hostapd/ChangeLog
index ab28973f9bba..46f085246c7a 100644
--- a/contrib/hostapd/ChangeLog
+++ b/hostapd/ChangeLog
@@ -1,38 +1,156 @@
ChangeLog for hostapd
-2008-02-19 - v0.5.10
- * fixed EAP-SIM and EAP-AKA message parser to validate attribute
- lengths properly to avoid potential crash caused by invalid messages
+2009-02-15 - v0.6.8
+ * increased hostapd_cli ping interval to 5 seconds and made this
+ configurable with a new command line options (-G<seconds>)
+ * driver_nl80211: use Linux socket filter to improve performance
+ * added support for external Registrars with WPS (UPnP transport)
+
+2009-01-06 - v0.6.7
+ * added support for Wi-Fi Protected Setup (WPS)
+ (hostapd can now be configured to act as an integrated WPS Registrar
+ and provision credentials for WPS Enrollees using PIN and PBC
+ methods; external wireless Registrar can configure the AP, but
+ external WLAN Manager Registrars are not supported); WPS support can
+ be enabled by adding CONFIG_WPS=y into .config and setting the
+ runtime configuration variables in hostapd.conf (see WPS section in
+ the example configuration file); new hostapd_cli commands wps_pin and
+ wps_pbc are used to configure WPS negotiation; see README-WPS for
+ more details
+ * added IEEE 802.11n HT capability configuration (ht_capab)
+ * added support for generating Country IE based on nl80211 regulatory
+ information (added if ieee80211d=1 in configuration)
+ * fixed WEP authentication (both Open System and Shared Key) with
+ mac80211
+ * added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
+ * added support for using driver_test over UDP socket
+ * changed EAP-GPSK to use the IANA assigned EAP method type 51
+ * updated management frame protection to use IEEE 802.11w/D7.0
+ * fixed retransmission of EAP requests if no response is received
+
+2008-11-23 - v0.6.6
+ * added a new configuration option, wpa_ptk_rekey, that can be used to
+ enforce frequent PTK rekeying, e.g., to mitigate some attacks against
+ TKIP deficiencies
+ * updated OpenSSL code for EAP-FAST to use an updated version of the
+ session ticket overriding API that was included into the upstream
+ OpenSSL 0.9.9 tree on 2008-11-15 (no additional OpenSSL patch is
+ needed with that version anymore)
+ * changed channel flags configuration to read the information from
+ the driver (e.g., via driver_nl80211 when using mac80211) instead of
+ using hostapd as the source of the regulatory information (i.e.,
+ information from CRDA is now used with mac80211); this allows 5 GHz
+ channels to be used with hostapd (if allowed in the current
+ regulatory domain)
+ * fixed EAP-TLS message processing for the last TLS message if it is
+ large enough to require fragmentation (e.g., if a large Session
+ Ticket data is included)
+ * fixed listen interval configuration for nl80211 drivers
+
+2008-11-01 - v0.6.5
+ * added support for SHA-256 as X.509 certificate digest when using the
+ internal X.509/TLSv1 implementation
+ * fixed EAP-FAST PAC-Opaque padding (0.6.4 broke this for some peer
+ identity lengths)
+ * fixed internal TLSv1 implementation for abbreviated handshake (used
+ by EAP-FAST server)
+ * added support for setting VLAN ID for STAs based on local MAC ACL
+ (accept_mac_file) as an alternative for RADIUS server-based
+ configuration
+ * updated management frame protection to use IEEE 802.11w/D6.0
+ (adds a new association ping to protect against unauthenticated
+ authenticate or (re)associate request frames dropping association)
+ * added support for using SHA256-based stronger key derivation for WPA2
+ (IEEE 802.11w)
+ * added new "driver wrapper" for RADIUS-only configuration
+ (driver=none in hostapd.conf; CONFIG_DRIVER_NONE=y in .config)
+ * fixed WPA/RSN IE validation to verify that the proto (WPA vs. WPA2)
+ is enabled in configuration
+ * changed EAP-FAST configuration to use separate fields for A-ID and
+ A-ID-Info (eap_fast_a_id_info) to allow A-ID to be set to a fixed
+ 16-octet len binary value for better interoperability with some peer
+ implementations; eap_fast_a_id is now configured as a hex string
+ * driver_nl80211: Updated to match the current Linux mac80211 AP mode
+ configuration (wireless-testing.git and Linux kernel releases
+ starting from 2.6.29)
+
+2008-08-10 - v0.6.4
+ * added peer identity into EAP-FAST PAC-Opaque and skip Phase 2
+ Identity Request if identity is already known
+ * added support for EAP Sequences in EAP-FAST Phase 2
+ * added support for EAP-TNC (Trusted Network Connect)
+ (this version implements the EAP-TNC method and EAP-TTLS/EAP-FAST
+ changes needed to run two methods in sequence (IF-T) and the IF-IMV
+ and IF-TNCCS interfaces from TNCS)
+ * added support for optional cryptobinding with PEAPv0
+ * added fragmentation support for EAP-TNC
+ * added support for fragmenting EAP-TTLS/PEAP/FAST Phase 2 (tunneled)
+ data
+ * added support for opportunistic key caching (OKC)
+
+2008-02-22 - v0.6.3
* fixed Reassociation Response callback processing when using internal
- MLME (driver_{hostap,devicescape,test}.c)
+ 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
- * copy optional Proxy-State attributes into RADIUS response when acting
- as a RADIUS authentication server
+ * 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
-2007-12-02 - v0.5.9
+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)
- * fixed debugging code not to use potentially unaligned read to fetch
- IPv4 addresses
-
-2007-05-28 - v0.5.8
- * updated driver_devicescape.c to build with the current
- wireless-dev.git tree and net/d80211 changes
- * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
- draft (draft-ietf-emu-eap-gpsk-03.txt)
- * 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
- * RADIUS server: added support for processing duplicate messages
- (retransmissions from RADIUS client) by replying with the previous
- reply
-
-2006-12-31 - v0.5.7
+ * 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
@@ -40,6 +158,22 @@ ChangeLog for hostapd
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
diff --git a/hostapd/Makefile b/hostapd/Makefile
new file mode 100644
index 000000000000..7737e2344916
--- /dev/null
+++ b/hostapd/Makefile
@@ -0,0 +1,602 @@
+ifndef CC
+CC=gcc
+endif
+
+ifndef CFLAGS
+CFLAGS = -MMD -O2 -Wall -g
+endif
+
+# 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
+
+CFLAGS += -I../src
+CFLAGS += -I../src/crypto
+CFLAGS += -I../src/utils
+CFLAGS += -I../src/common
+
+# 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 = hostapd.o ieee802_1x.o eapol_sm.o \
+ ieee802_11.o config.o ieee802_11_auth.o accounting.o \
+ sta_info.o wpa.o ctrl_iface.o \
+ drivers.o preauth.o pmksa_cache.o beacon.o \
+ hw_features.o wme.o ap_list.o \
+ mlme.o vlan_init.o wpa_auth_ie.o
+
+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/radius/radius.o
+OBJS += ../src/radius/radius_client.o
+
+OBJS += ../src/crypto/md5.o
+OBJS += ../src/crypto/rc4.o
+OBJS += ../src/crypto/md4.o
+OBJS += ../src/crypto/sha1.o
+OBJS += ../src/crypto/des.o
+OBJS += ../src/crypto/aes_wrap.o
+OBJS += ../src/crypto/aes.o
+
+HOBJS=../src/hlr_auc_gw/hlr_auc_gw.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).o ../src/hlr_auc_gw/milenage.o ../src/crypto/aes_wrap.o ../src/crypto/aes.o
+
+CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX
+
+ifdef CONFIG_IAPP
+CFLAGS += -DCONFIG_IAPP
+OBJS += iapp.o
+endif
+
+ifdef CONFIG_RSN_PREAUTH
+CFLAGS += -DCONFIG_RSN_PREAUTH
+CONFIG_L2_PACKET=y
+endif
+
+ifdef CONFIG_PEERKEY
+CFLAGS += -DCONFIG_PEERKEY
+OBJS += peerkey.o
+endif
+
+ifdef CONFIG_IEEE80211W
+CFLAGS += -DCONFIG_IEEE80211W
+NEED_SHA256=y
+endif
+
+ifdef CONFIG_IEEE80211R
+CFLAGS += -DCONFIG_IEEE80211R
+OBJS += wpa_ft.o
+NEED_SHA256=y
+endif
+
+ifdef CONFIG_IEEE80211N
+CFLAGS += -DCONFIG_IEEE80211N
+endif
+
+ifdef CONFIG_DRIVER_HOSTAP
+CFLAGS += -DCONFIG_DRIVER_HOSTAP
+OBJS += driver_hostap.o
+endif
+
+ifdef CONFIG_DRIVER_WIRED
+CFLAGS += -DCONFIG_DRIVER_WIRED
+OBJS += driver_wired.o
+endif
+
+ifdef CONFIG_DRIVER_MADWIFI
+CFLAGS += -DCONFIG_DRIVER_MADWIFI
+OBJS += driver_madwifi.o
+CONFIG_L2_PACKET=y
+endif
+
+ifdef CONFIG_DRIVER_PRISM54
+CFLAGS += -DCONFIG_DRIVER_PRISM54
+OBJS += driver_prism54.o
+endif
+
+ifdef CONFIG_DRIVER_NL80211
+CFLAGS += -DCONFIG_DRIVER_NL80211
+OBJS += driver_nl80211.o radiotap.o
+LIBS += -lnl
+ifdef CONFIG_LIBNL20
+LIBS += -lnl-genl
+CFLAGS += -DCONFIG_LIBNL20
+endif
+endif
+
+ifdef CONFIG_DRIVER_BSD
+CFLAGS += -DCONFIG_DRIVER_BSD
+OBJS += driver_bsd.o
+CONFIG_L2_PACKET=y
+CONFIG_DNET_PCAP=y
+CONFIG_L2_FREEBSD=y
+endif
+
+ifdef CONFIG_DRIVER_TEST
+CFLAGS += -DCONFIG_DRIVER_TEST
+OBJS += driver_test.o
+endif
+
+ifdef CONFIG_DRIVER_NONE
+CFLAGS += -DCONFIG_DRIVER_NONE
+OBJS += driver_none.o
+endif
+
+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_MD5
+OBJS += ../src/eap_server/eap_md5.o
+CHAP=y
+endif
+
+ifdef CONFIG_EAP_TLS
+CFLAGS += -DEAP_TLS
+OBJS += ../src/eap_server/eap_tls.o
+TLS_FUNCS=y
+endif
+
+ifdef CONFIG_EAP_PEAP
+CFLAGS += -DEAP_PEAP
+OBJS += ../src/eap_server/eap_peap.o
+OBJS += ../src/eap_common/eap_peap_common.o
+TLS_FUNCS=y
+CONFIG_EAP_MSCHAPV2=y
+endif
+
+ifdef CONFIG_EAP_TTLS
+CFLAGS += -DEAP_TTLS
+OBJS += ../src/eap_server/eap_ttls.o
+TLS_FUNCS=y
+CHAP=y
+endif
+
+ifdef CONFIG_EAP_MSCHAPV2
+CFLAGS += -DEAP_MSCHAPv2
+OBJS += ../src/eap_server/eap_mschapv2.o
+MS_FUNCS=y
+endif
+
+ifdef CONFIG_EAP_GTC
+CFLAGS += -DEAP_GTC
+OBJS += ../src/eap_server/eap_gtc.o
+endif
+
+ifdef CONFIG_EAP_SIM
+CFLAGS += -DEAP_SIM
+OBJS += ../src/eap_server/eap_sim.o
+CONFIG_EAP_SIM_COMMON=y
+endif
+
+ifdef CONFIG_EAP_AKA
+CFLAGS += -DEAP_AKA
+OBJS += ../src/eap_server/eap_aka.o
+CONFIG_EAP_SIM_COMMON=y
+endif
+
+ifdef CONFIG_EAP_AKA_PRIME
+CFLAGS += -DEAP_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_PAX
+OBJS += ../src/eap_server/eap_pax.o ../src/eap_common/eap_pax_common.o
+endif
+
+ifdef CONFIG_EAP_PSK
+CFLAGS += -DEAP_PSK
+OBJS += ../src/eap_server/eap_psk.o ../src/eap_common/eap_psk_common.o
+endif
+
+ifdef CONFIG_EAP_SAKE
+CFLAGS += -DEAP_SAKE
+OBJS += ../src/eap_server/eap_sake.o ../src/eap_common/eap_sake_common.o
+endif
+
+ifdef CONFIG_EAP_GPSK
+CFLAGS += -DEAP_GPSK
+OBJS += ../src/eap_server/eap_gpsk.o ../src/eap_common/eap_gpsk_common.o
+ifdef CONFIG_EAP_GPSK_SHA256
+CFLAGS += -DEAP_GPSK_SHA256
+endif
+NEED_SHA256=y
+endif
+
+ifdef CONFIG_EAP_VENDOR_TEST
+CFLAGS += -DEAP_VENDOR_TEST
+OBJS += ../src/eap_server/eap_vendor_test.o
+endif
+
+ifdef CONFIG_EAP_FAST
+CFLAGS += -DEAP_FAST
+OBJS += ../src/eap_server/eap_fast.o
+OBJS += ../src/eap_common/eap_fast_common.o
+TLS_FUNCS=y
+NEED_T_PRF=y
+endif
+
+ifdef CONFIG_WPS
+CFLAGS += -DCONFIG_WPS -DEAP_WSC
+OBJS += ../src/utils/uuid.o
+OBJS += wps_hostapd.o
+OBJS += ../src/eap_server/eap_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_CRYPTO=y
+NEED_BASE64=y
+
+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/httpread.o
+endif
+
+endif
+
+ifdef CONFIG_EAP_IKEV2
+CFLAGS += -DEAP_IKEV2
+OBJS += ../src/eap_server/eap_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
+endif
+
+ifdef CONFIG_EAP_TNC
+CFLAGS += -DEAP_TNC
+OBJS += ../src/eap_server/eap_tnc.o
+OBJS += ../src/eap_server/tncs.o
+NEED_BASE64=y
+LIBS += -ldl
+endif
+
+# Basic EAP functionality is needed for EAPOL
+OBJS += ../src/eap_server/eap.o
+OBJS += ../src/eap_common/eap_common.o
+OBJS += ../src/eap_server/eap_methods.o
+OBJS += ../src/eap_server/eap_identity.o
+
+ifdef CONFIG_EAP
+CFLAGS += -DEAP_SERVER
+endif
+
+ifndef CONFIG_TLS
+CONFIG_TLS=openssl
+endif
+
+ifeq ($(CONFIG_TLS), internal)
+ifndef CONFIG_CRYPTO
+CONFIG_CRYPTO=internal
+endif
+endif
+ifeq ($(CONFIG_CRYPTO), libtomcrypt)
+CFLAGS += -DCONFIG_INTERNAL_X509
+endif
+ifeq ($(CONFIG_CRYPTO), internal)
+CFLAGS += -DCONFIG_INTERNAL_X509
+endif
+
+
+ifdef TLS_FUNCS
+# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
+CFLAGS += -DEAP_TLS_FUNCS
+OBJS += ../src/eap_server/eap_tls_common.o
+NEED_TLS_PRF=y
+ifeq ($(CONFIG_TLS), openssl)
+OBJS += ../src/crypto/tls_openssl.o
+LIBS += -lssl -lcrypto
+LIBS_p += -lcrypto
+LIBS_h += -lcrypto
+endif
+ifeq ($(CONFIG_TLS), gnutls)
+OBJS += ../src/crypto/tls_gnutls.o
+LIBS += -lgnutls -lgcrypt -lgpg-error
+LIBS_p += -lgcrypt
+LIBS_h += -lgcrypt
+endif
+ifdef CONFIG_GNUTLS_EXTRA
+CFLAGS += -DCONFIG_GNUTLS_EXTRA
+LIBS += -lgnutls-extra
+endif
+ifeq ($(CONFIG_TLS), internal)
+OBJS += ../src/crypto/tls_internal.o
+OBJS += ../src/tls/tlsv1_common.o ../src/tls/tlsv1_record.o
+OBJS += ../src/tls/tlsv1_cred.o ../src/tls/tlsv1_server.o
+OBJS += ../src/tls/tlsv1_server_write.o ../src/tls/tlsv1_server_read.o
+OBJS += ../src/tls/asn1.o ../src/tls/x509v3.o
+OBJS_p += ../src/tls/asn1.o
+OBJS_p += ../src/crypto/rc4.o ../src/crypto/aes_wrap.o ../src/crypto/aes.o
+NEED_BASE64=y
+CFLAGS += -DCONFIG_TLS_INTERNAL
+CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
+ifeq ($(CONFIG_CRYPTO), internal)
+ifdef CONFIG_INTERNAL_LIBTOMMATH
+CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
+else
+LIBS += -ltommath
+LIBS_p += -ltommath
+endif
+endif
+ifeq ($(CONFIG_CRYPTO), libtomcrypt)
+LIBS += -ltomcrypt -ltfm
+LIBS_p += -ltomcrypt -ltfm
+endif
+endif
+NEED_CRYPTO=y
+else
+OBJS += ../src/crypto/tls_none.o
+endif
+
+ifdef CONFIG_PKCS12
+CFLAGS += -DPKCS12_FUNCS
+endif
+
+ifdef MS_FUNCS
+OBJS += ../src/crypto/ms_funcs.o
+NEED_CRYPTO=y
+endif
+
+ifdef CHAP
+OBJS += ../src/eap_common/chap.o
+endif
+
+ifdef NEED_CRYPTO
+ifndef TLS_FUNCS
+ifeq ($(CONFIG_TLS), openssl)
+LIBS += -lcrypto
+LIBS_p += -lcrypto
+LIBS_h += -lcrypto
+endif
+ifeq ($(CONFIG_TLS), gnutls)
+LIBS += -lgcrypt
+LIBS_p += -lgcrypt
+LIBS_h += -lgcrypt
+endif
+ifeq ($(CONFIG_TLS), internal)
+ifeq ($(CONFIG_CRYPTO), libtomcrypt)
+LIBS += -ltomcrypt -ltfm
+LIBS_p += -ltomcrypt -ltfm
+endif
+endif
+endif
+ifeq ($(CONFIG_TLS), openssl)
+OBJS += ../src/crypto/crypto_openssl.o
+OBJS_p += ../src/crypto/crypto_openssl.o
+HOBJS += ../src/crypto/crypto_openssl.o
+CONFIG_INTERNAL_SHA256=y
+endif
+ifeq ($(CONFIG_TLS), gnutls)
+OBJS += ../src/crypto/crypto_gnutls.o
+OBJS_p += ../src/crypto/crypto_gnutls.o
+HOBJS += ../src/crypto/crypto_gnutls.o
+CONFIG_INTERNAL_SHA256=y
+endif
+ifeq ($(CONFIG_TLS), internal)
+ifeq ($(CONFIG_CRYPTO), libtomcrypt)
+OBJS += ../src/crypto/crypto_libtomcrypt.o
+OBJS_p += ../src/crypto/crypto_libtomcrypt.o
+CONFIG_INTERNAL_SHA256=y
+endif
+ifeq ($(CONFIG_CRYPTO), internal)
+OBJS += ../src/crypto/crypto_internal.o ../src/tls/rsa.o ../src/tls/bignum.o
+OBJS_p += ../src/crypto/crypto_internal.o ../src/tls/rsa.o ../src/tls/bignum.o
+CFLAGS += -DCONFIG_CRYPTO_INTERNAL
+CONFIG_INTERNAL_AES=y
+CONFIG_INTERNAL_DES=y
+CONFIG_INTERNAL_SHA1=y
+CONFIG_INTERNAL_MD4=y
+CONFIG_INTERNAL_MD5=y
+CONFIG_INTERNAL_SHA256=y
+endif
+endif
+else
+CONFIG_INTERNAL_AES=y
+CONFIG_INTERNAL_SHA1=y
+CONFIG_INTERNAL_MD5=y
+CONFIG_INTERNAL_SHA256=y
+endif
+
+ifdef CONFIG_INTERNAL_AES
+CFLAGS += -DINTERNAL_AES
+endif
+ifdef CONFIG_INTERNAL_SHA1
+CFLAGS += -DINTERNAL_SHA1
+endif
+ifdef CONFIG_INTERNAL_SHA256
+CFLAGS += -DINTERNAL_SHA256
+endif
+ifdef CONFIG_INTERNAL_MD5
+CFLAGS += -DINTERNAL_MD5
+endif
+ifdef CONFIG_INTERNAL_MD4
+CFLAGS += -DINTERNAL_MD4
+endif
+ifdef CONFIG_INTERNAL_DES
+CFLAGS += -DINTERNAL_DES
+endif
+
+ifdef NEED_SHA256
+OBJS += ../src/crypto/sha256.o
+endif
+
+ifdef NEED_DH_GROUPS
+OBJS += ../src/crypto/dh_groups.o
+endif
+
+ifndef NEED_FIPS186_2_PRF
+CFLAGS += -DCONFIG_NO_FIPS186_2_PRF
+endif
+
+ifndef NEED_T_PRF
+CFLAGS += -DCONFIG_NO_T_PRF
+endif
+
+ifndef NEED_TLS_PRF
+CFLAGS += -DCONFIG_NO_TLS_PRF
+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 CONFIG_NO_STDOUT_DEBUG
+CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
+endif
+
+ifdef CONFIG_NO_AES_EXTRAS
+CFLAGS += -DCONFIG_NO_AES_UNWRAP
+CFLAGS += -DCONFIG_NO_AES_CTR -DCONFIG_NO_AES_OMAC1
+CFLAGS += -DCONFIG_NO_AES_EAX -DCONFIG_NO_AES_CBC
+CFLAGS += -DCONFIG_NO_AES_DECRYPT
+CFLAGS += -DCONFIG_NO_AES_ENCRYPT_BLOCK
+endif
+
+ALL=hostapd hostapd_cli
+
+all: verify_config $(ALL)
+
+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 $$i /usr/local/bin/$$i; done
+
+hostapd: $(OBJS)
+ $(CC) -o hostapd $(OBJS) $(LIBS)
+
+OBJS_c = hostapd_cli.o ../src/common/wpa_ctrl.o ../src/utils/os_$(CONFIG_OS).o
+hostapd_cli: $(OBJS_c)
+ $(CC) -o hostapd_cli $(OBJS_c)
+
+NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o ../src/crypto/sha1.o ../src/crypto/rc4.o ../src/crypto/md5.o
+NOBJS += ../src/crypto/crypto_openssl.o ../src/utils/os_$(CONFIG_OS).o
+ifdef TLS_FUNCS
+LIBS_n += -lcrypto
+endif
+
+nt_password_hash: $(NOBJS)
+ $(CC) -o nt_password_hash $(NOBJS) $(LIBS_n)
+
+hlr_auc_gw: $(HOBJS)
+ $(CC) -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
+
+%.eps: %.fig
+ fig2dev -L eps $*.fig $*.eps
+
+%.png: %.fig
+ fig2dev -L png -m 3 $*.fig | pngtopnm | pnmscale 0.4 | pnmtopng \
+ > $*.png
+
+docs-pics: doc/hostapd.png doc/hostapd.eps
+
+docs: docs-pics
+ (cd ..; doxygen hostapd/doc/doxygen.full; cd hostapd)
+ $(MAKE) -C doc/latex
+ cp doc/latex/refman.pdf hostapd-devel.pdf
+
+docs-fast: docs-pics
+ (cd ..; doxygen hostapd/doc/doxygen.fast; cd hostapd)
+
+clean-docs:
+ rm -rf doc/latex doc/html
+ rm -f doc/hostapd.{eps,png} hostapd-devel.pdf
+
+TEST_SRC_MILENAGE = ../src/hlr_auc_gw/milenage.c ../src/crypto/aes_wrap.c ../src/crypto/aes.c ../src/utils/common.c ../src/utils/wpa_debug.o ../src/utils/os_$(CONFIG_OS).c
+test-milenage: $(TEST_SRC_MILENAGE)
+ $(CC) -o test-milenage -Wall -Werror $(TEST_SRC_MILENAGE) \
+ -DTEST_MAIN_MILENAGE -I. -DINTERNAL_AES \
+ -I../src/crypto -I../src/utils
+ ./test-milenage
+ rm test-milenage
+
+-include $(OBJS:%.o=%.d)
diff --git a/contrib/hostapd/README b/hostapd/README
index dd242042d406..eb9aa4815b4f 100644
--- a/contrib/hostapd/README
+++ b/hostapd/README
@@ -2,7 +2,7 @@ hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
Authenticator and RADIUS authentication server
================================================================
-Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved.
This program is dual-licensed under both the GPL version 2 and BSD
@@ -98,6 +98,10 @@ Current hardware/software requirements:
Prism54 driver for Intersil/Conexant Prism GT/Duette/Indigo
(http://www.prism54.org/)
+ mac80211-based drivers that support AP mode (with driver=nl80211).
+ This includes drivers for Atheros (ath9k) and Broadcom (b43)
+ chipsets.
+
Any wired Ethernet driver for wired IEEE 802.1X authentication
(experimental code)
diff --git a/hostapd/README-WPS b/hostapd/README-WPS
new file mode 100644
index 000000000000..b46d76796614
--- /dev/null
+++ b/hostapd/README-WPS
@@ -0,0 +1,232 @@
+hostapd and Wi-Fi Protected Setup (WPS)
+=======================================
+
+This document describes how the WPS implementation in hostapd can be
+configured and how an external component on an AP (e.g., web UI) is
+used to enable enrollment of client devices.
+
+
+Introduction to WPS
+-------------------
+
+Wi-Fi Protected Setup (WPS) is a mechanism for easy configuration of a
+wireless network. It allows automated generation of random keys (WPA
+passphrase/PSK) and configuration of an access point and client
+devices. WPS includes number of methods for setting up connections
+with PIN method and push-button configuration (PBC) being the most
+commonly deployed options.
+
+While WPS can enable more home networks to use encryption in the
+wireless network, it should be noted that the use of the PIN and
+especially PBC mechanisms for authenticating the initial key setup is
+not very secure. As such, use of WPS may not be suitable for
+environments that require secure network access without chance for
+allowing outsiders to gain access during the setup phase.
+
+WPS uses following terms to describe the entities participating in the
+network setup:
+- access point: the WLAN access point
+- Registrar: a device that control a network and can authorize
+ addition of new devices); this may be either in the AP ("internal
+ Registrar") or in an external device, e.g., a laptop, ("external
+ Registrar")
+- Enrollee: a device that is being authorized to use the network
+
+It should also be noted that the AP and a client device may change
+roles (i.e., AP acts as an Enrollee and client device as a Registrar)
+when WPS is used to configure the access point.
+
+
+More information about WPS is available from Wi-Fi Alliance:
+http://www.wi-fi.org/wifi-protected-setup
+
+
+hostapd implementation
+----------------------
+
+hostapd includes an optional WPS component that can be used as an
+internal WPS Registrar to manage addition of new WPS enabled clients
+to the network. In addition, WPS Enrollee functionality in hostapd can
+be used to allow external WPS Registrars to configure the access
+point, e.g., for initial network setup. In addition, hostapd can proxy a
+WPS registration between a wireless Enrollee and an external Registrar
+(e.g., Microsoft Vista or Atheros JumpStart) with UPnP.
+
+
+hostapd configuration
+---------------------
+
+WPS is an optional component that needs to be enabled in hostapd build
+configuration (.config). Here is an example configuration that
+includes WPS support and uses madwifi driver interface:
+
+CONFIG_DRIVER_MADWIFI=y
+CFLAGS += -I/usr/src/madwifi-0.9.3
+CONFIG_EAP=y
+CONFIG_WPS=y
+CONFIG_WPS_UPNP=y
+
+
+Following section shows an example runtime configuration
+(hostapd.conf) that enables WPS:
+
+# Configure the driver and network interface
+driver=madwifi
+interface=ath0
+
+# WPA2-Personal configuration for the AP
+ssid=wps-test
+wpa=2
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=CCMP
+# Default WPA passphrase for legacy (non-WPS) clients
+wpa_passphrase=12345678
+# Enable random per-device PSK generation for WPS clients
+# Please note that the file has to exists for hostapd to start (i.e., create an
+# empty file as a starting point).
+wpa_psk_file=/etc/hostapd.psk
+
+# Enable control interface for PBC/PIN entry
+ctrl_interface=/var/run/hostapd
+
+# Enable internal EAP server for EAP-WSC (part of Wi-Fi Protected Setup)
+eap_server=1
+
+# WPS configuration (AP configured, do not allow external WPS Registrars)
+wps_state=2
+ap_setup_locked=1
+# If UUID is not configured, it will be generated based on local MAC address.
+uuid=87654321-9abc-def0-1234-56789abc0000
+wps_pin_requests=/var/run/hostapd.pin-req
+device_name=Wireless AP
+manufacturer=Company
+model_name=WAP
+model_number=123
+serial_number=12345
+device_type=6-0050F204-1
+os_version=01020300
+config_methods=label display push_button keypad
+
+# if external Registrars are allowed, UPnP support could be added:
+#upnp_iface=br0
+#friendly_name=WPS Access Point
+
+
+External operations
+-------------------
+
+WPS requires either a device PIN code (usually, 8-digit number) or a
+pushbutton event (for PBC) to allow a new WPS Enrollee to join the
+network. hostapd uses the control interface as an input channel for
+these events.
+
+When a client device (WPS Enrollee) connects to hostapd (WPS
+Registrar) in order to start PIN mode negotiation for WPS, an
+identifier (Enrollee UUID) is sent. hostapd will need to be configured
+with a device password (PIN) for this Enrollee. This is an operation
+that requires user interaction (assuming there are no pre-configured
+PINs on the AP for a set of Enrollee).
+
+The PIN request with information about the device is appended to the
+wps_pin_requests file (/var/run/hostapd.pin-req in this example). In
+addition, hostapd control interface event is sent as a notification of
+a new device. The AP could use, e.g., a web UI for showing active
+Enrollees to the user and request a PIN for an Enrollee.
+
+The PIN request file has one line for every Enrollee that connected to
+the AP, but for which there was no PIN. Following information is
+provided for each Enrollee (separated with tabulators):
+- timestamp (seconds from 1970-01-01)
+- Enrollee UUID
+- MAC address
+- Device name
+- Manufacturer
+- Model Name
+- Model Number
+- Serial Number
+- Device category
+
+Example line in the /var/run/hostapd.pin-req file:
+1200188391 53b63a98-d29e-4457-a2ed-094d7e6a669c Intel(R) Centrino(R) Intel Corporation Intel(R) Centrino(R) - - 1-0050F204-1
+
+Control interface data:
+WPS-PIN-NEEDED [UUID-E|MAC Address|Device Name|Manufacturer|Model Name|Model Number|Serial Number|Device Category]
+For example:
+<2>WPS-PIN-NEEDED [53b63a98-d29e-4457-a2ed-094d7e6a669c|02:12:34:56:78:9a|Device|Manuf|Model|Model Number|Serial Number|1-0050F204-1]
+
+When the user enters a PIN for a pending Enrollee, e.g., on the web
+UI), hostapd needs to be notified of the new PIN over the control
+interface. This can be done either by using the UNIX domain socket
+-based control interface directly (src/common/wpa_ctrl.c provides
+helper functions for using the interface) or by calling hostapd_cli.
+
+Example command to add a PIN (12345670) for an Enrollee:
+
+hostapd_cli wps_pin 53b63a98-d29e-4457-a2ed-094d7e6a669c 12345670
+
+If the UUID-E is not available (e.g., Enrollee waits for the Registrar
+to be selected before connecting), wildcard UUID may be used to allow the PIN to be used once with any UUID:
+
+hostapd_cli wps_pin any 12345670
+
+
+After this, the Enrollee can connect to the AP again and complete WPS
+negotiation. At that point, a new, random WPA PSK is generated for the
+client device and the client can then use that key to connect to the
+AP to access the network.
+
+
+If the AP includes a pushbutton, WPS PBC mode can be used. It is
+enabled by pushing a button on both the AP and the client at about the
+same time (2 minute window). hostapd needs to be notified about the AP
+button pushed event over the control interface, e.g., by calling
+hostapd_cli:
+
+hostapd_cli wps_pbc
+
+At this point, the client has two minutes to complete WPS negotiation
+which will generate a new WPA PSK in the same way as the PIN method
+described above.
+
+
+Credential generation and configuration changes
+-----------------------------------------------
+
+By default, hostapd generates credentials for Enrollees and processing
+AP configuration updates internally. However, it is possible to
+control these operations from external programs, if desired.
+
+The internal credential generation can be disabled with
+skip_cred_build=1 option in the configuration. extra_cred option will
+then need to be used to provide pre-configured Credential attribute(s)
+for hostapd to use. The exact data from this binary file will be sent,
+i.e., it will have to include valid WPS attributes. extra_cred can
+also be used to add additional networks if the Registrar is used to
+configure credentials for multiple networks.
+
+Processing of received configuration updates can be disabled with
+wps_cred_processing=1 option. When this is used, an external program
+is responsible for creating hostapd configuration files and processing
+configuration updates based on messages received from hostapd over
+control interface. This will also include the initial configuration on
+first successful registration if the AP is initially set in
+unconfigured state.
+
+Following control interface messages are sent out for external programs:
+
+WPS-REG-SUCCESS <Enrollee MAC address <UUID-E>
+For example:
+<2>WPS-REG-SUCCESS 02:66:a0:ee:17:27 2b7093f1-d6fb-5108-adbb-bea66bb87333
+
+This can be used to tricker change from unconfigured to configured
+state (random configuration based on the first successful WPS
+registration). In addition, this can be used to update AP UI about the
+status of WPS registration progress.
+
+
+WPS-NEW-AP-SETTINGS <hexdump of AP Setup attributes>
+For example:
+<2>WPS-NEW-AP-SETTINGS 10260001011045000c6a6b6d2d7770732d74657374100300020020100f00020008102700403065346230343536633236366665306433396164313535346131663462663731323433376163666462376633393965353466316631623032306164343438623510200006024231cede15101e000844
+
+This can be used to update the externally stored AP configuration and
+then update hostapd configuration (followed by restarting of hostapd).
diff --git a/contrib/hostapd/accounting.c b/hostapd/accounting.c
index b22347b2ac2e..ce71678af4e9 100644
--- a/contrib/hostapd/accounting.c
+++ b/hostapd/accounting.c
@@ -1,6 +1,6 @@
/*
* hostapd / RADIUS Accounting
- * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,11 +13,10 @@
*/
#include "includes.h"
-#include <assert.h>
#include "hostapd.h"
-#include "radius.h"
-#include "radius_client.h"
+#include "radius/radius.h"
+#include "radius/radius_client.h"
#include "eloop.h"
#include "accounting.h"
#include "ieee802_1x.h"
@@ -29,9 +28,8 @@
* input/output octets and updates Acct-{Input,Output}-Gigawords. */
#define ACCT_DEFAULT_UPDATE_INTERVAL 300
-/* from ieee802_1x.c */
-const char *radius_mode_txt(struct hostapd_data *hapd);
-int radius_sta_rate(struct hostapd_data *hapd, struct sta_info *sta);
+static void accounting_sta_get_id(struct hostapd_data *hapd,
+ struct sta_info *sta);
static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
@@ -54,10 +52,10 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
if (sta) {
radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
- snprintf(buf, sizeof(buf), "%08X-%08X",
- sta->acct_session_id_hi, sta->acct_session_id_lo);
+ os_snprintf(buf, sizeof(buf), "%08X-%08X",
+ sta->acct_session_id_hi, sta->acct_session_id_lo);
if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
- (u8 *) buf, strlen(buf))) {
+ (u8 *) buf, os_strlen(buf))) {
printf("Could not add Acct-Session-Id\n");
goto fail;
}
@@ -82,10 +80,10 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
if (sta) {
val = ieee802_1x_get_identity(sta->eapol_sm, &len);
if (!val) {
- snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
- MAC2STR(sta->addr));
+ os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
+ MAC2STR(sta->addr));
val = (u8 *) buf;
- len = strlen(buf);
+ len = os_strlen(buf);
}
if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, val,
@@ -114,7 +112,7 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
if (hapd->conf->nas_identifier &&
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
(u8 *) hapd->conf->nas_identifier,
- strlen(hapd->conf->nas_identifier))) {
+ os_strlen(hapd->conf->nas_identifier))) {
printf("Could not add NAS-Identifier\n");
goto fail;
}
@@ -125,19 +123,19 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
goto fail;
}
- snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
- MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
+ os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
+ MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
- (u8 *) buf, strlen(buf))) {
+ (u8 *) buf, os_strlen(buf))) {
printf("Could not add Called-Station-Id\n");
goto fail;
}
if (sta) {
- snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
- MAC2STR(sta->addr));
+ os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
+ MAC2STR(sta->addr));
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
- (u8 *) buf, strlen(buf))) {
+ (u8 *) buf, os_strlen(buf))) {
printf("Could not add Calling-Station-Id\n");
goto fail;
}
@@ -149,12 +147,12 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
goto fail;
}
- snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
- radius_sta_rate(hapd, sta) / 2,
- (radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
- radius_mode_txt(hapd));
+ os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
+ radius_sta_rate(hapd, sta) / 2,
+ (radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
+ radius_mode_txt(hapd));
if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
- (u8 *) buf, strlen(buf))) {
+ (u8 *) buf, os_strlen(buf))) {
printf("Could not add Connect-Info\n");
goto fail;
}
@@ -177,7 +175,7 @@ static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
fail:
radius_msg_free(msg);
- free(msg);
+ os_free(msg);
return NULL;
}
@@ -227,6 +225,11 @@ static void accounting_interim_update(void *eloop_ctx, void *timeout_ctx)
}
+/**
+ * accounting_sta_start - Start STA accounting
+ * @hapd: hostapd BSS data
+ * @sta: The station
+ */
void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
{
struct radius_msg *msg;
@@ -235,6 +238,12 @@ void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
if (sta->acct_session_started)
return;
+ accounting_sta_get_id(hapd, sta);
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
+ HOSTAPD_LEVEL_INFO,
+ "starting accounting session %08X-%08X",
+ sta->acct_session_id_hi, sta->acct_session_id_lo);
+
time(&sta->acct_session_start);
sta->last_rx_bytes = sta->last_tx_bytes = 0;
sta->acct_input_gigawords = sta->acct_output_gigawords = 0;
@@ -258,8 +267,8 @@ void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
}
-void accounting_sta_report(struct hostapd_data *hapd, struct sta_info *sta,
- int stop)
+static void accounting_sta_report(struct hostapd_data *hapd,
+ struct sta_info *sta, int stop)
{
struct radius_msg *msg;
int cause = sta->acct_terminate_cause;
@@ -355,10 +364,15 @@ void accounting_sta_report(struct hostapd_data *hapd, struct sta_info *sta,
fail:
radius_msg_free(msg);
- free(msg);
+ os_free(msg);
}
+/**
+ * accounting_sta_interim - Send a interim STA accounting report
+ * @hapd: hostapd BSS data
+ * @sta: The station
+ */
void accounting_sta_interim(struct hostapd_data *hapd, struct sta_info *sta)
{
if (sta->acct_session_started)
@@ -366,17 +380,28 @@ void accounting_sta_interim(struct hostapd_data *hapd, struct sta_info *sta)
}
+/**
+ * accounting_sta_stop - Stop STA accounting
+ * @hapd: hostapd BSS data
+ * @sta: The station
+ */
void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta)
{
if (sta->acct_session_started) {
accounting_sta_report(hapd, sta, 1);
eloop_cancel_timeout(accounting_interim_update, hapd, sta);
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
+ HOSTAPD_LEVEL_INFO,
+ "stopped accounting session %08X-%08X",
+ sta->acct_session_id_hi,
+ sta->acct_session_id_lo);
sta->acct_session_started = 0;
}
}
-void accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta)
+static void accounting_sta_get_id(struct hostapd_data *hapd,
+ struct sta_info *sta)
{
sta->acct_session_id_lo = hapd->acct_session_id_lo++;
if (hapd->acct_session_id_lo == 0) {
@@ -386,10 +411,19 @@ void accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta)
}
-/* Process the RADIUS frames from Accounting Server */
+/**
+ * accounting_receive - Process the RADIUS frames from Accounting Server
+ * @msg: RADIUS response message
+ * @req: RADIUS request message
+ * @shared_secret: RADIUS shared secret
+ * @shared_secret_len: Length of shared_secret in octets
+ * @data: Context data (struct hostapd_data *)
+ * Returns: Processing status
+ */
static RadiusRxResult
accounting_receive(struct radius_msg *msg, struct radius_msg *req,
- u8 *shared_secret, size_t shared_secret_len, void *data)
+ const u8 *shared_secret, size_t shared_secret_len,
+ void *data)
{
if (msg->hdr->code != RADIUS_CODE_ACCOUNTING_RESPONSE) {
printf("Unknown RADIUS message code\n");
@@ -426,7 +460,7 @@ static void accounting_report_state(struct hostapd_data *hapd, int on)
{
printf("Could not add Acct-Terminate-Cause\n");
radius_msg_free(msg);
- free(msg);
+ os_free(msg);
return;
}
@@ -434,6 +468,11 @@ static void accounting_report_state(struct hostapd_data *hapd, int on)
}
+/**
+ * accounting_init: Initialize accounting
+ * @hapd: hostapd BSS data
+ * Returns: 0 on success, -1 on failure
+ */
int accounting_init(struct hostapd_data *hapd)
{
/* Acct-Session-Id should be unique over reboots. If reliable clock is
@@ -450,6 +489,10 @@ int accounting_init(struct hostapd_data *hapd)
}
+/**
+ * accounting_deinit: Deinitilize accounting
+ * @hapd: hostapd BSS data
+ */
void accounting_deinit(struct hostapd_data *hapd)
{
accounting_report_state(hapd, 0);
diff --git a/contrib/hostapd/accounting.h b/hostapd/accounting.h
index ee2ee64e3b02..51e6b4d49870 100644
--- a/contrib/hostapd/accounting.h
+++ b/hostapd/accounting.h
@@ -18,7 +18,6 @@
void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta);
void accounting_sta_interim(struct hostapd_data *hapd, struct sta_info *sta);
void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta);
-void accounting_sta_get_id(struct hostapd_data *hapd, struct sta_info *sta);
int accounting_init(struct hostapd_data *hapd);
void accounting_deinit(struct hostapd_data *hapd);
int accounting_reconfig(struct hostapd_data *hapd,
diff --git a/contrib/hostapd/ap.h b/hostapd/ap.h
index b73c5b47a6fb..98f8ee7449da 100644
--- a/contrib/hostapd/ap.h
+++ b/hostapd/ap.h
@@ -1,6 +1,7 @@
/*
* hostapd / Station table data structures
- * Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2008, Intel Corporation
*
* 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
@@ -15,6 +16,10 @@
#ifndef AP_H
#define AP_H
+#ifdef CONFIG_IEEE80211N
+#include "ieee802_11_defs.h"
+#endif /* CONFIG_IEEE80211N */
+
/* STA flags */
#define WLAN_STA_AUTH BIT(0)
#define WLAN_STA_ASSOC BIT(1)
@@ -26,6 +31,10 @@
#define WLAN_STA_SHORT_PREAMBLE BIT(7)
#define WLAN_STA_PREAUTH BIT(8)
#define WLAN_STA_WME BIT(9)
+#define WLAN_STA_MFP BIT(10)
+#define WLAN_STA_HT BIT(11)
+#define WLAN_STA_WPS BIT(12)
+#define WLAN_STA_MAYBE_WPS BIT(13)
#define WLAN_STA_NONERP BIT(31)
/* Maximum number of supported rates (from both Supported Rates and Extended
@@ -47,6 +56,9 @@ struct sta_info {
unsigned int nonerp_set:1;
unsigned int no_short_slot_time_set:1;
unsigned int no_short_preamble_set:1;
+ unsigned int no_ht_gf_set:1;
+ unsigned int no_ht_set:1;
+ unsigned int ht_20mhz_set:1;
u16 auth_alg;
u8 previous_ap[6];
@@ -82,6 +94,22 @@ struct sta_info {
struct hostapd_ssid *ssid_probe; /* SSID selection based on ProbeReq */
int vlan_id;
+
+#ifdef CONFIG_IEEE80211N
+ struct ht_cap_ie ht_capabilities; /* IEEE 802.11n capabilities */
+#endif /* CONFIG_IEEE80211N */
+
+#ifdef CONFIG_IEEE80211W
+ int sa_query_count; /* number of pending SA Query requests;
+ * 0 = no SA Query in progress */
+ int sa_query_timed_out;
+ u8 *sa_query_trans_id; /* buffer of WLAN_SA_QUERY_TR_ID_LEN *
+ * sa_query_count octets of pending SA Query
+ * transaction identifiers */
+ struct os_time sa_query_start;
+#endif /* CONFIG_IEEE80211W */
+
+ struct wpabuf *wps_ie; /* WPS IE from (Re)Association Request */
};
diff --git a/contrib/hostapd/ap_list.c b/hostapd/ap_list.c
index f2d322125fc8..4f217dc54121 100644
--- a/contrib/hostapd/ap_list.c
+++ b/hostapd/ap_list.c
@@ -1,8 +1,9 @@
/*
* hostapd / AP table
- * Copyright 2002-2003, Jouni Malinen <j@w1.fi>
- * Copyright 2003-2004, Instant802 Networks, Inc.
- * Copyright 2006, Devicescape Software, Inc.
+ * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2004, Instant802 Networks, Inc.
+ * Copyright (c) 2006, Devicescape Software, Inc.
+ * Copyright (c) 2007-2008, Intel Corporation
*
* 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
@@ -107,12 +108,21 @@ static int ap_list_beacon_olbc(struct hostapd_iface *iface, struct ap_info *ap)
}
+#ifdef CONFIG_IEEE80211N
+static int ap_list_beacon_olbc_ht(struct hostapd_iface *iface,
+ struct ap_info *ap)
+{
+ return !ap->ht_support;
+}
+#endif /* CONFIG_IEEE80211N */
+
+
struct ap_info * ap_get_ap(struct hostapd_iface *iface, u8 *ap)
{
struct ap_info *s;
s = iface->ap_hash[STA_HASH(ap)];
- while (s != NULL && memcmp(s->addr, ap, ETH_ALEN) != 0)
+ while (s != NULL && os_memcmp(s->addr, ap, ETH_ALEN) != 0)
s = s->hnext;
return s;
}
@@ -185,13 +195,13 @@ static void ap_ap_hash_del(struct hostapd_iface *iface, struct ap_info *ap)
s = iface->ap_hash[STA_HASH(ap->addr)];
if (s == NULL) return;
- if (memcmp(s->addr, ap->addr, ETH_ALEN) == 0) {
+ if (os_memcmp(s->addr, ap->addr, ETH_ALEN) == 0) {
iface->ap_hash[STA_HASH(ap->addr)] = s->hnext;
return;
}
while (s->hnext != NULL &&
- memcmp(s->hnext->addr, ap->addr, ETH_ALEN) != 0)
+ os_memcmp(s->hnext->addr, ap->addr, ETH_ALEN) != 0)
s = s->hnext;
if (s->hnext != NULL)
s->hnext = s->hnext->hnext;
@@ -208,7 +218,7 @@ static void ap_free_ap(struct hostapd_iface *iface, struct ap_info *ap)
ap_ap_iter_list_del(iface, ap);
iface->num_ap--;
- free(ap);
+ os_free(ap);
}
@@ -251,12 +261,12 @@ static struct ap_info * ap_ap_add(struct hostapd_iface *iface, u8 *addr)
{
struct ap_info *ap;
- ap = wpa_zalloc(sizeof(struct ap_info));
+ ap = os_zalloc(sizeof(struct ap_info));
if (ap == NULL)
return NULL;
/* initialize AP info data */
- memcpy(ap->addr, addr, ETH_ALEN);
+ os_memcpy(ap->addr, addr, ETH_ALEN);
ap_ap_list_add(iface, ap);
iface->num_ap++;
ap_ap_hash_add(iface, ap);
@@ -282,6 +292,7 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
struct ap_info *ap;
int new_ap = 0;
size_t len;
+ int set_beacon = 0;
if (iface->conf->ap_table_max_size < 1)
return;
@@ -303,18 +314,18 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
len = elems->ssid_len;
if (len >= sizeof(ap->ssid))
len = sizeof(ap->ssid) - 1;
- memcpy(ap->ssid, elems->ssid, len);
+ os_memcpy(ap->ssid, elems->ssid, len);
ap->ssid[len] = '\0';
ap->ssid_len = len;
}
- memset(ap->supported_rates, 0, WLAN_SUPP_RATES_MAX);
+ os_memset(ap->supported_rates, 0, WLAN_SUPP_RATES_MAX);
len = 0;
if (elems->supp_rates) {
len = elems->supp_rates_len;
if (len > WLAN_SUPP_RATES_MAX)
len = WLAN_SUPP_RATES_MAX;
- memcpy(ap->supported_rates, elems->supp_rates, len);
+ os_memcpy(ap->supported_rates, elems->supp_rates, len);
}
if (elems->ext_supp_rates) {
int len2;
@@ -322,7 +333,8 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
len2 = WLAN_SUPP_RATES_MAX - len;
else
len2 = elems->ext_supp_rates_len;
- memcpy(ap->supported_rates + len, elems->ext_supp_rates, len2);
+ os_memcpy(ap->supported_rates + len, elems->ext_supp_rates,
+ len2);
}
ap->wpa = elems->wpa_ie != NULL;
@@ -337,6 +349,11 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
else if (fi)
ap->channel = fi->channel;
+ if (elems->ht_capabilities)
+ ap->ht_support = 1;
+ else
+ ap->ht_support = 0;
+
ap->num_beacons++;
time(&ap->last_beacon);
if (fi) {
@@ -357,13 +374,24 @@ void ap_list_process_beacon(struct hostapd_iface *iface,
if (!iface->olbc &&
ap_list_beacon_olbc(iface, ap)) {
- struct hostapd_data *hapd = iface->bss[0];
iface->olbc = 1;
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "OLBC AP detected: " MACSTR " - enable "
- "protection\n", MAC2STR(ap->addr));
- ieee802_11_set_beacons(hapd->iface);
+ wpa_printf(MSG_DEBUG, "OLBC AP detected: " MACSTR " - enable "
+ "protection", MAC2STR(ap->addr));
+ set_beacon++;
}
+
+#ifdef CONFIG_IEEE80211N
+ if (!iface->olbc_ht && ap_list_beacon_olbc_ht(iface, ap)) {
+ iface->olbc_ht = 1;
+ hostapd_ht_operation_update(iface);
+ wpa_printf(MSG_DEBUG, "OLBC HT AP detected: " MACSTR
+ " - enable protection", MAC2STR(ap->addr));
+ set_beacon++;
+ }
+#endif /* CONFIG_IEEE80211N */
+
+ if (set_beacon)
+ ieee802_11_set_beacons(iface);
}
@@ -372,6 +400,7 @@ static void ap_list_timer(void *eloop_ctx, void *timeout_ctx)
struct hostapd_iface *iface = eloop_ctx;
time_t now;
struct ap_info *ap;
+ int set_beacon = 0;
eloop_register_timeout(10, 0, ap_list_timer, iface, NULL);
@@ -395,24 +424,37 @@ static void ap_list_timer(void *eloop_ctx, void *timeout_ctx)
ap_free_ap(iface, ap);
}
- if (iface->olbc) {
+ if (iface->olbc || iface->olbc_ht) {
int olbc = 0;
+ int olbc_ht = 0;
+
ap = iface->ap_list;
- while (ap) {
- if (ap_list_beacon_olbc(iface, ap)) {
+ while (ap && (olbc == 0 || olbc_ht == 0)) {
+ if (ap_list_beacon_olbc(iface, ap))
olbc = 1;
- break;
- }
+#ifdef CONFIG_IEEE80211N
+ if (ap_list_beacon_olbc_ht(iface, ap))
+ olbc_ht = 1;
+#endif /* CONFIG_IEEE80211N */
ap = ap->next;
}
- if (!olbc) {
- struct hostapd_data *hapd = iface->bss[0];
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "OLBC not detected anymore\n");
+ if (!olbc && iface->olbc) {
+ wpa_printf(MSG_DEBUG, "OLBC not detected anymore");
iface->olbc = 0;
- ieee802_11_set_beacons(hapd->iface);
+ set_beacon++;
+ }
+#ifdef CONFIG_IEEE80211N
+ if (!olbc_ht && iface->olbc_ht) {
+ wpa_printf(MSG_DEBUG, "OLBC HT not detected anymore");
+ iface->olbc_ht = 0;
+ hostapd_ht_operation_update(iface);
+ set_beacon++;
}
+#endif /* CONFIG_IEEE80211N */
}
+
+ if (set_beacon)
+ ieee802_11_set_beacons(iface);
}
diff --git a/contrib/hostapd/ap_list.h b/hostapd/ap_list.h
index 668d9096341c..93704f8bb612 100644
--- a/contrib/hostapd/ap_list.h
+++ b/hostapd/ap_list.h
@@ -1,8 +1,9 @@
/*
* hostapd / AP table
- * Copyright 2002-2003, Jouni Malinen <j@w1.fi>
- * Copyright 2003-2004, Instant802 Networks, Inc.
- * Copyright 2006, Devicescape Software, Inc.
+ * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2004, Instant802 Networks, Inc.
+ * Copyright (c) 2006, Devicescape Software, Inc.
+ * Copyright (c) 2007-2008, Intel Corporation
*
* 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
@@ -43,6 +44,8 @@ struct ap_info {
int datarate; /* in 100 kbps */
int ssi_signal;
+ int ht_support;
+
unsigned int num_beacons; /* number of beacon frames received */
time_t last_beacon;
diff --git a/contrib/hostapd/beacon.c b/hostapd/beacon.c
index 7af2bc1754e2..31323e864b70 100644
--- a/contrib/hostapd/beacon.c
+++ b/hostapd/beacon.c
@@ -2,6 +2,8 @@
* hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
* Copyright (c) 2002-2004, Instant802 Networks, Inc.
* Copyright (c) 2005-2006, Devicescape Software, Inc.
+ * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2008, Intel Corporation
*
* 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
@@ -25,14 +27,14 @@
#include "hw_features.h"
#include "driver.h"
#include "sta_info.h"
-#include "ieee802_11h.h"
+#include "wps_hostapd.h"
static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
{
u8 erp = 0;
- if (hapd->iface == NULL || hapd->iface->current_mode == NULL ||
+ if (hapd->iface->current_mode == NULL ||
hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
return 0;
@@ -72,7 +74,7 @@ static u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid)
static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
{
- if (hapd->iface == NULL || hapd->iface->current_mode == NULL ||
+ if (hapd->iface->current_mode == NULL ||
hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
return eid;
@@ -94,27 +96,78 @@ static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
}
+static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
+ struct hostapd_channel_data *start,
+ struct hostapd_channel_data *prev)
+{
+ if (end - pos < 3)
+ return pos;
+
+ /* first channel number */
+ *pos++ = start->chan;
+ /* number of channels */
+ *pos++ = (prev->chan - start->chan) / chan_spacing + 1;
+ /* maximum transmit power level */
+ *pos++ = start->max_tx_power;
+
+ return pos;
+}
+
+
static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
int max_len)
{
- int left;
u8 *pos = eid;
-
- if ((!hapd->iconf->ieee80211d && !hapd->iface->dfs_enable) ||
- max_len < 6)
+ u8 *end = eid + max_len;
+ int i;
+ struct hostapd_hw_modes *mode;
+ struct hostapd_channel_data *start, *prev;
+ int chan_spacing = 1;
+
+ if (!hapd->iconf->ieee80211d || max_len < 6 ||
+ hapd->iface->current_mode == NULL)
return eid;
*pos++ = WLAN_EID_COUNTRY;
pos++; /* length will be set later */
- memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
+ os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
pos += 3;
- left = max_len - 3;
+
+ mode = hapd->iface->current_mode;
+ if (mode->mode == HOSTAPD_MODE_IEEE80211A)
+ chan_spacing = 4;
+
+ start = prev = NULL;
+ for (i = 0; i < mode->num_channels; i++) {
+ struct hostapd_channel_data *chan = &mode->channels[i];
+ if (chan->flag & HOSTAPD_CHAN_DISABLED)
+ continue;
+ if (start && prev &&
+ prev->chan + chan_spacing == chan->chan &&
+ start->max_tx_power == chan->max_tx_power) {
+ prev = chan;
+ continue; /* can use same entry */
+ }
+
+ if (start) {
+ pos = hostapd_eid_country_add(pos, end, chan_spacing,
+ start, prev);
+ start = NULL;
+ }
+
+ /* Start new group */
+ start = prev = chan;
+ }
+
+ if (start) {
+ pos = hostapd_eid_country_add(pos, end, chan_spacing,
+ start, prev);
+ }
if ((pos - eid) & 1) {
- if (left < 1)
+ if (end - pos < 1)
return eid;
*pos++ = 0; /* pad for 16-bit alignment */
- left--;
}
eid[1] = (pos - eid) - 2;
@@ -123,45 +176,6 @@ static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
}
-static u8 * hostapd_eid_power_constraint(struct hostapd_data *hapd, u8 *eid)
-
-{
- if (!hapd->iface->dfs_enable)
- return eid;
- *eid++ = WLAN_EID_PWR_CONSTRAINT;
- *eid++ = 1;
- *eid++ = hapd->iface->pwr_const;
- return eid;
-}
-
-
-static u8 * hostapd_eid_tpc_report(struct hostapd_data *hapd, u8 *eid)
-
-{
- if (!hapd->iface->dfs_enable)
- return eid;
- *eid++ = WLAN_EID_TPC_REPORT;
- *eid++ = 2;
- *eid++ = hapd->iface->tx_power; /* TX POWER */
- *eid++ = 0; /* Link Margin */
- return eid;
-}
-
-static u8 * hostapd_eid_channel_switch(struct hostapd_data *hapd, u8 *eid)
-
-{
- if (!hapd->iface->dfs_enable || !hapd->iface->channel_switch)
- return eid;
- *eid++ = WLAN_EID_CHANNEL_SWITCH;
- *eid++ = 3;
- *eid++ = CHAN_SWITCH_MODE_QUIET;
- *eid++ = hapd->iface->channel_switch; /* New channel */
- /* 0 - very soon; 1 - before next TBTT; num - after num beacons */
- *eid++ = 0;
- return eid;
-}
-
-
static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len,
struct sta_info *sta)
{
@@ -172,7 +186,7 @@ static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len,
if (ie == NULL || ielen > len)
return eid;
- memcpy(eid, ie, ielen);
+ os_memcpy(eid, ie, ielen);
return eid + ielen;
}
@@ -183,21 +197,21 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
struct ieee80211_mgmt *resp;
struct ieee802_11_elems elems;
char *ssid;
- u8 *pos, *epos;
- size_t ssid_len;
+ u8 *pos, *epos, *ie;
+ size_t ssid_len, ie_len;
struct sta_info *sta = NULL;
+ ie = mgmt->u.probe_req.variable;
+ ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
+
+ hostapd_wps_probe_req_rx(hapd, mgmt->sa, ie, ie_len);
+
if (!hapd->iconf->send_probe_response)
return;
- if (ieee802_11_parse_elems(hapd, mgmt->u.probe_req.variable,
- len - (IEEE80211_HDRLEN +
- sizeof(mgmt->u.probe_req)), &elems,
- 0)
- == ParseFailed) {
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "Could not parse ProbeReq from " MACSTR "\n",
- MAC2STR(mgmt->sa));
+ if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
+ wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR,
+ MAC2STR(mgmt->sa));
return;
}
@@ -205,15 +219,15 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
ssid_len = 0;
if ((!elems.ssid || !elems.supp_rates)) {
- printf("STA " MACSTR " sent probe request without SSID or "
- "supported rates element\n", MAC2STR(mgmt->sa));
+ wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request "
+ "without SSID or supported rates element",
+ MAC2STR(mgmt->sa));
return;
}
if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0) {
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS,
- "Probe Request from " MACSTR " for broadcast "
- "SSID ignored\n", MAC2STR(mgmt->sa));
+ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
+ "broadcast SSID ignored", MAC2STR(mgmt->sa));
return;
}
@@ -221,7 +235,8 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
if (elems.ssid_len == 0 ||
(elems.ssid_len == hapd->conf->ssid.ssid_len &&
- memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) == 0)) {
+ os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) ==
+ 0)) {
ssid = hapd->conf->ssid.ssid;
ssid_len = hapd->conf->ssid.ssid_len;
if (sta)
@@ -229,29 +244,31 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
}
if (!ssid) {
- if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS)) {
- printf("Probe Request from " MACSTR " for foreign "
- "SSID '", MAC2STR(mgmt->sa));
- ieee802_11_print_ssid(elems.ssid, elems.ssid_len);
- printf("'\n");
+ if (!(mgmt->da[0] & 0x01)) {
+ char ssid_txt[33];
+ ieee802_11_print_ssid(ssid_txt, elems.ssid,
+ elems.ssid_len);
+ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
+ " for foreign SSID '%s'",
+ MAC2STR(mgmt->sa), ssid_txt);
}
return;
}
/* TODO: verify that supp_rates contains at least one matching rate
* with AP configuration */
-#define MAX_PROBERESP_LEN 512
- resp = wpa_zalloc(MAX_PROBERESP_LEN);
+#define MAX_PROBERESP_LEN 768
+ resp = os_zalloc(MAX_PROBERESP_LEN);
if (resp == NULL)
return;
epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
WLAN_FC_STYPE_PROBE_RESP);
- memcpy(resp->da, mgmt->sa, ETH_ALEN);
- memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
+ os_memcpy(resp->da, mgmt->sa, ETH_ALEN);
+ os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
- memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
+ os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
resp->u.probe_resp.beacon_int =
host_to_le16(hapd->iconf->beacon_int);
@@ -262,7 +279,7 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
pos = resp->u.probe_resp.variable;
*pos++ = WLAN_EID_SSID;
*pos++ = ssid_len;
- memcpy(pos, ssid, ssid_len);
+ os_memcpy(pos, ssid, ssid_len);
pos += ssid_len;
/* Supported rates */
@@ -273,9 +290,6 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
pos = hostapd_eid_country(hapd, pos, epos - pos);
- pos = hostapd_eid_power_constraint(hapd, pos);
- pos = hostapd_eid_tpc_report(hapd, pos);
-
/* ERP Information element */
pos = hostapd_eid_erp_info(hapd, pos);
@@ -285,18 +299,27 @@ void handle_probe_req(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
pos = hostapd_eid_wpa(hapd, pos, epos - pos, sta);
/* Wi-Fi Wireless Multimedia Extensions */
- if (hapd->conf->wme_enabled)
- pos = hostapd_eid_wme(hapd, pos);
+ pos = hostapd_eid_wme(hapd, pos);
+
+ pos = hostapd_eid_ht_capabilities_info(hapd, pos);
+ pos = hostapd_eid_ht_operation(hapd, pos);
+
+#ifdef CONFIG_WPS
+ if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
+ os_memcpy(pos, hapd->wps_probe_resp_ie,
+ hapd->wps_probe_resp_ie_len);
+ pos += hapd->wps_probe_resp_ie_len;
+ }
+#endif /* CONFIG_WPS */
if (hostapd_send_mgmt_frame(hapd, resp, pos - (u8 *) resp, 0) < 0)
perror("handle_probe_req: send");
- free(resp);
+ os_free(resp);
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MSGDUMPS, "STA " MACSTR
- " sent probe request for %s SSID\n",
- MAC2STR(mgmt->sa), elems.ssid_len == 0 ? "broadcast" :
- "our");
+ wpa_printf(MSG_MSGDUMP, "STA " MACSTR " sent probe request for %s "
+ "SSID", MAC2STR(mgmt->sa),
+ elems.ssid_len == 0 ? "broadcast" : "our");
}
@@ -311,23 +334,23 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
ERP_INFO_USE_PROTECTION) ? 1 : 0);
#define BEACON_HEAD_BUF_SIZE 256
-#define BEACON_TAIL_BUF_SIZE 256
- head = wpa_zalloc(BEACON_HEAD_BUF_SIZE);
- tailpos = tail = malloc(BEACON_TAIL_BUF_SIZE);
+#define BEACON_TAIL_BUF_SIZE 512
+ head = os_zalloc(BEACON_HEAD_BUF_SIZE);
+ tailpos = tail = os_malloc(BEACON_TAIL_BUF_SIZE);
if (head == NULL || tail == NULL) {
- printf("Failed to set beacon data\n");
- free(head);
- free(tail);
+ wpa_printf(MSG_ERROR, "Failed to set beacon data");
+ os_free(head);
+ os_free(tail);
return;
}
head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
WLAN_FC_STYPE_BEACON);
head->duration = host_to_le16(0);
- memset(head->da, 0xff, ETH_ALEN);
+ os_memset(head->da, 0xff, ETH_ALEN);
- memcpy(head->sa, hapd->own_addr, ETH_ALEN);
- memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
+ os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
+ os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
head->u.beacon.beacon_int =
host_to_le16(hapd->iconf->beacon_int);
@@ -341,13 +364,14 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
if (hapd->conf->ignore_broadcast_ssid == 2) {
/* clear the data, but keep the correct length of the SSID */
*pos++ = hapd->conf->ssid.ssid_len;
- memset(pos, 0, hapd->conf->ssid.ssid_len);
+ os_memset(pos, 0, hapd->conf->ssid.ssid_len);
pos += hapd->conf->ssid.ssid_len;
} else if (hapd->conf->ignore_broadcast_ssid) {
*pos++ = 0; /* empty SSID */
} else {
*pos++ = hapd->conf->ssid.ssid_len;
- memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
+ os_memcpy(pos, hapd->conf->ssid.ssid,
+ hapd->conf->ssid.ssid_len);
pos += hapd->conf->ssid.ssid_len;
}
@@ -362,10 +386,6 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
tailpos = hostapd_eid_country(hapd, tailpos,
tail + BEACON_TAIL_BUF_SIZE - tailpos);
- tailpos = hostapd_eid_power_constraint(hapd, tailpos);
- tailpos = hostapd_eid_channel_switch(hapd, tailpos);
- tailpos = hostapd_eid_tpc_report(hapd, tailpos);
-
/* ERP Information element */
tailpos = hostapd_eid_erp_info(hapd, tailpos);
@@ -376,36 +396,64 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
tailpos, NULL);
/* Wi-Fi Wireless Multimedia Extensions */
- if (hapd->conf->wme_enabled)
- tailpos = hostapd_eid_wme(hapd, tailpos);
+ tailpos = hostapd_eid_wme(hapd, tailpos);
+
+#ifdef CONFIG_IEEE80211N
+ if (hapd->iconf->ieee80211n) {
+ u8 *ht_capab, *ht_oper;
+ ht_capab = tailpos;
+ tailpos = hostapd_eid_ht_capabilities_info(hapd, tailpos);
+
+ ht_oper = tailpos;
+ tailpos = hostapd_eid_ht_operation(hapd, tailpos);
+
+ if (tailpos > ht_oper && ht_oper > ht_capab &&
+ hostapd_set_ht_params(hapd->conf->iface, hapd,
+ ht_capab + 2, ht_capab[1],
+ ht_oper + 2, ht_oper[1])) {
+ wpa_printf(MSG_ERROR, "Could not set HT capabilities "
+ "for kernel driver");
+ }
+ }
+#endif /* CONFIG_IEEE80211N */
+
+#ifdef CONFIG_WPS
+ if (hapd->conf->wps_state && hapd->wps_beacon_ie) {
+ os_memcpy(tailpos, hapd->wps_beacon_ie,
+ hapd->wps_beacon_ie_len);
+ tailpos += hapd->wps_beacon_ie_len;
+ }
+#endif /* CONFIG_WPS */
tail_len = tailpos > tail ? tailpos - tail : 0;
if (hostapd_set_beacon(hapd->conf->iface, hapd, (u8 *) head, head_len,
tail, tail_len))
- printf("Failed to set beacon head/tail\n");
+ wpa_printf(MSG_ERROR, "Failed to set beacon head/tail");
- free(tail);
- free(head);
+ os_free(tail);
+ os_free(head);
if (hostapd_set_cts_protect(hapd, cts_protection))
- printf("Failed to set CTS protect in kernel driver\n");
+ wpa_printf(MSG_ERROR, "Failed to set CTS protect in kernel "
+ "driver");
- if (hapd->iface && hapd->iface->current_mode &&
+ if (hapd->iface->current_mode &&
hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
hostapd_set_short_slot_time(hapd,
hapd->iface->num_sta_no_short_slot_time
> 0 ? 0 : 1))
- printf("Failed to set Short Slot Time option in kernel "
- "driver\n");
+ wpa_printf(MSG_ERROR, "Failed to set Short Slot Time option "
+ "in kernel driver");
- if (hapd->iface && hapd->iface->num_sta_no_short_preamble == 0 &&
+ if (hapd->iface->num_sta_no_short_preamble == 0 &&
hapd->iconf->preamble == SHORT_PREAMBLE)
preamble = SHORT_PREAMBLE;
else
preamble = LONG_PREAMBLE;
if (hostapd_set_preamble(hapd, preamble))
- printf("Could not set preamble for kernel driver\n");
+ wpa_printf(MSG_ERROR, "Could not set preamble for kernel "
+ "driver");
}
diff --git a/contrib/hostapd/beacon.h b/hostapd/beacon.h
index 18e0da2e89f6..18e0da2e89f6 100644
--- a/contrib/hostapd/beacon.h
+++ b/hostapd/beacon.h
diff --git a/hostapd/config.c b/hostapd/config.c
new file mode 100644
index 000000000000..6ad14d2d4cfa
--- /dev/null
+++ b/hostapd/config.c
@@ -0,0 +1,2617 @@
+/*
+ * hostapd / Configuration file
+ * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2008, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+#ifndef CONFIG_NATIVE_WINDOWS
+#include <grp.h>
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+#include "hostapd.h"
+#include "driver.h"
+#include "sha1.h"
+#include "eap_server/eap.h"
+#include "radius/radius_client.h"
+#include "wpa_common.h"
+#include "wpa.h"
+#include "uuid.h"
+#include "eap_common/eap_wsc_common.h"
+
+
+#define MAX_STA_COUNT 2007
+
+extern struct wpa_driver_ops *hostapd_drivers[];
+
+
+static int hostapd_config_read_vlan_file(struct hostapd_bss_config *bss,
+ const char *fname)
+{
+ FILE *f;
+ char buf[128], *pos, *pos2;
+ int line = 0, vlan_id;
+ struct hostapd_vlan *vlan;
+
+ f = fopen(fname, "r");
+ if (!f) {
+ wpa_printf(MSG_ERROR, "VLAN file '%s' not readable.", fname);
+ return -1;
+ }
+
+ while (fgets(buf, sizeof(buf), f)) {
+ line++;
+
+ if (buf[0] == '#')
+ continue;
+ pos = buf;
+ while (*pos != '\0') {
+ if (*pos == '\n') {
+ *pos = '\0';
+ break;
+ }
+ pos++;
+ }
+ if (buf[0] == '\0')
+ continue;
+
+ if (buf[0] == '*') {
+ vlan_id = VLAN_ID_WILDCARD;
+ pos = buf + 1;
+ } else {
+ vlan_id = strtol(buf, &pos, 10);
+ if (buf == pos || vlan_id < 1 ||
+ vlan_id > MAX_VLAN_ID) {
+ wpa_printf(MSG_ERROR, "Invalid VLAN ID at "
+ "line %d in '%s'", line, fname);
+ fclose(f);
+ return -1;
+ }
+ }
+
+ while (*pos == ' ' || *pos == '\t')
+ pos++;
+ pos2 = pos;
+ while (*pos2 != ' ' && *pos2 != '\t' && *pos2 != '\0')
+ pos2++;
+ *pos2 = '\0';
+ if (*pos == '\0' || os_strlen(pos) > IFNAMSIZ) {
+ wpa_printf(MSG_ERROR, "Invalid VLAN ifname at line %d "
+ "in '%s'", line, fname);
+ fclose(f);
+ return -1;
+ }
+
+ vlan = os_malloc(sizeof(*vlan));
+ if (vlan == NULL) {
+ wpa_printf(MSG_ERROR, "Out of memory while reading "
+ "VLAN interfaces from '%s'", fname);
+ fclose(f);
+ return -1;
+ }
+
+ os_memset(vlan, 0, sizeof(*vlan));
+ vlan->vlan_id = vlan_id;
+ os_strlcpy(vlan->ifname, pos, sizeof(vlan->ifname));
+ if (bss->vlan_tail)
+ bss->vlan_tail->next = vlan;
+ else
+ bss->vlan = vlan;
+ bss->vlan_tail = vlan;
+ }
+
+ fclose(f);
+
+ return 0;
+}
+
+
+static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
+{
+ struct hostapd_vlan *vlan, *prev;
+
+ vlan = bss->vlan;
+ prev = NULL;
+ while (vlan) {
+ prev = vlan;
+ vlan = vlan->next;
+ os_free(prev);
+ }
+
+ bss->vlan = NULL;
+}
+
+
+/* convert floats with one decimal place to value*10 int, i.e.,
+ * "1.5" will return 15 */
+static int hostapd_config_read_int10(const char *value)
+{
+ int i, d;
+ char *pos;
+
+ i = atoi(value);
+ pos = os_strchr(value, '.');
+ d = 0;
+ if (pos) {
+ pos++;
+ if (*pos >= '0' && *pos <= '9')
+ d = *pos - '0';
+ }
+
+ return i * 10 + d;
+}
+
+
+static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
+{
+ bss->logger_syslog_level = HOSTAPD_LEVEL_INFO;
+ bss->logger_stdout_level = HOSTAPD_LEVEL_INFO;
+ bss->logger_syslog = (unsigned int) -1;
+ bss->logger_stdout = (unsigned int) -1;
+
+ bss->auth_algs = WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED;
+
+ bss->wep_rekeying_period = 300;
+ /* use key0 in individual key and key1 in broadcast key */
+ bss->broadcast_key_idx_min = 1;
+ bss->broadcast_key_idx_max = 2;
+ bss->eap_reauth_period = 3600;
+
+ bss->wpa_group_rekey = 600;
+ bss->wpa_gmk_rekey = 86400;
+ bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
+ bss->wpa_pairwise = WPA_CIPHER_TKIP;
+ bss->wpa_group = WPA_CIPHER_TKIP;
+ bss->rsn_pairwise = 0;
+
+ bss->max_num_sta = MAX_STA_COUNT;
+
+ bss->dtim_period = 2;
+
+ bss->radius_server_auth_port = 1812;
+ bss->ap_max_inactivity = AP_MAX_INACTIVITY;
+ bss->eapol_version = EAPOL_VERSION;
+
+ bss->max_listen_interval = 65535;
+
+#ifdef CONFIG_IEEE80211W
+ bss->assoc_sa_query_max_timeout = 1000;
+ bss->assoc_sa_query_retry_timeout = 201;
+#endif /* CONFIG_IEEE80211W */
+#ifdef EAP_FAST
+ /* both anonymous and authenticated provisioning */
+ bss->eap_fast_prov = 3;
+ bss->pac_key_lifetime = 7 * 24 * 60 * 60;
+ bss->pac_key_refresh_time = 1 * 24 * 60 * 60;
+#endif /* EAP_FAST */
+}
+
+
+static struct hostapd_config * hostapd_config_defaults(void)
+{
+ struct hostapd_config *conf;
+ struct hostapd_bss_config *bss;
+ int i;
+ const int aCWmin = 15, aCWmax = 1024;
+ const struct hostapd_wme_ac_params ac_bk =
+ { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
+ const struct hostapd_wme_ac_params ac_be =
+ { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
+ const struct hostapd_wme_ac_params ac_vi = /* video traffic */
+ { aCWmin >> 1, aCWmin, 2, 3000 / 32, 1 };
+ const struct hostapd_wme_ac_params ac_vo = /* voice traffic */
+ { aCWmin >> 2, aCWmin >> 1, 2, 1500 / 32, 1 };
+
+ conf = os_zalloc(sizeof(*conf));
+ bss = os_zalloc(sizeof(*bss));
+ if (conf == NULL || bss == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to allocate memory for "
+ "configuration data.");
+ os_free(conf);
+ os_free(bss);
+ return NULL;
+ }
+
+ /* set default driver based on configuration */
+ conf->driver = hostapd_drivers[0];
+ if (conf->driver == NULL) {
+ wpa_printf(MSG_ERROR, "No driver wrappers registered!");
+ os_free(conf);
+ os_free(bss);
+ return NULL;
+ }
+
+ bss->radius = os_zalloc(sizeof(*bss->radius));
+ if (bss->radius == NULL) {
+ os_free(conf);
+ os_free(bss);
+ return NULL;
+ }
+
+ hostapd_config_defaults_bss(bss);
+
+ conf->num_bss = 1;
+ conf->bss = bss;
+
+ conf->beacon_int = 100;
+ conf->rts_threshold = -1; /* use driver default: 2347 */
+ conf->fragm_threshold = -1; /* user driver default: 2346 */
+ conf->send_probe_response = 1;
+ conf->bridge_packets = INTERNAL_BRIDGE_DO_NOT_CONTROL;
+
+ for (i = 0; i < NUM_TX_QUEUES; i++)
+ conf->tx_queue[i].aifs = -1; /* use hw default */
+
+ conf->wme_ac_params[0] = ac_be;
+ conf->wme_ac_params[1] = ac_bk;
+ conf->wme_ac_params[2] = ac_vi;
+ conf->wme_ac_params[3] = ac_vo;
+
+#ifdef CONFIG_IEEE80211N
+ conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED;
+#endif /* CONFIG_IEEE80211N */
+
+ return conf;
+}
+
+
+int hostapd_mac_comp(const void *a, const void *b)
+{
+ return os_memcmp(a, b, sizeof(macaddr));
+}
+
+
+int hostapd_mac_comp_empty(const void *a)
+{
+ macaddr empty = { 0 };
+ return os_memcmp(a, empty, sizeof(macaddr));
+}
+
+
+static int hostapd_acl_comp(const void *a, const void *b)
+{
+ const struct mac_acl_entry *aa = a;
+ const struct mac_acl_entry *bb = b;
+ return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
+}
+
+
+static int hostapd_config_read_maclist(const char *fname,
+ struct mac_acl_entry **acl, int *num)
+{
+ FILE *f;
+ char buf[128], *pos;
+ int line = 0;
+ u8 addr[ETH_ALEN];
+ struct mac_acl_entry *newacl;
+ int vlan_id;
+
+ if (!fname)
+ return 0;
+
+ f = fopen(fname, "r");
+ if (!f) {
+ wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname);
+ return -1;
+ }
+
+ while (fgets(buf, sizeof(buf), f)) {
+ line++;
+
+ if (buf[0] == '#')
+ continue;
+ pos = buf;
+ while (*pos != '\0') {
+ if (*pos == '\n') {
+ *pos = '\0';
+ break;
+ }
+ pos++;
+ }
+ if (buf[0] == '\0')
+ continue;
+
+ if (hwaddr_aton(buf, addr)) {
+ wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at "
+ "line %d in '%s'", buf, line, fname);
+ fclose(f);
+ return -1;
+ }
+
+ vlan_id = 0;
+ pos = buf;
+ while (*pos != '\0' && *pos != ' ' && *pos != '\t')
+ pos++;
+ while (*pos == ' ' || *pos == '\t')
+ pos++;
+ if (*pos != '\0')
+ vlan_id = atoi(pos);
+
+ newacl = os_realloc(*acl, (*num + 1) * sizeof(**acl));
+ if (newacl == NULL) {
+ wpa_printf(MSG_ERROR, "MAC list reallocation failed");
+ fclose(f);
+ return -1;
+ }
+
+ *acl = newacl;
+ os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
+ (*acl)[*num].vlan_id = vlan_id;
+ (*num)++;
+ }
+
+ fclose(f);
+
+ qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
+
+ return 0;
+}
+
+
+static int hostapd_config_read_wpa_psk(const char *fname,
+ struct hostapd_ssid *ssid)
+{
+ FILE *f;
+ char buf[128], *pos;
+ int line = 0, ret = 0, len, ok;
+ u8 addr[ETH_ALEN];
+ struct hostapd_wpa_psk *psk;
+
+ if (!fname)
+ return 0;
+
+ f = fopen(fname, "r");
+ if (!f) {
+ wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname);
+ return -1;
+ }
+
+ while (fgets(buf, sizeof(buf), f)) {
+ line++;
+
+ if (buf[0] == '#')
+ continue;
+ pos = buf;
+ while (*pos != '\0') {
+ if (*pos == '\n') {
+ *pos = '\0';
+ break;
+ }
+ pos++;
+ }
+ if (buf[0] == '\0')
+ continue;
+
+ if (hwaddr_aton(buf, addr)) {
+ wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on "
+ "line %d in '%s'", buf, line, fname);
+ ret = -1;
+ break;
+ }
+
+ psk = os_zalloc(sizeof(*psk));
+ if (psk == NULL) {
+ wpa_printf(MSG_ERROR, "WPA PSK allocation failed");
+ ret = -1;
+ break;
+ }
+ if (is_zero_ether_addr(addr))
+ psk->group = 1;
+ else
+ os_memcpy(psk->addr, addr, ETH_ALEN);
+
+ pos = buf + 17;
+ if (*pos == '\0') {
+ wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'",
+ line, fname);
+ os_free(psk);
+ ret = -1;
+ break;
+ }
+ pos++;
+
+ ok = 0;
+ len = os_strlen(pos);
+ if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0)
+ ok = 1;
+ else if (len >= 8 && len < 64) {
+ pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len,
+ 4096, psk->psk, PMK_LEN);
+ ok = 1;
+ }
+ if (!ok) {
+ wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in "
+ "'%s'", pos, line, fname);
+ os_free(psk);
+ ret = -1;
+ break;
+ }
+
+ psk->next = ssid->wpa_psk;
+ ssid->wpa_psk = psk;
+ }
+
+ fclose(f);
+
+ return ret;
+}
+
+
+int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf)
+{
+ struct hostapd_ssid *ssid = &conf->ssid;
+
+ if (ssid->wpa_passphrase != NULL) {
+ if (ssid->wpa_psk != NULL) {
+ wpa_printf(MSG_ERROR, "Warning: both WPA PSK and "
+ "passphrase set. Using passphrase.");
+ os_free(ssid->wpa_psk);
+ }
+ ssid->wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
+ if (ssid->wpa_psk == NULL) {
+ wpa_printf(MSG_ERROR, "Unable to alloc space for PSK");
+ return -1;
+ }
+ wpa_hexdump_ascii(MSG_DEBUG, "SSID",
+ (u8 *) ssid->ssid, ssid->ssid_len);
+ wpa_hexdump_ascii(MSG_DEBUG, "PSK (ASCII passphrase)",
+ (u8 *) ssid->wpa_passphrase,
+ os_strlen(ssid->wpa_passphrase));
+ pbkdf2_sha1(ssid->wpa_passphrase,
+ ssid->ssid, ssid->ssid_len,
+ 4096, ssid->wpa_psk->psk, PMK_LEN);
+ wpa_hexdump(MSG_DEBUG, "PSK (from passphrase)",
+ ssid->wpa_psk->psk, PMK_LEN);
+ ssid->wpa_psk->group = 1;
+ }
+
+ if (ssid->wpa_psk_file) {
+ if (hostapd_config_read_wpa_psk(ssid->wpa_psk_file,
+ &conf->ssid))
+ return -1;
+ }
+
+ return 0;
+}
+
+
+#ifdef EAP_SERVER
+static int hostapd_config_read_eap_user(const char *fname,
+ struct hostapd_bss_config *conf)
+{
+ FILE *f;
+ char buf[512], *pos, *start, *pos2;
+ int line = 0, ret = 0, num_methods;
+ struct hostapd_eap_user *user, *tail = NULL;
+
+ if (!fname)
+ return 0;
+
+ f = fopen(fname, "r");
+ if (!f) {
+ wpa_printf(MSG_ERROR, "EAP user file '%s' not found.", fname);
+ return -1;
+ }
+
+ /* Lines: "user" METHOD,METHOD2 "password" (password optional) */
+ while (fgets(buf, sizeof(buf), f)) {
+ line++;
+
+ if (buf[0] == '#')
+ continue;
+ pos = buf;
+ while (*pos != '\0') {
+ if (*pos == '\n') {
+ *pos = '\0';
+ break;
+ }
+ pos++;
+ }
+ if (buf[0] == '\0')
+ continue;
+
+ user = NULL;
+
+ if (buf[0] != '"' && buf[0] != '*') {
+ wpa_printf(MSG_ERROR, "Invalid EAP identity (no \" in "
+ "start) on line %d in '%s'", line, fname);
+ goto failed;
+ }
+
+ user = os_zalloc(sizeof(*user));
+ if (user == NULL) {
+ wpa_printf(MSG_ERROR, "EAP user allocation failed");
+ goto failed;
+ }
+ user->force_version = -1;
+
+ if (buf[0] == '*') {
+ pos = buf;
+ } else {
+ pos = buf + 1;
+ start = pos;
+ while (*pos != '"' && *pos != '\0')
+ pos++;
+ if (*pos == '\0') {
+ wpa_printf(MSG_ERROR, "Invalid EAP identity "
+ "(no \" in end) on line %d in '%s'",
+ line, fname);
+ goto failed;
+ }
+
+ user->identity = os_malloc(pos - start);
+ if (user->identity == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to allocate "
+ "memory for EAP identity");
+ goto failed;
+ }
+ os_memcpy(user->identity, start, pos - start);
+ user->identity_len = pos - start;
+
+ if (pos[0] == '"' && pos[1] == '*') {
+ user->wildcard_prefix = 1;
+ pos++;
+ }
+ }
+ pos++;
+ while (*pos == ' ' || *pos == '\t')
+ pos++;
+
+ if (*pos == '\0') {
+ wpa_printf(MSG_ERROR, "No EAP method on line %d in "
+ "'%s'", line, fname);
+ goto failed;
+ }
+
+ start = pos;
+ while (*pos != ' ' && *pos != '\t' && *pos != '\0')
+ pos++;
+ if (*pos == '\0') {
+ pos = NULL;
+ } else {
+ *pos = '\0';
+ pos++;
+ }
+ num_methods = 0;
+ while (*start) {
+ char *pos3 = os_strchr(start, ',');
+ if (pos3) {
+ *pos3++ = '\0';
+ }
+ user->methods[num_methods].method =
+ eap_server_get_type(
+ start,
+ &user->methods[num_methods].vendor);
+ if (user->methods[num_methods].vendor ==
+ EAP_VENDOR_IETF &&
+ user->methods[num_methods].method == EAP_TYPE_NONE)
+ {
+ if (os_strcmp(start, "TTLS-PAP") == 0) {
+ user->ttls_auth |= EAP_TTLS_AUTH_PAP;
+ goto skip_eap;
+ }
+ if (os_strcmp(start, "TTLS-CHAP") == 0) {
+ user->ttls_auth |= EAP_TTLS_AUTH_CHAP;
+ goto skip_eap;
+ }
+ if (os_strcmp(start, "TTLS-MSCHAP") == 0) {
+ user->ttls_auth |=
+ EAP_TTLS_AUTH_MSCHAP;
+ goto skip_eap;
+ }
+ if (os_strcmp(start, "TTLS-MSCHAPV2") == 0) {
+ user->ttls_auth |=
+ EAP_TTLS_AUTH_MSCHAPV2;
+ goto skip_eap;
+ }
+ wpa_printf(MSG_ERROR, "Unsupported EAP type "
+ "'%s' on line %d in '%s'",
+ start, line, fname);
+ goto failed;
+ }
+
+ num_methods++;
+ if (num_methods >= EAP_USER_MAX_METHODS)
+ break;
+ skip_eap:
+ if (pos3 == NULL)
+ break;
+ start = pos3;
+ }
+ if (num_methods == 0 && user->ttls_auth == 0) {
+ wpa_printf(MSG_ERROR, "No EAP types configured on "
+ "line %d in '%s'", line, fname);
+ goto failed;
+ }
+
+ if (pos == NULL)
+ goto done;
+
+ while (*pos == ' ' || *pos == '\t')
+ pos++;
+ if (*pos == '\0')
+ goto done;
+
+ if (os_strncmp(pos, "[ver=0]", 7) == 0) {
+ user->force_version = 0;
+ goto done;
+ }
+
+ if (os_strncmp(pos, "[ver=1]", 7) == 0) {
+ user->force_version = 1;
+ goto done;
+ }
+
+ if (os_strncmp(pos, "[2]", 3) == 0) {
+ user->phase2 = 1;
+ goto done;
+ }
+
+ if (*pos == '"') {
+ pos++;
+ start = pos;
+ while (*pos != '"' && *pos != '\0')
+ pos++;
+ if (*pos == '\0') {
+ wpa_printf(MSG_ERROR, "Invalid EAP password "
+ "(no \" in end) on line %d in '%s'",
+ line, fname);
+ goto failed;
+ }
+
+ user->password = os_malloc(pos - start);
+ if (user->password == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to allocate "
+ "memory for EAP password");
+ goto failed;
+ }
+ os_memcpy(user->password, start, pos - start);
+ user->password_len = pos - start;
+
+ pos++;
+ } else if (os_strncmp(pos, "hash:", 5) == 0) {
+ pos += 5;
+ pos2 = pos;
+ while (*pos2 != '\0' && *pos2 != ' ' &&
+ *pos2 != '\t' && *pos2 != '#')
+ pos2++;
+ if (pos2 - pos != 32) {
+ wpa_printf(MSG_ERROR, "Invalid password hash "
+ "on line %d in '%s'", line, fname);
+ goto failed;
+ }
+ user->password = os_malloc(16);
+ if (user->password == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to allocate "
+ "memory for EAP password hash");
+ goto failed;
+ }
+ if (hexstr2bin(pos, user->password, 16) < 0) {
+ wpa_printf(MSG_ERROR, "Invalid hash password "
+ "on line %d in '%s'", line, fname);
+ goto failed;
+ }
+ user->password_len = 16;
+ user->password_hash = 1;
+ pos = pos2;
+ } else {
+ pos2 = pos;
+ while (*pos2 != '\0' && *pos2 != ' ' &&
+ *pos2 != '\t' && *pos2 != '#')
+ pos2++;
+ if ((pos2 - pos) & 1) {
+ wpa_printf(MSG_ERROR, "Invalid hex password "
+ "on line %d in '%s'", line, fname);
+ goto failed;
+ }
+ user->password = os_malloc((pos2 - pos) / 2);
+ if (user->password == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to allocate "
+ "memory for EAP password");
+ goto failed;
+ }
+ if (hexstr2bin(pos, user->password,
+ (pos2 - pos) / 2) < 0) {
+ wpa_printf(MSG_ERROR, "Invalid hex password "
+ "on line %d in '%s'", line, fname);
+ goto failed;
+ }
+ user->password_len = (pos2 - pos) / 2;
+ pos = pos2;
+ }
+
+ while (*pos == ' ' || *pos == '\t')
+ pos++;
+ if (os_strncmp(pos, "[2]", 3) == 0) {
+ user->phase2 = 1;
+ }
+
+ done:
+ if (tail == NULL) {
+ tail = conf->eap_user = user;
+ } else {
+ tail->next = user;
+ tail = user;
+ }
+ continue;
+
+ failed:
+ if (user) {
+ os_free(user->password);
+ os_free(user->identity);
+ os_free(user);
+ }
+ ret = -1;
+ break;
+ }
+
+ fclose(f);
+
+ return ret;
+}
+#endif /* EAP_SERVER */
+
+
+static int
+hostapd_config_read_radius_addr(struct hostapd_radius_server **server,
+ int *num_server, const char *val, int def_port,
+ struct hostapd_radius_server **curr_serv)
+{
+ struct hostapd_radius_server *nserv;
+ int ret;
+ static int server_index = 1;
+
+ nserv = os_realloc(*server, (*num_server + 1) * sizeof(*nserv));
+ if (nserv == NULL)
+ return -1;
+
+ *server = nserv;
+ nserv = &nserv[*num_server];
+ (*num_server)++;
+ (*curr_serv) = nserv;
+
+ os_memset(nserv, 0, sizeof(*nserv));
+ nserv->port = def_port;
+ ret = hostapd_parse_ip_addr(val, &nserv->addr);
+ nserv->index = server_index++;
+
+ return ret;
+}
+
+
+static int hostapd_config_parse_key_mgmt(int line, const char *value)
+{
+ int val = 0, last;
+ char *start, *end, *buf;
+
+ buf = os_strdup(value);
+ if (buf == NULL)
+ return -1;
+ start = buf;
+
+ while (*start != '\0') {
+ while (*start == ' ' || *start == '\t')
+ start++;
+ if (*start == '\0')
+ break;
+ end = start;
+ while (*end != ' ' && *end != '\t' && *end != '\0')
+ end++;
+ last = *end == '\0';
+ *end = '\0';
+ if (os_strcmp(start, "WPA-PSK") == 0)
+ val |= WPA_KEY_MGMT_PSK;
+ else if (os_strcmp(start, "WPA-EAP") == 0)
+ val |= WPA_KEY_MGMT_IEEE8021X;
+#ifdef CONFIG_IEEE80211R
+ else if (os_strcmp(start, "FT-PSK") == 0)
+ val |= WPA_KEY_MGMT_FT_PSK;
+ else if (os_strcmp(start, "FT-EAP") == 0)
+ val |= WPA_KEY_MGMT_FT_IEEE8021X;
+#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
+ val |= WPA_KEY_MGMT_PSK_SHA256;
+ else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
+ val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
+#endif /* CONFIG_IEEE80211W */
+ else {
+ wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
+ line, start);
+ os_free(buf);
+ return -1;
+ }
+
+ if (last)
+ break;
+ start = end + 1;
+ }
+
+ os_free(buf);
+ if (val == 0) {
+ wpa_printf(MSG_ERROR, "Line %d: no key_mgmt values "
+ "configured.", line);
+ return -1;
+ }
+
+ return val;
+}
+
+
+static int hostapd_config_parse_cipher(int line, const char *value)
+{
+ int val = 0, last;
+ char *start, *end, *buf;
+
+ buf = os_strdup(value);
+ if (buf == NULL)
+ return -1;
+ start = buf;
+
+ while (*start != '\0') {
+ while (*start == ' ' || *start == '\t')
+ start++;
+ if (*start == '\0')
+ break;
+ end = start;
+ while (*end != ' ' && *end != '\t' && *end != '\0')
+ end++;
+ last = *end == '\0';
+ *end = '\0';
+ if (os_strcmp(start, "CCMP") == 0)
+ val |= WPA_CIPHER_CCMP;
+ else if (os_strcmp(start, "TKIP") == 0)
+ val |= WPA_CIPHER_TKIP;
+ else if (os_strcmp(start, "WEP104") == 0)
+ val |= WPA_CIPHER_WEP104;
+ else if (os_strcmp(start, "WEP40") == 0)
+ val |= WPA_CIPHER_WEP40;
+ else if (os_strcmp(start, "NONE") == 0)
+ val |= WPA_CIPHER_NONE;
+ else {
+ wpa_printf(MSG_ERROR, "Line %d: invalid cipher '%s'.",
+ line, start);
+ os_free(buf);
+ return -1;
+ }
+
+ if (last)
+ break;
+ start = end + 1;
+ }
+ os_free(buf);
+
+ if (val == 0) {
+ wpa_printf(MSG_ERROR, "Line %d: no cipher values configured.",
+ line);
+ return -1;
+ }
+ return val;
+}
+
+
+static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
+ struct hostapd_config *conf)
+{
+ if (bss->ieee802_1x && !bss->eap_server &&
+ !bss->radius->auth_servers) {
+ wpa_printf(MSG_ERROR, "Invalid IEEE 802.1X configuration (no "
+ "EAP authenticator configured).");
+ return -1;
+ }
+
+ if (bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
+ bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
+ bss->ssid.wpa_psk_file == NULL) {
+ wpa_printf(MSG_ERROR, "WPA-PSK enabled, but PSK or passphrase "
+ "is not configured.");
+ return -1;
+ }
+
+ if (hostapd_mac_comp_empty(bss->bssid) != 0) {
+ size_t i;
+
+ for (i = 0; i < conf->num_bss; i++) {
+ if ((&conf->bss[i] != bss) &&
+ (hostapd_mac_comp(conf->bss[i].bssid,
+ bss->bssid) == 0)) {
+ wpa_printf(MSG_ERROR, "Duplicate BSSID " MACSTR
+ " on interface '%s' and '%s'.",
+ MAC2STR(bss->bssid),
+ conf->bss[i].iface, bss->iface);
+ return -1;
+ }
+ }
+ }
+
+#ifdef CONFIG_IEEE80211R
+ if ((bss->wpa_key_mgmt &
+ (WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_FT_IEEE8021X)) &&
+ (bss->nas_identifier == NULL ||
+ os_strlen(bss->nas_identifier) < 1 ||
+ os_strlen(bss->nas_identifier) > FT_R0KH_ID_MAX_LEN)) {
+ wpa_printf(MSG_ERROR, "FT (IEEE 802.11r) requires "
+ "nas_identifier to be configured as a 1..48 octet "
+ "string");
+ return -1;
+ }
+#endif /* CONFIG_IEEE80211R */
+
+#ifdef CONFIG_IEEE80211N
+ if (conf->ieee80211n && bss->wpa &&
+ !(bss->wpa_pairwise & WPA_CIPHER_CCMP) &&
+ !(bss->rsn_pairwise & WPA_CIPHER_CCMP)) {
+ wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WPA/WPA2 "
+ "requires CCMP to be enabled");
+ return -1;
+ }
+#endif /* CONFIG_IEEE80211N */
+
+ return 0;
+}
+
+
+static int hostapd_config_check(struct hostapd_config *conf)
+{
+ size_t i;
+
+ if (conf->ieee80211d && (!conf->country[0] || !conf->country[1])) {
+ wpa_printf(MSG_ERROR, "Cannot enable IEEE 802.11d without "
+ "setting the country_code");
+ return -1;
+ }
+
+ for (i = 0; i < conf->num_bss; i++) {
+ if (hostapd_config_check_bss(&conf->bss[i], conf))
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int hostapd_config_read_wep(struct hostapd_wep_keys *wep, int keyidx,
+ char *val)
+{
+ size_t len = os_strlen(val);
+
+ if (keyidx < 0 || keyidx > 3 || wep->key[keyidx] != NULL)
+ return -1;
+
+ if (val[0] == '"') {
+ if (len < 2 || val[len - 1] != '"')
+ return -1;
+ len -= 2;
+ wep->key[keyidx] = os_malloc(len);
+ if (wep->key[keyidx] == NULL)
+ return -1;
+ os_memcpy(wep->key[keyidx], val + 1, len);
+ wep->len[keyidx] = len;
+ } else {
+ if (len & 1)
+ return -1;
+ len /= 2;
+ wep->key[keyidx] = os_malloc(len);
+ if (wep->key[keyidx] == NULL)
+ return -1;
+ wep->len[keyidx] = len;
+ if (hexstr2bin(val, wep->key[keyidx], len) < 0)
+ return -1;
+ }
+
+ wep->keys_set++;
+
+ return 0;
+}
+
+
+static int hostapd_parse_rates(int **rate_list, char *val)
+{
+ int *list;
+ int count;
+ char *pos, *end;
+
+ os_free(*rate_list);
+ *rate_list = NULL;
+
+ pos = val;
+ count = 0;
+ while (*pos != '\0') {
+ if (*pos == ' ')
+ count++;
+ pos++;
+ }
+
+ list = os_malloc(sizeof(int) * (count + 2));
+ if (list == NULL)
+ return -1;
+ pos = val;
+ count = 0;
+ while (*pos != '\0') {
+ end = os_strchr(pos, ' ');
+ if (end)
+ *end = '\0';
+
+ list[count++] = atoi(pos);
+ if (!end)
+ break;
+ pos = end + 1;
+ }
+ list[count] = -1;
+
+ *rate_list = list;
+ return 0;
+}
+
+
+static int hostapd_config_bss(struct hostapd_config *conf, const char *ifname)
+{
+ struct hostapd_bss_config *bss;
+
+ if (*ifname == '\0')
+ return -1;
+
+ bss = os_realloc(conf->bss, (conf->num_bss + 1) *
+ sizeof(struct hostapd_bss_config));
+ if (bss == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to allocate memory for "
+ "multi-BSS entry");
+ return -1;
+ }
+ conf->bss = bss;
+
+ bss = &(conf->bss[conf->num_bss]);
+ os_memset(bss, 0, sizeof(*bss));
+ bss->radius = os_zalloc(sizeof(*bss->radius));
+ if (bss->radius == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to allocate memory for "
+ "multi-BSS RADIUS data");
+ return -1;
+ }
+
+ conf->num_bss++;
+ conf->last_bss = bss;
+
+ hostapd_config_defaults_bss(bss);
+ os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
+ os_memcpy(bss->ssid.vlan, bss->iface, IFNAMSIZ + 1);
+
+ return 0;
+}
+
+
+static int valid_cw(int cw)
+{
+ return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
+ cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023);
+}
+
+
+enum {
+ IEEE80211_TX_QUEUE_DATA0 = 0, /* used for EDCA AC_VO data */
+ IEEE80211_TX_QUEUE_DATA1 = 1, /* used for EDCA AC_VI data */
+ IEEE80211_TX_QUEUE_DATA2 = 2, /* used for EDCA AC_BE data */
+ IEEE80211_TX_QUEUE_DATA3 = 3, /* used for EDCA AC_BK data */
+ IEEE80211_TX_QUEUE_DATA4 = 4,
+ IEEE80211_TX_QUEUE_AFTER_BEACON = 6,
+ IEEE80211_TX_QUEUE_BEACON = 7
+};
+
+static int hostapd_config_tx_queue(struct hostapd_config *conf, char *name,
+ char *val)
+{
+ int num;
+ char *pos;
+ struct hostapd_tx_queue_params *queue;
+
+ /* skip 'tx_queue_' prefix */
+ pos = name + 9;
+ if (os_strncmp(pos, "data", 4) == 0 &&
+ pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
+ num = pos[4] - '0';
+ pos += 6;
+ } else if (os_strncmp(pos, "after_beacon_", 13) == 0) {
+ num = IEEE80211_TX_QUEUE_AFTER_BEACON;
+ pos += 13;
+ } else if (os_strncmp(pos, "beacon_", 7) == 0) {
+ num = IEEE80211_TX_QUEUE_BEACON;
+ pos += 7;
+ } else {
+ wpa_printf(MSG_ERROR, "Unknown tx_queue name '%s'", pos);
+ return -1;
+ }
+
+ queue = &conf->tx_queue[num];
+
+ if (os_strcmp(pos, "aifs") == 0) {
+ queue->aifs = atoi(val);
+ if (queue->aifs < 0 || queue->aifs > 255) {
+ wpa_printf(MSG_ERROR, "Invalid AIFS value %d",
+ queue->aifs);
+ return -1;
+ }
+ } else if (os_strcmp(pos, "cwmin") == 0) {
+ queue->cwmin = atoi(val);
+ if (!valid_cw(queue->cwmin)) {
+ wpa_printf(MSG_ERROR, "Invalid cwMin value %d",
+ queue->cwmin);
+ return -1;
+ }
+ } else if (os_strcmp(pos, "cwmax") == 0) {
+ queue->cwmax = atoi(val);
+ if (!valid_cw(queue->cwmax)) {
+ wpa_printf(MSG_ERROR, "Invalid cwMax value %d",
+ queue->cwmax);
+ return -1;
+ }
+ } else if (os_strcmp(pos, "burst") == 0) {
+ queue->burst = hostapd_config_read_int10(val);
+ } else {
+ wpa_printf(MSG_ERROR, "Unknown tx_queue field '%s'", pos);
+ return -1;
+ }
+
+ queue->configured = 1;
+
+ return 0;
+}
+
+
+static int hostapd_config_wme_ac(struct hostapd_config *conf, char *name,
+ char *val)
+{
+ int num, v;
+ char *pos;
+ struct hostapd_wme_ac_params *ac;
+
+ /* skip 'wme_ac_' prefix */
+ pos = name + 7;
+ if (os_strncmp(pos, "be_", 3) == 0) {
+ num = 0;
+ pos += 3;
+ } else if (os_strncmp(pos, "bk_", 3) == 0) {
+ num = 1;
+ pos += 3;
+ } else if (os_strncmp(pos, "vi_", 3) == 0) {
+ num = 2;
+ pos += 3;
+ } else if (os_strncmp(pos, "vo_", 3) == 0) {
+ num = 3;
+ pos += 3;
+ } else {
+ wpa_printf(MSG_ERROR, "Unknown wme name '%s'", pos);
+ return -1;
+ }
+
+ ac = &conf->wme_ac_params[num];
+
+ if (os_strcmp(pos, "aifs") == 0) {
+ v = atoi(val);
+ if (v < 1 || v > 255) {
+ wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
+ return -1;
+ }
+ ac->aifs = v;
+ } else if (os_strcmp(pos, "cwmin") == 0) {
+ v = atoi(val);
+ if (v < 0 || v > 12) {
+ wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
+ return -1;
+ }
+ ac->cwmin = v;
+ } else if (os_strcmp(pos, "cwmax") == 0) {
+ v = atoi(val);
+ if (v < 0 || v > 12) {
+ wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
+ return -1;
+ }
+ ac->cwmax = v;
+ } else if (os_strcmp(pos, "txop_limit") == 0) {
+ v = atoi(val);
+ if (v < 0 || v > 0xffff) {
+ wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
+ return -1;
+ }
+ ac->txopLimit = v;
+ } else if (os_strcmp(pos, "acm") == 0) {
+ v = atoi(val);
+ if (v < 0 || v > 1) {
+ wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
+ return -1;
+ }
+ ac->admission_control_mandatory = v;
+ } else {
+ wpa_printf(MSG_ERROR, "Unknown wme_ac_ field '%s'", pos);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+#ifdef CONFIG_IEEE80211R
+static int add_r0kh(struct hostapd_bss_config *bss, char *value)
+{
+ struct ft_remote_r0kh *r0kh;
+ char *pos, *next;
+
+ r0kh = os_zalloc(sizeof(*r0kh));
+ if (r0kh == NULL)
+ return -1;
+
+ /* 02:01:02:03:04:05 a.example.com 000102030405060708090a0b0c0d0e0f */
+ pos = value;
+ next = os_strchr(pos, ' ');
+ if (next)
+ *next++ = '\0';
+ if (next == NULL || hwaddr_aton(pos, r0kh->addr)) {
+ wpa_printf(MSG_ERROR, "Invalid R0KH MAC address: '%s'", pos);
+ os_free(r0kh);
+ return -1;
+ }
+
+ pos = next;
+ next = os_strchr(pos, ' ');
+ if (next)
+ *next++ = '\0';
+ if (next == NULL || next - pos > FT_R0KH_ID_MAX_LEN) {
+ wpa_printf(MSG_ERROR, "Invalid R0KH-ID: '%s'", pos);
+ os_free(r0kh);
+ return -1;
+ }
+ r0kh->id_len = next - pos - 1;
+ os_memcpy(r0kh->id, pos, r0kh->id_len);
+
+ pos = next;
+ if (hexstr2bin(pos, r0kh->key, sizeof(r0kh->key))) {
+ wpa_printf(MSG_ERROR, "Invalid R0KH key: '%s'", pos);
+ os_free(r0kh);
+ return -1;
+ }
+
+ r0kh->next = bss->r0kh_list;
+ bss->r0kh_list = r0kh;
+
+ return 0;
+}
+
+
+static int add_r1kh(struct hostapd_bss_config *bss, char *value)
+{
+ struct ft_remote_r1kh *r1kh;
+ char *pos, *next;
+
+ r1kh = os_zalloc(sizeof(*r1kh));
+ if (r1kh == NULL)
+ return -1;
+
+ /* 02:01:02:03:04:05 02:01:02:03:04:05
+ * 000102030405060708090a0b0c0d0e0f */
+ pos = value;
+ next = os_strchr(pos, ' ');
+ if (next)
+ *next++ = '\0';
+ if (next == NULL || hwaddr_aton(pos, r1kh->addr)) {
+ wpa_printf(MSG_ERROR, "Invalid R1KH MAC address: '%s'", pos);
+ os_free(r1kh);
+ return -1;
+ }
+
+ pos = next;
+ next = os_strchr(pos, ' ');
+ if (next)
+ *next++ = '\0';
+ if (next == NULL || hwaddr_aton(pos, r1kh->id)) {
+ wpa_printf(MSG_ERROR, "Invalid R1KH-ID: '%s'", pos);
+ os_free(r1kh);
+ return -1;
+ }
+
+ pos = next;
+ if (hexstr2bin(pos, r1kh->key, sizeof(r1kh->key))) {
+ wpa_printf(MSG_ERROR, "Invalid R1KH key: '%s'", pos);
+ os_free(r1kh);
+ return -1;
+ }
+
+ r1kh->next = bss->r1kh_list;
+ bss->r1kh_list = r1kh;
+
+ return 0;
+}
+#endif /* CONFIG_IEEE80211R */
+
+
+#ifdef CONFIG_IEEE80211N
+static int hostapd_config_ht_capab(struct hostapd_config *conf,
+ const char *capab)
+{
+ if (os_strstr(capab, "[LDPC]"))
+ conf->ht_capab |= HT_CAP_INFO_LDPC_CODING_CAP;
+ if (os_strstr(capab, "[HT40-]")) {
+ conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
+ conf->secondary_channel = -1;
+ }
+ if (os_strstr(capab, "[HT40+]")) {
+ conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
+ conf->secondary_channel = 1;
+ }
+ if (os_strstr(capab, "[SMPS-STATIC]")) {
+ conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK;
+ conf->ht_capab |= HT_CAP_INFO_SMPS_STATIC;
+ }
+ if (os_strstr(capab, "[SMPS-DYNAMIC]")) {
+ conf->ht_capab &= ~HT_CAP_INFO_SMPS_MASK;
+ conf->ht_capab |= HT_CAP_INFO_SMPS_DYNAMIC;
+ }
+ if (os_strstr(capab, "[GF]"))
+ conf->ht_capab |= HT_CAP_INFO_GREEN_FIELD;
+ if (os_strstr(capab, "[SHORT-GI-20]"))
+ conf->ht_capab |= HT_CAP_INFO_SHORT_GI20MHZ;
+ if (os_strstr(capab, "[SHORT-GI-40]"))
+ conf->ht_capab |= HT_CAP_INFO_SHORT_GI40MHZ;
+ if (os_strstr(capab, "[TX-STBC]"))
+ conf->ht_capab |= HT_CAP_INFO_TX_STBC;
+ if (os_strstr(capab, "[RX-STBC1]")) {
+ conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
+ conf->ht_capab |= HT_CAP_INFO_RX_STBC_1;
+ }
+ if (os_strstr(capab, "[RX-STBC12]")) {
+ conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
+ conf->ht_capab |= HT_CAP_INFO_RX_STBC_12;
+ }
+ if (os_strstr(capab, "[RX-STBC123]")) {
+ conf->ht_capab &= ~HT_CAP_INFO_RX_STBC_MASK;
+ conf->ht_capab |= HT_CAP_INFO_RX_STBC_123;
+ }
+ if (os_strstr(capab, "[DELAYED-BA]"))
+ conf->ht_capab |= HT_CAP_INFO_DELAYED_BA;
+ if (os_strstr(capab, "[MAX-AMSDU-7935]"))
+ conf->ht_capab |= HT_CAP_INFO_MAX_AMSDU_SIZE;
+ if (os_strstr(capab, "[DSSS_CCK-40]"))
+ conf->ht_capab |= HT_CAP_INFO_DSSS_CCK40MHZ;
+ if (os_strstr(capab, "[PSMP]"))
+ conf->ht_capab |= HT_CAP_INFO_PSMP_SUPP;
+ if (os_strstr(capab, "[LSIG-TXOP-PROT]"))
+ conf->ht_capab |= HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT;
+
+ return 0;
+}
+#endif /* CONFIG_IEEE80211N */
+
+
+/**
+ * hostapd_config_read - Read and parse a configuration file
+ * @fname: Configuration file name (including path, if needed)
+ * Returns: Allocated configuration data structure
+ */
+struct hostapd_config * hostapd_config_read(const char *fname)
+{
+ struct hostapd_config *conf;
+ struct hostapd_bss_config *bss;
+ FILE *f;
+ char buf[256], *pos;
+ int line = 0;
+ int errors = 0;
+ int pairwise;
+ size_t i;
+
+ f = fopen(fname, "r");
+ if (f == NULL) {
+ wpa_printf(MSG_ERROR, "Could not open configuration file '%s' "
+ "for reading.", fname);
+ return NULL;
+ }
+
+ conf = hostapd_config_defaults();
+ if (conf == NULL) {
+ fclose(f);
+ return NULL;
+ }
+ bss = conf->last_bss = conf->bss;
+
+ while (fgets(buf, sizeof(buf), f)) {
+ bss = conf->last_bss;
+ line++;
+
+ if (buf[0] == '#')
+ continue;
+ pos = buf;
+ while (*pos != '\0') {
+ if (*pos == '\n') {
+ *pos = '\0';
+ break;
+ }
+ pos++;
+ }
+ if (buf[0] == '\0')
+ continue;
+
+ pos = os_strchr(buf, '=');
+ if (pos == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid line '%s'",
+ line, buf);
+ errors++;
+ continue;
+ }
+ *pos = '\0';
+ pos++;
+
+ if (os_strcmp(buf, "interface") == 0) {
+ os_strlcpy(conf->bss[0].iface, pos,
+ sizeof(conf->bss[0].iface));
+ } else if (os_strcmp(buf, "bridge") == 0) {
+ os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
+ } else if (os_strcmp(buf, "driver") == 0) {
+ int i;
+ /* clear to get error below if setting is invalid */
+ conf->driver = NULL;
+ for (i = 0; hostapd_drivers[i]; i++) {
+ if (os_strcmp(pos, hostapd_drivers[i]->name) ==
+ 0) {
+ conf->driver = hostapd_drivers[i];
+ break;
+ }
+ }
+ if (conf->driver == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid/"
+ "unknown driver '%s'", line, pos);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "debug") == 0) {
+ wpa_printf(MSG_DEBUG, "Line %d: DEPRECATED: 'debug' "
+ "configuration variable is not used "
+ "anymore", line);
+ } else if (os_strcmp(buf, "logger_syslog_level") == 0) {
+ bss->logger_syslog_level = atoi(pos);
+ } else if (os_strcmp(buf, "logger_stdout_level") == 0) {
+ bss->logger_stdout_level = atoi(pos);
+ } else if (os_strcmp(buf, "logger_syslog") == 0) {
+ bss->logger_syslog = atoi(pos);
+ } else if (os_strcmp(buf, "logger_stdout") == 0) {
+ bss->logger_stdout = atoi(pos);
+ } else if (os_strcmp(buf, "dump_file") == 0) {
+ bss->dump_log_name = os_strdup(pos);
+ } else if (os_strcmp(buf, "ssid") == 0) {
+ bss->ssid.ssid_len = os_strlen(pos);
+ if (bss->ssid.ssid_len > HOSTAPD_MAX_SSID_LEN ||
+ bss->ssid.ssid_len < 1) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid SSID "
+ "'%s'", line, pos);
+ errors++;
+ } else {
+ os_memcpy(bss->ssid.ssid, pos,
+ bss->ssid.ssid_len);
+ bss->ssid.ssid[bss->ssid.ssid_len] = '\0';
+ bss->ssid.ssid_set = 1;
+ }
+ } else if (os_strcmp(buf, "macaddr_acl") == 0) {
+ bss->macaddr_acl = atoi(pos);
+ if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
+ bss->macaddr_acl != DENY_UNLESS_ACCEPTED &&
+ bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
+ wpa_printf(MSG_ERROR, "Line %d: unknown "
+ "macaddr_acl %d",
+ line, bss->macaddr_acl);
+ }
+ } else if (os_strcmp(buf, "accept_mac_file") == 0) {
+ if (hostapd_config_read_maclist(pos, &bss->accept_mac,
+ &bss->num_accept_mac))
+ {
+ wpa_printf(MSG_ERROR, "Line %d: Failed to "
+ "read accept_mac_file '%s'",
+ line, pos);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "deny_mac_file") == 0) {
+ if (hostapd_config_read_maclist(pos, &bss->deny_mac,
+ &bss->num_deny_mac)) {
+ wpa_printf(MSG_ERROR, "Line %d: Failed to "
+ "read deny_mac_file '%s'",
+ line, pos);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "ap_max_inactivity") == 0) {
+ bss->ap_max_inactivity = atoi(pos);
+ } else if (os_strcmp(buf, "country_code") == 0) {
+ os_memcpy(conf->country, pos, 2);
+ /* FIX: make this configurable */
+ conf->country[2] = ' ';
+ } else if (os_strcmp(buf, "ieee80211d") == 0) {
+ conf->ieee80211d = atoi(pos);
+ } else if (os_strcmp(buf, "ieee8021x") == 0) {
+ bss->ieee802_1x = atoi(pos);
+ } else if (os_strcmp(buf, "eapol_version") == 0) {
+ bss->eapol_version = atoi(pos);
+ if (bss->eapol_version < 1 ||
+ bss->eapol_version > 2) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid EAPOL "
+ "version (%d): '%s'.",
+ line, bss->eapol_version, pos);
+ errors++;
+ } else
+ wpa_printf(MSG_DEBUG, "eapol_version=%d",
+ bss->eapol_version);
+#ifdef EAP_SERVER
+ } else if (os_strcmp(buf, "eap_authenticator") == 0) {
+ bss->eap_server = atoi(pos);
+ wpa_printf(MSG_ERROR, "Line %d: obsolete "
+ "eap_authenticator used; this has been "
+ "renamed to eap_server", line);
+ } else if (os_strcmp(buf, "eap_server") == 0) {
+ bss->eap_server = atoi(pos);
+ } else if (os_strcmp(buf, "eap_user_file") == 0) {
+ if (hostapd_config_read_eap_user(pos, bss))
+ errors++;
+ } else if (os_strcmp(buf, "ca_cert") == 0) {
+ os_free(bss->ca_cert);
+ bss->ca_cert = os_strdup(pos);
+ } else if (os_strcmp(buf, "server_cert") == 0) {
+ os_free(bss->server_cert);
+ bss->server_cert = os_strdup(pos);
+ } else if (os_strcmp(buf, "private_key") == 0) {
+ os_free(bss->private_key);
+ bss->private_key = os_strdup(pos);
+ } else if (os_strcmp(buf, "private_key_passwd") == 0) {
+ os_free(bss->private_key_passwd);
+ bss->private_key_passwd = os_strdup(pos);
+ } else if (os_strcmp(buf, "check_crl") == 0) {
+ bss->check_crl = atoi(pos);
+ } else if (os_strcmp(buf, "dh_file") == 0) {
+ os_free(bss->dh_file);
+ bss->dh_file = os_strdup(pos);
+#ifdef EAP_FAST
+ } else if (os_strcmp(buf, "pac_opaque_encr_key") == 0) {
+ os_free(bss->pac_opaque_encr_key);
+ bss->pac_opaque_encr_key = os_malloc(16);
+ if (bss->pac_opaque_encr_key == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: No memory for "
+ "pac_opaque_encr_key", line);
+ errors++;
+ } else if (hexstr2bin(pos, bss->pac_opaque_encr_key,
+ 16)) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid "
+ "pac_opaque_encr_key", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "eap_fast_a_id") == 0) {
+ size_t idlen = os_strlen(pos);
+ if (idlen & 1) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid "
+ "eap_fast_a_id", line);
+ errors++;
+ } else {
+ os_free(bss->eap_fast_a_id);
+ bss->eap_fast_a_id = os_malloc(idlen / 2);
+ if (bss->eap_fast_a_id == NULL ||
+ hexstr2bin(pos, bss->eap_fast_a_id,
+ idlen / 2)) {
+ wpa_printf(MSG_ERROR, "Line %d: "
+ "Failed to parse "
+ "eap_fast_a_id", line);
+ errors++;
+ } else
+ bss->eap_fast_a_id_len = idlen / 2;
+ }
+ } else if (os_strcmp(buf, "eap_fast_a_id_info") == 0) {
+ os_free(bss->eap_fast_a_id_info);
+ bss->eap_fast_a_id_info = os_strdup(pos);
+ } else if (os_strcmp(buf, "eap_fast_prov") == 0) {
+ bss->eap_fast_prov = atoi(pos);
+ } else if (os_strcmp(buf, "pac_key_lifetime") == 0) {
+ bss->pac_key_lifetime = atoi(pos);
+ } else if (os_strcmp(buf, "pac_key_refresh_time") == 0) {
+ bss->pac_key_refresh_time = atoi(pos);
+#endif /* EAP_FAST */
+#ifdef EAP_SIM
+ } else if (os_strcmp(buf, "eap_sim_db") == 0) {
+ os_free(bss->eap_sim_db);
+ bss->eap_sim_db = os_strdup(pos);
+ } else if (os_strcmp(buf, "eap_sim_aka_result_ind") == 0) {
+ bss->eap_sim_aka_result_ind = atoi(pos);
+#endif /* EAP_SIM */
+#ifdef EAP_TNC
+ } else if (os_strcmp(buf, "tnc") == 0) {
+ bss->tnc = atoi(pos);
+#endif /* EAP_TNC */
+#endif /* EAP_SERVER */
+ } else if (os_strcmp(buf, "eap_message") == 0) {
+ char *term;
+ bss->eap_req_id_text = os_strdup(pos);
+ if (bss->eap_req_id_text == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: Failed to "
+ "allocate memory for "
+ "eap_req_id_text", line);
+ errors++;
+ continue;
+ }
+ bss->eap_req_id_text_len =
+ os_strlen(bss->eap_req_id_text);
+ term = os_strstr(bss->eap_req_id_text, "\\0");
+ if (term) {
+ *term++ = '\0';
+ os_memmove(term, term + 1,
+ bss->eap_req_id_text_len -
+ (term - bss->eap_req_id_text) - 1);
+ bss->eap_req_id_text_len--;
+ }
+ } else if (os_strcmp(buf, "wep_key_len_broadcast") == 0) {
+ bss->default_wep_key_len = atoi(pos);
+ if (bss->default_wep_key_len > 13) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
+ "key len %lu (= %lu bits)", line,
+ (unsigned long)
+ bss->default_wep_key_len,
+ (unsigned long)
+ bss->default_wep_key_len * 8);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "wep_key_len_unicast") == 0) {
+ bss->individual_wep_key_len = atoi(pos);
+ if (bss->individual_wep_key_len < 0 ||
+ bss->individual_wep_key_len > 13) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
+ "key len %d (= %d bits)", line,
+ bss->individual_wep_key_len,
+ bss->individual_wep_key_len * 8);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "wep_rekey_period") == 0) {
+ bss->wep_rekeying_period = atoi(pos);
+ if (bss->wep_rekeying_period < 0) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "period %d",
+ line, bss->wep_rekeying_period);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "eap_reauth_period") == 0) {
+ bss->eap_reauth_period = atoi(pos);
+ if (bss->eap_reauth_period < 0) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "period %d",
+ line, bss->eap_reauth_period);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "eapol_key_index_workaround") == 0) {
+ bss->eapol_key_index_workaround = atoi(pos);
+#ifdef CONFIG_IAPP
+ } else if (os_strcmp(buf, "iapp_interface") == 0) {
+ bss->ieee802_11f = 1;
+ os_strlcpy(bss->iapp_iface, pos,
+ sizeof(bss->iapp_iface));
+#endif /* CONFIG_IAPP */
+ } else if (os_strcmp(buf, "own_ip_addr") == 0) {
+ if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid IP "
+ "address '%s'", line, pos);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "nas_identifier") == 0) {
+ bss->nas_identifier = os_strdup(pos);
+ } else if (os_strcmp(buf, "auth_server_addr") == 0) {
+ if (hostapd_config_read_radius_addr(
+ &bss->radius->auth_servers,
+ &bss->radius->num_auth_servers, pos, 1812,
+ &bss->radius->auth_server)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid IP "
+ "address '%s'", line, pos);
+ errors++;
+ }
+ } else if (bss->radius->auth_server &&
+ os_strcmp(buf, "auth_server_port") == 0) {
+ bss->radius->auth_server->port = atoi(pos);
+ } else if (bss->radius->auth_server &&
+ os_strcmp(buf, "auth_server_shared_secret") == 0) {
+ int len = os_strlen(pos);
+ if (len == 0) {
+ /* RFC 2865, Ch. 3 */
+ wpa_printf(MSG_ERROR, "Line %d: empty shared "
+ "secret is not allowed.", line);
+ errors++;
+ }
+ bss->radius->auth_server->shared_secret =
+ (u8 *) os_strdup(pos);
+ bss->radius->auth_server->shared_secret_len = len;
+ } else if (os_strcmp(buf, "acct_server_addr") == 0) {
+ if (hostapd_config_read_radius_addr(
+ &bss->radius->acct_servers,
+ &bss->radius->num_acct_servers, pos, 1813,
+ &bss->radius->acct_server)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid IP "
+ "address '%s'", line, pos);
+ errors++;
+ }
+ } else if (bss->radius->acct_server &&
+ os_strcmp(buf, "acct_server_port") == 0) {
+ bss->radius->acct_server->port = atoi(pos);
+ } else if (bss->radius->acct_server &&
+ os_strcmp(buf, "acct_server_shared_secret") == 0) {
+ int len = os_strlen(pos);
+ if (len == 0) {
+ /* RFC 2865, Ch. 3 */
+ wpa_printf(MSG_ERROR, "Line %d: empty shared "
+ "secret is not allowed.", line);
+ errors++;
+ }
+ bss->radius->acct_server->shared_secret =
+ (u8 *) os_strdup(pos);
+ bss->radius->acct_server->shared_secret_len = len;
+ } else if (os_strcmp(buf, "radius_retry_primary_interval") ==
+ 0) {
+ bss->radius->retry_primary_interval = atoi(pos);
+ } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0)
+ {
+ bss->radius->acct_interim_interval = atoi(pos);
+ } else if (os_strcmp(buf, "auth_algs") == 0) {
+ bss->auth_algs = atoi(pos);
+ if (bss->auth_algs == 0) {
+ wpa_printf(MSG_ERROR, "Line %d: no "
+ "authentication algorithms allowed",
+ line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "max_num_sta") == 0) {
+ bss->max_num_sta = atoi(pos);
+ if (bss->max_num_sta < 0 ||
+ bss->max_num_sta > MAX_STA_COUNT) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid "
+ "max_num_sta=%d; allowed range "
+ "0..%d", line, bss->max_num_sta,
+ MAX_STA_COUNT);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "wpa") == 0) {
+ bss->wpa = atoi(pos);
+ } else if (os_strcmp(buf, "wpa_group_rekey") == 0) {
+ bss->wpa_group_rekey = atoi(pos);
+ } else if (os_strcmp(buf, "wpa_strict_rekey") == 0) {
+ bss->wpa_strict_rekey = atoi(pos);
+ } else if (os_strcmp(buf, "wpa_gmk_rekey") == 0) {
+ bss->wpa_gmk_rekey = atoi(pos);
+ } else if (os_strcmp(buf, "wpa_ptk_rekey") == 0) {
+ bss->wpa_ptk_rekey = atoi(pos);
+ } else if (os_strcmp(buf, "wpa_passphrase") == 0) {
+ int len = os_strlen(pos);
+ if (len < 8 || len > 63) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid WPA "
+ "passphrase length %d (expected "
+ "8..63)", line, len);
+ errors++;
+ } else {
+ os_free(bss->ssid.wpa_passphrase);
+ bss->ssid.wpa_passphrase = os_strdup(pos);
+ }
+ } else if (os_strcmp(buf, "wpa_psk") == 0) {
+ os_free(bss->ssid.wpa_psk);
+ bss->ssid.wpa_psk =
+ os_zalloc(sizeof(struct hostapd_wpa_psk));
+ if (bss->ssid.wpa_psk == NULL)
+ errors++;
+ else if (hexstr2bin(pos, bss->ssid.wpa_psk->psk,
+ PMK_LEN) ||
+ pos[PMK_LEN * 2] != '\0') {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid PSK "
+ "'%s'.", line, pos);
+ errors++;
+ } else {
+ bss->ssid.wpa_psk->group = 1;
+ }
+ } else if (os_strcmp(buf, "wpa_psk_file") == 0) {
+ os_free(bss->ssid.wpa_psk_file);
+ bss->ssid.wpa_psk_file = os_strdup(pos);
+ if (!bss->ssid.wpa_psk_file) {
+ wpa_printf(MSG_ERROR, "Line %d: allocation "
+ "failed", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "wpa_key_mgmt") == 0) {
+ bss->wpa_key_mgmt =
+ hostapd_config_parse_key_mgmt(line, pos);
+ if (bss->wpa_key_mgmt == -1)
+ errors++;
+ } else if (os_strcmp(buf, "wpa_pairwise") == 0) {
+ bss->wpa_pairwise =
+ hostapd_config_parse_cipher(line, pos);
+ if (bss->wpa_pairwise == -1 ||
+ bss->wpa_pairwise == 0)
+ errors++;
+ else if (bss->wpa_pairwise &
+ (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
+ WPA_CIPHER_WEP104)) {
+ wpa_printf(MSG_ERROR, "Line %d: unsupported "
+ "pairwise cipher suite '%s'",
+ bss->wpa_pairwise, pos);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "rsn_pairwise") == 0) {
+ bss->rsn_pairwise =
+ hostapd_config_parse_cipher(line, pos);
+ if (bss->rsn_pairwise == -1 ||
+ bss->rsn_pairwise == 0)
+ errors++;
+ else if (bss->rsn_pairwise &
+ (WPA_CIPHER_NONE | WPA_CIPHER_WEP40 |
+ WPA_CIPHER_WEP104)) {
+ wpa_printf(MSG_ERROR, "Line %d: unsupported "
+ "pairwise cipher suite '%s'",
+ bss->rsn_pairwise, pos);
+ errors++;
+ }
+#ifdef CONFIG_RSN_PREAUTH
+ } else if (os_strcmp(buf, "rsn_preauth") == 0) {
+ bss->rsn_preauth = atoi(pos);
+ } else if (os_strcmp(buf, "rsn_preauth_interfaces") == 0) {
+ bss->rsn_preauth_interfaces = os_strdup(pos);
+#endif /* CONFIG_RSN_PREAUTH */
+#ifdef CONFIG_PEERKEY
+ } else if (os_strcmp(buf, "peerkey") == 0) {
+ bss->peerkey = atoi(pos);
+#endif /* CONFIG_PEERKEY */
+#ifdef CONFIG_IEEE80211R
+ } else if (os_strcmp(buf, "mobility_domain") == 0) {
+ if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN ||
+ hexstr2bin(pos, bss->mobility_domain,
+ MOBILITY_DOMAIN_ID_LEN) != 0) {
+ wpa_printf(MSG_DEBUG, "Line %d: Invalid "
+ "mobility_domain '%s'", line, pos);
+ errors++;
+ continue;
+ }
+ } else if (os_strcmp(buf, "r1_key_holder") == 0) {
+ if (os_strlen(pos) != 2 * FT_R1KH_ID_LEN ||
+ hexstr2bin(pos, bss->r1_key_holder,
+ FT_R1KH_ID_LEN) != 0) {
+ wpa_printf(MSG_DEBUG, "Line %d: Invalid "
+ "r1_key_holder '%s'", line, pos);
+ errors++;
+ continue;
+ }
+ } else if (os_strcmp(buf, "r0_key_lifetime") == 0) {
+ bss->r0_key_lifetime = atoi(pos);
+ } else if (os_strcmp(buf, "reassociation_deadline") == 0) {
+ bss->reassociation_deadline = atoi(pos);
+ } else if (os_strcmp(buf, "r0kh") == 0) {
+ if (add_r0kh(bss, pos) < 0) {
+ wpa_printf(MSG_DEBUG, "Line %d: Invalid "
+ "r0kh '%s'", line, pos);
+ errors++;
+ continue;
+ }
+ } else if (os_strcmp(buf, "r1kh") == 0) {
+ if (add_r1kh(bss, pos) < 0) {
+ wpa_printf(MSG_DEBUG, "Line %d: Invalid "
+ "r1kh '%s'", line, pos);
+ errors++;
+ continue;
+ }
+ } else if (os_strcmp(buf, "pmk_r1_push") == 0) {
+ bss->pmk_r1_push = atoi(pos);
+#endif /* CONFIG_IEEE80211R */
+ } else if (os_strcmp(buf, "ctrl_interface") == 0) {
+ os_free(bss->ctrl_interface);
+ bss->ctrl_interface = os_strdup(pos);
+ } else if (os_strcmp(buf, "ctrl_interface_group") == 0) {
+#ifndef CONFIG_NATIVE_WINDOWS
+ struct group *grp;
+ char *endp;
+ const char *group = pos;
+
+ grp = getgrnam(group);
+ if (grp) {
+ bss->ctrl_interface_gid = grp->gr_gid;
+ bss->ctrl_interface_gid_set = 1;
+ wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
+ " (from group name '%s')",
+ bss->ctrl_interface_gid, group);
+ continue;
+ }
+
+ /* Group name not found - try to parse this as gid */
+ bss->ctrl_interface_gid = strtol(group, &endp, 10);
+ if (*group == '\0' || *endp != '\0') {
+ wpa_printf(MSG_DEBUG, "Line %d: Invalid group "
+ "'%s'", line, group);
+ errors++;
+ continue;
+ }
+ bss->ctrl_interface_gid_set = 1;
+ wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
+ bss->ctrl_interface_gid);
+#endif /* CONFIG_NATIVE_WINDOWS */
+#ifdef RADIUS_SERVER
+ } else if (os_strcmp(buf, "radius_server_clients") == 0) {
+ os_free(bss->radius_server_clients);
+ bss->radius_server_clients = os_strdup(pos);
+ } else if (os_strcmp(buf, "radius_server_auth_port") == 0) {
+ bss->radius_server_auth_port = atoi(pos);
+ } else if (os_strcmp(buf, "radius_server_ipv6") == 0) {
+ bss->radius_server_ipv6 = atoi(pos);
+#endif /* RADIUS_SERVER */
+ } else if (os_strcmp(buf, "test_socket") == 0) {
+ os_free(bss->test_socket);
+ bss->test_socket = os_strdup(pos);
+ } else if (os_strcmp(buf, "use_pae_group_addr") == 0) {
+ bss->use_pae_group_addr = atoi(pos);
+ } else if (os_strcmp(buf, "hw_mode") == 0) {
+ if (os_strcmp(pos, "a") == 0)
+ conf->hw_mode = HOSTAPD_MODE_IEEE80211A;
+ else if (os_strcmp(pos, "b") == 0)
+ conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
+ else if (os_strcmp(pos, "g") == 0)
+ conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
+ else {
+ wpa_printf(MSG_ERROR, "Line %d: unknown "
+ "hw_mode '%s'", line, pos);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "channel") == 0) {
+ conf->channel = atoi(pos);
+ } else if (os_strcmp(buf, "beacon_int") == 0) {
+ int val = atoi(pos);
+ /* MIB defines range as 1..65535, but very small values
+ * cause problems with the current implementation.
+ * Since it is unlikely that this small numbers are
+ * useful in real life scenarios, do not allow beacon
+ * period to be set below 15 TU. */
+ if (val < 15 || val > 65535) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "beacon_int %d (expected "
+ "15..65535)", line, val);
+ errors++;
+ } else
+ conf->beacon_int = val;
+ } else if (os_strcmp(buf, "dtim_period") == 0) {
+ bss->dtim_period = atoi(pos);
+ if (bss->dtim_period < 1 || bss->dtim_period > 255) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "dtim_period %d",
+ line, bss->dtim_period);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "rts_threshold") == 0) {
+ conf->rts_threshold = atoi(pos);
+ if (conf->rts_threshold < 0 ||
+ conf->rts_threshold > 2347) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "rts_threshold %d",
+ line, conf->rts_threshold);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "fragm_threshold") == 0) {
+ conf->fragm_threshold = atoi(pos);
+ if (conf->fragm_threshold < 256 ||
+ conf->fragm_threshold > 2346) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "fragm_threshold %d",
+ line, conf->fragm_threshold);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "send_probe_response") == 0) {
+ int val = atoi(pos);
+ if (val != 0 && val != 1) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "send_probe_response %d (expected "
+ "0 or 1)", line, val);
+ } else
+ conf->send_probe_response = val;
+ } else if (os_strcmp(buf, "supported_rates") == 0) {
+ if (hostapd_parse_rates(&conf->supported_rates, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid rate "
+ "list", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "basic_rates") == 0) {
+ if (hostapd_parse_rates(&conf->basic_rates, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid rate "
+ "list", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "preamble") == 0) {
+ if (atoi(pos))
+ conf->preamble = SHORT_PREAMBLE;
+ else
+ conf->preamble = LONG_PREAMBLE;
+ } else if (os_strcmp(buf, "ignore_broadcast_ssid") == 0) {
+ bss->ignore_broadcast_ssid = atoi(pos);
+ } else if (os_strcmp(buf, "bridge_packets") == 0) {
+ conf->bridge_packets = atoi(pos);
+ } else if (os_strcmp(buf, "wep_default_key") == 0) {
+ bss->ssid.wep.idx = atoi(pos);
+ if (bss->ssid.wep.idx > 3) {
+ wpa_printf(MSG_ERROR, "Invalid "
+ "wep_default_key index %d",
+ bss->ssid.wep.idx);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "wep_key0") == 0 ||
+ os_strcmp(buf, "wep_key1") == 0 ||
+ os_strcmp(buf, "wep_key2") == 0 ||
+ os_strcmp(buf, "wep_key3") == 0) {
+ if (hostapd_config_read_wep(&bss->ssid.wep,
+ buf[7] - '0', pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid WEP "
+ "key '%s'", line, buf);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "dynamic_vlan") == 0) {
+ bss->ssid.dynamic_vlan = atoi(pos);
+ } else if (os_strcmp(buf, "vlan_file") == 0) {
+ if (hostapd_config_read_vlan_file(bss, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: failed to "
+ "read VLAN file '%s'", line, pos);
+ errors++;
+ }
+#ifdef CONFIG_FULL_DYNAMIC_VLAN
+ } else if (os_strcmp(buf, "vlan_tagged_interface") == 0) {
+ bss->ssid.vlan_tagged_interface = os_strdup(pos);
+#endif /* CONFIG_FULL_DYNAMIC_VLAN */
+ } else if (os_strcmp(buf, "passive_scan_interval") == 0) {
+ conf->passive_scan_interval = atoi(pos);
+ } else if (os_strcmp(buf, "passive_scan_listen") == 0) {
+ conf->passive_scan_listen = atoi(pos);
+ } else if (os_strcmp(buf, "passive_scan_mode") == 0) {
+ conf->passive_scan_mode = atoi(pos);
+ } else if (os_strcmp(buf, "ap_table_max_size") == 0) {
+ conf->ap_table_max_size = atoi(pos);
+ } else if (os_strcmp(buf, "ap_table_expiration_time") == 0) {
+ conf->ap_table_expiration_time = atoi(pos);
+ } else if (os_strncmp(buf, "tx_queue_", 9) == 0) {
+ if (hostapd_config_tx_queue(conf, buf, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid TX "
+ "queue item", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "wme_enabled") == 0) {
+ bss->wme_enabled = atoi(pos);
+ } else if (os_strncmp(buf, "wme_ac_", 7) == 0) {
+ if (hostapd_config_wme_ac(conf, buf, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid wme "
+ "ac item", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "bss") == 0) {
+ if (hostapd_config_bss(conf, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid bss "
+ "item", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "bssid") == 0) {
+ if (bss == conf->bss &&
+ (!conf->driver || !conf->driver->init_bssid)) {
+ wpa_printf(MSG_ERROR, "Line %d: bssid item "
+ "not allowed for the default "
+ "interface and this driver", line);
+ errors++;
+ } else if (hwaddr_aton(pos, bss->bssid)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid bssid "
+ "item", line);
+ errors++;
+ }
+#ifdef CONFIG_IEEE80211W
+ } else if (os_strcmp(buf, "ieee80211w") == 0) {
+ bss->ieee80211w = atoi(pos);
+ } else if (os_strcmp(buf, "assoc_sa_query_max_timeout") == 0) {
+ bss->assoc_sa_query_max_timeout = atoi(pos);
+ if (bss->assoc_sa_query_max_timeout == 0) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "assoc_sa_query_max_timeout", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "assoc_sa_query_retry_timeout") == 0)
+ {
+ bss->assoc_sa_query_retry_timeout = atoi(pos);
+ if (bss->assoc_sa_query_retry_timeout == 0) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "assoc_sa_query_retry_timeout",
+ line);
+ errors++;
+ }
+#endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_IEEE80211N
+ } else if (os_strcmp(buf, "ieee80211n") == 0) {
+ conf->ieee80211n = atoi(pos);
+ } else if (os_strcmp(buf, "ht_capab") == 0) {
+ if (hostapd_config_ht_capab(conf, pos) < 0) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "ht_capab", line);
+ errors++;
+ }
+#endif /* CONFIG_IEEE80211N */
+ } else if (os_strcmp(buf, "max_listen_interval") == 0) {
+ bss->max_listen_interval = atoi(pos);
+ } else if (os_strcmp(buf, "okc") == 0) {
+ bss->okc = atoi(pos);
+#ifdef CONFIG_WPS
+ } else if (os_strcmp(buf, "wps_state") == 0) {
+ bss->wps_state = atoi(pos);
+ if (bss->wps_state < 0 || bss->wps_state > 2) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "wps_state", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "ap_setup_locked") == 0) {
+ bss->ap_setup_locked = atoi(pos);
+ } else if (os_strcmp(buf, "uuid") == 0) {
+ if (uuid_str2bin(pos, bss->uuid)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid UUID",
+ line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "wps_pin_requests") == 0) {
+ os_free(bss->wps_pin_requests);
+ bss->wps_pin_requests = os_strdup(pos);
+ } else if (os_strcmp(buf, "device_name") == 0) {
+ if (os_strlen(pos) > 32) {
+ wpa_printf(MSG_ERROR, "Line %d: Too long "
+ "device_name", line);
+ errors++;
+ }
+ os_free(bss->device_name);
+ bss->device_name = os_strdup(pos);
+ } else if (os_strcmp(buf, "manufacturer") == 0) {
+ if (os_strlen(pos) > 64) {
+ wpa_printf(MSG_ERROR, "Line %d: Too long "
+ "manufacturer", line);
+ errors++;
+ }
+ os_free(bss->manufacturer);
+ bss->manufacturer = os_strdup(pos);
+ } else if (os_strcmp(buf, "model_name") == 0) {
+ if (os_strlen(pos) > 32) {
+ wpa_printf(MSG_ERROR, "Line %d: Too long "
+ "model_name", line);
+ errors++;
+ }
+ os_free(bss->model_name);
+ bss->model_name = os_strdup(pos);
+ } else if (os_strcmp(buf, "model_number") == 0) {
+ if (os_strlen(pos) > 32) {
+ wpa_printf(MSG_ERROR, "Line %d: Too long "
+ "model_number", line);
+ errors++;
+ }
+ os_free(bss->model_number);
+ bss->model_number = os_strdup(pos);
+ } else if (os_strcmp(buf, "serial_number") == 0) {
+ if (os_strlen(pos) > 32) {
+ wpa_printf(MSG_ERROR, "Line %d: Too long "
+ "serial_number", line);
+ errors++;
+ }
+ os_free(bss->serial_number);
+ bss->serial_number = os_strdup(pos);
+ } else if (os_strcmp(buf, "device_type") == 0) {
+ os_free(bss->device_type);
+ bss->device_type = os_strdup(pos);
+ } else if (os_strcmp(buf, "config_methods") == 0) {
+ os_free(bss->config_methods);
+ bss->config_methods = os_strdup(pos);
+ } else if (os_strcmp(buf, "os_version") == 0) {
+ if (hexstr2bin(pos, bss->os_version, 4)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "os_version", line);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "ap_pin") == 0) {
+ os_free(bss->ap_pin);
+ bss->ap_pin = os_strdup(pos);
+ } else if (os_strcmp(buf, "skip_cred_build") == 0) {
+ bss->skip_cred_build = atoi(pos);
+ } else if (os_strcmp(buf, "extra_cred") == 0) {
+ os_free(bss->extra_cred);
+ bss->extra_cred =
+ (u8 *) os_readfile(pos, &bss->extra_cred_len);
+ if (bss->extra_cred == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: could not "
+ "read Credentials from '%s'",
+ line, pos);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "wps_cred_processing") == 0) {
+ bss->wps_cred_processing = atoi(pos);
+ } else if (os_strcmp(buf, "ap_settings") == 0) {
+ os_free(bss->ap_settings);
+ bss->ap_settings =
+ (u8 *) os_readfile(pos, &bss->ap_settings_len);
+ if (bss->ap_settings == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: could not "
+ "read AP Settings from '%s'",
+ line, pos);
+ errors++;
+ }
+ } else if (os_strcmp(buf, "upnp_iface") == 0) {
+ bss->upnp_iface = os_strdup(pos);
+ } else if (os_strcmp(buf, "friendly_name") == 0) {
+ os_free(bss->friendly_name);
+ bss->friendly_name = os_strdup(pos);
+ } else if (os_strcmp(buf, "manufacturer_url") == 0) {
+ os_free(bss->manufacturer_url);
+ bss->manufacturer_url = os_strdup(pos);
+ } else if (os_strcmp(buf, "model_description") == 0) {
+ os_free(bss->model_description);
+ bss->model_description = os_strdup(pos);
+ } else if (os_strcmp(buf, "model_url") == 0) {
+ os_free(bss->model_url);
+ bss->model_url = os_strdup(pos);
+ } else if (os_strcmp(buf, "upc") == 0) {
+ os_free(bss->upc);
+ bss->upc = os_strdup(pos);
+#endif /* CONFIG_WPS */
+ } else {
+ wpa_printf(MSG_ERROR, "Line %d: unknown configuration "
+ "item '%s'", line, buf);
+ errors++;
+ }
+ }
+
+ fclose(f);
+
+ if (bss->individual_wep_key_len == 0) {
+ /* individual keys are not use; can use key idx0 for broadcast
+ * keys */
+ bss->broadcast_key_idx_min = 0;
+ }
+
+ /* Select group cipher based on the enabled pairwise cipher suites */
+ pairwise = 0;
+ if (bss->wpa & 1)
+ pairwise |= bss->wpa_pairwise;
+ if (bss->wpa & 2) {
+ if (bss->rsn_pairwise == 0)
+ bss->rsn_pairwise = bss->wpa_pairwise;
+ pairwise |= bss->rsn_pairwise;
+ }
+ if (pairwise & WPA_CIPHER_TKIP)
+ bss->wpa_group = WPA_CIPHER_TKIP;
+ else
+ bss->wpa_group = WPA_CIPHER_CCMP;
+
+ for (i = 0; i < conf->num_bss; i++) {
+ bss = &conf->bss[i];
+
+ bss->radius->auth_server = bss->radius->auth_servers;
+ bss->radius->acct_server = bss->radius->acct_servers;
+
+ if (bss->wpa && bss->ieee802_1x) {
+ bss->ssid.security_policy = SECURITY_WPA;
+ } else if (bss->wpa) {
+ bss->ssid.security_policy = SECURITY_WPA_PSK;
+ } else if (bss->ieee802_1x) {
+ bss->ssid.security_policy = SECURITY_IEEE_802_1X;
+ bss->ssid.wep.default_len = bss->default_wep_key_len;
+ } else if (bss->ssid.wep.keys_set)
+ bss->ssid.security_policy = SECURITY_STATIC_WEP;
+ else
+ bss->ssid.security_policy = SECURITY_PLAINTEXT;
+ }
+
+ if (hostapd_config_check(conf))
+ errors++;
+
+ if (errors) {
+ wpa_printf(MSG_ERROR, "%d errors found in configuration file "
+ "'%s'", errors, fname);
+ hostapd_config_free(conf);
+ conf = NULL;
+ }
+
+ return conf;
+}
+
+
+int hostapd_wep_key_cmp(struct hostapd_wep_keys *a, struct hostapd_wep_keys *b)
+{
+ int i;
+
+ if (a->idx != b->idx || a->default_len != b->default_len)
+ return 1;
+ for (i = 0; i < NUM_WEP_KEYS; i++)
+ if (a->len[i] != b->len[i] ||
+ os_memcmp(a->key[i], b->key[i], a->len[i]) != 0)
+ return 1;
+ return 0;
+}
+
+
+static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
+ int num_servers)
+{
+ int i;
+
+ for (i = 0; i < num_servers; i++) {
+ os_free(servers[i].shared_secret);
+ }
+ os_free(servers);
+}
+
+
+static void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
+{
+ os_free(user->identity);
+ os_free(user->password);
+ os_free(user);
+}
+
+
+static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
+{
+ int i;
+ for (i = 0; i < NUM_WEP_KEYS; i++) {
+ os_free(keys->key[i]);
+ keys->key[i] = NULL;
+ }
+}
+
+
+static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
+{
+ struct hostapd_wpa_psk *psk, *prev;
+ struct hostapd_eap_user *user, *prev_user;
+
+ if (conf == NULL)
+ return;
+
+ psk = conf->ssid.wpa_psk;
+ while (psk) {
+ prev = psk;
+ psk = psk->next;
+ os_free(prev);
+ }
+
+ os_free(conf->ssid.wpa_passphrase);
+ os_free(conf->ssid.wpa_psk_file);
+#ifdef CONFIG_FULL_DYNAMIC_VLAN
+ os_free(conf->ssid.vlan_tagged_interface);
+#endif /* CONFIG_FULL_DYNAMIC_VLAN */
+
+ user = conf->eap_user;
+ while (user) {
+ prev_user = user;
+ user = user->next;
+ hostapd_config_free_eap_user(prev_user);
+ }
+
+ os_free(conf->dump_log_name);
+ os_free(conf->eap_req_id_text);
+ os_free(conf->accept_mac);
+ os_free(conf->deny_mac);
+ os_free(conf->nas_identifier);
+ hostapd_config_free_radius(conf->radius->auth_servers,
+ conf->radius->num_auth_servers);
+ hostapd_config_free_radius(conf->radius->acct_servers,
+ conf->radius->num_acct_servers);
+ os_free(conf->rsn_preauth_interfaces);
+ os_free(conf->ctrl_interface);
+ os_free(conf->ca_cert);
+ os_free(conf->server_cert);
+ os_free(conf->private_key);
+ os_free(conf->private_key_passwd);
+ os_free(conf->dh_file);
+ os_free(conf->pac_opaque_encr_key);
+ os_free(conf->eap_fast_a_id);
+ os_free(conf->eap_fast_a_id_info);
+ os_free(conf->eap_sim_db);
+ os_free(conf->radius_server_clients);
+ os_free(conf->test_socket);
+ os_free(conf->radius);
+ hostapd_config_free_vlan(conf);
+ if (conf->ssid.dyn_vlan_keys) {
+ struct hostapd_ssid *ssid = &conf->ssid;
+ size_t i;
+ for (i = 0; i <= ssid->max_dyn_vlan_keys; i++) {
+ if (ssid->dyn_vlan_keys[i] == NULL)
+ continue;
+ hostapd_config_free_wep(ssid->dyn_vlan_keys[i]);
+ os_free(ssid->dyn_vlan_keys[i]);
+ }
+ os_free(ssid->dyn_vlan_keys);
+ ssid->dyn_vlan_keys = NULL;
+ }
+
+#ifdef CONFIG_IEEE80211R
+ {
+ struct ft_remote_r0kh *r0kh, *r0kh_prev;
+ struct ft_remote_r1kh *r1kh, *r1kh_prev;
+
+ r0kh = conf->r0kh_list;