]> git.ipfire.org Git - people/ms/network.git/blame - src/hooks/ports/wireless-ap
wireless-ap: Add support for WPA3 and rewrite WPA2
[people/ms/network.git] / src / hooks / ports / wireless-ap
CommitLineData
d76f5107
MT
1#!/bin/bash
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2010 Michael Tremer & Christian Schmidt #
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
8ee92277 22. /usr/lib/network/header-port
d76f5107 23
54bae947
MT
24HOOK_PORT_PATTERN="${PORT_PATTERN_ACCESSPOINT}"
25
d389e96b
MT
26HOOK_SETTINGS=(
27 "ADDRESS"
28 "BROADCAST_SSID"
29 "CHANNEL"
30 "CHANNEL_BANDWIDTH"
31 "DFS"
d389e96b 32 "ENVIRONMENT"
d389e96b
MT
33 "MFP"
34 "MODE"
35 "PHY"
0a4c5aba 36 "SECRET"
d389e96b 37 "SSID"
0a4c5aba
MT
38 "WPA3_PERSONAL"
39 "WPA2_PERSONAL"
d389e96b 40)
d76f5107 41
0a4c5aba
MT
42# Disable WPA3+2 by default
43DEFAULT_WPA3_PERSONAL="off"
44DEFAULT_WPA2_PERSONAL="off"
45
4637109c
MT
46# Broadcast SSID by default
47DEFAULT_BROADCAST_SSID="on"
d76f5107 48
7b297fb2 49# Perform radar detection by default when possible
4637109c 50DEFAULT_DFS="on"
7b297fb2 51
34ca3936
MT
52# 802.11w - Management Frame Protection
53# Disable by default because many clients cannot connect when enabled
4637109c 54DEFAULT_MFP="off"
34ca3936 55
4637109c 56DEFAULT_ENVIRONMENT="${WIRELESS_DEFAULT_ENVIRONMENT}"
7842c2ce 57
1c6a4e30 58hook_check_settings() {
d76f5107
MT
59 assert isset ADDRESS
60 assert ismac ADDRESS
61 assert isset BROADCAST_SSID
62 assert isbool BROADCAST_SSID
63 assert isset CHANNEL
7b297fb2 64 assert isbool DFS
34ca3936 65 assert isbool MFP
d76f5107 66 assert isset MODE
6c262922 67 assert isoneof MODE ${HOSTAPD_SUPPORTED_MODES}
d76f5107
MT
68 assert isset PHY
69 assert ismac PHY
70 assert isset SSID
25e32463 71
7842c2ce 72 assert wireless_environment_is_valid "${ENVIRONMENT}"
d76f5107
MT
73}
74
270aab39 75hook_parse_cmdline() {
d76f5107
MT
76 while [ $# -gt 0 ]; do
77 case "${1}" in
78 --broadcast-ssid=*)
2212045f 79 BROADCAST_SSID=$(cli_get_val "${1}")
d76f5107
MT
80 ;;
81 --channel=*)
2212045f 82 CHANNEL=$(cli_get_val "${1}")
d76f5107 83 ;;
54094fc7
MT
84 --channel-bandwidth=*)
85 CHANNEL_BANDWIDTH="$(cli_get_val "${1}")"
86 ;;
7b297fb2
MT
87 --dfs=*)
88 DFS="$(cli_get_val "${1}")"
89
90 if enabled DFS; then
91 DFS="on"
92 elif disabled DFS; then
93 DFS="off"
94 else
95 error "Invalid value for DFS: ${DFS}"
96 return ${EXIT_ERROR}
97 fi
98 ;;
7842c2ce
MT
99 --environment=*)
100 ENVIRONMENT="$(cli_get_val "${1}")"
101
102 if ! wireless_environment_is_valid "${ENVIRONMENT}"; then
103 error "Invalid wireless environment: ${ENVIRONMENT}"
104 return ${EXIT_ERROR}
105 fi
106 ;;
d76f5107 107 --mac=*)
2212045f 108 ADDRESS=$(cli_get_val "${1}")
d76f5107 109 ;;
34ca3936
MT
110 --mfp=*)
111 MFP="$(cli_get_val "${1}")"
112
113 if enabled MFP; then
114 MFP="on"
115 elif disabled MFP; then
116 MFP="off"
117 else
118 error "Invalid value for --mfp: ${MFP}"
119 return ${EXIT_ERROR}
120 fi
121 ;;
d76f5107 122 --mode=*)
2212045f 123 MODE=$(cli_get_val "${1}")
6c262922
MT
124
125 if ! isoneof MODE ${HOSTAPD_SUPPORTED_MODES}; then
126 error "Unsupported mode: ${MODE}"
127 error "Mode must be one of ${HOSTAPD_SUPPORTED_MODES}"
128 return ${EXIT_ERROR}
129 fi
d76f5107
MT
130 ;;
131 --phy=*)
2212045f 132 PHY=$(cli_get_val "${1}")
d76f5107 133 ;;
0a4c5aba
MT
134 --secret=*)
135 SECRET="$(cli_get_val "${1}")"
136 ;;
d76f5107 137 --ssid=*)
2212045f 138 SSID=$(cli_get_val "${1}")
d76f5107 139 ;;
0a4c5aba
MT
140 --wpa2-personal=*)
141 WPA2_PERSONAL="$(cli_get_bool "${1}")"
142 ;;
143 --wpa3-personal=*)
144 WPA3_PERSONAL="$(cli_get_bool "${1}")"
145 ;;
d76f5107
MT
146 *)
147 warning "Ignoring unknown argument '${1}'"
148 ;;
149 esac
150 shift
151 done
152
8578e61d
MT
153 # Generate a random MAC address if none is set
154 if ! isset ADDRESS; then
155 ADDRESS="$(mac_generate)"
156 fi
157
6c262922
MT
158 # MODE must be set
159 if ! isset MODE; then
160 error "--mode is not set"
161 return ${EXIT_ERROR}
162 fi
163
1b4aa2ca
MT
164 # Automatically enable ACS if no channel is set and ACS is available
165 if ! isset CHANNEL && phy_supports_acs "${PHY}"; then
166 CHANNEL="0"
167
168 log INFO "Automatic Channel Selection (ACS) enabled"
169 fi
170
54094fc7
MT
171 # Channel bandwidth must match the mode
172 if isset CHANNEL_BANDWIDTH && ! wireless_channel_bandwidth_is_valid "${MODE}" "${CHANNEL_BANDWIDTH}"; then
f9e980d9 173 error "Channel Bandwidth '${CHANNEL_BANDWIDTH}' is not supported for ${MODE}"
54094fc7
MT
174 return ${EXIT_ERROR}
175 fi
176
0a4c5aba
MT
177 # Check if SECRET is set when WPA* is enabled
178 if ! isset SECRET && (enabled WPA3_PERSONAL || enabled WPA2_PERSONAL); then
179 error "Secret is not set when PSK authentication is enabled"
180 return ${EXIT_ERROR}
181 fi
182
d76f5107
MT
183 # Save address of phy do identify it again
184 PHY=$(phy_get ${PHY})
185 PHY=$(phy_get_address ${PHY})
270aab39
MT
186}
187
1c6a4e30 188hook_edit() {
d76f5107 189 local port=${1}
d76f5107
MT
190 assert isset port
191
2212045f 192 if ! hook_default_edit "$@"; then
270aab39
MT
193 return ${EXIT_ERROR}
194 fi
d76f5107 195
270aab39
MT
196 # To apply all changes, we need to restart the port
197 port_restart "${port}"
d76f5107
MT
198}
199
1c6a4e30 200hook_create() {
1ba6a2bb 201 local port="${1}"
d76f5107
MT
202 assert isset port
203
1ba6a2bb
MT
204 device_exists "${port}" && exit ${EXIT_OK}
205
eba9fa9c 206 port_settings_read "${port}"
d76f5107 207
49ec20d8
MT
208 # Check if the PHY is present.
209 local phy=$(phy_get ${PHY})
210 if ! isset phy; then
211 log DEBUG "phy '${PHY}' is not present"
212 exit ${EXIT_ERROR}
213 fi
214
1ba6a2bb
MT
215 # Create the wireless device
216 wireless_create "${port}" \
217 --phy="${phy}" \
218 --type="ap" \
219 --address="${ADDRESS}"
d76f5107
MT
220
221 exit ${EXIT_OK}
222}
223
1c6a4e30 224hook_remove() {
1ba6a2bb 225 local port="${1}"
d76f5107
MT
226 assert isset port
227
b8026986
MT
228 # Remove the device if present
229 if device_exists "${port}"; then
230 wireless_remove "${port}"
47859d95 231 fi
d76f5107
MT
232
233 exit ${EXIT_OK}
234}
235
1c6a4e30 236hook_up() {
1ba6a2bb
MT
237 local port="${1}"
238 assert isset port
239
240 # The port must already exist before
241 # hostapd is started. Otherwise it will
242 # fail horribly over and over again.
243 assert device_exists "${port}"
244
245 hostapd_start "${port}"
246}
247
1c6a4e30 248hook_down() {
1ba6a2bb
MT
249 local port="${1}"
250 assert isset port
251
252 hostapd_stop "${port}"
253}
254
1c6a4e30 255hook_hotplug() {
b8026986 256 local port="${1}"
47859d95 257 assert isset port
49ec20d8 258
b8026986
MT
259 case "$(hotplug_action)" in
260 add)
1ba6a2bb
MT
261 # Create the port when the phy is plugged in
262 if hotplug_event_port_uses_phy "${port}"; then
263 hook_create "${port}"
b8026986
MT
264 fi
265 ;;
266
267 remove)
268 # Stop hostapd
269 if hotplug_event_port_is_interface "${port}"; then
270 hostapd_stop "${port}"
b8026986 271
1ba6a2bb
MT
272 exit ${EXIT_OK}
273 fi
b8026986
MT
274 ;;
275 esac
47859d95 276
1ba6a2bb 277 exit ${EXIT_NOT_HANDLED}
47859d95 278}