Commit 16b33d51 authored by Oded Mashbach's avatar Oded Mashbach Committed by Tomasz Zawadzki
Browse files

iscsi: Authenticating discovery based on givven credentials.



This commits verifies that iSCSI CHAP authentication functions correctly
during the discovery phase.

Previously, configuring CHAP using iscsi_set_discovery_auth did not
enforce authentication for host discovery sessions. This occurred
because the connection object's CHAP property remained unset.

The commit ensures that updating the connection's CHAP properties, when
discovery session negotiates its chap params - addresses this issue and enforces CHAP
authentication during discovery.

Change-Id: I1f9e59a1b7a4a507b3c9ddcd2a6e4b070176c8c3
Signed-off-by: default avatarOded Mashbach <oded.mashbach@silk.us>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/23616


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <smatsumoto@nvidia.com>
parent 9e6e8d1d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1546,6 +1546,11 @@ iscsi_negotiate_chap_param(struct spdk_iscsi_conn *conn)
static int
iscsi_op_login_session_discovery_chap(struct spdk_iscsi_conn *conn)
{
	conn->disable_chap = g_iscsi.disable_chap;
	conn->require_chap = g_iscsi.require_chap;
	conn->mutual_chap = g_iscsi.mutual_chap;
	conn->chap_group = g_iscsi.chap_group;

	return iscsi_negotiate_chap_param(conn);
}

+157 −0
Original line number Diff line number Diff line
#!/usr/bin/env bash
#  SPDX-License-Identifier: BSD-3-Clause
#  Copyright (C) 2018 Intel Corporation
#  All rights reserved.
#

TARGET_NAME="iqn.2016-06.io.spdk:disk1"
TARGET_ALIAS_NAME="disk1_alias"
MALLOC_BDEV_SIZE=64
MALLOC_BLOCK_SIZE=512

function parse_cmd_line() {
	OPTIND=0
	DURING_DISCOVERY=0
	DURING_LOGIN=0
	BI_DIRECT=0
	CHAP_USER="chapo"
	CHAP_PASS="123456789123"
	CHAP_MUSER=""
	CHAP_MUSER=""
	AUTH_GROUP_ID=1

	while getopts ":t:u:s:r:m:dlb" opt; do
		case ${opt} in
			t)
				AUTH_GROUP_ID=$OPTARG
				;;
			u)
				CHAP_USER=$OPTARG
				;;
			s)
				CHAP_PASS=$OPTARG
				;;
			r)
				CHAP_MUSER=$OPTARG
				;;
			m)
				CHAP_MPASS=$OPTARG
				;;
			d)
				DURING_DISCOVERY=1
				;;
			l)
				DURING_LOGIN=1
				;;
			b)
				BI_DIRECT=1
				;;
			\?)
				echo "Usage: config_chap_credentials_for_target/config_chap_credentials_for_initiator [-t auth_group id] \
            [-u user] [-s password] [-r muser] [-m mpassword] [-d] [-l] [-b]"
				;;
		esac
	done
}

function restart_iscsid() {
	sleep 3
	systemctl restart iscsid
	sleep 1
}

function default_initiator_chap_credentials() {
	iscsiadm -m node --logout || true
	iscsiadm -m node -o delete || true

	sed -i "s/^node.session.auth.authmethod = CHAP/#node.session.auth.authmethod = CHAP/" /etc/iscsi/iscsid.conf
	sed -i "s/^node.session.auth.username =.*/#node.session.auth.username = username/" /etc/iscsi/iscsid.conf
	sed -i "s/^node.session.auth.password =.*/#node.session.auth.password = password/" /etc/iscsi/iscsid.conf
	sed -i "s/^node.session.auth.username_in =.*/#node.session.auth.username_in = username_in/" /etc/iscsi/iscsid.conf
	sed -i "s/^node.session.auth.password_in =.*/#node.session.auth.password_in = password_in/" /etc/iscsi/iscsid.conf

	sed -i 's/^discovery.sendtargets.auth.authmethod = CHAP/#discovery.sendtargets.auth.authmethod = CHAP/' /etc/iscsi/iscsid.conf
	sed -i 's/^discovery.sendtargets.auth.username =.*/#discovery.sendtargets.auth.username = username/' /etc/iscsi/iscsid.conf
	sed -i 's/^discovery.sendtargets.auth.password =.*/#discovery.sendtargets.auth.password = password/' /etc/iscsi/iscsid.conf
	sed -i "s/^discovery.sendtargets.auth.username_in =.*/#discovery.sendtargets.auth.username_in = username_in/" /etc/iscsi/iscsid.conf
	sed -i "s/^discovery.sendtargets.auth.password_in =.*/#discovery.sendtargets.auth.password_in = password_in/" /etc/iscsi/iscsid.conf
	restart_iscsid
	trap "trap - ERR; print_backtrace >&2" ERR
}

