-
Notifications
You must be signed in to change notification settings - Fork 0
/
unified_client
executable file
·133 lines (116 loc) · 4.21 KB
/
unified_client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/sh
if [ -x "$(command -v id 2> /dev/null)" ]; then
USERID="$(id -u 2> /dev/null)"
fi
if [ -z "${USERID}" ] && [ -n "${UID}" ]; then
USERID=${UID}
fi
if [ -n "${USERID}" ] && [ "${USERID}" != "0" ]; then
printf "Run it as root\n" ; exit 1;
elif [ -z "${USERID}" ] && [ -z "${UID}" ]; then
printf "Unable to detect if running as root\n"
fi
if [ -z "${3}" ]; then
printf "Usage: %s <interface> <connection time in seconds> <wpa_supplicant.conf> [wpa_supplicant.conf]\n" "${0}"
exit 1
fi
interface="${1}"
shift
connection_timeout="${1}"
shift
conf_files="${*}"
#wait for interface
printf "Waiting for %s...\n" "${interface}"
while true; do
if ip addr show "${interface}" > /dev/null 2>&1; then
break
fi
sleep 1
done
printf "We have %s, continuing...\n" "${interface}"
politekill() {
for i in "${@}"; do
pkill -TERM -f "${i}"
done
sleep 1
for i in "${@}"; do
pkill -9 -f "${1}"
done
}
control_c() {
politekill "${arping_cmdline}" "${dhcp_cmdline}" "${wpa_supplicant_cmdline}"
ip addr flush dev "${interface}"
exit
}
trap control_c INT
trap control_c TERM
trap control_c EXIT
#todo: detect arping more correctly, including debian/raspbian arping
if [ -x /usr/bin/arping ]; then
which_arping="/usr/bin/arping -c 5 -w 5 -I"
elif [ -x /usr/sbin/arping ]; then
which_arping="/usr/sbin/arping -c 5 -W 1 -i -v"
elif [ -x /bin/arping ]; then
which_arping="/bin/arping -c 5 -w 5 -I"
fi
while true;
do
#this loop includes between 10 and 50 seconds of sleep for each config file in "conf_files"
#so each AP will have a client connected for 30ish seconds at least once every number of conf_files minutes (absent deauth floods)
for conffile in ${conf_files}; do
if [ ! -e "config/${conffile}" ]; then
printf "config/%s specified at the command line is not present, failing.\n" "${conffile}"
exit 1
fi
if [ ! -r "config/${conffile}" ]; then
printf "config/%s specified at the command line is not readable, failing.\n" "${conffile}"
exit 1
fi
ssid=$(sed -n -e 's/^[[:space:]]*//g' -e 's/"//g' -e '/^ssid=/s/ssid=//p' "config/${conffile}" | head -n1)
#set each command as a variable so it is always identical in the code
dhcp_cmdline="dhcpcd --waitip=4 --hostname=${ssid} --noipv4ll --ipv4only ${interface} --request=0.0.0.0"
wpa_supplicant_cmdline="wpa_supplicant -Dnl80211 -i ${interface} -c config/${conffile}"
arping_cmdline="${which_arping} ${interface}"
#kill everything and ensure it's dead
politekill "${wpa_supplicant_cmdline}" "${dhcp_cmdline}" "${arping_cmdline}"
#start new wpa_supplicant and wait up to 12 seconds for a connection
printf "Attempting to connect %s to SSID: %s for %ss using config %s...\n" "${interface}" "${ssid}" "${connection_timeout}" "${conffile}"
${wpa_supplicant_cmdline} &
for i in $(seq 12); do
if iw "${interface}" link | grep -q '^Connected'; then
break
fi
sleep 1
done
#start new dhcp client and wait up to 28 seconds for success
${dhcp_cmdline} &
for i in $(seq 28); do
if [ -n "$(ip route show dev "${interface}" | awk '/default/ {print $3}')" ]; then
break
fi
sleep 1
done
#register connection attempt
touch "/run/rfctf_status/${ssid}_attempt"
if [ -n "$(ip route show dev "${interface}" | awk '/default/ {print $3}')" ]; then
printf "We have an ip address\n"
start_time=$(date '+%s')
while [ "${start_time}" -gt $(( $(date '+%s') - connection_timeout )) ]; do
#we should be checking arping success but the exit codes are weird
${arping_cmdline} "$(ip route show dev "${interface}" | awk '/default/ {print $3}')"
#register connection success
#since we are not 100% sure we are connected, let's include the ip address for now
ip addr show dev "${interface}" 2>&1 | awk '/inet / {print $2}' > "/run/rfctf_status/${ssid}_active"
if [ -x "helpers/${conffile%.*}" ]; then
timeout 10 "helpers/${conffile%.*}"
fi
done
else
printf "We never got an ip address, recycling.\n"
fi
#disconnect and cleanup
politekill "${wpa_supplicant_cmdline}" "${dhcp_cmdline}" "${arping_cmdline}"
sleep 1
ip addr flush dev "${interface}"
done
done