Skip to content
This repository has been archived by the owner on Sep 30, 2021. It is now read-only.

Commit

Permalink
Enable WPS push button (PBC) and PIN modes
Browse files Browse the repository at this point in the history
Use 'sudo create_ap --wps-pbc <id>' to simulate the button being pushed,
or 'sudo create_ap --wps-pin <id>,<pin>' to enroll a specific PIN
requested by a device.
  • Loading branch information
dlenski committed Jan 21, 2022
1 parent 69ae387 commit 86a3d60
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 3 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This project is a fork of the no-longer-maintained [oblique/create_ap](//github.
* Create an AP (Access Point) at any channel.
* Choose one of the following encryptions: WPA, WPA2, WPA/WPA2, Open (no encryption).
* Hide your SSID.
* Enable [Wi-Fi Protected Setup](https://en.wikipedia.org/wiki/Wi-Fi_Protected_Setup) (WPS) with push-button or PIN methods.
* Disable communication between clients (client isolation).
* IEEE 802.11n & 802.11ac support
* Internet sharing methods: NATed or Bridged or None (no Internet sharing).
Expand Down Expand Up @@ -50,6 +51,11 @@ This project is a fork of the no-longer-maintained [oblique/create_ap](//github.
### WPA + WPA2 passphrase:
create_ap wlan0 eth0 MyAccessPoint MyPassPhrase

### WPS Push Button or PIN entry:
create_ap wlan0 eth0 MyAccessPoint MyPassPhrase
create_ap --wps-pbc wlan0 # Device will have 2 minutes to connect
create_ap --wps-pin wlan0,12345678 # Enroll PIN 12345678 for device requesting it

### AP without Internet sharing:
create_ap -n wlan0 MyAccessPoint MyPassPhrase

Expand Down
83 changes: 80 additions & 3 deletions create_ap
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ usage() {
echo " Use: 'nat' for NAT (default)"
echo " 'bridge' for bridging"
echo " 'none' for no Internet sharing (equivalent to -n)"
echo " --wps Enable WPS (Wireless Protected Setup) with push button (PBC) and PIN modes"
echo " --psk Use 64 hex digits pre-shared-key instead of passphrase"
echo " --hidden Make the Access Point hidden (do not broadcast the SSID)"
echo " --mac-filter Enable MAC address filtering"
Expand Down Expand Up @@ -77,6 +78,8 @@ usage() {
echo " For an <id> you can put the PID of create_ap or the WiFi interface."
echo " If virtual WiFi interface was created, then use that one."
echo " You can get them with --list-running"
echo " --wps-pbc <id> Simulate WPS push button (PBC)"
echo " --wps-pin <id>,<pin> Enroll PIN for WPS"
echo " --mkconfig <conf_file> Store configs in conf_file"
echo " --config <conf_file> Load configs from conf_file"
echo
Expand Down Expand Up @@ -686,14 +689,15 @@ DAEMON_LOGFILE=/dev/null
NO_HAVEGED=0
USE_PSK=0
IPV6=0
WPS=0

HOSTAPD_DEBUG_ARGS=
REDIRECT_TO_LOCALHOST=0

CONFIG_OPTS=(CHANNEL GATEWAY WPA_VERSION ETC_HOSTS DHCP_DNS DHCP_DNS6 NO_DNS NO_DNSMASQ HIDDEN MAC_FILTER MAC_FILTER_ACCEPT ISOLATE_CLIENTS
SHARE_METHOD IEEE80211N IEEE80211AC HT_CAPAB VHT_CAPAB DRIVER NO_VIRT COUNTRY FREQ_BAND
NEW_MACADDR DAEMONIZE DAEMON_PIDFILE DAEMON_LOGFILE NO_HAVEGED WIFI_IFACE INTERNET_IFACE
SSID PASSPHRASE USE_PSK BEACON_INTERVAL DTIM_PERIOD IPV6 ADDN_HOSTS)
SSID PASSPHRASE USE_PSK BEACON_INTERVAL DTIM_PERIOD IPV6 ADDN_HOSTS WPS)

FIX_UNMANAGED=0
LIST_RUNNING=0
Expand Down Expand Up @@ -1006,6 +1010,40 @@ list_clients() {
fi
}

wps_trigger() {
local wifi_iface pid

# If PID is given, get the associated wifi iface
if [[ "$1" =~ ^[1-9][0-9]*$ ]]; then
pid="$1"
wifi_iface=$(get_wifi_iface_from_pid "$pid")
[[ -z "$wifi_iface" ]] && die "'$pid' is not the pid of a running $PROGNAME instance."
fi

[[ -z "$wifi_iface" ]] && wifi_iface="$1"
is_wifi_interface "$wifi_iface" || die "'$wifi_iface' is not a WiFi interface."

[[ -z "$pid" ]] && pid=$(get_pid_from_wifi_iface "$wifi_iface")
[[ -z "$pid" ]] && die "'$wifi_iface' is not used from $PROGNAME instance.\n\
Maybe you need to pass the virtual interface instead.\n\
Use --list-running to find it out."
[[ -z "$CONFDIR" ]] && CONFDIR=$(get_confdir_from_pid "$pid")

HOSTAPD_CLI=$(which hostapd_cli)
if ! $HOSTAPD_CLI -p $CONFDIR/hostapd_ctrl get_config | grep -q wps_state=configured; then
die "WPS is not configured. You need to run $PROGNAME with --wps, or add WPS=1 to config file."
fi

if [[ "$2" = "PBC" ]]; then
echo "Triggering WPS pushbutton; your device will have 120 seconds to connect..."
$HOSTAPD_CLI -p $CONFDIR/hostapd_ctrl wps_pbc
else
echo "Enrolling WPS PIN '$2'..."
$HOSTAPD_CLI -p $CONFDIR/hostapd_ctrl wps_pin any "$2"
fi
$HOSTAPD_CLI -p $CONFDIR/hostapd_ctrl wps_get_status
}

has_running_instance() {
local PID x

Expand Down Expand Up @@ -1120,7 +1158,7 @@ for ((i=0; i<$#; i++)); do
fi
done

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" -- "$@")
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" -- "$@")
[[ $? -ne 0 ]] && exit 1
eval set -- "$GETOPT_ARGS"

Expand Down Expand Up @@ -1278,10 +1316,26 @@ while :; do
LIST_CLIENTS_ID="$1"
shift
;;
--wps-pbc)
shift
WPS_TRIGGER_ID="$1"
WPS_TRIGGER_PIN="PBC"
shift;
;;
--wps-pin)
shift
WPS_TRIGGER_ID="${1/,*/}"
WPS_TRIGGER_PIN="${1/*,/}"
shift;
;;
--no-haveged)
shift
NO_HAVEGED=1
;;
--wps)
shift
WPS=1
;;
--psk)
shift
USE_PSK=1
Expand Down Expand Up @@ -1342,7 +1396,7 @@ fi

# Check if required number of positional args are present
if [[ $# -lt 1 && $FIX_UNMANAGED -eq 0 && -z "$STOP_ID" &&
$LIST_RUNNING -eq 0 && -z "$LIST_CLIENTS_ID" ]]; then
$LIST_RUNNING -eq 0 && -z "$LIST_CLIENTS_ID" && -z "$WPS_TRIGGER_ID" ]]; then
usage >&2
exit 1
fi
Expand Down Expand Up @@ -1383,6 +1437,11 @@ if [[ $(id -u) -ne 0 ]]; then
exit 1
fi

