# #
###############################################################################
-WIRELESS_NETWORK_CONFIG_SETTINGS="ENCRYPTION_MODE KEY PRIORITY SSID"
+WIRELESS_NETWORK_SUPPORTED_PSK_MODES="WPA2-PSK-SHA256 WPA2-PSK WPA-PSK-SHA256 WPA-PSK"
-WIRELESS_NETWORKS_VALID_ENCRYPTION_MODES="WPA2-PSK"
+WIRELESS_NETWORK_SUPPORTED_MODES="${WIRELESS_NETWORK_SUPPORTED_PSK_MODES} NONE"
+
+WIRELESS_NETWORK_CONFIG_SETTINGS="EAP_MODES ENCRYPTION_MODES PRIORITY PSK SSID"
cli_wireless_network() {
case "${1}" in
*)
local ssid="${1}"
local key="${2//-/_}"
- shift
+ shift 2
if ! wireless_network_exists "${ssid}"; then
error "No such wireless network: ${ssid}"
return ${EXIT_ERROR}
fi
+ # Convert SSID into usable format
+ local handle="$(wireless_network_hash "${ssid}")"
+
case "${key}" in
- encryption_mode|key|priority)
- wireless_network_${key} "${ssid}" "$@"
+ encryption_mode|pre_shared_key|priority)
+ wireless_network_${key} "${handle}" "$@"
;;
show)
- wireless_network_show "${ssid}"
+ wireless_network_show "${handle}"
exit $?
;;
*)
esac
}
+wireless_network_list() {
+ list_directory "${NETWORK_WIRELESS_NETWORKS_DIR}"
+}
+
+wireless_network_list_ssids() {
+ local handle
+ for handle in $(wireless_network_list); do
+ local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
+ if ! wireless_network_read_config "${handle}"; then
+ continue
+ fi
+
+ print "${SSID}"
+ done
+}
+
# 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 handle="${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"
+ local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
if ! settings_write "${path}" ${WIRELESS_NETWORK_CONFIG_SETTINGS}; then
- log ERROR "Could not write configuration settings for wireless network ${ssid}"
+ log ERROR "Could not write configuration"
return ${EXIT_ERROR}
fi
wireless_network_write_config_key() {
assert [ $# -ge 3 ]
- local ssid="${1}"
+ local handle="${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
+ if ! wireless_network_read_config "${handle}"; then
return ${EXIT_ERROR}
fi
+ log DEBUG "Set '${key}' to new value '${value}' in wireless network '${SSID}'"
+
# Set the key to a new value
assign "${key}" "${value}"
- if ! wireless_network_write_config "${ssid}"; then
+ if ! wireless_network_write_config "${handle}"; then
return ${EXIT_ERROR}
fi
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 handle="${1}"
+ shift
local args
if [ $# -eq 0 ] && [ -n "${WIRELESS_NETWORK_CONFIG_SETTINGS}" ]; then
list_append args "$@"
fi
- local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
+ local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
if ! settings_read "${path}" ${args}; then
- log ERROR "Could not read settings for wireless network ${ssid}"
+ log ERROR "Could not read settings for wireless network ${handle}"
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}"
+ local handle="$(wireless_network_hash "${ssid}")"
+ assert isset handle
# 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
+ if ! settings_read "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings" SSID; then
return ${EXIT_FALSE}
fi
- assert isset SSID
-
- if [ -d "${path}" ] && [[ "${ssid}" = "${SSID}" ]]; then
+ if [ "${SSID}" = "${ssid}" ]; then
return ${EXIT_TRUE}
else
return ${EXIT_FALSE}
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
+ local handle="$(wireless_network_hash "${ssid}")"
+ assert isset handle
+
log DEBUG "Creating wireless network '${ssid}'"
- if ! mkdir -p "${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}"; then
+ if ! mkdir -p "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; 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}
+ ENCRYPTION_MODE="${WIRELESS_DEFAULT_ENCRYPTION_MODE}"
SSID="${ssid}"
PRIORITY=500
- if ! wireless_network_write_config "${ssid}"; then
+ if ! wireless_network_write_config "${handle}"; then
log ERROR "Could not write new config file"
return ${EXIT_ERROR}
fi
}
-# Function that deletes based on the passed parameters
-# one ore more wireless networks
+# Deletes a wireless network
wireless_network_destroy() {
- local ssid
- for ssid in "$@"; do
- local ssid_hash="$(wireless_network_hash "${ssid}")"
- assert isset ssid_hash
+ local ssid="${1}"
- if ! wireless_network_exists "${ssid}"; then
- log ERROR "The wireless network ${ssid} does not exist."
- continue
- fi
+ if ! wireless_network_exists "${ssid}"; then
+ error "No such wireless network: ${ssid}"
+ return ${EXIT_ERROR}
+ fi
- log DEBUG "Deleting wireless network ${ssid}"
+ local handle="$(wireless_network_hash "${ssid}")"
+ assert isset handle
- 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
+ if ! rm -rf "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
+ error "Could not delete the wireless network"
+ return ${EXIT_ERROR}
+ fi
+
+ log INFO "Successfully destroyed wireless network ${ssid}"
+ return ${EXIT_OK}
}
wireless_network_encryption_mode() {
log ERROR "Not enough arguments"
return ${EXIT_ERROR}
fi
- local ssid="${1}"
+ local handle="${1}"
local mode="${2}"
- if ! isoneof mode ${WIRELESS_NETWORKS_VALID_ENCRYPTION_MODES}; then
+ if ! isoneof mode ${WIRELESS_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
+ local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
+ if ! wireless_network_read_config "${handle}"; then
+ error "Could not read configuration"
+ return ${EXIT_ERROR}
+ fi
+
+ # Validate the PSK when changing mode and reset if needed
+ if isset PSK && [ "${mode}" != "NONE" ] && \
+ ! wireless_pre_shared_key_is_valid "${mode}" "${PSK}"; then
+ log WARNING "The configured pre-shared-key is incompatible with this encryption mode and has been reset"
+ PSK=""
+ fi
+
+ # Save new encryption mode
+ ENCRYPTION_MODE="${mode}"
+
+ if ! wireless_network_write_config "${handle}"; then
log ERROR "Could not write configuration settings"
return ${EXIT_ERROR}
fi
}
-wireless_network_key() {
+wireless_network_pre_shared_key() {
if [ ! $# -eq 2 ]; then
log ERROR "Not enough arguments"
return ${EXIT_ERROR}
fi
- local ssid="${1}"
- local key="${2}"
- if ! wireless_network_write_config_key "${ssid}" "KEY" "${key}"; then
+ local handle="${1}"
+ local psk="${2}"
+
+ local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
+ if ! wireless_network_read_config "${handle}"; then
+ error "Could not read configuration"
+ return ${EXIT_ERROR}
+ fi
+
+ # Validate the key if encryption mode is known
+ if isset ENCRYPTION_MODE && [ "${ENCRYPTION_MODE}" != "NONE" ]; then
+ if ! wireless_pre_share_key_is_valid "${ENCRYPTION_MODE}" "${psk}"; then
+ error "The pre-shared-key is invalid for this wireless network: ${psk}"
+ return ${EXIT_ERROR}
+ fi
+ fi
+
+ if ! wireless_network_write_config_key "${handle}" "PSK" "${psk}"; then
log ERROR "Could not write configuration settings"
return ${EXIT_ERROR}
fi
log ERROR "Not enough arguments"
return ${EXIT_ERROR}
fi
- local ssid="${1}"
+
+ local handle="${1}"
local priority=${2}
if ! isinteger priority && [ ! ${priority} -ge 0 ]; then
return ${EXIT_ERROR}
fi
- if ! wireless_network_write_config_key "${ssid}" "PRIORITY" "${priority}"; then
+ if ! wireless_network_write_config_key "${handle}" "PRIORITY" "${priority}"; then
log ERROR "Could not write configuration settings"
return ${EXIT_ERROR}
fi
}
+
+wireless_networks_write_wpa_supplicant_configuration() {
+ local device="${1}"
+
+ local file="${WPA_SUPPLICANT_CONF_DIR}/${device}.conf"
+
+ # Ensure we can write the file
+ make_parent_directory "${file}"
+
+ local country="$(wireless_get_reg_domain)"
+
+ (
+ config_header "WPA supplicant configuration file"
+
+ # Honour country
+ if isset country; then
+ print "country=${country}"
+ print
+ fi
+
+ wireless_networks_to_wpa_supplicant
+ ) > ${file}
+}
+
+wireless_networks_to_wpa_supplicant() {
+ local handle
+ for handle in $(wireless_network_list); do
+ wireless_network_to_wpa_supplicant "${handle}"
+ done
+}
+
+wireless_network_to_wpa_supplicant() {
+ local handle="${1}"
+
+ local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
+ if ! wireless_network_read_config "${handle}"; then
+ error "Could not read configuration for ${handle}"
+ return ${EXIT_ERROR}
+ fi
+
+ local auth_alg
+ local group
+ local key_mgmt
+ local pairwise
+ local proto
+
+ local mode
+ for mode in ${WIRELESS_NETWORK_SUPPORTED_MODES}; do
+ # Skip any disabled modes
+ if isset ENCRYPTION_MODES && ! list_match "${mode}" ${ENCRYPTION_MODES}; then
+ continue
+ fi
+
+ case "${mode}" in
+ # WPA2 (802.11i)
+ WPA2-PSK|WPA2-PSK-SHA256)
+ list_append_unique auth_alg "OPEN"
+ list_append_unique key_mgmt "${mode/WPA2/WPA}"
+ list_append_unique proto "RSN"
+
+ local p
+ for p in CCMP TKIP; do
+ list_append_unique pairwise "${p}"
+ done
+
+ local g
+ for g in CCMP TKIP WEP104 WEP40; do
+ list_append_unique group "${g}"
+ done
+ ;;
+
+ # WPA
+ WPA-PSK|WPA-PSK-SHA256)
+ list_append_unique auth_alg "OPEN"
+ list_append_unique key_mgmt "${mode}"
+ list_append_unique proto "WPA"
+
+ local p
+ for p in CCMP TKIP; do
+ list_append_unique pairwise "${p}"
+ done
+
+ local g
+ for g in CCMP TKIP WEP104 WEP40; do
+ list_append_unique group "${g}"
+ done
+ ;;
+
+ # No encryption. DANGEROUS!
+ NONE)
+ list_append_unique auth_alg "OPEN"
+ list_append_unique key_mgmt "NONE"
+ ;;
+ esac
+ done
+
+ assert isset auth_alg
+ assert isset key_mgmt
+
+ print_indent 0 "# ${SSID}"
+ print_indent 0 "network = {"
+ print_indent 1 "ssid=\"${SSID}\""
+
+ # Priority
+ if isinteger PRIORITY; then
+ print_indent 1 "priority=${PRIORITY}"
+ fi
+ print
+
+ # Authentication
+ print_indent 1 "# Authentication"
+ print_indent 1 "auth_alg=${auth_alg}"
+ print_indent 1 "key_mgmt=${key_mgmt}"
+
+ local i
+ for i in proto pairwise group; do
+ print_indent 1 "${i}=${!i}"
+ done
+ print
+
+ # PSK
+ if isset PSK; then
+ print_indent 1 "# Pre Shared Key"
+ print_indent 1 "psk=\"${PSK}\""
+ fi
+
+ if isset EAP_MODES; then
+ print_indent 1 "# EAP"
+ print_indent 1 "eap=${EAP_MODES}"
+ print
+ fi
+
+ print_indent 0 "}"
+ print
+}