File: int-test-common.sh

package info (click to toggle)
aircrack-ng 1%3A1.6%2Bgit20210130.91820bc-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 19,056 kB
  • sloc: ansic: 67,045; cs: 5,392; sh: 3,773; python: 2,565; pascal: 1,074; asm: 570; makefile: 253; cpp: 46
file content (431 lines) | stat: -rwxr-xr-x 9,788 bytes parent folder | download | duplicates (2)
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
#!/bin/sh

cleanup() {
	echo "Cleanup"
	kill_wpa_supplicant
	kill_hostapd
	# takes care of killing tcpdump if necessary
	clean_tcpdump
	unload_module
	restore_regdomain
}

screen_cleanup() {
	SCREEN_NAME=capture
	[ -n "$1" ] && SCREEN_NAME="$1"
	screen -S ${SCREEN_NAME} -p 0 -X quit
	screen -wipe
}

check_arg_is_number() {
	if [ -z "$1" ]; then
		echo "${2}() requires an argument, and it must be a number"
		exit 1
	fi
	if [ -z "$(echo $1 | ${GREP} -E '^[0-9]{1,}$')" ]; then
		echo "${2}() expects the a number, got $1"
		exit 1
	fi
}

MODULE_LOADED=0
load_module() {
	check_arg_is_number "$1" 'load_module'

	if [ -z "$(lsmod | ${GREP} mac80211_hwsim)" ]; then
		echo "Loading mac80211_hwsim with $1 radios"
		modprobe mac80211_hwsim radios=$1 2>&1 >/dev/null
		if [ $? -ne 0 ]; then
			# XXX: It can fail if inside a container too
			echo "Failed inserting module, skipping"
			exit 1
		fi
		MODULE_LOADED=1
	else
		echo 'mac80211_hwsim already loaded, unload it first!'
		exit 1
	fi
}

check_radios_present() {
	check_arg_is_number "$1" 'check_radios_present'

	AMOUNT_RADIOS=$("${abs_builddir}/../scripts/airmon-ng" | ${GREP} hwsim | wc -l)
	if [ ${AMOUNT_RADIOS} -ne $1 ]; then
		echo "Expected $1 radios, got ${AMOUNT_RADIOS}, hwsim may be in use by something else, aborting"
		exit 1
	fi

	echo "Correct amount of radios present: $1"
}

airmon_ng_check() {
	# Display output of "airmon-ng check" if there are interfering process
	# Can help in detecting if previous tests didn't clean up
	# Or, if running the first test, check if there are interfering processes
	if [ $("${abs_builddir}/../scripts/airmon-ng" check | grep "PID" | wc -l) -eq 1 ]; then
		"${abs_builddir}/../scripts/airmon-ng" check
	fi
}

unload_module() {
	if [ ${MODULE_LOADED} -eq 1 ]; then
		echo 'Unloading mac80211_hwsim'
		rmmod mac80211_hwsim 2>/dev/null >/dev/null
	fi
}

is_pid_running() {
	check_arg_is_number "$1" 'is_pid_running'

	[ ! -f "/proc/${1}/status" ] && return 0

	return 1
}

check_tools_compiled() {
	echo 'Checking required Aircrack-ng tools are compiled'

	# Check that all the tools are compiled
	if [ ! -f "${abs_builddir}/../scripts/airmon-ng" ]; then
		echo 'Tools are unlikely to be compiled - airmon-ng is not present'
		exit 1
	fi

	# Linux only, we'll have to adapt if we ever support Windows officially
	if [ ! -f "${abs_builddir}/../aircrack-ng" ] \
		|| [ ! -f "${abs_builddir}/../aircrack-ng" ] \
		|| [ ! -f "${abs_builddir}/../airodump-ng" ] \
		|| [ ! -f "${abs_builddir}/../aireplay-ng" ]; then
		echo 'Aircrack-ng tools not compiled'
		exit 1
	fi
}

check_root() {
	if [ $(id -u) -ne 0 ]; then
		echo 'Not root, skipping'
		exit 77
	fi

	echo 'User is root'
}

is_tool_present() {
	if [ -z "$1" ]; then
		echo 'is_tool_present() requires the name of the tool'
		exit 1
	fi

	hash $1 2>&1 >/dev/null
	if [ $? -ne 0 ]; then
		echo "$1 is not installed, aborting!"
		exit 1
	fi
	echo "$1 is present"
}

check_airmon_ng_deps_present() {
	is_tool_present iw
	is_tool_present lsusb
}

get_hwsim_interface_name() {
	check_arg_is_number "$1" 'get_hwsim_interface_name'

	IFACE=$("${abs_builddir}/../scripts/airmon-ng" 2>/dev/null | ${GREP} hwsim | head -n $1 | tail -n 1 | ${AWK} '{print $2}')

	if [ -z "${IFACE}" ]; then
		echo "Failed getting interface $1"
		cleanup
		exit 1
	fi
	echo "Interface $1 name: ${IFACE}"
}

