]> git.ipfire.org Git - people/stevee/network.git/blob - src/functions/functions.wireless-networks
wireless networks: Convert to use handles internally
[people/stevee/network.git] / src / functions / functions.wireless-networks
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
22 WIRELESS_NETWORK_CONFIG_SETTINGS="ENCRYPTION_MODE PRIORITY PSK SSID"
23
24 cli_wireless_network() {
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//-/_}"
35 shift 2
36
37 if ! wireless_network_exists "${ssid}"; then
38 error "No such wireless network: ${ssid}"
39 return ${EXIT_ERROR}
40 fi
41
42 # Convert SSID into usable format
43 local handle="$(wireless_network_hash "${ssid}")"
44
45 case "${key}" in
46 encryption_mode|pre_shared_key|priority)
47 wireless_network_${key} "${handle}" "$@"
48 ;;
49 show)
50 wireless_network_show "${handle}"
51 exit $?
52 ;;
53 *)
54 error "Unrecognized argument: ${key}"
55 exit ${EXIT_ERROR}
56 ;;
57 esac
58 ;;
59 esac
60 }
61
62 wireless_network_list() {
63 list_directory "${NETWORK_WIRELESS_NETWORKS_DIR}"
64 }
65
66 wireless_network_list_ssids() {
67 local handle
68 for handle in $(wireless_network_list); do
69 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
70 if ! wireless_network_read_config "${handle}"; then
71 continue
72 fi
73
74 print "${SSID}"
75 done
76 }
77
78 # This function writes all values to a via ${ssid} specificated wireless network configuration file
79 wireless_network_write_config() {
80 assert [ $# -ge 1 ]
81
82 local handle="${1}"
83
84 local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
85
86 if ! settings_write "${path}" ${WIRELESS_NETWORK_CONFIG_SETTINGS}; then
87 log ERROR "Could not write configuration"
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
97 wireless_network_write_config_key() {
98 assert [ $# -ge 3 ]
99
100 local handle="${1}"
101 local key="${2}"
102 shift 2
103
104 local value="$@"
105
106 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
107
108 # Read the config settings
109 if ! wireless_network_read_config "${handle}"; then
110 return ${EXIT_ERROR}
111 fi
112
113 log DEBUG "Set '${key}' to new value '${value}' in wireless network '${SSID}'"
114
115 # Set the key to a new value
116 assign "${key}" "${value}"
117
118 if ! wireless_network_write_config "${handle}"; then
119 return ${EXIT_ERROR}
120 fi
121
122 return ${EXIT_OK}
123 }
124
125 # Reads one or more keys out of a settings file or all if no key is provided.
126 wireless_network_read_config() {
127 assert [ $# -ge 1 ]
128
129 local handle="${1}"
130 shift
131
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
139 local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings"
140
141 if ! settings_read "${path}" ${args}; then
142 log ERROR "Could not read settings for wireless network ${handle}"
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
149 wireless_network_exists() {
150 local ssid="${1}"
151
152 local handle="$(wireless_network_hash "${ssid}")"
153 assert isset handle
154
155 # We cannot use wireless_network_read_config here beacuse we would end in a loop
156 local SSID
157 if ! settings_read "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}/settings" SSID; then
158 return ${EXIT_FALSE}
159 fi
160
161 if [ "${SSID}" = "${ssid}" ]; then
162 return ${EXIT_TRUE}
163 else
164 return ${EXIT_FALSE}
165 fi
166 }
167
168 wireless_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
187 wireless_network_new() {
188 if [ $# -gt 1 ]; then
189 error "Too many arguments"
190 return ${EXIT_ERROR}
191 fi
192
193 local ssid="${1}"
194
195 if ! isset ssid; then
196 error "Please provide a SSID"
197 return ${EXIT_ERROR}
198 fi
199
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
206 local handle="$(wireless_network_hash "${ssid}")"
207 assert isset handle
208
209 log DEBUG "Creating wireless network '${ssid}'"
210
211 if ! mkdir -p "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
212 log ERROR "Could not create config directory for wireless network ${ssid}"
213 return ${EXIT_ERROR}
214 fi
215
216 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
217 ENCRYPTION_MODE="${WIRELESS_DEFAULT_ENCRYPTION_MODE}"
218 SSID="${ssid}"
219 PRIORITY=500
220
221 if ! wireless_network_write_config "${handle}"; then
222 log ERROR "Could not write new config file"
223 return ${EXIT_ERROR}
224 fi
225 }
226
227 # Deletes a wireless network
228 wireless_network_destroy() {
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
236 local handle="$(wireless_network_hash "${ssid}")"
237 assert isset handle
238
239 if ! rm -rf "${NETWORK_WIRELESS_NETWORKS_DIR}/${handle}"; then
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}
246 }
247
248 wireless_network_encryption_mode() {
249 if [ ! $# -eq 2 ]; then
250 log ERROR "Not enough arguments"
251 return ${EXIT_ERROR}
252 fi
253 local handle="${1}"
254 local mode="${2}"
255
256 if ! isoneof mode ${WIRELESS_VALID_ENCRYPTION_MODES}; then
257 log ERROR "Encryption mode '${mode}' is invalid"
258 return ${EXIT_ERROR}
259 fi
260
261 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
262 if ! wireless_network_read_config "${handle}"; then
263 error "Could not read configuration"
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
277 if ! wireless_network_write_config "${handle}"; then
278 log ERROR "Could not write configuration settings"
279 return ${EXIT_ERROR}
280 fi
281 }
282
283 wireless_network_pre_shared_key() {
284 if [ ! $# -eq 2 ]; then
285 log ERROR "Not enough arguments"
286 return ${EXIT_ERROR}
287 fi
288
289 local handle="${1}"
290 local psk="${2}"
291
292 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
293 if ! wireless_network_read_config "${handle}"; then
294 error "Could not read configuration"
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
306 if ! wireless_network_write_config_key "${handle}" "PSK" "${psk}"; then
307 log ERROR "Could not write configuration settings"
308 return ${EXIT_ERROR}
309 fi
310 }
311
312 wireless_network_priority() {
313 if [ ! $# -eq 2 ]; then
314 log ERROR "Not enough arguments"
315 return ${EXIT_ERROR}
316 fi
317
318 local handle="${1}"
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
326 if ! wireless_network_write_config_key "${handle}" "PRIORITY" "${priority}"; then
327 log ERROR "Could not write configuration settings"
328 return ${EXIT_ERROR}
329 fi
330 }
331
332 wireless_networks_to_wpa_supplicant() {
333 local handle
334 for handle in $(wireless_network_list); do
335 wireless_network_to_wpa_supplicant "${handle}"
336 done
337 }
338
339 wireless_network_to_wpa_supplicant() {
340 local handle="${1}"
341
342 local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
343 if ! wireless_network_read_config "${handle}"; then
344 error "Could not read configuration for ${handle}"
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 = {"
410 print_indent 1 "ssid=\"${SSID}\""
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 }