@@ -40,6 +40,7 @@ usage() {
4040 echo " Use: 'nat' for NAT (default)"
4141 echo " 'bridge' for bridging"
4242 echo " 'none' for no Internet sharing (equivalent to -n)"
43+ echo " --wps Enable WPS (Wireless Protected Setup) with push button (PBC) and PIN modes"
4344 echo " --psk Use 64 hex digits pre-shared-key instead of passphrase"
4445 echo " --hidden Make the Access Point hidden (do not broadcast the SSID)"
4546 echo " --mac-filter Enable MAC address filtering"
@@ -77,6 +78,8 @@ usage() {
7778 echo " For an <id> you can put the PID of create_ap or the WiFi interface."
7879 echo " If virtual WiFi interface was created, then use that one."
7980 echo " You can get them with --list-running"
81+ echo " --wps-pbc <id> Simulate WPS push button (PBC)"
82+ echo " --wps-pin <id>,<pin> Enroll PIN for WPS"
8083 echo " --mkconfig <conf_file> Store configs in conf_file"
8184 echo " --config <conf_file> Load configs from conf_file"
8285 echo
@@ -686,14 +689,15 @@ DAEMON_LOGFILE=/dev/null
686689NO_HAVEGED=0
687690USE_PSK=0
688691IPV6=0
692+ WPS=0
689693
690694HOSTAPD_DEBUG_ARGS=
691695REDIRECT_TO_LOCALHOST=0
692696
693697CONFIG_OPTS=(CHANNEL GATEWAY WPA_VERSION ETC_HOSTS DHCP_DNS DHCP_DNS6 NO_DNS NO_DNSMASQ HIDDEN MAC_FILTER MAC_FILTER_ACCEPT ISOLATE_CLIENTS
694698 SHARE_METHOD IEEE80211N IEEE80211AC HT_CAPAB VHT_CAPAB DRIVER NO_VIRT COUNTRY FREQ_BAND
695699 NEW_MACADDR DAEMONIZE DAEMON_PIDFILE DAEMON_LOGFILE NO_HAVEGED WIFI_IFACE INTERNET_IFACE
696- SSID PASSPHRASE USE_PSK BEACON_INTERVAL DTIM_PERIOD IPV6 ADDN_HOSTS)
700+ SSID PASSPHRASE USE_PSK BEACON_INTERVAL DTIM_PERIOD IPV6 ADDN_HOSTS WPS )
697701
698702FIX_UNMANAGED=0
699703LIST_RUNNING=0
@@ -1006,6 +1010,40 @@ list_clients() {
10061010 fi
10071011}
10081012
1013+ wps_trigger () {
1014+ local wifi_iface pid
1015+
1016+ # If PID is given, get the associated wifi iface
1017+ if [[ " $1 " =~ ^[1-9][0-9]* $ ]]; then
1018+ pid=" $1 "
1019+ wifi_iface=$( get_wifi_iface_from_pid " $pid " )
1020+ [[ -z " $wifi_iface " ]] && die " '$pid ' is not the pid of a running $PROGNAME instance."
1021+ fi
1022+
1023+ [[ -z " $wifi_iface " ]] && wifi_iface=" $1 "
1024+ is_wifi_interface " $wifi_iface " || die " '$wifi_iface ' is not a WiFi interface."
1025+
1026+ [[ -z " $pid " ]] && pid=$( get_pid_from_wifi_iface " $wifi_iface " )
1027+ [[ -z " $pid " ]] && die " '$wifi_iface ' is not used from $PROGNAME instance.\n\
1028+ Maybe you need to pass the virtual interface instead.\n\
1029+ Use --list-running to find it out."
1030+ [[ -z " $CONFDIR " ]] && CONFDIR=$( get_confdir_from_pid " $pid " )
1031+
1032+ HOSTAPD_CLI=$( which hostapd_cli)
1033+ if ! $HOSTAPD_CLI -p $CONFDIR /hostapd_ctrl get_config | grep -q wps_state=configured; then
1034+ die " WPS is not configured. You need to run $PROGNAME with --wps, or add WPS=1 to config file."
1035+ fi
1036+
1037+ if [[ " $2 " = " PBC" ]]; then
1038+ echo " Triggering WPS pushbutton; your device will have 120 seconds to connect..."
1039+ $HOSTAPD_CLI -p $CONFDIR /hostapd_ctrl wps_pbc
1040+ else
1041+ echo " Enrolling WPS PIN '$2 '..."
1042+ $HOSTAPD_CLI -p $CONFDIR /hostapd_ctrl wps_pin any " $2 "
1043+ fi
1044+ $HOSTAPD_CLI -p $CONFDIR /hostapd_ctrl wps_get_status
1045+ }
1046+
10091047has_running_instance () {
10101048 local PID x
10111049
@@ -1120,7 +1158,7 @@ for ((i=0; i<$#; i++)); do
11201158 fi
11211159done
11221160
1123- GETOPT_ARGS=$( getopt -o hc:w:g:de:nm: -l " help" ," hidden" ," hostapd-debug:" ," redirect-to-localhost" ," mac-filter" ," mac-filter-accept:" ," isolate-clients" ," ieee80211n" ," ieee80211ac" ," ht_capab:" ," vht_capab:" ," driver:" ," no-virt" ," fix-unmanaged" ," country:" ," freq-band:" ," mac:" ," dhcp-dns:" ," dhcp-dns6:" ," daemon" ," pidfile:" ," logfile:" ," stop:" ," list" ," list-running" ," list-clients:" ," version" ," psk" ," no-haveged" ," no-dns" ," no-dnsmasq" ," ipv6" ," mkconfig:" ," config:" -n " $PROGNAME " -- " $@ " )
1161+ GETOPT_ARGS=$( getopt -o hc:w:g:de:nm: -l " help" ," hidden" ," hostapd-debug:" ," redirect-to-localhost" ," mac-filter" ," mac-filter-accept:" ," isolate-clients" ," ieee80211n" ," ieee80211ac" ," ht_capab:" ," vht_capab:" ," driver:" ," no-virt" ," fix-unmanaged" ," country:" ," freq-band:" ," mac:" ," dhcp-dns:" ," dhcp-dns6:" ," daemon" ," pidfile:" ," logfile:" ," stop:" ," list" ," list-running" ," list-clients:" ," version" ," psk" ," no-haveged" ," no-dns" ," no-dnsmasq" ," ipv6" ," mkconfig:" ," config:" , " wps " , " wps-pbc: " , " wps-pin: " -n " $PROGNAME " -- " $@ " )
11241162[[ $? -ne 0 ]] && exit 1
11251163eval set -- " $GETOPT_ARGS "
11261164
@@ -1278,10 +1316,26 @@ while :; do
12781316 LIST_CLIENTS_ID=" $1 "
12791317 shift
12801318 ;;
1319+ --wps-pbc)
1320+ shift
1321+ WPS_TRIGGER_ID=" $1 "
1322+ WPS_TRIGGER_PIN=" PBC"
1323+ shift ;
1324+ ;;
1325+ --wps-pin)
1326+ shift
1327+ WPS_TRIGGER_ID=" ${1/ ,*/ } "
1328+ WPS_TRIGGER_PIN=" ${1/* ,/ } "
1329+ shift ;
1330+ ;;
12811331 --no-haveged)
12821332 shift
12831333 NO_HAVEGED=1
12841334 ;;
1335+ --wps)
1336+ shift
1337+ WPS=1
1338+ ;;
12851339 --psk)
12861340 shift
12871341 USE_PSK=1
13421396
13431397# Check if required number of positional args are present
13441398if [[ $# -lt 1 && $FIX_UNMANAGED -eq 0 && -z " $STOP_ID " &&
1345- $LIST_RUNNING -eq 0 && -z " $LIST_CLIENTS_ID " ]]; then
1399+ $LIST_RUNNING -eq 0 && -z " $LIST_CLIENTS_ID " && -z " $WPS_TRIGGER_ID " ]]; then
13461400 usage >&2
13471401 exit 1
13481402fi
@@ -1383,6 +1437,11 @@ if [[ $(id -u) -ne 0 ]]; then
13831437 exit 1
13841438fi
13851439
1440+ if [[ -n " $WPS_TRIGGER_ID " ]]; then
1441+ wps_trigger " $WPS_TRIGGER_ID " " $WPS_TRIGGER_PIN "
1442+ exit 0
1443+ fi
1444+
13861445if [[ -n " $STOP_ID " ]]; then
13871446 echo " Trying to kill $PROGNAME instance associated with $STOP_ID ..."
13881447 send_stop " $STOP_ID "
@@ -1744,6 +1803,24 @@ beacon_int=${BEACON_INTERVAL}
17441803dtim_period=${DTIM_PERIOD}
17451804EOF
17461805
1806+ if [[ $WPS -eq 1 ]]; then
1807+ echo " Enabling WPS push button (PBC) and PIN modes!"
1808+ # WPS configuration: AP configured, do not allow external WPS Registrars,
1809+ # device type is "Network Infrastructure / AP"
1810+ cat << EOF >> $CONFDIR /hostapd.conf
1811+ wps_state=2
1812+ ap_setup_locked=1
1813+ device_type=6-0050F204-1
1814+ config_methods=push_button label
1815+ EOF
1816+ # Show SSID as device_name unless hidden
1817+ # (other potential descriptive options are manufacturer, model_name,
1818+ # model_number, serial_number, os_version)
1819+ if [[ $HIDDEN -ne 1 ]]; then
1820+ echo " device_name=${SSID} " >> $CONFDIR /hostapd.conf
1821+ fi
1822+ fi
1823+
17471824if [[ -n " $COUNTRY " ]]; then
17481825 cat << EOF >> $CONFDIR /hostapd.conf
17491826country_code=${COUNTRY}
0 commit comments