######################## regdomain iw commands ########################

REG_DOMAIN=""

backup_regdomain() {
	REG_DOMAIN="$(iw reg get | ${GREP} country | ${AWK} -F\: '{print $1}' | ${AWK} '{print $2}')"
	echo "Current regdomain: ${REG_DOMAIN}"
}

set_regdomain() {
	if [ -z "$1" ]; then
		echo "set_regdomain(): No regdomain given"
		retun 1
	fi

	echo "Changing regdomain to $1"
	iw reg set $1
}

restore_regdomain() {
	[ -n "${REG_DOMAIN}" ] && set_regdomain ${REG_DOMAIN}
}

########################## Channel settings ##########################

FIRST_5GHZ_CHANNEL=""

get_first_5ghz_channel() {
	if [ -z "$1" ]; then
		echo 'get_first_5ghz_channel(): missing interface name'
		return 1
	fi

	TMP_IFACE_PHY=$(iw dev $1 info | ${GREP} wiphy | ${AWK} '{print $2}')

	if [ -z "${TMP_IFACE_PHY}" ]; then
		echo "get_first_5ghz_channel(): Interface $1 does not exist or does not have associated PHY"
		return 1
	fi

	FIRST_5GHZ_CHANNEL=$(iw phy phy${TMP_IFACE_PHY} info | ${GREP} -E '\* 5[0-9]{3} MHz' | ${GREP} -v -E '(no IR|disabled)' | ${AWK} -F\[ '{ print $2}' | ${AWK} -F\] '{print $1}' | head -n 1)

	if [ -z "${FIRST_5GHZ_CHANNEL}" ]; then
		echo "get_first_5ghz_channel(): No 5GHz channel available"
		return 1
	fi

	if [ $(echo "${FIRST_5GHZ_CHANNEL}" | ${GREP} -E '^[1-9][0-9]{1,2}$' | wc -l) -ne 1 ]; then
		echo "get_first_5ghz_channel(): Failure to get channel: ${FIRST_5GHZ_CHANNEL}"
		return 1
	fi
	echo "First 5GHz channel: ${FIRST_5GHZ_CHANNEL}"

	return 0
}

set_interface_channel() {
	if [ -z "$1" ]; then
		echo 'set_monitor_mode(): missing interface name'
		return 1
	fi

	check_arg_is_number "$2" 'set_interface_channel'

	echo "Setting $1 on channel $2"
	ip link set $1 up
	iw dev $1 set channel $2
	if [ $? -eq 1 ]; then
		echo "iw dev $1 set channel $2 failed, exiting"
		return 1
	fi
	return 0
}

set_monitor_mode() {
	if [ -z "$1" ]; then
		echo 'set_monitor_mode(): missing interface name'
		return 1
	fi

	echo "Putting $1 in monitor mode"
	ip link set $1 down
	iw dev $1 set monitor none
	if [ $? -eq 1 ]; then
		echo "iw dev $1 set monitor none failed, exiting"
		return 1
	fi
	ip link set $1 up

	# Check card is in monitor mode
	IFACE_MODE=$(iw dev $1 info | grep type | awk '{print $2}')
	if [ "${IFACE_MODE}" != 'monitor' ]; then
		echo "Failed to set $1 in monitor mode: ${IFACE_MODE}"
		return 1
	fi

	return 0
}

########################## tcpdump ##########################

TCPDUMP_PID=""
TEMP_TCPDUMP_PCAP=$(mktemp -u)
TCPDUMP_IFACE=""
run_tcpdump() {
	ADDL_TCPDUMP_PARAMS="$1"

	if [ -z "{TCPDUMP_IFACE}" ]; then
		echo 'Missing capture interface'
		cleanup
		exit 1
	fi

	if [ -n "$1" ]; then
		echo "Additional tcpdump parameters: $1"
		cleanup
		exit 1
	fi

	# Run tcpdump
	echo "Starting tcpdump on ${TCPDUMP_IFACE}"
	tcpdump -Z root -i ${TCPDUMP_IFACE} -w ${TEMP_TCPDUMP_PCAP} -U ${ADDL_TCPDUMP_PARAMS} & 2>&1 >/dev/null

	# Get PID
	TCPDUMP_PID=$!
	sleep 1
	is_pid_running ${TCPDUMP_PID}
	if [ $? -eq 0 ]; then
		echo 'Failed starting tcpdump'
		cleanup
		return 0
	fi

	# Display PID
	echo "tcpdump PID: ${TCPDUMP_PID}"

	return 1
}

kill_tcpdump() {
	if [ -n "${TCPDUMP_PID}" ] && [ -f "/proc/${TCPDUMP_PID}/status" ]; then

		echo "Killing tcpdump PID ${TCPDUMP_PID}"

		# If there is nothing, just kill it slowly
		if [ -z "$1" ]; then
			# Kill tcpdump (SIGTERM)
			kill -15 ${TCPDUMP_PID}

			# Wait a few seconds so it exits gracefully and
			# writes the frames to the file
			sleep 3
		fi

		# Kill and cleanup
		kill -9 ${TCPDUMP_PID} 2>/dev/null
		TCPDUMP_PID=""
	fi
}

