summaryrefslogtreecommitdiffstats
path: root/tests/ssh-test-plugin
blob: 2475034eabda16cb6035286b02982d6a306fce04 (plain)
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
#!/bin/bash

[ -z "$CRYPTSETUP_PATH" ] && {
	CRYPTSETUP_PATH=".."
	if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
		SSH_BUILD_DIR="$PWD/../.libs"
	fi
}
CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
CRYPTSETUP_SSH=$CRYPTSETUP_PATH/cryptsetup-ssh
IMG="ssh_test.img"
MAP="sshtest"
USER="sshtest"
PASSWD="sshtest1"
PASSWD2="sshtest2"
SSH_OPTIONS="-o StrictHostKeyChecking=no"

SSH_SERVER="localhost"
SSH_PATH="/home/$USER/keyfile"
SSH_KEY_PATH="$HOME/sshtest-key"

FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"

if [ -n "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
	CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
	CRYPTSETUP_VALGRIND=$CRYPTSETUP
	CRYPTSETUP_SSH=$CRYPTSETUP_PATH/../tokens/ssh/cryptsetup-ssh
	CRYPTSETUP_SSH_VALGRIND=$CRYPTSETUP_SSH
else
	CRYPTSETUP_VALGRIND=../.libs/cryptsetup
	CRYPTSETUP_SSH_VALGRIND=../.libs/cryptsetup-ssh
	CRYPTSETUP_LIB_VALGRIND=../.libs
fi

[ -z "$srcdir" ] && srcdir="."

[ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ] || {
	# test runs on meson build
	CRYPTSETUP_SSH="$CRYPTSETUP_PATH/../tokens/ssh/cryptsetup-ssh"
}

function remove_mapping()
{
	[ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP
	rm -f $IMG >/dev/null 2>&1
}

function remove_user()
{
	id -u $USER >/dev/null 2>&1 && userdel -r -f $USER >/dev/null 2>&1
	rm -f $SSH_KEY_PATH "$SSH_KEY_PATH.pub" >/dev/null 2>&1
}

function create_user()
{
	id -u $USER >/dev/null 2>&1
	[ $? -eq 0 ] && skip "User account $USER exists, aborting."
	[ -f $SSH_KEY_PATH ] && skip "SSH key $SSH_KEY_PATH already exists, aborting."

	useradd -m $USER -p $(openssl passwd $PASSWD) || skip "Failed to add user for SSH plugin test."

	ssh-keygen -f $SSH_KEY_PATH -q -N "" >/dev/null 2>&1
	[ $? -ne 0 ] && remove_user && skip "Failed to create SSH key."
}

function ssh_check()
{
	# try to use netcat to check port 22
	nc -zv $SSH_SERVER 22 >/dev/null 2>&1 || skip "SSH server does not seem to be running, skipping."
}

function bin_check()
{
	command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped."
}

function ssh_setup()
{
	# copy the ssh key
	[ -d "/home/$USER/.ssh" ] || mkdir /home/$USER/.ssh
	touch /home/$USER/.ssh/authorized_keys

	cat $SSH_KEY_PATH.pub >> /home/$USER/.ssh/authorized_keys
	[ $? -ne 0 ] && remove_user && fail "Failed to copy SSH key."

	# make sure /home/sshtest/.ssh and /home/sshtest/.ssh/authorized_keys have correct permissions
	chown -R $USER:$USER /home/$USER/.ssh
	chmod 700 /home/$USER/.ssh
	chmod 644 /home/$USER/.ssh/authorized_keys

	# try to ssh and also create keyfile
	ssh -i $SSH_KEY_PATH $SSH_OPTIONS -o BatchMode=yes -n $USER@$SSH_SERVER "echo -n $PASSWD > $SSH_PATH" >/dev/null 2>&1
	[ $? -ne 0 ] && remove_user && fail "Failed to connect using SSH."
}

function fail()
{
	echo "[FAILED]"
	[ -n "$1" ] && echo "$1"
	echo "FAILED backtrace:"
	while caller $frame; do ((frame++)); done
	remove_mapping
	remove_user
	exit 2
}

function skip()
{
	[ -n "$1" ] && echo "$1"
	remove_mapping
	exit 77
}

function valgrind_setup()
{
	command -v valgrind >/dev/null || fail "Cannot find valgrind."
	[ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable."
	[ ! -f $CRYPTSETUP_SSH_VALGRIND ] && fail "Unable to get location of cryptsetup-ssh executable."
	if [ -z "$CRYPTSETUP_TESTS_RUN_IN_MESON" ]; then
		export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH"
	fi
}

function valgrind_run()
{
	INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@"
}

function valgrind_run_ssh()
{
	INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_SSH_VALGRIND} "$@"
}

format()
{
	dd if=/dev/zero of=$IMG bs=1M count=32 >/dev/null 2>&1

	echo $PASSWD | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $IMG --force-password -q
	[ $? -ne 0 ] && fail "Format failed."

	echo -e "$PASSWD\n$PASSWD2" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $IMG -q
	[ $? -ne 0 ] && fail "Add key failed."
}

check_dump()
{
	dump=$1
	keyslot=$2

	token=$(echo "$dump" | grep Tokens -A 1 | tail -1 | cut -d: -f2 | tr -d "\t\n ")
	[ "$token" = "ssh"  ] || fail " token check from dump failed."

	server=$(echo "$dump" | grep ssh_server | cut -d: -f2 | tr -d "\t\n ")
	[ "$server" = $SSH_SERVER ] || fail " server check from dump failed."

	user=$(echo "$dump" | grep ssh_user | cut -d: -f2 | tr -d "\t\n ")
	[ "$user" = "$USER"  ] || fail " user check from dump failed."

	path=$(echo "$dump" | grep ssh_path | cut -d: -f2 | tr -d "\t\n ")
	[ "$path" = "$SSH_PATH"  ] || fail " path check from dump failed."

	key_path=$(echo "$dump" | grep ssh_key_path | cut -d: -f2 | tr -d "\t\n ")
	[ "$key_path" = "$SSH_KEY_PATH"  ] || fail " key_path check from dump failed."

	keyslot_dump=$(echo "$dump" | grep Keyslot: | cut -d: -f2 | tr -d "\t\n ")
	[ "$keyslot_dump" = "$keyslot" ] || fail " keyslot check from dump failed."
}

if [ -n "$SSH_BUILD_DIR" ]; then
	CUSTOM_TOKENS_PATH="--external-tokens-path $SSH_BUILD_DIR"
fi
[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped."
[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run && CRYPTSETUP_SSH=valgrind_run_ssh
[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped."

# Prevent running dangerous useradd operation by default
[ -z "$RUN_SSH_PLUGIN_TEST" ] && skip "WARNING: Variable RUN_SSH_PLUGIN_TEST must be defined, test skipped."

bin_check nc
bin_check useradd
bin_check ssh
bin_check ssh-keygen
bin_check sshpass
bin_check openssl

format

echo -n "Adding SSH token: "

ssh_check
create_user
ssh_setup

$CRYPTSETUP_SSH add $IMG --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH $CUSTOM_TOKENS_PATH
[ $? -ne 0 ] && fail "Failed to add SSH token to $IMG"

out=$($CRYPTSETUP luksDump $CUSTOM_TOKENS_PATH $IMG)
check_dump "$out" 0
echo "[OK]"

echo -n "Activating using SSH token: "

$CRYPTSETUP luksOpen --token-only --disable-external-tokens -r $IMG $MAP && fail "Tokens should be disabled"
$CRYPTSETUP luksOpen $CUSTOM_TOKENS_PATH -r $IMG $MAP -q >/dev/null 2>&1 <&-
[ $? -ne 0 ] && fail "Failed to open $IMG using SSH token"
echo "[OK]"

# Remove the newly added token and test adding with --key-slot
$CRYPTSETUP token remove --token-id 0 $IMG || fail "Failed to remove token"

echo -n "Adding SSH token with --key-slot: "

$CRYPTSETUP_SSH add $IMG --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH --key-slot 1 $CUSTOM_TOKENS_PATH
[ $? -ne 0 ] && fail "Failed to add SSH token to $IMG"

out=$($CRYPTSETUP luksDump $CUSTOM_TOKENS_PATH $IMG)
check_dump "$out" 1
echo "[OK]"

remove_mapping
remove_user