27
WPA_SUP_BIN="/sbin/wpa_supplicant"
28
WPA_SUP_PNAME="wpa_supplicant"
29
WPA_SUP_PIDFILE="/var/run/wpa_supplicant.$IFACE.pid"
31
WPA_CLI_BIN="/sbin/wpa_cli"
32
WPA_CLI_PNAME="wpa_cli"
33
WPA_CLI_PIDFILE="/var/run/wpa_action.$IFACE.pid"
34
WPA_CLI_LOCKFILE="/var/lock/wpa_action.$IFACE.lock"
36
# path to common ctrl_interface socket for active interfaces
37
# this is the default path provided by upstream
38
WPA_CTRL_DIR="/var/run/wpa_supplicant"
27
if [ -f /etc/wpa_supplicant/functions.sh ]; then
28
. /etc/wpa_supplicant/functions.sh
40
33
# quit if executables are not installed
41
if [ ! -x "$WPA_SUP_BIN" -o ! -x "$WPA_CLI_BIN" ]; then
34
if [ ! -x "$WPA_SUP_BIN" ] || [ ! -x "$WPA_CLI_BIN" ]; then
45
if [ -n "$IF_WPA_VERBOSITY" -o "$VERBOSITY" = "1" ]; then
46
# show wpa_cli messages when VERBOSITY has been set
48
# start-stop-daemon verbosity
49
DAEMON_VERBOSITY="--verbose"
51
# hide infomational messages when VERBOSITY is not set
53
# start-stop-daemon is quiet
54
DAEMON_VERBOSITY="--quiet"
57
# error and verbose informational messages
61
# verbose message terminated with newline
63
echo "$WPA_SUP_PNAME: $@" >$TO_NULL
66
# verbose action message with no trailing newline
67
# useful for displaying wpa_cli feedback (OK|FAILED)
69
echo -n "$WPA_SUP_PNAME: $@ -- " >$TO_NULL
73
# commonly followed by an exit statement
75
echo "$WPA_SUP_PNAME: $@...aborting!" >/dev/stderr
82
test_daemon_pidfile () {
84
# daemon executable is first argument
88
# daemon pidfile to be tested
92
# do the test if both exist
93
if [ -n "$DAEMON" -a -f "$PIDFILE" ]; then
94
# return 0 when $PIDFILE was created by $DAEMON
96
if start-stop-daemon --stop --quiet --signal 0 \
97
--exec "$DAEMON" --pidfile "$PIDFILE"; then
100
# pidfile is invalid, not created by $DAEMON
101
wpa_msg verbose "removing stale pidfile \"$PIDFILE\""
110
38
# quit if wpa_action is active
111
if test_daemon_pidfile "$WPA_CLI_BIN" "$WPA_CLI_PIDFILE"; then
43
# preliminary sanity checks for roaming daemon
115
44
if [ -n "$IF_WPA_ROAM" ]; then
116
# wpa-roam is only funtional in conjunction with the 'manual' inet METHOD
117
45
if [ "$METHOD" != "manual" ]; then
118
46
wpa_msg stderr "wpa-roam can only be used with the \"manual\" inet METHOD"
121
# mapping script must exist
122
49
if [ -n "$IF_WPA_MAPPING_SCRIPT" ]; then
123
50
if ! type "$IF_WPA_MAPPING_SCRIPT" >/dev/null; then
124
wpa_msg stderr "mapping script \"$IF_WPA_MAPPING_SCRIPT\" is not valid"
51
wpa_msg stderr "wpa-mapping-script \"$IF_WPA_MAPPING_SCRIPT\" is not valid"
128
# if an external mapping script is to be used, one must be given
129
if [ -n "$IF_WPA_MAPPING_SCRIPT_PRIORITY" -a -z "$IF_WPA_MAPPING_SCRIPT" ]; then
130
wpa_msg stderr "cannot set \"wpa-mapping-script-priority 1\" without a valid \"wpa-mapping-script\""
55
if [ -n "$IF_WPA_MAPPING_SCRIPT_PRIORITY" ] && [ -z "$IF_WPA_MAPPING_SCRIPT" ]; then
56
wpa_msg stderr "\"wpa-mapping-script-priority 1\" is invalid without a wpa-mapping-script"
133
# shunt roam conf to IF_WPA_CONF
134
59
IF_WPA_CONF="$IF_WPA_ROAM"
135
# action script is wpa_action
136
60
WPA_ACTION_SCRIPT="/sbin/wpa_action"
139
63
# master function; determines if ifupdown.sh should do something or not
140
64
if [ -s "$IF_WPA_CONF" ]; then
141
# get ctrl_interface socket path defined in conf
142
WPA_SUP_CONF_CTRL_DIR=$(sed -n -e \
65
WPA_SUP_CONF_CTRL_DIR=$(sed --quiet \
143
66
's/[[:space:]]*#.*//g;s/[[:space:]]\+.*$//g;s/^\(ctrl_interface\|DIR\)=\(.*\)/\2/p' "$IF_WPA_CONF")
144
# use ctrl_interface socket path when defined in user supplied conf, overriding the pre-set default
145
67
if [ -n "$WPA_SUP_CONF_CTRL_DIR" ]; then
146
68
WPA_CTRL_DIR="$WPA_SUP_CONF_CTRL_DIR"
148
# always supply ctrl_interface socket path to daemon
149
# it may not be created when not explicitly specified in IF_WPA_CONF but we depend on it
150
70
WPA_SUP_CONF="-c $IF_WPA_CONF -C $WPA_CTRL_DIR"
151
elif set | grep -q "^IF_WPA"; then
152
# any wpa-* line causes wpa_supplicant to launch with an unconfigured ctrl_interface socket
153
# the socket is later configured by a series of set_network cmd's in conf_wpa_supplicant()
71
elif set | grep --quiet "^IF_WPA"; then
154
72
WPA_SUP_CONF="-C $WPA_CTRL_DIR"
159
# wpa_cli wrapper function
160
# avoid language related interferences
161
# supply path to common ctrl_interface socket(s)
162
# supply IFACE as argument
164
LC_ALL=C $WPA_CLI_BIN -p $WPA_CTRL_DIR -i $IFACE "$@"
167
# wpa_cli_do <value> <type> <variable> [set_network variable] <desc>
168
# process environment variables resulting from wpa-* lines in the interfaces file
169
# $1 = envorinment variable
170
# $2 = data type of variable {raw|ascii}
171
# $3 = wpa_cli variable, if $3 is set_network, shift and take set_network subvariable
172
# $4 = wpa-* string as it would appear in interfaces file, enhances information messages
176
# environment variable not defined, no-op
180
local WPACLISET_VALUE WPACLISET_VARIABLE WPACLISET_DESC
182
# provide a method to disable the forced choice of ascii data type
183
# using this option requires that strings are quoted as required in interfaces file
184
if [ -n "$IF_WPA_INPUT_TYPE" ]; then
187
# wpa_cli value and type
191
WPACLISET_VALUE="\"$1\""
203
if [ -z "$WPA_ID" ]; then
204
# WPA_ID is required for set_network commands
207
# Shift to set_network variable
209
WPACLISET_VARIABLE="set_network $WPA_ID $3"
212
WPACLISET_VARIABLE="$3"
216
# display description of wpa_cli command, censor sensitive knowledge
218
*-psk|*-passphrase|*-passwd*|*-wep-key*)
219
# For sensitive knowledge
220
WPACLISET_DESC="$4 *****"
223
# Echo actual value used
224
WPACLISET_DESC="$4 $WPACLISET_VALUE"
228
# echo debug/verbosity messages
229
wpa_msg action "$WPACLISET_DESC"
231
# NB: $WPACLISET_VARIABLE must be unprotected and $WPACLISET_VALUE must be protected
232
wpa_cli $WPACLISET_VARIABLE "$WPACLISET_VALUE" >$TO_NULL
235
init_wpa_supplicant () {
236
if [ ! -S "$WPA_CTRL_DIR/$IFACE" ]; then
238
if [ -n "$IF_WPA_ACTION" ]; then
239
wpa_msg stderr "wpa-action support has been removed, see wpa_action(8) manpage"
243
local WPA_SUP_DRIVER WPA_SUP_OPTIONS
245
# action script sanity checking
246
if [ -n "$WPA_ACTION_SCRIPT" ]; then
247
if [ -x "$WPA_ACTION_SCRIPT" ]; then
248
# wait for wpa_cli to attach
249
WPA_SUP_OPTIONS="-W -B -P $WPA_SUP_PIDFILE -i $IFACE"
250
wpa_msg verbose "wait for wpa_cli to attach"
252
wpa_msg stderr "action script \"$WPA_ACTION_SCRIPT\" not executable"
256
# default options, daemonise, create pidfile, supply IFACE
257
WPA_SUP_OPTIONS="-B -P $WPA_SUP_PIDFILE -i $IFACE"
260
if [ -n "$IF_WPA_BRIDGE" ]; then
261
WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -b $IF_WPA_BRIDGE"
262
wpa_msg verbose "wpa-bridge $IF_WPA_BRIDGE"
265
# driver type of interface, defaults to wext when undefined
266
if [ -n "$IF_WPA_DRIVER" ]; then
267
WPA_SUP_DRIVER="$IF_WPA_DRIVER"
268
wpa_msg verbose "wpa-driver $WPA_SUP_DRIVER"
270
# wext is default/fallback
271
WPA_SUP_DRIVER="wext"
272
wpa_msg verbose "using default driver type: wpa-driver $WPA_SUP_DRIVER"
275
# if we have passed the criteria, start wpa_supplicant
276
if [ -n "$WPA_SUP_CONF" ]; then
278
wpa_msg verbose "$WPA_SUP_BIN $WPA_SUP_OPTIONS -D $WPA_SUP_DRIVER $WPA_SUP_CONF"
280
start-stop-daemon --start --oknodo $DAEMON_VERBOSITY \
281
--name $WPA_SUP_PNAME --startas $WPA_SUP_BIN --pidfile $WPA_SUP_PIDFILE \
282
-- $WPA_SUP_OPTIONS -D $WPA_SUP_DRIVER $WPA_SUP_CONF
285
# loop wait until ctrl_interface socket exists for a max of 5 seconds
286
# in some situations, init_wpa_cli() or conf_wpa_supplicant() were being launched
287
# before wpa_supplicant had established the ctrl_interface socket
288
# i cannot say for certain if this is absolutely required, but it cannot hurt to have a buffer
289
local WPA_SOCKET_WAIT="0" MAX_WPA_SOCKET_WAIT="5"
290
until [ -S "$WPA_CTRL_DIR/$IFACE" ]; do
291
if [ "$WPA_SOCKET_WAIT" -ge "$MAX_WPA_SOCKET_WAIT" ]; then
292
# socket should be created immediately after invocation
293
# a few seconds is ample time even on ancient hardware
294
wpa_msg stderr "ctrl_interface socket not found at $WPA_CTRL_DIR/$IFACE"
297
wpa_msg verbose "waiting for \"$WPA_CTRL_DIR/$IFACE\": $WPA_SOCKET_WAIT (max. $MAX_WPA_SOCKET_WAIT)"
298
WPA_SOCKET_WAIT=$(($WPA_SOCKET_WAIT+1))
303
wpa_msg verbose "ctrl_interface socket located at $WPA_CTRL_DIR/$IFACE"
306
wpa_msg stderr "unknown or stale ctrl_interface socket located at $WPA_CTRL_DIR/$IFACE"
311
conf_wpa_supplicant () {
314
wpa_cli_do "$IF_WPA_AP_SCAN" raw \
317
wpa_cli_do "$IF_WPA_PREAUTHENTICATE" raw \
318
preauthenticate wpa-preauthenticate
320
# per ssid specific settings
321
if [ -n "$IF_WPA_SSID" ]; then
323
# initialize a new network block, record the unique WPA_ID
324
WPA_ID=$(wpa_cli add_network)
326
wpa_msg verbose "configuring network block -- $WPA_ID"
329
wpa_cli_do "$IF_WPA_SSID" ascii \
330
set_network ssid wpa-ssid
332
# configure the new network block
333
wpa_cli_do "$IF_WPA_PRIORITY" raw \
334
set_network priority wpa-priority
336
wpa_cli_do "$IF_WPA_BSSID" raw \
337
set_network bssid wpa-bssid
339
if [ -s "$IF_WPA_PSK_FILE" ]; then
340
IF_WPA_PSK=$(cat "$IF_WPA_PSK_FILE")
342
wpa_cli_do "$IF_WPA_PSK" raw \
343
set_network psk wpa-psk
345
if [ -s "$IF_WPA_PASSPHRASE_FILE" ]; then
346
IF_WPA_PASSPHRASE=$(cat "$IF_WPA_PASSPHRASE_FILE")
348
wpa_cli_do "$IF_WPA_PASSPHRASE" ascii \
349
set_network psk wpa-passphrase
351
wpa_cli_do "$IF_WPA_PAIRWISE" raw \
352
set_network pairwise wpa-pairwise
354
wpa_cli_do "$IF_WPA_GROUP" raw \
355
set_network group wpa-group
357
wpa_cli_do "$IF_WPA_KEY_MGMT" raw \
358
set_network key_mgmt wpa-key-mgmt
360
wpa_cli_do "$IF_WPA_PROTO" raw \
361
set_network proto wpa-proto
363
wpa_cli_do "$IF_WPA_AUTH_ALG" raw \
364
set_network auth_alg wpa-auth-alg
366
wpa_cli_do "$IF_WPA_SCAN_SSID" raw \
367
set_network scan_ssid wpa-scan-ssid
369
wpa_cli_do "$IF_WPA_IDENTITY" ascii \
370
set_network identity wpa-identity
372
wpa_cli_do "$IF_WPA_ANONYMOUS_IDENTITY" ascii \
373
set_network anonymous_identity wpa-anonymous-identity
375
wpa_cli_do "$IF_WPA_EAP" raw \
376
set_network eap wpa-eap
378
wpa_cli_do "$IF_WPA_EAPPSK" raw \
379
set_network eappsk wpa-eappsk
381
wpa_cli_do "$IF_WPA_NAI" ascii \
382
set_network nai wpa-nai
384
wpa_cli_do "$IF_WPA_PASSWORD" ascii \
385
set_network password wpa-password
387
wpa_cli_do "$IF_WPA_CA_CERT" ascii \
388
set_network ca_cert wpa-ca-cert
390
wpa_cli_do "$IF_WPA_CA_PATH" ascii \
391
set_network ca_path wpa-ca-path
393
wpa_cli_do "$IF_WPA_CLIENT_CERT" ascii \
394
set_network client_cert wpa-client-cert
396
wpa_cli_do "$IF_WPA_PRIVATE_KEY" ascii \
397
set_network private_key wpa-private-key
399
wpa_cli_do "$IF_WPA_PRIVATE_KEY_PASSWD" ascii \
400
set_network private_key_passwd wpa-private-key-passwd
402
wpa_cli_do "$IF_WPA_DH_FILE" ascii \
403
set_network dh_file wpa-dh-file
405
wpa_cli_do "$IF_WPA_SUBJECT_MATCH" ascii \
406
set_network subject_match wpa-subject-match
408
wpa_cli_do "$IF_WPA_ALTSUBJECT_MATCH" ascii \
409
set_network altsubject_match wpa-altsubject-match
411
wpa_cli_do "$IF_WPA_CA_CERT2" ascii \
412
set_network ca_cert2 wpa-ca-cert2
414
wpa_cli_do "$IF_WPA_CA_PATH2" ascii \
415
set_network ca_path2 wpa-ca-path2
417
wpa_cli_do "$IF_WPA_CLIENT_CERT2" ascii \
418
set_network client_cert2 wpa-client-cert2
420
wpa_cli_do "$IF_WPA_PRIVATE_KEY2" ascii \
421
set_network private_key2 wpa-private-key2
423
wpa_cli_do "$IF_WPA_PRIVATE_KEY_PASSWD2" ascii \
424
set_network private_key_passwd2 wpa-private-key-passwd2
426
wpa_cli_do "$IF_WPA_DH_FILE2" ascii \
427
set_network dh_file2 wpa-dh-file2
429
wpa_cli_do "$IF_WPA_SUBJECT_MATCH2" ascii \
430
set_network subject_match2 wpa-subject-match2
432
wpa_cli_do "$IF_WPA_ALTSUBJECT_MATCH2" ascii \
433
set_network altsubject_match2 wpa-altsubject-match2
435
wpa_cli_do "$IF_WPA_EAP_METHODS" raw \
436
set_network eap_methods wpa-eap-methods
438
wpa_cli_do "$IF_WPA_PHASE1" ascii \
439
set_network phase1 wpa-phase1
441
wpa_cli_do "$IF_WPA_PHASE2" ascii \
442
set_network phase2 wpa-phase2
444
wpa_cli_do "$IF_WPA_PCSC" raw \
445
set_network pcsc wpa-pcsc
447
wpa_cli_do "$IF_WPA_PIN" ascii \
448
set_network pin wpa-pin
450
wpa_cli_do "$IF_WPA_ENGINE" raw \
451
set_network engine wpa-engine
453
wpa_cli_do "$IF_WPA_ENGINE_ID" ascii \
454
set_network engine_id wpa-engine-id
456
wpa_cli_do "$IF_WPA_KEY_ID" ascii \
457
set_network key_id wpa-key-id
459
wpa_cli_do "$IF_WPA_EAPOL_FLAGS" raw \
460
set_network eapol_flags wpa-eapol-flags
462
wpa_cli_do "$IF_WPA_WEP_KEY0" raw \
463
set_network wep_key0 wpa-wep-key0
465
wpa_cli_do "$IF_WPA_WEP_KEY1" raw \
466
set_network wep_key1 wpa-wep-key1
468
wpa_cli_do "$IF_WPA_WEP_KEY2" raw \
469
set_network wep_key2 wpa-wep-key2
471
wpa_cli_do "$IF_WPA_WEP_KEY3" raw \
472
set_network wep_key3 wpa-wep-key3
474
wpa_cli_do "$IF_WPA_WEP_TX_KEYIDX" raw \
475
set_network wep_tx_keyidx wpa-wep-tx-keyidx
477
wpa_cli_do "$IF_WPA_PROACTIVE_KEY_CACHING" raw \
478
set_network proactive_key_caching wpa-proactive-key-caching
480
wpa_cli_do "$IF_WPA_PAC_FILE" ascii \
481
set_network pac_file wpa-pac-file
483
wpa_cli_do "$IF_WPA_MODE" raw \
484
set_network mode wpa-mode
486
wpa_cli_do "$IF_WPA_STAKEY" raw \
487
set_network stakey wpa-stakey
489
wpa_cli_do "$IF_WPA_PEERKEY" raw \
490
set_network peerkey wpa-peerkey
492
wpa_cli_do "$IF_FRAGMENT_SIZE" raw \
493
set_network fragment_size wpa-fragment-size
495
wpa_cli_do "$IF_WPA_ID_STR" ascii \
496
set_network id_str wpa-id-str
498
# finality: activate the new network block
499
wpa_cli_do "$WPA_ID" raw \
500
enable_network "enabling network block"
504
kill_wpa_supplicant () {
505
if test_daemon_pidfile "$WPA_SUP_BIN" "$WPA_SUP_PIDFILE"; then
507
wpa_msg verbose "terminating $WPA_SUP_PNAME daemon via pidfile $WPA_SUP_PIDFILE"
509
start-stop-daemon --stop --oknodo $DAEMON_VERBOSITY \
510
--exec $WPA_SUP_BIN --pidfile $WPA_SUP_PIDFILE
512
if [ -f "$WPA_SUP_PIDFILE" ]; then
513
rm -f "$WPA_SUP_PIDFILE"
515
elif [ -S "$WPA_CTRL_DIR/$IFACE" ]; then
517
# terminate existing ctrl_interface socket
518
wpa_msg action "terminating via ctrl_interface socket $WPA_CTRL_DIR/$IFACE"
520
wpa_cli terminate >$TO_NULL
522
# remove stale socket
523
if [ -S "$WPA_CTRL_DIR/$IFACE" ]; then
524
rm -f "$WPA_CTRL_DIR/$IFACE"
530
if [ -n "$WPA_ACTION_SCRIPT" ]; then
532
# default wpa_cli daemon options
533
# daemonise, create pidfile, supply IFACE
534
WPA_CLI_OPTIONS="-B -P $WPA_CLI_PIDFILE -i $IFACE"
536
# ensure the lockfile does not exist
537
if [ -e "$WPA_CLI_LOCKFILE" ]; then
538
rm -f "$WPA_CLI_LOCKFILE"
541
wpa_msg verbose "$WPA_CLI_BIN $WPA_CLI_OPTIONS -p $WPA_CTRL_DIR -a $WPA_ACTION_SCRIPT"
543
start-stop-daemon --start --oknodo $DAEMON_VERBOSITY \
544
--name $WPA_CLI_PNAME --startas $WPA_CLI_BIN --pidfile $WPA_CLI_PIDFILE \
545
-- $WPA_CLI_OPTIONS -p $WPA_CTRL_DIR -a $WPA_ACTION_SCRIPT
550
if test_daemon_pidfile "$WPA_CLI_BIN" "$WPA_CLI_PIDFILE"; then
552
wpa_msg action "sending disconnect signal to $WPA_CLI_PNAME daemon"
554
# send DISCONNECTED signal first
555
# allow wpa_action the opportunity to undo network settings
556
wpa_cli disconnect >$TO_NULL
558
wpa_msg verbose "terminating $WPA_CLI_PNAME daemon via pidfile $WPA_CLI_PIDFILE"
560
start-stop-daemon --stop --oknodo $DAEMON_VERBOSITY \
561
--exec $WPA_CLI_BIN --pidfile $WPA_CLI_PIDFILE
563
if [ -f "$WPA_CLI_PIDFILE" ]; then
564
rm -f "$WPA_CLI_PIDFILE"
567
if [ -f "$WPA_CLI_LOCKFILE" ]; then
568
rm -f "$WPA_CLI_LOCKFILE"
577
81
kill_wpa_supplicant
578
if init_wpa_supplicant; then
82
init_wpa_supplicant || exit 1
83
conf_wpa_supplicant || { kill_wpa_supplicant; exit 1; }
586
wpa_msg stderr "unknown phase: \"$PHASE\""
86
init_wpa_cli || { kill_wpa_supplicant; exit 1; }