function config_chap_credentials_for_target() {

	parse_cmd_line "$@"
	#create auth group $AUTH_GROUP_ID
	$rpc_py iscsi_create_auth_group $AUTH_GROUP_ID
	#add secret + msecret to the auth group
	if [ -z "$CHAP_MUSER" ] || [ -z "$CHAP_MPASS" ]; then
		$rpc_py iscsi_auth_group_add_secret -u $CHAP_USER -s $CHAP_PASS $AUTH_GROUP_ID
	else
		$rpc_py iscsi_auth_group_add_secret -u $CHAP_USER -s $CHAP_PASS -m $CHAP_MUSER -r $CHAP_MPASS $AUTH_GROUP_ID
	fi

	#set chap authentication method during discovery phase
	if [ $DURING_LOGIN -eq 1 ]; then
		if [ $BI_DIRECT -eq 1 ]; then
			$rpc_py iscsi_target_node_set_auth -g $AUTH_GROUP_ID -r -m $TARGET_NAME
		else
			$rpc_py iscsi_target_node_set_auth -g $AUTH_GROUP_ID -r $TARGET_NAME
		fi
	fi
	if [ $DURING_DISCOVERY -eq 1 ]; then
		if [ $BI_DIRECT -eq 1 ]; then
			$rpc_py iscsi_set_discovery_auth -r -m -g $AUTH_GROUP_ID
		else
			$rpc_py iscsi_set_discovery_auth -r -g $AUTH_GROUP_ID
		fi
	fi
}

function config_chap_credentials_for_initiator() {

	parse_cmd_line "$@"
	default_initiator_chap_credentials

	if [ $DURING_LOGIN -eq 1 ]; then
		sed -i "s/#node.session.auth.authmethod = CHAP/node.session.auth.authmethod = CHAP/" /etc/iscsi/iscsid.conf
		sed -i "s/#node.session.auth.username =.*/node.session.auth.username = ${CHAP_USER}/" /etc/iscsi/iscsid.conf
		sed -i "s/#node.session.auth.password =.*/node.session.auth.password = ${CHAP_PASS}/" /etc/iscsi/iscsid.conf
		if [ $BI_DIRECT -eq 1 ] && [ -n "$CHAP_MPASS" ] && [ -n "$CHAP_MUSER" ]; then
			sed -i "s/#node.session.auth.username_in =.*/node.session.auth.username_in = ${CHAP_MUSER}/" /etc/iscsi/iscsid.conf
			sed -i "s/#node.session.auth.password_in =.*/node.session.auth.password_in = ${CHAP_MPASS}/" /etc/iscsi/iscsid.conf
		fi
	fi

	if [ $DURING_DISCOVERY -eq 1 ]; then
		sed -i "s/#discovery.sendtargets.auth.authmethod = CHAP/discovery.sendtargets.auth.authmethod = CHAP/" /etc/iscsi/iscsid.conf
		sed -i "s/#discovery.sendtargets.auth.username =.*/discovery.sendtargets.auth.username = ${CHAP_USER}/" /etc/iscsi/iscsid.conf
		sed -i "s/#discovery.sendtargets.auth.password =.*/discovery.sendtargets.auth.password = ${CHAP_PASS}/" /etc/iscsi/iscsid.conf
		if [ $BI_DIRECT -eq 1 ] && [ -n "$CHAP_MPASS" ] && [ -n "$CHAP_MUSER" ]; then
			sed -i "s/#discovery.sendtargets.auth.username_in =.*/discovery.sendtargets.auth.username_in = ${CHAP_MUSER}/" /etc/iscsi/iscsid.conf
			sed -i "s/#discovery.sendtargets.auth.password_in =.*/discovery.sendtargets.auth.password_in = ${CHAP_MPASS}/" /etc/iscsi/iscsid.conf
		fi
	fi
	restart_iscsid
	trap "trap - ERR; default_initiator_chap_credentials; print_backtrace >&2" ERR
}

