WPS support with Hostapd
General
WPS is a standard allowing easy and standard solution for establishing connection between client and access point without typing passphrase. After initiating WPS on bot devices (e.g. by pressing buttons) devices will exchange credentials without involving user into that process. WPS can significantly simplify connecting new devices to clients' home networks.
The implementation supports only WPS configuration using Push Button method. Other methods like PIN or NFC are intentionally not supported.
WPS (Wi-Fi Protected Setup) is a security risk and is generally recommended to be disabled due to vulnerabilities that can be exploited by attackers.
Northbound API
Introduce new fields in OVSDB for toggling and configuring WPS on APs.
Wifi_VIF_Config
wps [bool] - Enable support for WPS on AP (i.e. broadcast support for WPS in beacons)
true - Enable WPS
false - Disable WPS
wps_pbc [bool] - Initiate WPS single session
true - Start WPS session
false - Cancel ongoing WPS session
wps_pbc_key_id [string] - The value has to match to one of passwords' keyid in map in security filed configure on given AP
Wifi_VIF_State
wps [bool] - Current status of WPS support on the device
true - AP supports WPS and broadcasts that in beacons
false - WPS in disabled on AP
wps_pbc [bool] - Current status of WPS session
true - WPS session is ongoing
false - WPS session is inactive (it either succeeded, failed, timed out or was canceled)
wps_pbc_key_id [string] - Current PSK ID being used by WPS
Interface constraints and caveats
Control interface is idempotent, e.g. multiple writes to wps_pbc filed setting it to 1 won't start multiple WPS sessions. Only one WPS session will be started (when wps_pbc transits 0 → 1), subsequent writes won't trigger any action on the device.
Device will unset Wifi_VIF_Config::wps_pbc field shortly after cloud set that field to "true" and target issue command starting WPS session (e.g. to hostapd)
On platform running single hostapd instance, it's impossible to enable WPS on multiple interfaces (wps:=true) and start WPS session only on one of them (wps_pbc:=true). For instance, let's assume that wps:=true on both home-ap-24 and home-ap-u50. Now on home-ap-u50 WPS session is started (wps_pbc:= true wps_pbc_key_id:=key). This will implicitly start WPS session on home-ap-24 (to make things worse this interface doesn't have correct configuration).
Workaround: Don't set wps:=true by default. Instead treat wps & wps_pbc fields pair and configure them in tandem
Actions constraints and requirements
Enable WPS on the device
Wifi_VIF_Config::wps 0 → 1
No requirements
Disable WPS on the device
Wifi_VIF_Config::wps 1 → 0
Cannot be done when WPS session is ongoing (Wifi_VIF_State::wps_pbc == 1)
Start WPS session
Wifi_VIF_Config::wps_pbc 0 → 1
Wifi_VIF_State::wps has to be set to 1
Wifi_VIF_State::wps_keyid has to be set
Note: Device will unset Wifi_VIF_Config::wps_pbc after WPS session is stared by target
Cancel WPS session
Wifi_VIF_Config::wps_pbc 1 → 0
No requirements (when Wifi_VIF_State::wps_pbc == 1 it will cancel ongoing WPS session otherwise NOP)
Change PSK ID
Wifi_VIF_Config::wps_pbc_key_id [unset → value OR value1 → value2]
Forbidden during ongoing WPS session (Wifi_VIF_State::wps_pbc has to be 0)
Sample session
WPS is disabled
root@opensync:~# ovsh s Wifi_VIF_State -w if_name==home-ap-24
------------------------------------------------------------------------------------------------
_uuid | f6b2~4973 |
_version | b39e~8f53 |
ap_bridge | false |
ap_vlan_sta_addr | ["set",[]] |
associated_clients | ["set",[]] |
bridge | br-home |
btm | 1 |
channel | 1 |
dynamic_beacon | false |
enabled | true |
ft_mobility_domain | ["set",[]] |
ft_psk | 0 |
group_rekey | 86400 |
if_name | home-ap-24 |
mac | 12:23:34:45:56:67 |
mac_list | ["set",[]] |
mac_list_type | none |
mcast2ucast | false |
min_hw_mode | 11b |
mode | ap |
multi_ap | ["set",[]] |
parent | ["set",[]] |
rrm | 1 |
security | ["map",[["encryption","WPA-PSK"],["key","opensync11"],["key-2","12345678"], |
: ["key-3","opensync22"],["mode","2"],["oftag","home--1"],["oftag-key-2", :
: "home-2"],["oftag-key-3","home-3"]]] :
ssid | OPENSYNC-SSID |
ssid_broadcast | enabled |
state | ["set",[]] |
uapsd_enable | true |
vif_config | 6cbe~6c08 |
vif_radio_idx | 2 |
vlan_id | ["set",[]] |
wds | false |
wps | false |
wps_pbc | false |
wps_pbc_key_id | |
------------------------------------------------------------------------------------------------
root@opensync:~# cat /var/run/hostapd-home-ap-24.config
driver=atheros
interface=home-ap-24
ctrl_interface=/var/run/hostapd-wifi0
logger_syslog=-1
logger_syslog_level=3
ssid=OPENSYNC-SSID
hw_mode=g
channel=1
ignore_broadcast_ssid=0
wmm_enabled=1
#ft_psk=0
bss_transition=1
rrm_neighbor_report=1
bridge=br-home
wpa_group_rekey=86400
auth_algs=1
wpa_key_mgmt=WPA-PSK
wpa_psk_file=/var/run/hostapd-home-ap-24.pskfile
wpa=2
wpa_pairwise=CCMP
wps_state=0
eap_server=0
root@opensync:~# cat /var/run/hostapd-home-ap-24.pskfile
#oftag=home--1
wps=0 keyid=key 00:00:00:00:00:00 opensync11
#oftag=home-2
wps=0 keyid=key-2 00:00:00:00:00:00 12345678
#oftag=home-3
wps=0 keyid=key-3 00:00:00:00:00:00 opensync22Configure & run WPS on all VAPs within SSID using key key-3.
root@opensync:~# ovsh u Wifi_VIF_Config -w ssid==OPENSYNC-SSID wps_pbc_key_id:="key-3" wps:=true wps_pbc:=true
root@opensync:~# cat /var/run/hostapd-home-ap-24.config
driver=atheros
interface=home-ap-24
ctrl_interface=/var/run/hostapd-wifi0
logger_syslog=-1
logger_syslog_level=3
ssid=OPENSYNC-SSID
hw_mode=g
channel=1
ignore_broadcast_ssid=0
wmm_enabled=1
#ft_psk=0
bss_transition=1
rrm_neighbor_report=1
bridge=br-home
wpa_group_rekey=86400
auth_algs=1
wpa_key_mgmt=WPA-PSK
wpa_psk_file=/var/run/hostapd-home-ap-24.pskfile
wpa=2
wpa_pairwise=CCMP
wps_state=2
eap_server=1
root@opensync:~# cat /var/run/hostapd-home-ap-24.pskfile
#oftag=home--1
wps=0 keyid=key 00:00:00:00:00:00 opensync11
#oftag=home-2
wps=0 keyid=key-2 00:00:00:00:00:00 12345678
#oftag=home-3
wps=1 keyid=key-3 00:00:00:00:00:00 opensync22
root@opensync:~# ovsh s Wifi_VIF_State -w if_name==home-ap-24
------------------------------------------------------------------------------------------------
_uuid | f6b2~4973 |
_version | b39e~8f53 |
ap_bridge | false |
ap_vlan_sta_addr | ["set",[]] |
associated_clients | ["set",[]] |
bridge | br-home |
btm | 1 |
channel | 1 |
dynamic_beacon | false |
enabled | true |
ft_mobility_domain | ["set",[]] |
ft_psk | 0 |
group_rekey | 86400 |
if_name | home-ap-24 |
mac | 12:23:34:45:56:67 |
mac_list | ["set",[]] |
mac_list_type | none |
mcast2ucast | false |
min_hw_mode | 11b |
mode | ap |
multi_ap | ["set",[]] |
parent | ["set",[]] |
rrm | 1 |
security | ["map",[["encryption","WPA-PSK"],["key","opensync11"],["key-2","12345678"], |
: ["key-3","opensync22"],["mode","2"],["oftag","home--1"],["oftag-key-2", :
: "home-2"],["oftag-key-3","home-3"]]] :
ssid | OPENSYNC-SSID |
ssid_broadcast | enabled |
state | ["set",[]] |
uapsd_enable | true |
vif_config | 6cbe~6c08 |
vif_radio_idx | 2 |
vlan_id | ["set",[]] |
wds | false |
wps | true |
wps_pbc | true |
wps_pbc_key_id | key-3 |
------------------------------------------------------------------------------------------------At the moment WPS session should be active. The Wifi_VIF_Config::wps_pbc field should be unset at that time.
Start WPS session on STA and see whether it connects. In meantime hostap_cli should show something similar
root@opensync:~# hostapd_cli -p /var/run/hostapd-wifi0 -i home-ap-24
... skipped ...
Interactive mode
<3>WPS-PBC-ACTIVE
<3>WPS-ENROLLEE-SEEN 12:23:34:45:56:67 d58cb60c-14c0-54cd-b1b2-a57c22dd9685 0-00000000-0 0x3108 0 0 [ ]
... skipped ...
<3>CTRL-EVENT-EAP-STARTED 12:23:34:45:56:67
<3>CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=1
<3>CTRL-EVENT-EAP-PROPOSED-METHOD vendor=14122 method=254
<3>WPS-REG-SUCCESS 12:23:34:45:56:67 d58cb60c-14c0-54cd-b1b2-a57c22dd9685
<3>WPS-PBC-DISABLE
<3>WPS-SUCCESS
<3>CTRL-EVENT-EAP-FAILURE 12:23:34:45:56:67
<3>AP-STA-CONNECTED 12:23:34:45:56:67 keyid=key-3
... skipped ... Known issues
On platform using hostapd toggling
wpsfield causes client disconnection on given interface.