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} 802.1X NONE"
26 WIRELESS_NETWORK_CONFIG_SETTINGS
="ANONYMOUS_IDENTITY EAP_MODES IDENTITY \
27 MODES PASSWORD PRIORITY PSK SSID"
29 cli_wireless_network
() {
32 wireless_network_new
"${@:2}"
35 wireless_network_destroy
"${@:2}"
42 if ! wireless_network_exists
"${ssid}"; then
43 error
"No such wireless network: ${ssid}"
47 # Convert SSID into usable format
48 local handle
="$(wireless_network_hash "${ssid}")"
51 encryption_mode|pre_shared_key|priority
)
52 wireless_network_
${key} "${handle}" "$@"
55 wireless_network_show
"${handle}"
59 error
"Unrecognized argument: ${key}"
67 wireless_network_list
() {
68 list_directory
"${NETWORK_WIRELESS_NETWORKS_DIR}"
71 wireless_network_list_ssids
() {
73 for handle
in $
(wireless_network_list
); do
74 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
75 if ! wireless_network_read_config
"${handle}"; then
83 # This function writes all values to a via ${ssid} specificated wireless network configuration file
84 wireless_network_write_config
() {
89 local path
="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
91 if ! settings_write
"${path}" ${WIRELESS_NETWORK_CONFIG_SETTINGS}; then
92 log ERROR
"Could not write configuration"
96 # When we get here the writing of the config file was successful
100 # This funtion writes the value for one key to a via ${ssid} specificated
101 # wireless network configuration file
102 wireless_network_write_config_key
() {
111 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
113 # Read the config settings
114 if ! wireless_network_read_config
"${handle}"; then
118 log DEBUG
"Set '${key}' to new value '${value}' in wireless network '${SSID}'"
120 # Set the key to a new value
121 assign
"${key}" "${value}"
123 if ! wireless_network_write_config
"${handle}"; then
130 # Reads one or more keys out of a settings file or all if no key is provided.
131 wireless_network_read_config
() {
138 if [ $# -eq 0 ] && [ -n "${WIRELESS_NETWORK_CONFIG_SETTINGS}" ]; then
139 list_append args
${WIRELESS_NETWORK_CONFIG_SETTINGS}
141 list_append args
"$@"
144 local path
="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
146 if ! settings_read
"${path}" ${args}; then
147 log ERROR
"Could not read settings for wireless network ${handle}"
152 # This function checks if a wireless network exists
153 # Returns True when yes and false when not
154 wireless_network_exists
() {
157 local handle
="$(wireless_network_hash "${ssid}")"
160 # We cannot use wireless_network_read_config here beacuse we would end in a loop
162 if ! settings_read
"${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings" SSID
; then
166 if [ "${SSID}" = "${ssid}" ]; then
173 wireless_network_hash
() {
178 local hash=$
(echo -n "${string}" |
md5sum )
181 local path
="${NETWORK_WIRELESS_NETWORKS_DIR}/*${hash}"
183 if [ -d "${path}" ]; then
186 local normalized
=$
(normalize
"${string}")
187 normalized
=${normalized%-}
188 echo "${normalized}-${hash}"
192 wireless_network_new
() {
193 if [ $# -gt 1 ]; then
194 error
"Too many arguments"
200 if ! isset ssid
; then
201 error
"Please provide a SSID"
205 # Check for duplicates
206 if wireless_network_exists
"${ssid}"; then
207 error
"The wireless network ${ssid} already exists"
211 local handle
="$(wireless_network_hash "${ssid}")"
214 log DEBUG
"Creating wireless network '${ssid}'"
216 if ! mkdir
-p "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
217 log ERROR
"Could not create config directory for wireless network ${ssid}"
221 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
222 ENCRYPTION_MODE
="${WIRELESS_DEFAULT_ENCRYPTION_MODE}"
226 if ! wireless_network_write_config
"${handle}"; then
227 log ERROR
"Could not write new config file"
232 # Deletes a wireless network
233 wireless_network_destroy
() {
236 if ! wireless_network_exists
"${ssid}"; then
237 error
"No such wireless network: ${ssid}"
241 local handle
="$(wireless_network_hash "${ssid}")"
244 if ! rm -rf "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
245 error
"Could not delete the wireless network"
249 log INFO
"Successfully destroyed wireless network ${ssid}"
253 wireless_network_encryption_mode
() {
254 if [ ! $# -eq 2 ]; then
255 log ERROR
"Not enough arguments"
261 if ! isoneof mode
${WIRELESS_VALID_ENCRYPTION_MODES}; then
262 log ERROR
"Encryption mode '${mode}' is invalid"
266 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
267 if ! wireless_network_read_config
"${handle}"; then
268 error
"Could not read configuration"
272 # Validate the PSK when changing mode and reset if needed
273 if isset PSK
&& [ "${mode}" != "NONE" ] && \
274 ! wireless_pre_shared_key_is_valid
"${mode}" "${PSK}"; then
275 log WARNING
"The configured pre-shared-key is incompatible with this encryption mode and has been reset"
279 # Save new encryption mode
280 ENCRYPTION_MODE
="${mode}"
282 if ! wireless_network_write_config
"${handle}"; then
283 log ERROR
"Could not write configuration settings"
288 wireless_network_pre_shared_key
() {
289 if [ ! $# -eq 2 ]; then
290 log ERROR
"Not enough arguments"
297 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
298 if ! wireless_network_read_config
"${handle}"; then
299 error
"Could not read configuration"
303 # Validate the key if encryption mode is known
304 if isset ENCRYPTION_MODE
&& [ "${ENCRYPTION_MODE}" != "NONE" ]; then
305 if ! wireless_pre_share_key_is_valid
"${ENCRYPTION_MODE}" "${psk}"; then
306 error
"The pre-shared-key is invalid for this wireless network: ${psk}"
311 if ! wireless_network_write_config_key
"${handle}" "PSK" "${psk}"; then
312 log ERROR
"Could not write configuration settings"
317 wireless_network_priority
() {
318 if [ ! $# -eq 2 ]; then
319 log ERROR
"Not enough arguments"
326 if ! isinteger priority
&& [ ! ${priority} -ge 0 ]; then
327 log ERROR
"The priority must be an integer greater or eqal zero"
331 if ! wireless_network_write_config_key
"${handle}" "PRIORITY" "${priority}"; then
332 log ERROR
"Could not write configuration settings"
337 wireless_networks_write_wpa_supplicant_configuration
() {
340 local file="${WPA_SUPPLICANT_CONF_DIR}/${device}.conf"
342 # Ensure we can write the file
343 make_parent_directory
"${file}"
346 # Write a config header
347 wpa_supplicant_config_header
349 wireless_networks_to_wpa_supplicant
353 wireless_networks_to_wpa_supplicant
() {
355 for handle
in $
(wireless_network_list
); do
356 wireless_network_to_wpa_supplicant
"${handle}"
360 wireless_network_to_wpa_supplicant
() {
363 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
364 if ! wireless_network_read_config
"${handle}"; then
365 error
"Could not read configuration for ${handle}"
376 for mode
in ${WIRELESS_NETWORK_SUPPORTED_MODES}; do
377 # Skip any disabled modes
378 if isset MODES
&& ! list_match
"${mode}" ${MODES}; then
384 WPA2-PSK|WPA2-PSK-SHA256
)
385 list_append_unique auth_alg
"OPEN"
386 list_append_unique key_mgmt
"${mode/WPA2/WPA}"
387 list_append_unique proto
"RSN"
390 for p
in CCMP TKIP
; do
391 list_append_unique pairwise
"${p}"
395 for g
in CCMP TKIP WEP104 WEP40
; do
396 list_append_unique group
"${g}"
401 WPA-PSK|WPA-PSK-SHA256
)
402 list_append_unique auth_alg
"OPEN"
403 list_append_unique key_mgmt
"${mode}"
404 list_append_unique proto
"WPA"
407 for p
in CCMP TKIP
; do
408 list_append_unique pairwise
"${p}"
412 for g
in CCMP TKIP WEP104 WEP40
; do
413 list_append_unique group
"${g}"
419 list_append_unique key_mgmt
"IEEE8021X"
422 # No encryption. DANGEROUS!
424 list_append_unique auth_alg
"OPEN"
425 list_append_unique key_mgmt
"NONE"
430 assert isset auth_alg
431 assert isset key_mgmt
433 # Read CA certificate
434 local ca_cert_path
="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/ca.pem"
436 print_indent
0 "# ${SSID}"
437 print_indent
0 "network={"
438 print_indent
1 "ssid=\"${SSID}\""
441 if isinteger PRIORITY
; then
442 print_indent
1 "priority=${PRIORITY}"
447 print_indent
1 "# Authentication"
448 print_indent
1 "auth_alg=${auth_alg}"
449 print_indent
1 "key_mgmt=${key_mgmt}"
452 for i
in proto pairwise group
; do
453 print_indent
1 "${i}=${!i}"
459 print_indent
1 "# Pre Shared Key"
460 print_indent
1 "psk=\"${PSK}\""
463 if isset EAP_MODES
; then
464 print_indent
1 "# EAP"
465 print_indent
1 "eap=${EAP_MODES}"
469 if isset IDENTITY
; then
470 print_indent
1 "# Credentials"
471 print_indent
1 "identity=\"${IDENTITY}\""
473 if isset PASSWORD
; then
474 print_indent
1 "password=\"${PASSWORD}\""
477 if isset ANONYMOUS_IDENTITY
; then
478 print_indent
1 "anonymous_identity=\"${ANONYMOUS_IDENTITY}\""
483 # Validate server certificates
484 if file_exists
"${ca_cert_path}"; then
485 print_indent
1 "ca_cert=\"${ca_cert_path}\""
487 elif isset CA_BUNDLE
; then
488 print_indent
1 "ca_cert=\"${CA_BUNDLE}\""