if [[ -n "$WPS_TRIGGER_ID" ]]; then
wps_trigger "$WPS_TRIGGER_ID" "$WPS_TRIGGER_PIN"
exit 0
fi

if [[ -n "$STOP_ID" ]]; then
echo "Trying to kill $PROGNAME instance associated with $STOP_ID..."
send_stop "$STOP_ID"
Expand Down Expand Up @@ -1744,6 +1803,24 @@ beacon_int=${BEACON_INTERVAL}
dtim_period=${DTIM_PERIOD}
EOF

if [[ $WPS -eq 1 ]]; then
echo "Enabling WPS push button (PBC) and PIN modes!"
# WPS configuration: AP configured, do not allow external WPS Registrars,
# device type is "Network Infrastructure / AP"
cat << EOF >> $CONFDIR/hostapd.conf
wps_state=2
ap_setup_locked=1
device_type=6-0050F204-1
config_methods=push_button label
EOF
# Show SSID as device_name unless hidden
# (other potential descriptive options are manufacturer, model_name,
# model_number, serial_number, os_version)
if [[ $HIDDEN -ne 1 ]]; then
echo "device_name=${SSID}" >> $CONFDIR/hostapd.conf
fi
fi

if [[ -n "$COUNTRY" ]]; then
cat << EOF >> $CONFDIR/hostapd.conf
country_code=${COUNTRY}
Expand Down
3 changes: 3 additions & 0 deletions create_ap.conf
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ WPA_VERSION=2
IEEE80211N=0
# Whether IEEE 802.11ac (VHT) is enabled
IEEE80211AC=0
# Whether Wi-Fi Protected Setup (WPS) is enabled
# Use '--wps-pbc' to simulate the push button, or '--wps-pin' for PIN entry.
WPS=0
# HT / VHT capabilities
# For all possible options please look at
# https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf
Expand Down

0 comments on commit 86a3d60

Please sign in to comment.