X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fhooks%2Fports%2Fwireless-ap;h=7176ee58dfe54768e151a30ed7697c24568d1f24;hb=0a4c5abab952ae0d864505f037f46cd0a27d6701;hp=4983f9c268b4122c0b5daa60addd0bb5cdbdeca7;hpb=b8026986e69b2fe26fe99b5c15b71ecf6ff95039;p=people%2Fms%2Fnetwork.git diff --git a/src/hooks/ports/wireless-ap b/src/hooks/ports/wireless-ap index 4983f9c2..7176ee58 100644 --- a/src/hooks/ports/wireless-ap +++ b/src/hooks/ports/wireless-ap @@ -21,64 +21,127 @@ . /usr/lib/network/header-port -HOOK_SETTINGS="HOOK ADDRESS BROADCAST_SSID CHANNEL MODE PHY SSID" -HOOK_SETTINGS="${HOOK_SETTINGS} ENCRYPTION KEY" - -ADDRESS=$(mac_generate) -BROADCAST_SSID=on -CHANNEL=1 -ENCRYPTION="" -KEY="" -MODE="g" -SSID= - -function hook_check() { +HOOK_PORT_PATTERN="${PORT_PATTERN_ACCESSPOINT}" + +HOOK_SETTINGS=( + "ADDRESS" + "BROADCAST_SSID" + "CHANNEL" + "CHANNEL_BANDWIDTH" + "DFS" + "ENVIRONMENT" + "MFP" + "MODE" + "PHY" + "SECRET" + "SSID" + "WPA3_PERSONAL" + "WPA2_PERSONAL" +) + +# Disable WPA3+2 by default +DEFAULT_WPA3_PERSONAL="off" +DEFAULT_WPA2_PERSONAL="off" + +# Broadcast SSID by default +DEFAULT_BROADCAST_SSID="on" + +# Perform radar detection by default when possible +DEFAULT_DFS="on" + +# 802.11w - Management Frame Protection +# Disable by default because many clients cannot connect when enabled +DEFAULT_MFP="off" + +DEFAULT_ENVIRONMENT="${WIRELESS_DEFAULT_ENVIRONMENT}" + +hook_check_settings() { assert isset ADDRESS assert ismac ADDRESS assert isset BROADCAST_SSID assert isbool BROADCAST_SSID assert isset CHANNEL + assert isbool DFS + assert isbool MFP assert isset MODE - assert isoneof MODE a b g n + assert isoneof MODE ${HOSTAPD_SUPPORTED_MODES} assert isset PHY assert ismac PHY assert isset SSID - if isset ENCRYPTION; then - assert isoneof ENCRYPTION WPA WPA2 WPA/WPA2 - - assert isset KEY - assert [ ${#KEY} -ge 8 ] - assert [ ${#KEY} -le 63 ] - fi + assert wireless_environment_is_valid "${ENVIRONMENT}" } -function hook_create() { +hook_parse_cmdline() { while [ $# -gt 0 ]; do case "${1}" in --broadcast-ssid=*) - BROADCAST_SSID=$(cli_get_val ${1}) + BROADCAST_SSID=$(cli_get_val "${1}") ;; --channel=*) - CHANNEL=$(cli_get_val ${1}) + CHANNEL=$(cli_get_val "${1}") ;; - --encryption=*) - ENCRYPTION=$(cli_get_val ${1}) + --channel-bandwidth=*) + CHANNEL_BANDWIDTH="$(cli_get_val "${1}")" ;; - --key=*) - KEY=$(cli_get_val ${1}) + --dfs=*) + DFS="$(cli_get_val "${1}")" + + if enabled DFS; then + DFS="on" + elif disabled DFS; then + DFS="off" + else + error "Invalid value for DFS: ${DFS}" + return ${EXIT_ERROR} + fi + ;; + --environment=*) + ENVIRONMENT="$(cli_get_val "${1}")" + + if ! wireless_environment_is_valid "${ENVIRONMENT}"; then + error "Invalid wireless environment: ${ENVIRONMENT}" + return ${EXIT_ERROR} + fi ;; --mac=*) - ADDRESS=$(cli_get_val ${1}) + ADDRESS=$(cli_get_val "${1}") + ;; + --mfp=*) + MFP="$(cli_get_val "${1}")" + + if enabled MFP; then + MFP="on" + elif disabled MFP; then + MFP="off" + else + error "Invalid value for --mfp: ${MFP}" + return ${EXIT_ERROR} + fi ;; --mode=*) - MODE=$(cli_get_val ${1}) + MODE=$(cli_get_val "${1}") + + if ! isoneof MODE ${HOSTAPD_SUPPORTED_MODES}; then + error "Unsupported mode: ${MODE}" + error "Mode must be one of ${HOSTAPD_SUPPORTED_MODES}" + return ${EXIT_ERROR} + fi ;; --phy=*) - PHY=$(cli_get_val ${1}) + PHY=$(cli_get_val "${1}") + ;; + --secret=*) + SECRET="$(cli_get_val "${1}")" ;; --ssid=*) - SSID=$(cli_get_val ${1}) + SSID=$(cli_get_val "${1}") + ;; + --wpa2-personal=*) + WPA2_PERSONAL="$(cli_get_bool "${1}")" + ;; + --wpa3-personal=*) + WPA3_PERSONAL="$(cli_get_bool "${1}")" ;; *) warning "Ignoring unknown argument '${1}'" @@ -87,63 +150,60 @@ function hook_create() { shift done - # Save address of phy do identify it again - PHY=$(phy_get ${PHY}) - PHY=$(phy_get_address ${PHY}) + # Generate a random MAC address if none is set + if ! isset ADDRESS; then + ADDRESS="$(mac_generate)" + fi - local port=$(port_find_free ${PORT_PATTERN_ACCESSPOINT}) - assert isset port + # MODE must be set + if ! isset MODE; then + error "--mode is not set" + return ${EXIT_ERROR} + fi - port_settings_write "${port}" ${HOOK_SETTINGS} + # Automatically enable ACS if no channel is set and ACS is available + if ! isset CHANNEL && phy_supports_acs "${PHY}"; then + CHANNEL="0" - exit ${EXIT_OK} -} + log INFO "Automatic Channel Selection (ACS) enabled" + fi -function hook_edit() { - local port=${1} - shift + # Channel bandwidth must match the mode + if isset CHANNEL_BANDWIDTH && ! wireless_channel_bandwidth_is_valid "${MODE}" "${CHANNEL_BANDWIDTH}"; then + error "Channel Bandwidth '${CHANNEL_BANDWIDTH}' is not supported for ${MODE}" + return ${EXIT_ERROR} + fi - assert isset port + # Check if SECRET is set when WPA* is enabled + if ! isset SECRET && (enabled WPA3_PERSONAL || enabled WPA2_PERSONAL); then + error "Secret is not set when PSK authentication is enabled" + return ${EXIT_ERROR} + fi - port_settings_read "${port}" ${HOOK_SETTINGS} + # Save address of phy do identify it again + PHY=$(phy_get ${PHY}) + PHY=$(phy_get_address ${PHY}) +} - while [ $# -gt 0 ]; do - case "${1}" in - --broadcast-ssid=*) - BROADCAST_SSID=$(cli_get_val ${1}) - ;; - --channel=*) - CHANNEL=$(cli_get_val ${1}) - ;; - --encryption=*) - ENCRYPTION=$(cli_get_val ${1}) - ;; - --key=*) - KEY=$(cli_get_val ${1}) - ;; - --ssid=*) - SSID=$(cli_get_val ${1}) - ;; - --mode=*) - MODE=$(cli_get_val ${1}) - ;; - *) - warning "Unknown argument '${1}'" - ;; - esac - shift - done +hook_edit() { + local port=${1} + assert isset port - port_settings_write "${port}" ${HOOK_SETTINGS} + if ! hook_default_edit "$@"; then + return ${EXIT_ERROR} + fi - exit ${EXIT_OK} + # To apply all changes, we need to restart the port + port_restart "${port}" } -function hook_up() { - local port=${1} +hook_create() { + local port="${1}" assert isset port - port_settings_read "${port}" ${HOOK_SETTINGS} + device_exists "${port}" && exit ${EXIT_OK} + + port_settings_read "${port}" # Check if the PHY is present. local phy=$(phy_get ${PHY}) @@ -152,26 +212,17 @@ function hook_up() { exit ${EXIT_ERROR} fi - # Create the wireless device, if it does not exist, yet. - if ! device_exists ${port}; then - wireless_create ${port} --phy="${phy}" --type="ap" \ - --address="${ADDRESS}" - fi - - # Start the hostapd service. - #hostapd_start ${port} - local ret=$? - - if [ ${ret} -ne ${EXIT_OK} ]; then - log ERROR "Could not start hostapd on port '${port}': ${ret}" - exit ${EXIT_ERROR} - fi + # Create the wireless device + wireless_create "${port}" \ + --phy="${phy}" \ + --type="ap" \ + --address="${ADDRESS}" exit ${EXIT_OK} } -function hook_down() { - local port=${1} +hook_remove() { + local port="${1}" assert isset port # Remove the device if present @@ -182,19 +233,34 @@ function hook_down() { exit ${EXIT_OK} } -function hook_hotplug() { +hook_up() { + local port="${1}" + assert isset port + + # The port must already exist before + # hostapd is started. Otherwise it will + # fail horribly over and over again. + assert device_exists "${port}" + + hostapd_start "${port}" +} + +hook_down() { + local port="${1}" + assert isset port + + hostapd_stop "${port}" +} + +hook_hotplug() { local port="${1}" assert isset port case "$(hotplug_action)" in add) - # Start hostapd after the port has been brought up - if hotplug_event_port_is_interface "${port}"; then - hostapd_start "${port}" - - # Bring up the port when the phy is plugged in - elif hotplug_event_port_uses_phy "${port}"; then - hook_up "${port}" + # Create the port when the phy is plugged in + if hotplug_event_port_uses_phy "${port}"; then + hook_create "${port}" fi ;; @@ -202,13 +268,11 @@ function hook_hotplug() { # Stop hostapd if hotplug_event_port_is_interface "${port}"; then hostapd_stop "${port}" - fi - ;; - *) - exit ${EXIT_NOT_HANDLED} + exit ${EXIT_OK} + fi ;; esac - exit ${EXIT_OK} + exit ${EXIT_NOT_HANDLED} }