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