]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/bsdinstall/scripts/wlanconfig
Remove unnecessary `-n' parameter to head/tail
[FreeBSD/FreeBSD.git] / usr.sbin / bsdinstall / scripts / wlanconfig
1 #!/bin/sh
2 #-
3 # Copyright (c) 2011 Nathan Whitehorn
4 # Copyright (c) 2013-2016 Devin Teske
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 # SUCH DAMAGE.
27 #
28 # $FreeBSD$
29 #
30 ############################################################ INCLUDES
31
32 BSDCFG_SHARE="/usr/share/bsdconfig"
33 . $BSDCFG_SHARE/common.subr || exit 1
34 f_include $BSDCFG_SHARE/dialog.subr
35
36 ############################################################ FUNCTIONS
37
38 country_set()
39 {
40         local error_str iface_up ifconfig_args=
41
42         #
43         # Setup what was selected
44         # NB: Do not change order of arguments (or regdomain will be ignored)
45         #
46         [ "$2" ] && ifconfig_args="$ifconfig_args country $2"
47         [ "$1" ] && ifconfig_args="$ifconfig_args regdomain $1"
48         [ "$ifconfig_args" ] || return $SUCCESS # Nothing to do
49         ifconfig_args="${ifconfig_args# }"
50
51         # Regdomain/country cannot be applied while interface is running
52         iface_up=$( ifconfig -lu | grep -w $WLAN_IFACE )
53         [ "$iface_up" ] && ifconfig $WLAN_IFACE down
54         error_str=$( ifconfig $WLAN_IFACE $ifconfig_args 2>&1 |
55                 sed -e 's/ifconfig: //' )
56         if [ "$iface_up" ]; then
57                 # Restart wpa_supplicant(8) (should not fail).
58                 wpa_supplicant -B -i $WLAN_IFACE -c \
59                     "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
60         fi
61         if [ "$error_str" ]; then
62                 dialog --backtitle "FreeBSD Installer" --title "Error" \
63                     --yes-label Change --no-label Ignore --yesno \
64                     "Error while applying chosen settings ($error_str)" 0 0
65                 if [ $? -eq $DIALOG_OK ]; then
66                         return $FAILURE # Restart
67                 else
68                         return $SUCCESS # Skip
69                 fi
70         else
71                 : > "$BSDINSTALL_TMPETC/rc.conf.net.wlan"
72                 echo create_args_$WLAN_IFACE=\"$ifconfig_args\" >> \
73                     "$BSDINSTALL_TMPETC/rc.conf.net.wlan"
74         fi
75
76         return $SUCCESS
77 }
78
79 dialog_country_select()
80 {
81         local input regdomains countries regdomain country
82         local def_item_regdomain=
83         local def_item_country=
84
85         #
86         # Parse available countries/regdomains
87         #
88         input=$( ifconfig $WLAN_IFACE list countries | sed -e 's/DEBUG//gi' )
89         regdomains=$( echo $input | sed -e 's/.*domains://' | tr ' ' '\n' |
90                 sort | tr '\n' ' ' )
91         countries=$( echo $input | awk '{
92                 sub(/Country codes:/, "")
93                 sub(/Regulatory.*/, "")
94                 for (i = 1; i <= NF; i++) {
95                         printf "%s", $i
96                         if (match($i, /[[:lower:]]/))
97                                 if (match($(i+1), /[[:lower:]]/))
98                                         printf "\\\\\\ "
99                                 else
100                                         printf "\n"
101                         else
102                                 printf " "
103                 }
104             }' | sort -k 2 | tr '\n' ' ' )
105
106         # Change default cursor position (if required).
107         if [ "$1" != "<not selected>" ]; then
108                 def_item_regdomain="--default-item $1"
109         fi
110         if [ "$2" != "<not selected>" ]; then
111                 def_item_country="--default-item $2"
112         fi
113
114         f_dialog_menu_size height width rows \"Regdomain selection\" \
115             \"FreeBSD Installer\" \"Select your regdomain.\" \
116             \"\" $regdomains
117         regdomain=$( sh -c "dialog \
118             --backtitle \"FreeBSD Installer\" \
119             --title \"Regdomain selection\" \
120             --cancel-label \"Skip\" \
121             $def_item_regdomain \
122             --no-items \
123             --stdout \
124             --menu \"Select your regdomain.\" \
125             $height $width $rows $regdomains" )
126
127         f_dialog_menu_size height width rows \"Country selection\" \
128             \"FreeBSD Installer\" \"Select your country.\" \
129             \"\" $countries
130         country=$( sh -c "dialog \
131             --backtitle \"FreeBSD Installer\" \
132             --title \"Country selection\" \
133             --cancel-label \"Skip\" \
134             $def_item_country \
135             --stdout \
136             --menu \"Select your country.\" \
137             $height $width $rows $countries" )
138
139         country_set "$regdomain" "$country"
140
141         return $?
142 }
143
144 ############################################################ MAIN
145
146 : > "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
147 chmod 0600 "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
148
149 echo "ctrl_interface=/var/run/wpa_supplicant" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
150 echo "eapol_version=2" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
151 echo "ap_scan=1" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
152 echo "fast_reauth=1" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
153 echo >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
154
155 #
156 # Try to reach wpa_supplicant. If it isn't running and we can modify the
157 # existing system, start it. Otherwise, fail.
158 #
159 (wpa_cli ping >/dev/null 2>/dev/null || ([ "$BSDINSTALL_CONFIGCURRENT" ] &&
160         wpa_supplicant -B -i $1 -c "$BSDINSTALL_TMPETC/wpa_supplicant.conf")) ||
161         (dialog --backtitle "FreeBSD Installer" --title "Error" --msgbox \
162         "Could not start wpa_supplicant!" 0 0; exit 1) || exit 1
163
164 # See if we succeeded
165 wpa_cli ping >/dev/null 2>/dev/null
166 if [ $? -ne 0 -a ! "$BSDINSTALL_CONFIGCURRENT" ]; then
167         dialog --backtitle "FreeBSD Installer" --title "Error" --msgbox \
168         "Wireless cannot be configured without making changes to the local system!" \ 0 0
169         exit 1
170 fi
171
172 #
173 # There is no way to check country/regdomain without (possible)
174 # interface state modification
175 #
176 if [ "$BSDINSTALL_CONFIGCURRENT" ]; then
177         # Get current country/regdomain for selected interface
178         WLAN_IFACE=$( wpa_cli ifname | tail -1 )
179         INPUT=$( ifconfig $WLAN_IFACE list regdomain | head -1 )
180         DEF_REGDOMAIN=$( echo $INPUT | cut -w -f 2 )
181         DEF_COUNTRY=$( echo $INPUT | cut -w -f 4 )
182         [ "$DEF_REGDOMAIN" = 0 ] && DEF_REGDOMAIN="<not selected>"
183         [ "$DEF_COUNTRY" = 0 ] && DEF_COUNTRY="<not selected>"
184         dialog --backtitle "FreeBSD Installer" --title "Regdomain/country" \
185             --yesno "Change regdomain/country (now \
186             $DEF_REGDOMAIN/$DEF_COUNTRY)?" 0 0
187         if [ $? -eq 0 ]; then
188                 while :
189                 do
190                         dialog_country_select "$DEF_REGDOMAIN" "$DEF_COUNTRY"
191                         if [ $? -eq $SUCCESS ]; then
192                                 break
193                         fi
194                 done
195         fi
196 fi
197
198 while :
199 do
200         SCANSSID=0
201         output=$( wpa_cli scan 2>&1 )
202         f_dprintf "%s" "$output"
203         dialog --backtitle "FreeBSD Installer" --title "Scanning" \
204             --ok-label "Skip" \
205             --pause "Waiting 5 seconds to scan for wireless networks..." \
206             9 40 5 || exit 1
207
208         SCAN_RESULTS=$( wpa_cli scan_results )
209         NETWORKS=$( echo "$SCAN_RESULTS" | awk -F '\t' \
210            '/..:..:..:..:..:../ {if (length($5) > 0) \
211            printf("\"%s\"\t%s\n", $5, $4);}' | sort | uniq )
212
213         if [ ! "$NETWORKS" ]; then
214                 dialog --backtitle "FreeBSD Installer" --title "Error" \
215                     --yesno "No wireless networks were found. Rescan?" 0 0 &&
216                     continue
217                 exit 1
218         fi
219
220         exec 3>&1
221         NETWORK=$( sh -c "dialog --extra-button --extra-label \"Rescan\" \
222             --backtitle \"FreeBSD Installer\" --title \"Network Selection\" \
223             --menu \"Select a wireless network to connect to.\" 0 0 0 \
224             $(echo $NETWORKS | tr '\n' ' ')" 2>&1 1>&3 )
225         case $? in
226         0)      # OK
227                 break
228                 ;;
229         1)      # Cancel
230                 # here we ask if the user wants to select the network manually
231                 f_dialog_title "Network Selection"
232                 f_dialog_yesno "Do you want to select the network manually?" || exit 1
233                 f_dialog_input NETWORK "Enter SSID" || exit 1
234                 ENCRYPTION=$( dialog --backtitle "$DIALOG_BACKTITLE" --title \
235                         "$DIALOG_TITLE" --menu "Select encryption type" 0 0 0 \
236                         "1 WPA/WPA2 PSK" "" "2 WPA/WPA2 EAP" "" "3 WEP" "" "0 None" "" 2>&1 1>&3 ) || exit 1
237                 SCANSSID=1
238                 f_dialog_title_restore
239                 break
240                 ;;
241         3)      # Rescan
242                 ;;
243         esac
244         exec 3>&-
245 done
246
247 [ "$ENCRYPTION" ] || ENCRYPTION=$( echo "$NETWORKS" | awk -F '\t' \
248     "/^\"$NETWORK\"\t/ {printf(\"%s\n\", \\\$2 );}" )
249
250 if echo $ENCRYPTION | grep -q 'PSK'; then
251         exec 3>&1
252         PASS=$( dialog --insecure --backtitle "FreeBSD Installer" \
253             --title "WPA Setup" --mixedform "" 0 0 0 \
254                 "SSID" 1 0 "$NETWORK" 1 12 0 0 2 \
255                 "Password" 2 0 "" 2 12 15 63 1 \
256                 2>&1 1>&3 ) \
257         || exec $0 $@
258         exec 3>&-
259 echo "network={
260         ssid=\"$NETWORK\"
261         scan_ssid=$SCANSSID
262         psk=\"$PASS\"
263         priority=5
264 }" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
265 elif echo $ENCRYPTION | grep -q EAP; then
266         exec 3>&1
267         USERPASS=$( dialog --insecure --backtitle "FreeBSD Installer" \
268             --title "WPA-Enterprise Setup" --mixedform "" 0 0 0 \
269                 "SSID" 1 0 "$NETWORK" 1 12 0 0 2 \
270                 "Username" 2 0 "" 2 12 25 63 0 \
271                 "Password" 3 0 "" 3 12 25 63 1 \
272                 2>&1 1>&3 ) \
273         || exec $0 $@
274         exec 3>&-
275 echo "network={
276         ssid=\"$NETWORK\"
277         scan_ssid=$SCANSSID
278         key_mgmt=WPA-EAP" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
279 echo "$USERPASS" | awk '
280 {
281         if (NR == 1) {
282                 printf "        identity=\"%s\"\n", $1;
283         } else if (NR == 2) {
284                 printf "        password=\"%s\"\n", $1;
285         }
286 }' >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
287 echo "  priority=5
288 }" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
289 elif echo $ENCRYPTION | grep -q WEP; then
290         exec 3>&1
291         WEPKEY=$( dialog --insecure --backtitle "FreeBSD Installer" \
292             --title "WEP Setup" --mixedform "" 0 0 0 \
293                 "SSID" 1 0 "$NETWORK" 1 12 0 0 2 \
294                 "WEP Key 0" 2 0 "" 2 12 15 0 1 \
295                 2>&1 1>&3 ) \
296         || exec $0 $@
297 echo "network={
298         ssid=\"$NETWORK\"
299         scan_ssid=$SCANSSID
300         key_mgmt=NONE
301         wep_key0=\"$WEPKEY\"
302         wep_tx_keyidx=0
303         priority=5
304 }" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
305 else    # Open
306 echo "network={
307         ssid=\"$NETWORK\"
308         scan_ssid=$SCANSSID
309         key_mgmt=NONE
310         priority=5
311 }" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
312 fi
313
314 # Connect to any open networks policy
315 echo "network={
316         priority=0
317         key_mgmt=NONE
318 }" >> "$BSDINSTALL_TMPETC/wpa_supplicant.conf"
319
320 # Bring up new network
321 if [ "$BSDINSTALL_CONFIGCURRENT" ]; then
322         output=$( wpa_cli reconfigure 2>&1 )
323         f_dprintf "%s" "$output"
324 fi
325
326 exit $SUCCESS
327
328 ################################################################################
329 # END
330 ################################################################################