clean_tcpdump() {
	kill_tcpdump nowait

	if [ -n "${TEMP_TCPDUMP_PCAP}" ] && [ -f ${TEMP_TCPDUMP_PCAP} ]; then
		rm -f ${TEMP_TCPDUMP_PCAP}
		TEMP_TCPDUMP_PCAP=""
	fi
}

########################## HostAPd ##########################

HOSTAPD_PID_FILE=$(mktemp -u)

# PID is more of a convenience
HOSTAPD_PID=""
TEMP_HOSTAPD_CONF_FILE=$(mktemp -u)
run_hostapd() {
	# Check configuration file is present
	if [ -z "$1" ]; then
		echo 'HostAPd requires a configuration file'
		cleanup
		exit 1
	fi

	if [ ! -f "$1" ]; then
		echo "HostAPd configuration file $1 does not exist"
		cleanup
		exit 1
	fi

	TEMP_HOSTAPD_CONF_FILE="$1"

	# Run HostAPd
	echo "Starting HostAPd with ${TEMP_HOSTAPD_CONF_FILE}"
	hostapd -P ${HOSTAPD_PID_FILE} -B ${TEMP_HOSTAPD_CONF_FILE} 2>&1
	if test $? -ne 0; then
		echo 'Failed starting HostAPd with the following configuration:'
		cat ${TEMP_HOSTAPD_CONF_FILE}
		echo '------------'
		echo 'Running airmon-ng check kill may fix the issue'
		cleanup
		return 0
	fi

	# Get PID
	sleep 0.5
	HOSTAPD_PID=$(cat ${HOSTAPD_PID_FILE} 2>/dev/null)
	echo "HostAPd PID: ${HOSTAPD_PID}"

	return 1
}

kill_hostapd() {
	if [ -n "${TEMP_HOSTAPD_CONF_FILE}" ] && [ -f ${HOSTAPD_PID_FILE} ]; then

		# Get HostAPd PID
		PID_TO_KILL=$(cat ${HOSTAPD_PID_FILE} 2>/dev/null)
		echo "Killing HostAPd PID ${PID_TO_KILL}"

		# Kill and cleanup
		kill -9 ${PID_TO_KILL}
		rm -f ${TEMP_HOSTAPD_CONF_FILE} ${HOSTAPD_PID_FILE}
		TEMP_HOSTAPD_CONF_FILE=""
		HOSTAPD_PID=""
		HOSTAPD_PID_FILE=""
	fi
}

########################## WPA supplicant ##########################

WPAS_PID_FILE=$(mktemp -u)

# PID is more of a convenience
WPAS_PID=""
TEMP_WPAS_CONF_FILE=$(mktemp -u)
run_wpa_supplicant() {
	# Check configuration file is present
	if [ -z "$1" ] || [ -z "$2" ]; then
		echo 'WPA_supplicant requires a configuration file and a wifi interface'
		cleanup
		exit 1
	fi

	if [ ! -f "$1" ]; then
		echo "WPA_supplicant configuration file $1 does not exist"
		cleanup
		exit 1
	fi

	TEMP_WPAS_CONF_FILE="$1"

	# Run WPA supplicant
	echo "Starting WPA_supplicant with ${TEMP_WPAS_CONF_FILE} on $2"
	wpa_supplicant -B -Dnl80211 -i $2 -c ${TEMP_WPAS_CONF_FILE} -P ${WPAS_PID_FILE} 2>&1
	if test $? -ne 0; then
		echo 'Failed starting WPA supplicant with the following configuration:'
		cat ${TEMP_WPAS_CONF_FILE}
		echo '------------'
		echo 'Running airmon-ng check kill may fix the issue'
		cleanup
		exit 1
	fi

	# Get PID
	sleep 0.5
	WPAS_PID=$(cat ${WPAS_PID_FILE} 2>/dev/null)
	echo "WPA supplicant PID: ${WPAS_PID}"
}

kill_wpa_supplicant() {
	if [ -n "${TEMP_WPAS_CONF_FILE}" ] && [ -f ${WPAS_PID_FILE} ]; then

		# Get WPA supplicant PID
		PID_TO_KILL=$(cat ${WPAS_PID_FILE} 2>/dev/null)
		echo "Killing WPA supplicant PID ${PID_TO_KILL}"

		# Kill and cleanup
		kill -9 ${PID_TO_KILL}
		rm -f ${TEMP_WPAS_CONF_FILE} ${WPAS_PID_FILE}
		TEMP_WPAS_CONF_FILE=""
		WPAS_PID=""
		WPAS_PID_FILE=""
	fi
}

check_tools_compiled