function set_up_iscsi_target() {
	timing_enter start_iscsi_tgt
	"${ISCSI_APP[@]}" -m 0x2 -p 1 -s 512 --wait-for-rpc &
	pid=$!
	echo "iSCSI target launched. pid: $pid"
	trap 'killprocess $pid;exit 1' SIGINT SIGTERM EXIT
	waitforlisten $pid
	$rpc_py iscsi_set_options -o 30 -a 4
	$rpc_py framework_start_init
	echo "iscsi_tgt is listening. Running tests..."
	timing_exit start_iscsi_tgt

	$rpc_py iscsi_create_portal_group $PORTAL_TAG $TARGET_IP:$ISCSI_PORT
	$rpc_py iscsi_create_initiator_group $INITIATOR_TAG $INITIATOR_NAME $NETMASK
	$rpc_py bdev_malloc_create $MALLOC_BDEV_SIZE $MALLOC_BLOCK_SIZE
	$rpc_py iscsi_create_target_node $TARGET_NAME $TARGET_ALIAS_NAME 'Malloc0:0' $PORTAL_TAG:$INITIATOR_TAG 256 -d
	sleep 1
	trap 'killprocess $pid; iscsitestfini; exit 1' SIGINT SIGTERM EXIT
}
+51 −0
Original line number Diff line number Diff line
#!/usr/bin/env bash
#  SPDX-License-Identifier: BSD-3-Clause
#  Copyright (C) 2018 Intel Corporation
#  All rights reserved.
#

testdir=$(readlink -f $(dirname $0))
rootdir=$(readlink -f $testdir/../../..)
source $rootdir/test/common/autotest_common.sh
source $rootdir/test/iscsi_tgt/common.sh
source $rootdir/test/iscsi_tgt/chap/chap_common.sh

USER="chapo"
MUSER="mchapo"
PASS="123456789123"
MPASS="321978654321"

#initialize test:
iscsitestinit
#set up iscsi target
set_up_iscsi_target

#configure target to require bi derectional chap authentication for discovery - mutual credentials:
echo "configuring target for bideerctional authentication"
config_chap_credentials_for_target -t 1 -u $USER -s $PASS -r $MUSER -m $MPASS -d -b
echo "executing discovery without adding credential to initiator - we expect failure"
rc=0
iscsiadm -m discovery -t sendtargets -p $TARGET_IP:$ISCSI_PORT || rc=$?
if [ $rc -eq 0 ]; then
	echo "[ERROR] - we are not allowed to discover targets without providing credentials"
	exit 1
fi

#configure  initiator credentials:
echo "configuring initiator for bideerctional authentication"
config_chap_credentials_for_initiator -t 1 -u $USER -s $PASS -r $MUSER -m $MPASS -d -b
echo "executing discovery with adding credential to initiator"
rc=0
iscsiadm -m discovery -t sendtargets -p $TARGET_IP:$ISCSI_PORT || rc=$?
if [ $rc -ne 0 ]; then
	echo "[ERROR] - now that we have credentials - we should be able to discover the target"
	exit 1
fi
echo "DONE"
default_initiator_chap_credentials

trap - SIGINT SIGTERM EXIT

killprocess $pid

iscsitestfini
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ else
	skip_run_test_with_warning "WARNING: Calsoft binaries not found, skipping test!"
fi
run_test "iscsi_tgt_filesystem" $rootdir/test/iscsi_tgt/filesystem/filesystem.sh
run_test "chap_during_discovery" $rootdir/test/iscsi_tgt/chap/chap_discovery.sh
run_test "iscsi_tgt_reset" $rootdir/test/iscsi_tgt/reset/reset.sh
run_test "iscsi_tgt_rpc_config" $rootdir/test/iscsi_tgt/rpc_config/rpc_config.sh
run_test "iscsi_tgt_iscsi_lvol" $rootdir/test/iscsi_tgt/lvol/iscsi_lvol.sh