2 ###############################################################################
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2017 IPFire Network Development Team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
22 WIRELESS_NETWORK_SUPPORTED_PSK_MODES
="WPA2-PSK-SHA256 WPA2-PSK WPA-PSK-SHA256 WPA-PSK"
24 WIRELESS_NETWORK_SUPPORTED_MODES
="${WIRELESS_NETWORK_SUPPORTED_PSK_MODES} \
27 WIRELESS_NETWORK_CONFIG_SETTINGS
="ANONYMOUS_IDENTITY EAP_MODES IDENTITY \
28 MODES PASSWORD PRIORITY PSK SSID"
30 cli_wireless_network
() {
33 wireless_network_new
"${@:2}"
36 wireless_network_destroy
"${@:2}"
43 if ! wireless_network_exists
"${ssid}"; then
44 error
"No such wireless network: ${ssid}"
48 # Convert SSID into usable format
49 local handle
="$(wireless_network_hash "${ssid}")"
52 encryption_mode|pre_shared_key|priority
)
53 wireless_network_
${key} "${handle}" "$@"
56 wireless_network_show
"${handle}"
60 error
"Unrecognized argument: ${key}"
68 wireless_network_list
() {
69 list_directory
"${NETWORK_WIRELESS_NETWORKS_DIR}"
72 wireless_network_list_ssids
() {
74 for handle
in $
(wireless_network_list
); do
75 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
76 if ! wireless_network_read_config
"${handle}"; then
84 # This function writes all values to a via ${ssid} specificated wireless network configuration file
85 wireless_network_write_config
() {
90 local path
="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
92 if ! settings_write
"${path}" ${WIRELESS_NETWORK_CONFIG_SETTINGS}; then
93 log ERROR
"Could not write configuration"
97 # When we get here the writing of the config file was successful
101 # This funtion writes the value for one key to a via ${ssid} specificated
102 # wireless network configuration file
103 wireless_network_write_config_key
() {
112 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
114 # Read the config settings
115 if ! wireless_network_read_config
"${handle}"; then
119 log DEBUG
"Set '${key}' to new value '${value}' in wireless network '${SSID}'"
121 # Set the key to a new value
122 assign
"${key}" "${value}"
124 if ! wireless_network_write_config
"${handle}"; then
131 # Reads one or more keys out of a settings file or all if no key is provided.
132 wireless_network_read_config
() {
139 if [ $# -eq 0 ] && [ -n "${WIRELESS_NETWORK_CONFIG_SETTINGS}" ]; then
140 list_append args
${WIRELESS_NETWORK_CONFIG_SETTINGS}
142 list_append args
"$@"
145 local path
="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
147 if ! settings_read
"${path}" ${args}; then
148 log ERROR
"Could not read settings for wireless network ${handle}"
153 # This function checks if a wireless network exists
154 # Returns True when yes and false when not
155 wireless_network_exists
() {
158 local handle
="$(wireless_network_hash "${ssid}")"
161 # We cannot use wireless_network_read_config here beacuse we would end in a loop
163 if ! settings_read
"${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings" SSID
; then
167 if [ "${SSID}" = "${ssid}" ]; then
174 wireless_network_hash
() {
179 local hash=$
(echo -n "${string}" |
md5sum )
182 local path
="${NETWORK_WIRELESS_NETWORKS_DIR}/*${hash}"
184 if [ -d "${path}" ]; then
187 local normalized
=$
(normalize
"${string}")
188 normalized
=${normalized%-}
189 echo "${normalized}-${hash}"
193 wireless_network_new
() {
194 if [ $# -gt 1 ]; then
195 error
"Too many arguments"
201 if ! isset ssid
; then
202 error
"Please provide a SSID"
206 # Check for duplicates
207 if wireless_network_exists
"${ssid}"; then
208 error
"The wireless network ${ssid} already exists"
212 local handle
="$(wireless_network_hash "${ssid}")"
215 log DEBUG
"Creating wireless network '${ssid}'"
217 if ! mkdir
-p "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
218 log ERROR
"Could not create config directory for wireless network ${ssid}"
222 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
223 MODES
="${WIRELESS_NETWORK_SUPPORTED_MODES}"
227 if ! wireless_network_write_config
"${handle}"; then
228 log ERROR
"Could not write new config file"
233 # Deletes a wireless network
234 wireless_network_destroy
() {
237 if ! wireless_network_exists
"${ssid}"; then
238 error
"No such wireless network: ${ssid}"
242 local handle
="$(wireless_network_hash "${ssid}")"
245 if ! rm -rf "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
246 error
"Could not delete the wireless network"
250 log INFO
"Successfully destroyed wireless network ${ssid}"
254 wireless_network_encryption_mode
() {
255 if [ ! $# -eq 2 ]; then
256 log ERROR
"Not enough arguments"
262 if ! isoneof mode
${WIRELESS_VALID_ENCRYPTION_MODES}; then
263 log ERROR
"Encryption mode '${mode}' is invalid"
267 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
268 if ! wireless_network_read_config
"${handle}"; then
269 error
"Could not read configuration"
273 # Validate the PSK when changing mode and reset if needed
274 if isset PSK
&& [ "${mode}" != "NONE" ] && \
275 ! wireless_pre_shared_key_is_valid
"${mode}" "${PSK}"; then
276 log WARNING
"The configured pre-shared-key is incompatible with this encryption mode and has been reset"
280 # Save new encryption mode
281 ENCRYPTION_MODE
="${mode}"
283 if ! wireless_network_write_config
"${handle}"; then
284 log ERROR
"Could not write configuration settings"
289 wireless_network_pre_shared_key
() {
290 if [ ! $# -eq 2 ]; then
291 log ERROR
"Not enough arguments"
298 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
299 if ! wireless_network_read_config
"${handle}"; then
300 error
"Could not read configuration"
304 # Validate the key if encryption mode is known
305 if isset ENCRYPTION_MODE
&& [ "${ENCRYPTION_MODE}" != "NONE" ]; then
306 if ! wireless_pre_share_key_is_valid
"${ENCRYPTION_MODE}" "${psk}"; then
307 error
"The pre-shared-key is invalid for this wireless network: ${psk}"
312 if ! wireless_network_write_config_key
"${handle}" "PSK" "${psk}"; then
313 log ERROR
"Could not write configuration settings"
318 wireless_network_priority
() {
319 if [ ! $# -eq 2 ]; then
320 log ERROR
"Not enough arguments"
327 if ! isinteger priority
&& [ ! ${priority} -ge 0 ]; then
328 log ERROR
"The priority must be an integer greater or eqal zero"
332 if ! wireless_network_write_config_key
"${handle}" "PRIORITY" "${priority}"; then
333 log ERROR
"Could not write configuration settings"
338 wireless_networks_write_wpa_supplicant_configuration
() {
341 local file="${WPA_SUPPLICANT_CONF_DIR}/${device}.conf"
343 # Ensure we can write the file
344 make_parent_directory
"${file}"
347 # Write a config header
348 wpa_supplicant_config_header
350 wireless_networks_to_wpa_supplicant
354 wireless_networks_to_wpa_supplicant
() {
356 for handle
in $
(wireless_network_list
); do
357 wireless_network_to_wpa_supplicant
"${handle}"
361 wireless_network_to_wpa_supplicant
() {
364 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
365 if ! wireless_network_read_config
"${handle}"; then
366 error
"Could not read configuration for ${handle}"
377 for mode
in ${WIRELESS_NETWORK_SUPPORTED_MODES}; do
378 # Skip any disabled modes
379 if isset MODES
&& ! list_match
"${mode}" ${MODES}; then
385 WPA2-PSK|WPA2-PSK-SHA256
)
386 list_append_unique auth_alg
"OPEN"
387 list_append_unique key_mgmt
"${mode/WPA2/WPA}"
388 list_append_unique proto
"RSN"
391 for p
in CCMP TKIP
; do
392 list_append_unique pairwise
"${p}"
396 for g
in CCMP TKIP WEP104 WEP40
; do
397 list_append_unique group
"${g}"
402 WPA-PSK|WPA-PSK-SHA256
)
403 list_append_unique auth_alg
"OPEN"
404 list_append_unique key_mgmt
"${mode}"
405 list_append_unique proto
"WPA"
408 for p
in CCMP TKIP
; do
409 list_append_unique pairwise
"${p}"
413 for g
in CCMP TKIP WEP104 WEP40
; do
414 list_append_unique group
"${g}"
420 list_append_unique key_mgmt
"IEEE8021X"
423 # No encryption. DANGEROUS!
425 list_append_unique auth_alg
"OPEN"
426 list_append_unique key_mgmt
"NONE"
431 assert isset auth_alg
432 assert isset key_mgmt
435 local ca_cert_path
="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/ca.pem"
436 local client_cert_path
="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/client.pem"
437 local client_key_path
="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/client.key"
439 print_indent
0 "# ${SSID}"
440 print_indent
0 "network={"
441 print_indent
1 "ssid=\"${SSID}\""
444 if isinteger PRIORITY
; then
445 print_indent
1 "priority=${PRIORITY}"
450 print_indent
1 "# Authentication"
451 print_indent
1 "auth_alg=${auth_alg}"
452 print_indent
1 "key_mgmt=${key_mgmt}"
455 for i
in proto pairwise group
; do
456 print_indent
1 "${i}=${!i}"
462 print_indent
1 "# Pre Shared Key"
463 print_indent
1 "psk=\"${PSK}\""
466 if isset EAP_MODES
; then
467 print_indent
1 "# EAP"
468 print_indent
1 "eap=${EAP_MODES}"
472 if isset IDENTITY
; then
473 print_indent
1 "# Credentials"
474 print_indent
1 "identity=\"${IDENTITY}\""
476 if isset PASSWORD
; then
477 print_indent
1 "password=\"${PASSWORD}\""
480 if isset ANONYMOUS_IDENTITY
; then
481 print_indent
1 "anonymous_identity=\"${ANONYMOUS_IDENTITY}\""
487 if file_exists
"${client_cert_path}" && file_exists
"${client_key_path}"; then
488 print_indent
1 "# Client Certificate"
489 print_indent
1 "client_cert=\"${client_cert_path}\""
490 print_indent
1 "private_key=\"${client_key_path}\""
494 # Validate server certificates
495 if file_exists
"${ca_cert_path}"; then
496 print_indent
1 "ca_cert=\"${ca_cert_path}\""
498 elif isset CA_BUNDLE
; then
499 print_indent
1 "ca_cert=\"${CA_BUNDLE}\""