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