]> git.ipfire.org Git - people/stevee/network.git/blame - src/functions/functions.wireless-networks
wireless networks: Convert to use handles internally
[people/stevee/network.git] / src / functions / functions.wireless-networks
CommitLineData
49958b8c
MT
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2017 IPFire Network Development Team #
6# #
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. #
11# #
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. #
16# #
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/>. #
19# #
20###############################################################################
21
364da6f4 22WIRELESS_NETWORK_CONFIG_SETTINGS="ENCRYPTION_MODE PRIORITY PSK SSID"
49958b8c 23
49958b8c 24cli_wireless_network() {
479b2273
MT
25 case "${1}" in
26 new)
27 wireless_network_new "${@:2}"
28 ;;
29 destroy)
30 wireless_network_destroy "${@:2}"
31 ;;
32 *)
33 local ssid="${1}"
34 local key="${2//-/_}"
549c5b97 35 shift 2
49958b8c 36
479b2273
MT
37 if ! wireless_network_exists "${ssid}"; then
38 error "No such wireless network: ${ssid}"
39 return ${EXIT_ERROR}
40 fi
49958b8c 41
2f64ac44
MT
42 # Convert SSID into usable format
43 local handle="$(wireless_network_hash "${ssid}")"
44
479b2273 45 case "${key}" in
364da6f4 46 encryption_mode|pre_shared_key|priority)
2f64ac44 47 wireless_network_${key} "${handle}" "$@"
479b2273
MT
48 ;;
49 show)
2f64ac44 50 wireless_network_show "${handle}"
479b2273
MT
51 exit $?
52 ;;
53 *)
54 error "Unrecognized argument: ${key}"
55 exit ${EXIT_ERROR}
56 ;;
57 esac
58 ;;
59 esac
49958b8c
MT
60}
61
d86b2dee
MT
62wireless_network_list() {
63 list_directory "${NETWORK_WIRELESS_NETWORKS_DIR}"
64}
65
66wireless_network_list_ssids() {
67 local handle
68 for handle in $(wireless_network_list); do
69 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
2f64ac44 70 if ! wireless_network_read_config "${handle}"; then
d86b2dee
MT
71 continue
72 fi
73
74 print "${SSID}"
75 done
76}
77
49958b8c
MT
78# This function writes all values to a via ${ssid} specificated wireless network configuration file
79wireless_network_write_config() {
80 assert [ $# -ge 1 ]
81
2f64ac44 82 local handle="${1}"
49958b8c 83
2f64ac44 84 local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
49958b8c
MT
85
86 if ! settings_write "${path}" ${WIRELESS_NETWORK_CONFIG_SETTINGS}; then
2f64ac44 87 log ERROR "Could not write configuration"
49958b8c
MT
88 return ${EXIT_ERROR}
89 fi
90
91 # When we get here the writing of the config file was successful
92 return ${EXIT_OK}
93}
94
95# This funtion writes the value for one key to a via ${ssid} specificated
96# wireless network configuration file
97wireless_network_write_config_key() {
98 assert [ $# -ge 3 ]
99
2f64ac44 100 local handle="${1}"
49958b8c
MT
101 local key="${2}"
102 shift 2
103
104 local value="$@"
105
49958b8c
MT
106 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
107
108 # Read the config settings
2f64ac44 109 if ! wireless_network_read_config "${handle}"; then
49958b8c
MT
110 return ${EXIT_ERROR}
111 fi
112
2f64ac44
MT
113 log DEBUG "Set '${key}' to new value '${value}' in wireless network '${SSID}'"
114
49958b8c
MT
115 # Set the key to a new value
116 assign "${key}" "${value}"
117
2f64ac44 118 if ! wireless_network_write_config "${handle}"; then
49958b8c
MT
119 return ${EXIT_ERROR}
120 fi
121
122 return ${EXIT_OK}
123}
124
d86b2dee 125# Reads one or more keys out of a settings file or all if no key is provided.
2f64ac44 126wireless_network_read_config() {
d86b2dee
MT
127 assert [ $# -ge 1 ]
128
129 local handle="${1}"
130 shift
131
49958b8c
MT
132 local args
133 if [ $# -eq 0 ] && [ -n "${WIRELESS_NETWORK_CONFIG_SETTINGS}" ]; then
134 list_append args ${WIRELESS_NETWORK_CONFIG_SETTINGS}
135 else
136 list_append args "$@"
137 fi
138
d86b2dee 139 local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
49958b8c
MT
140
141 if ! settings_read "${path}" ${args}; then
d86b2dee 142 log ERROR "Could not read settings for wireless network ${handle}"
49958b8c
MT
143 return ${EXIT_ERROR}
144 fi
145}
146
147# This function checks if a wireless network exists
148# Returns True when yes and false when not
149wireless_network_exists() {
49958b8c 150 local ssid="${1}"
49958b8c 151
2f64ac44
MT
152 local handle="$(wireless_network_hash "${ssid}")"
153 assert isset handle
49958b8c
MT
154
155 # We cannot use wireless_network_read_config here beacuse we would end in a loop
156 local SSID
2f64ac44 157 if ! settings_read "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings" SSID; then
49958b8c
MT
158 return ${EXIT_FALSE}
159 fi
160
2f64ac44 161 if [ "${SSID}" = "${ssid}" ]; then
49958b8c
MT
162 return ${EXIT_TRUE}
163 else
164 return ${EXIT_FALSE}
165 fi
166}
167
168wireless_network_hash() {
169 assert [ $# -eq 1 ]
170
171 local string="${1}"
172
173 local hash=$(echo -n "${string}" | md5sum )
174 hash=${hash%% -}
175
176 local path="${NETWORK_WIRELESS_NETWORKS_DIR}/*${hash}"
177
178 if [ -d "${path}" ]; then
179 basename "${path}"
180 else
181 local normalized=$(normalize "${string}")
182 normalized=${normalized%-}
183 echo "${normalized}-${hash}"
184 fi
185}
186
187wireless_network_new() {
188 if [ $# -gt 1 ]; then
189 error "Too many arguments"
190 return ${EXIT_ERROR}
191 fi
192
193 local ssid="${1}"
2f64ac44 194
49958b8c
MT
195 if ! isset ssid; then
196 error "Please provide a SSID"
197 return ${EXIT_ERROR}
198 fi
199
49958b8c
MT
200 # Check for duplicates
201 if wireless_network_exists "${ssid}"; then
202 error "The wireless network ${ssid} already exists"
203 return ${EXIT_ERROR}
204 fi
205
2f64ac44
MT
206 local handle="$(wireless_network_hash "${ssid}")"
207 assert isset handle
208
49958b8c
MT
209 log DEBUG "Creating wireless network '${ssid}'"
210
2f64ac44 211 if ! mkdir -p "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
49958b8c
MT
212 log ERROR "Could not create config directory for wireless network ${ssid}"
213 return ${EXIT_ERROR}
214 fi
215
49958b8c 216 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
1c9e2fa8 217 ENCRYPTION_MODE="${WIRELESS_DEFAULT_ENCRYPTION_MODE}"
49958b8c
MT
218 SSID="${ssid}"
219 PRIORITY=500
220
2f64ac44 221 if ! wireless_network_write_config "${handle}"; then
49958b8c
MT
222 log ERROR "Could not write new config file"
223 return ${EXIT_ERROR}
224 fi
225}
226
4b08d574 227# Deletes a wireless network
49958b8c 228wireless_network_destroy() {
4b08d574
MT
229 local ssid="${1}"
230
231 if ! wireless_network_exists "${ssid}"; then
232 error "No such wireless network: ${ssid}"
233 return ${EXIT_ERROR}
234 fi
235
2f64ac44
MT
236 local handle="$(wireless_network_hash "${ssid}")"
237 assert isset handle
4b08d574 238
2f64ac44 239 if ! rm -rf "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
4b08d574
MT
240 error "Could not delete the wireless network"
241 return ${EXIT_ERROR}
242 fi
243
244 log INFO "Successfully destroyed wireless network ${ssid}"
245 return ${EXIT_OK}
49958b8c
MT
246}
247
248wireless_network_encryption_mode() {
249 if [ ! $# -eq 2 ]; then
250 log ERROR "Not enough arguments"
251 return ${EXIT_ERROR}
252 fi
2f64ac44 253 local handle="${1}"
49958b8c
MT
254 local mode="${2}"
255
1c9e2fa8 256 if ! isoneof mode ${WIRELESS_VALID_ENCRYPTION_MODES}; then
49958b8c
MT
257 log ERROR "Encryption mode '${mode}' is invalid"
258 return ${EXIT_ERROR}
259 fi
260
549c5b97 261 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
2f64ac44
MT
262 if ! wireless_network_read_config "${handle}"; then
263 error "Could not read configuration"
549c5b97
MT
264 return ${EXIT_ERROR}
265 fi
266
267 # Validate the PSK when changing mode and reset if needed
268 if isset PSK && [ "${mode}" != "NONE" ] && \
269 ! wireless_pre_shared_key_is_valid "${mode}" "${PSK}"; then
270 log WARNING "The configured pre-shared-key is incompatible with this encryption mode and has been reset"
271 PSK=""
272 fi
273
274 # Save new encryption mode
275 ENCRYPTION_MODE="${mode}"
276
2f64ac44 277 if ! wireless_network_write_config "${handle}"; then
49958b8c
MT
278 log ERROR "Could not write configuration settings"
279 return ${EXIT_ERROR}
280 fi
281}
282
364da6f4 283wireless_network_pre_shared_key() {
49958b8c
MT
284 if [ ! $# -eq 2 ]; then
285 log ERROR "Not enough arguments"
286 return ${EXIT_ERROR}
287 fi
2f64ac44
MT
288
289 local handle="${1}"
364da6f4 290 local psk="${2}"
49958b8c 291
549c5b97 292 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
2f64ac44
MT
293 if ! wireless_network_read_config "${handle}"; then
294 error "Could not read configuration"
549c5b97
MT
295 return ${EXIT_ERROR}
296 fi
297
298 # Validate the key if encryption mode is known
299 if isset ENCRYPTION_MODE && [ "${ENCRYPTION_MODE}" != "NONE" ]; then
300 if ! wireless_pre_share_key_is_valid "${ENCRYPTION_MODE}" "${psk}"; then
301 error "The pre-shared-key is invalid for this wireless network: ${psk}"
302 return ${EXIT_ERROR}
303 fi
304 fi
305
2f64ac44 306 if ! wireless_network_write_config_key "${handle}" "PSK" "${psk}"; then
49958b8c
MT
307 log ERROR "Could not write configuration settings"
308 return ${EXIT_ERROR}
309 fi
310}
311
312wireless_network_priority() {
313 if [ ! $# -eq 2 ]; then
314 log ERROR "Not enough arguments"
315 return ${EXIT_ERROR}
316 fi
2f64ac44
MT
317
318 local handle="${1}"
49958b8c
MT
319 local priority=${2}
320
321 if ! isinteger priority && [ ! ${priority} -ge 0 ]; then
322 log ERROR "The priority must be an integer greater or eqal zero"
323 return ${EXIT_ERROR}
324 fi
325
2f64ac44 326 if ! wireless_network_write_config_key "${handle}" "PRIORITY" "${priority}"; then
49958b8c
MT
327 log ERROR "Could not write configuration settings"
328 return ${EXIT_ERROR}
329 fi
330}
d86b2dee
MT
331
332wireless_networks_to_wpa_supplicant() {
2f64ac44
MT
333 local handle
334 for handle in $(wireless_network_list); do
335 wireless_network_to_wpa_supplicant "${handle}"
d86b2dee
MT
336 done
337}
338
339wireless_network_to_wpa_supplicant() {
2f64ac44 340 local handle="${1}"
d86b2dee
MT
341
342 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
2f64ac44
MT
343 if ! wireless_network_read_config "${handle}"; then
344 error "Could not read configuration for ${handle}"
d86b2dee
MT
345 return ${EXIT_ERROR}
346 fi
347
348 local auth_alg
349 local group
350 local key_mgmt
351 local pairwise
352 local proto
353
354 case "${ENCRYPTION_MODE}" in
355 # Normal WPA
356 WPA-PSK)
357 auth_alg="OPEN"
358 key_mgmt="WPA-PSK"
359 proto="WPA"
360 pairwise="CCMP TKIP"
361 group="CCMP TKIP WEP104 WEP40"
362 ;;
363
364 # WPA with stronger algorithms
365 WPA-PSK-SHA256)
366 auth_alg="OPEN"
367 key_mgmt="WPA-PSK-SHA256"
368 proto="WPA"
369 pairwise="CCMP TKIP"
370 group="CCMP TKIP WEP104 WEP40"
371 ;;
372
373 # Normal WPA2 (802.11i)
374 WPA2-PSK)
375 auth_alg="OPEN"
376 key_mgmt="WPA-PSK"
377 proto="RSN"
378 pairwise="CCMP TKIP"
379 group="CCMP TKIP WEP104 WEP40"
380 ;;
381
382 # WPA2 with stronger algorithms
383 WPA2-PSK-SHA256)
384 auth_alg="OPEN"
385 key_mgmt="WPA-PSK-SHA256"
386 proto="RSN"
387 pairwise="CCMP TKIP"
388 group="CCMP TKIP WEP104 WEP40"
389 ;;
390
391 # WEP
392 WEP)
393 auth_alg="SHARED"
394 wep_key0="${key}"
395 wep_tx_keyidx="0"
396
397 # Reset PSK.
398 psk=""
399 ;;
400
401 # No encryption. DANGEROUS!
402 NONE)
403 auth_alg="OPEN"
404 key_mgmt="NONE"
405 ;;
406 esac
407
408 print_indent 0 "# ${SSID}"
409 print_indent 0 "network = {"
2f64ac44 410 print_indent 1 "ssid=\"${SSID}\""
d86b2dee
MT
411 print
412
413 # Authentication
414 print_indent 1 "# Authentication"
415 print_indent 1 "auth_alg=${auth_alg}"
416 print_indent 1 "key_mgmt=${key_mgmt}"
417
418 case "${ENCRYPTION_MODE}" in
419 WPA*)
420 print_indent 1 "proto=${proto}"
421 print_indent 1 "pairwise=${pairwise}"
422 ;;
423 esac
424
425 # PSKs
426 case "${ENCRYPTION_MODE}" in
427 WPA*PSK)
428 print_indent 1 "psk=\"${PSK}\""
429 ;;
430 WEP)
431 print_indent 1 "wep_key0=\"${PSK}\""
432 print_indent 1 "wep_tx_keyidx=0"
433 ;;
434 esac
435
436 print_indent 0 "}"
437 print
438}