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