]> git.ipfire.org Git - people/ms/network.git/blobdiff - src/functions/functions.wireless
wireless-ap: Check that secret has the correct length and no invalid characters
[people/ms/network.git] / src / functions / functions.wireless
index 6b33cf59dd46228cb6231e31ee780a626cf849fd..733a35621b3efbcbc0cd19589ebdc35063f11159 100644 (file)
@@ -25,13 +25,35 @@ NETWORK_SETTINGS_FILE_PARAMS="${NETWORK_SETTINGS_FILE_PARAMS} WIRELESS_REGULATOR
 
 WIRELESS_REGULATORY_DOMAIN_DATABASE="/usr/lib/crda/regulatory.bin"
 
-WIRELESS_NETWORK_CONFIG_SETTINGS="\
-       SSID \
-       ENCRYPTION_MODE \
-       KEY \
-       PRIORITY"
+WIRELESS_DEFAULT_ENCRYPTION_MODE="NONE"
+WIRELESS_VALID_ENCRYPTION_MODES="WPA2-PSK-SHA256 WPA2-PSK \
+       WPA-PSK-SHA256 WPA-PSK NONE"
 
-WIRELESS_NETWORKS_VALID_ENCRYPTION_MODES="WPA2-PSK"
+declare -A WIRELESS_CHANNEL_BANDWIDTHS=(
+       ["802.11ac"]="20 40 80 160 80+80"
+       ["802.11a/n"]="20 40"
+       ["802.11a"]="20 40"
+       ["802.11g/n"]="20 40"
+       ["802.11g"]="20 40"
+)
+
+WIRELESS_ENVIRONMENTS=( "indoor+outdoor" "indoor" "outdoor" )
+WIRELESS_DEFAULT_ENVIRONMENT="${WIRELESS_ENVIRONMENTS[0]}"
+
+cli_wireless() {
+       local action=${1}
+       shift 1
+
+       case "${action}" in
+               network)
+                       cli_wireless_network "$@"
+                       ;;
+               *)
+                       error "Unrecognized argument: ${action}"
+                       exit ${EXIT_ERROR}
+                       ;;
+       esac
+}
 
 wireless_create() {
        local device=${1}
@@ -100,7 +122,7 @@ wireless_create() {
 
        # Set the channel
        if isset channel; then
-               wireless_set_channel "${device}" "${channel}" || return $?
+               wireless_set_channel "${device}" "${channel}" "auto" || return $?
        fi
 
        return ${ret}
@@ -298,9 +320,46 @@ wireless_channel_is_valid() {
        return ${EXIT_FALSE}
 }
 
+wireless_channel_bandwidth_is_valid() {
+       local mode="${1}"
+       assert isset mode
+
+       local bandwidth="${2}"
+       assert isset bandwidth
+
+       local bandwidths="${WIRELESS_CHANNEL_BANDWIDTHS["${mode}"]}"
+
+       list_match "${bandwidth}" ${bandwidths}
+}
+
+wireless_channel_is_ht40_plus() {
+       local channel="${1}"
+       assert isinteger channel
+
+       # 2.4 GHz
+       if [ ${channel} -le 6 ]; then
+               return ${EXIT_TRUE}
+       fi
+
+       return ${EXIT_FALSE}
+}
+
+wireless_channel_is_ht40_minus() {
+       local channel="${1}"
+       assert isinteger channel
+
+       # 2.4 GHz
+       if [ ${channel} -ge 6 ]; then
+               return ${EXIT_TRUE}
+       fi
+
+       return ${EXIT_FALSE}
+}
+
 wireless_set_channel() {
-       local device=${1}
-       local channel=${2}
+       local device="${1}"
+       local channel="${2}"
+       local bandwidth="${3}"
 
        # Check if the device exists
        if ! device_exists "${device}"; then
@@ -314,8 +373,53 @@ wireless_set_channel() {
                return ${EXIT_ERROR}
        fi
 
+       local ht_flag
+       if [ "${bandwidth}" = "auto" ]; then
+               local phy="$(device_get_phy "${device}")"
+
+               # Offset of a 40 MHz channel
+               local ht_offset=5
+
+               if wireless_channel_is_ht40_plus "${channel}" \
+                               && phy_supports_ht_capability "${phy}" "HT40+" \
+                               && phy_supports_channel "${phy}" $(( channel + ht_offset )); then
+                       ht_flag="HT40+"
+
+               elif wireless_channel_is_ht40_minus "${channel}" \
+                               && phy_supports_ht_capability "${phy}" "HT40-" \
+                               && phy_supports_channel "${phy}" $(( channel - ht_offset )); then
+                       ht_flags="HT40-"
+               fi
+       fi
+
        log DEBUG "Setting wireless channel on device '${device}' to channel '${channel}'"
-       cmd iw dev "${device}" set channel "${channel}"
+       cmd iw dev "${device}" set channel "${channel}" "${ht_flag}"
+}
+
+wireless_pre_shared_key_is_valid() {
+       local psk="${1}"
+
+       # Length of the PSK
+       local l="${#psk}"
+
+       # For WPA*, the key must be between 8 and 63 chars
+       if [ ${l} -lt 8 ] || [ ${l} -gt 63 ]; then
+               return ${EXIT_FALSE}
+       fi
+
+       # Can only contain ASCII chararcters
+       if contains_non_ascii_characters "${psk}"; then
+               return ${EXIT_FALSE}
+       fi
+
+       # Seems OK
+       return ${EXIT_TRUE}
+}
+
+wireless_client_is_connected() {
+       local device="${1}"
+
+       device_has_carrier "${device}"
 }
 
 wireless_ibss_join() {
@@ -408,311 +512,60 @@ wireless_monitor() {
        return ${EXIT_OK}
 }
 
-cli_wireless() {
-       local action=${1}
-       shift 1
-
-       case "${action}" in
-               network)
-                       cli_wireless_network "$@"
-                       ;;
-               *)
-                       error "Unrecognized argument: ${action}"
-                       exit ${EXIT_ERROR}
-                       ;;
-       esac
-}
-
-cli_wireless_network() {
-       if wireless_network_exists "${1}"; then
-               local ssid="${1}"
-               local key="${2}"
-               key=${key//-/_}
-               shift 2
-
-               case "${key}" in
-                       encryption_mode|key|priority)
-                               wireless_network_${key} "${ssid}" "$@"
-                               ;;
-                       show)
-                               wireless_network_show "${ssid}"
-                               exit $?
-                               ;;
-                       *)
-                               error "Unrecognized argument: ${key}"
-                               exit ${EXIT_ERROR}
-                               ;;
-               esac
-       else
-               local action=${1}
-               shift
-
-               case "${action}" in
-                       new)
-                               wireless_network_new "$@"
-                               ;;
-                       destroy)
-                               wireless_network_destroy "$@"
-                               ;;
-                       ""|*)
-                               if [ -n "${action}" ]; then
-                                       error "Unrecognized argument: '${action}'"
-                               fi
-                               exit ${EXIT_ERROR}
-                               ;;
-               esac
-       fi
-}
-
-# This function writes all values to a via ${ssid} specificated wireless network configuration file
-wireless_network_write_config() {
-       assert [ $# -ge 1 ]
-
-       local ssid="${1}"
-
-       local ssid_hash="$(wireless_network_hash "${ssid}")"
-       assert isset ssid_hash
-
-       if ! wireless_network_exists "${ssid}"; then
-               log ERROR "No such wireless network: '${ssid}'"
-               return ${EXIT_ERROR}
-       fi
-
-       local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
-
-       if ! settings_write "${path}" ${WIRELESS_NETWORK_CONFIG_SETTINGS}; then
-               log ERROR "Could not write configuration settings for wireless network ${ssid}"
-               return ${EXIT_ERROR}
-       fi
-
-       # When we get here the writing of the config file was successful
-       return ${EXIT_OK}
-}
-
-# This funtion writes the value for one key to a via ${ssid} specificated
-# wireless network configuration file
-wireless_network_write_config_key() {
-       assert [ $# -ge 3 ]
-
-       local ssid="${1}"
-       local key="${2}"
-       shift 2
-
-       local value="$@"
-
-       if ! wireless_network_exists "${ssid}"; then
-               log ERROR "No such wireless network: ${ssid}"
-               return ${EXIT_ERROR}
-       fi
-
-       log DEBUG "Set '${key}' to new value '${value}' in wireless network '${ssid}'"
-
-       local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
-
-       # Read the config settings
-       if ! wireless_network_read_config "${ssid}"; then
-               return ${EXIT_ERROR}
-       fi
-
-       # Set the key to a new value
-       assign "${key}" "${value}"
+wireless_get_ht_caps() {
+       local device="${1}"
+       assert isset device
 
-       if ! wireless_network_write_config "${ssid}"; then
+       local phy="$(device_get_phy "${device}")"
+       if ! isset phy; then
+               log ERROR "Could not determine PHY for ${device}"
                return ${EXIT_ERROR}
        fi
 
-       return ${EXIT_OK}
+       network-phy-list-ht-caps "${phy}"
 }
 
-# Reads one or more keys out of a settings file or all if no key is provided.
-wireless_network_read_config() {
-       assert [ $# -ge 1 ]
-
-       local ssid="${1}"
-       shift 1
-
-       local ssid_hash="$(wireless_network_hash "${ssid}")"
-       assert isset ssid_hash
-
-       if ! wireless_network_exists "${ssid}"; then
-               log ERROR "No such wireless network : ${ssid}"
-               return ${EXIT_ERROR}
-       fi
-
-       local args
-       if [ $# -eq 0 ] && [ -n "${WIRELESS_NETWORK_CONFIG_SETTINGS}" ]; then
-               list_append args ${WIRELESS_NETWORK_CONFIG_SETTINGS}
-       else
-               list_append args "$@"
-       fi
-
-       local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
+wireless_get_vht_caps() {
+       local device="${1}"
+       assert isset device
 
-       if ! settings_read "${path}" ${args}; then
-               log ERROR "Could not read settings for wireless network ${ssid}"
+       local phy="$(device_get_phy "${device}")"
+       if ! isset phy; then
+               log ERROR "Could not determine PHY for ${device}"
                return ${EXIT_ERROR}
        fi
-}
-
-# This function checks if a wireless network exists
-# Returns True when yes and false when not
-wireless_network_exists() {
-       assert [ $# -eq 1 ]
-
-       local ssid="${1}"
-       local ssid_hash="$(wireless_network_hash "${ssid}")"
-       assert isset ssid_hash
-
-       local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}"
-
-       # We cannot use wireless_network_read_config here beacuse we would end in a loop
-       local SSID
-
-       local path_settings="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
-
-       if ! settings_read "${path_settings}" SSID; then
-               return ${EXIT_FALSE}
-       fi
 
-       assert isset SSID
-
-       if [ -d "${path}" ] && [[ "${ssid}" = "${SSID}" ]]; then
-               return ${EXIT_TRUE}
-       else
-               return ${EXIT_FALSE}
-       fi
+       network-phy-list-vht-caps "${phy}"
 }
 
-wireless_network_hash() {
-       assert [ $# -eq 1 ]
-
-       local string="${1}"
-
-       local hash=$(echo -n "${string}" | md5sum )
-       hash=${hash%%  -}
-
-       local path="${NETWORK_WIRELESS_NETWORKS_DIR}/*${hash}"
-
-       if [ -d "${path}" ]; then
-               basename "${path}"
-       else
-               local normalized=$(normalize "${string}")
-               normalized=${normalized%-}
-               echo "${normalized}-${hash}"
-       fi
-}
-
-wireless_network_new() {
-       if [ $# -gt 1 ]; then
-               error "Too many arguments"
-               return ${EXIT_ERROR}
-       fi
-
-       local ssid="${1}"
-       if ! isset ssid; then
-               error "Please provide a SSID"
-               return ${EXIT_ERROR}
-       fi
-
-       local ssid_hash="$(wireless_network_hash "${ssid}")"
-       assert isset ssid_hash
-
-       # Check for duplicates
-       if wireless_network_exists "${ssid}"; then
-               error "The wireless network ${ssid} already exists"
-               return ${EXIT_ERROR}
-       fi
-
-       log DEBUG "Creating wireless network '${ssid}'"
-
-       if ! mkdir -p "${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}"; then
-               log ERROR "Could not create config directory for wireless network ${ssid}"
-               return ${EXIT_ERROR}
-       fi
-
-       # When the ssid is not set in the settings file we cannot write it because wireless_network_exists fails
-       echo "SSID=\"${ssid}\"" >>"${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
-
-       local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
-       SSID="${ssid}"
-       PRIORITY=500
+wireless_supports_acs() {
+       local device="${1}"
+       assert isset device
 
-       if ! wireless_network_write_config "${ssid}"; then
-               log ERROR "Could not write new config file"
+       local phy="$(device_get_phy "${device}")"
+       if ! isset phy; then
+               log ERROR "Could not determine PHY for ${device}"
                return ${EXIT_ERROR}
        fi
-}
-
-# Function that deletes based on the passed parameters
-# one ore more wireless networks
-wireless_network_destroy() {
-       local ssid
-       for ssid in "$@"; do
-               local ssid_hash="$(wireless_network_hash "${ssid}")"
-               assert isset ssid_hash
-
-               if ! wireless_network_exists "${ssid}"; then
-                       log ERROR "The wireless network ${ssid} does not exist."
-                       continue
-               fi
 
-               log DEBUG "Deleting wireless network ${ssid}"
-
-               if ! rm -rf "${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}"; then
-                       log ERROR "Deleting the wireless network ${ssid} was not sucessful"
-                       return ${EXIT_ERROR}
-               fi
-       done
+       phy_supports_acs "${phy}"
 }
 
-wireless_network_encryption_mode() {
-       if [ ! $# -eq 2 ]; then
-               log ERROR "Not enough arguments"
-               return ${EXIT_ERROR}
-       fi
-       local ssid="${1}"
-       local mode="${2}"
-
-       if ! isoneof mode ${WIRELESS_NETWORKS_VALID_ENCRYPTION_MODES}; then
-               log ERROR "Encryption mode '${mode}' is invalid"
-               return ${EXIT_ERROR}
-       fi
-
-       if ! wireless_network_write_config_key "${ssid}" "ENCRYPTION_MODE" ${mode^^}; then
-               log ERROR "Could not write configuration settings"
-               return ${EXIT_ERROR}
-       fi
-}
+wireless_supports_dfs() {
+       local device="${1}"
+       assert isset device
 
-wireless_network_key() {
-       if [ ! $# -eq 2 ]; then
-               log ERROR "Not enough arguments"
+       local phy="$(device_get_phy "${device}")"
+       if ! isset phy; then
+               log ERROR "Could not determine PHY for ${device}"
                return ${EXIT_ERROR}
        fi
-       local ssid="${1}"
-       local key="${2}"
 
-       if ! wireless_network_write_config_key "${ssid}" "KEY" "${key}"; then
-               log ERROR "Could not write configuration settings"
-               return ${EXIT_ERROR}
-       fi
+       phy_supports_dfs "${phy}"
 }
 
-wireless_network_priority() {
-       if [ ! $# -eq 2 ]; then
-               log ERROR "Not enough arguments"
-               return ${EXIT_ERROR}
-       fi
-       local ssid="${1}"
-       local priority=${2}
-
-       if ! isinteger priority && [ ! ${priority} -ge 0 ]; then
-               log ERROR "The priority must be an integer greater or eqal zero"
-               return ${EXIT_ERROR}
-       fi
+wireless_environment_is_valid() {
+       local environment="${1}"
 
-       if ! wireless_network_write_config_key "${ssid}" "PRIORITY" "${priority}"; then
-               log ERROR "Could not write configuration settings"
-               return ${EXIT_ERROR}
-       fi
+       list_match "${environment}" "${WIRELESS_ENVIRONMENTS[@]}"
 }