xref: /spdk/test/nvmf/target/auth.sh (revision 16d862d0380886f6fc765f68a87e240bb4295595)
1#!/usr/bin/env bash
2# SPDX-License-Identifier: BSD-3-Clause
3# Copyright (c) 2024 Intel Corporation
4#
5
6testdir=$(readlink -f "$(dirname "$0")")
7rootdir=$(readlink -f "$testdir/../../../")
8
9source "$rootdir/test/common/autotest_common.sh"
10source "$rootdir/test/nvmf/common.sh"
11
12# shellcheck disable=SC2190
13digests=("sha256" "sha384" "sha512")
14dhgroups=("null" "ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192")
15subnqn="nqn.2024-03.io.spdk:cnode0"
16hostnqn="$NVME_HOSTNQN"
17hostsock="/var/tmp/host.sock"
18keys=() ckeys=()
19
20cleanup() {
21	killprocess $hostpid || :
22	nvmftestfini || :
23	rm -f "${keys[@]}" "${ckeys[@]}" "$output_dir"/nvm{e,f}-auth.log
24}
25
26dumplogs() {
27	cat "$output_dir/nvme-auth.log"
28	cat "$output_dir/nvmf-auth.log"
29}
30
31hostrpc() { "$rootdir/scripts/rpc.py" -s "$hostsock" "$@"; }
32
33connect_authenticate() {
34	local digest dhgroup key ckey qpairs
35
36	digest="$1" dhgroup="$2" key="key$3"
37	ckey=(${ckeys[$3]:+--dhchap-ctrlr-key "ckey$3"})
38
39	rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key "$key" "${ckey[@]}"
40	hostrpc bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
41		-a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
42		--dhchap-key "${key}" "${ckey[@]}"
43
44	[[ $(hostrpc bdev_nvme_get_controllers | jq -r '.[].name') == "nvme0" ]]
45	qpairs=$(rpc_cmd nvmf_subsystem_get_qpairs "$subnqn")
46	[[ $(jq -r ".[0].auth.digest" <<< "$qpairs") == "$digest" ]]
47	[[ $(jq -r ".[0].auth.dhgroup" <<< "$qpairs") == "$dhgroup" ]]
48	[[ $(jq -r ".[0].auth.state" <<< "$qpairs") == "completed" ]]
49	hostrpc bdev_nvme_detach_controller nvme0
50
51	# Force 1 I/O queue to speed up the connection
52	nvme connect -t "$TEST_TRANSPORT" -a "$NVMF_FIRST_TARGET_IP" -n "$subnqn" -i 1 \
53		-q "$hostnqn" --hostid "$NVME_HOSTID" --dhchap-secret "$(< "${keys[$3]}")" \
54		${ckeys[$3]:+--dhchap-ctrl-secret "$(< "${ckeys[$3]}")"}
55	nvme disconnect -n "$subnqn"
56	rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn"
57}
58
59nvmftestinit
60nvmfappstart -L nvmf_auth &> "$output_dir/nvmf-auth.log"
61"$rootdir/build/bin/spdk_tgt" -m 2 -r "$hostsock" -L nvme_auth &> "$output_dir/nvme-auth.log" &
62hostpid=$!
63
64trap "dumplogs; cleanup" SIGINT SIGTERM EXIT
65
66# Set host/ctrlr key pairs with one combination w/o bidirectional authentication
67keys[0]=$(gen_dhchap_key "null" 48) ckeys[0]=$(gen_dhchap_key "sha512" 64)
68keys[1]=$(gen_dhchap_key "sha256" 32) ckeys[1]=$(gen_dhchap_key "sha384" 48)
69keys[2]=$(gen_dhchap_key "sha384" 48) ckeys[2]=$(gen_dhchap_key "sha256" 32)
70keys[3]=$(gen_dhchap_key "sha512" 64) ckeys[3]=""
71
72waitforlisten "$nvmfpid"
73waitforlisten "$hostpid" "$hostsock"
74rpc_cmd <<- CONFIG
75	nvmf_create_transport -t "$TEST_TRANSPORT"
76	nvmf_create_subsystem "$subnqn"
77	nvmf_subsystem_add_listener -t "$TEST_TRANSPORT" -a "$NVMF_FIRST_TARGET_IP" \
78		-s "$NVMF_PORT" "$subnqn"
79CONFIG
80
81for i in "${!keys[@]}"; do
82	rpc_cmd keyring_file_add_key "key$i" "${keys[i]}"
83	hostrpc keyring_file_add_key "key$i" "${keys[i]}"
84	if [[ -n "${ckeys[i]}" ]]; then
85		rpc_cmd keyring_file_add_key "ckey$i" "${ckeys[i]}"
86		hostrpc keyring_file_add_key "ckey$i" "${ckeys[i]}"
87	fi
88done
89
90# Check all digest/dhgroup/key combinations
91for digest in "${digests[@]}"; do
92	for dhgroup in "${dhgroups[@]}"; do
93		for keyid in "${!keys[@]}"; do
94			hostrpc bdev_nvme_set_options --dhchap-digests "$digest" \
95				--dhchap-dhgroups "$dhgroup"
96			connect_authenticate "$digest" "$dhgroup" $keyid
97		done
98	done
99done
100
101# Connect with all digests/dhgroups enabled
102hostrpc bdev_nvme_set_options \
103	--dhchap-digests \
104	"$(
105		IFS=,
106		printf "%s" "${digests[*]}"
107	)" \
108	--dhchap-dhgroups \
109	"$(
110		IFS=,
111		printf "%s" "${dhgroups[*]}"
112	)"
113# The target should select the strongest digest/dhgroup
114connect_authenticate "${digests[-1]}" "${dhgroups[-1]}" 0
115
116# Check that mismatched keys result in failed attach
117rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key "key1"
118NOT hostrpc bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
119	-a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
120	--dhchap-key "key2"
121rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn"
122
123# Check that mismatched controller keys result in failed attach
124rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key "key1" --dhchap-ctrlr-key "ckey1"
125NOT hostrpc bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
126	-a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
127	--dhchap-key "key1" --dhchap-ctrlr-key "ckey2"
128rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn"
129
130# Check that a missing controller key results in a failed attach
131rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key "key1"
132NOT hostrpc bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
133	-a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
134	--dhchap-key "key1" --dhchap-ctrlr-key "ckey1"
135rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn"
136
137# Limit allowed digests/dhgroups on the target
138killprocess "$nvmfpid"
139nvmfappstart --wait-for-rpc -L nvmf_auth &>> "$output_dir/nvmf-auth.log"
140trap "dumplogs; cleanup" SIGINT SIGTERM EXIT
141
142waitforlisten "$nvmfpid"
143rpc_cmd <<- CONFIG
144	nvmf_set_config --dhchap-digests sha384,sha512 --dhchap-dhgroups ffdhe6144,ffdhe8192
145	framework_start_init
146	nvmf_create_transport -t "$TEST_TRANSPORT"
147	nvmf_create_subsystem "$subnqn"
148	nvmf_subsystem_add_listener -t "$TEST_TRANSPORT" -a "$NVMF_FIRST_TARGET_IP" \
149		-s "$NVMF_PORT" "$subnqn"
150	keyring_file_add_key key3 "${keys[3]}"
151CONFIG
152
153connect_authenticate "sha512" "ffdhe8192" 3
154
155# Check that authentication fails when no common digests are allowed
156rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn" --dhchap-key key3
157hostrpc bdev_nvme_set_options --dhchap-digests "sha256"
158NOT hostrpc bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
159	-a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
160	--dhchap-key "key3"
161
162# Check that authentication fails when no common dhgroups are allowed
163hostrpc bdev_nvme_set_options --dhchap-dhgroups "ffdhe2048" \
164	--dhchap-digests \
165	"$(
166		IFS=,
167		printf "%s" "${digests[*]}"
168	)"
169NOT hostrpc bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
170	-a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
171	--dhchap-key "key3"
172
173# Check that the authentication fails when the host wants to authenticate the target (i.e. user set
174# the dhchap_ctrlr_key), but the target doesn't require authentication
175hostrpc bdev_nvme_set_options \
176	--dhchap-digests \
177	"$(
178		IFS=,
179		printf "%s" "${digests[*]}"
180	)" \
181	--dhchap-dhgroups \
182	"$(
183		IFS=,
184		printf "%s" "${dhgroups[*]}"
185	)"
186rpc_cmd nvmf_subsystem_remove_host "$subnqn" "$hostnqn"
187rpc_cmd nvmf_subsystem_add_host "$subnqn" "$hostnqn"
188NOT hostrpc bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
189	-a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
190	--dhchap-key "key0" --dhchap-ctrlr-key "key1"
191# But it's fine when the host key is set and the controller key is not
192hostrpc bdev_nvme_attach_controller -b nvme0 -t "$TEST_TRANSPORT" -f ipv4 \
193	-a "$NVMF_FIRST_TARGET_IP" -s "$NVMF_PORT" -q "$hostnqn" -n "$subnqn" \
194	--dhchap-key "key0"
195[[ $(hostrpc bdev_nvme_get_controllers | jq -r '.[].name') == "nvme0" ]]
196hostrpc bdev_nvme_detach_controller nvme0
197
198trap - SIGINT SIGTERM EXIT
199cleanup
200