Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3160723c authored by Tejas Vaykole's avatar Tejas Vaykole Committed by Nicholas Bellinger
Browse files

iscsi-target: Fix CHAP_A parameter list handling



The target is failing to handle list of CHAP_A key-value pair form
initiator.The target is expecting CHAP_A=5 always. In other cases,
where initiator sends list (for example) CHAP_A=6,5 target is failing
the security negotiation. Which is incorrect.

This patch handles the case (RFC 3720 section 11.1.4).
where in the initiator may send list of CHAP_A values and target replies
with appropriate CHAP_A value in response

(Drop whitespaces + rename to chap_check_algorithm + save original
 pointer + add explicit check for CHAP_A key - nab)

Signed-off-by: default avatarTejas Vaykole <tejas.vaykole@calsoftinc.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent cee6029e
Loading
Loading
Loading
Loading
+51 −13
Original line number Diff line number Diff line
@@ -71,6 +71,40 @@ static void chap_gen_challenge(
			challenge_asciihex);
}

static int chap_check_algorithm(const char *a_str)
{
	char *tmp, *orig, *token;

	tmp = kstrdup(a_str, GFP_KERNEL);
	if (!tmp) {
		pr_err("Memory allocation failed for CHAP_A temporary buffer\n");
		return CHAP_DIGEST_UNKNOWN;
	}
	orig = tmp;

	token = strsep(&tmp, "=");
	if (!token)
		goto out;

	if (strcmp(token, "CHAP_A")) {
		pr_err("Unable to locate CHAP_A key\n");
		goto out;
	}
	while (token) {
		token = strsep(&tmp, ",");
		if (!token)
			goto out;

		if (!strncmp(token, "5", 1)) {
			pr_debug("Selected MD5 Algorithm\n");
			kfree(orig);
			return CHAP_DIGEST_MD5;
		}
	}
out:
	kfree(orig);
	return CHAP_DIGEST_UNKNOWN;
}

static struct iscsi_chap *chap_server_open(
	struct iscsi_conn *conn,
@@ -79,6 +113,7 @@ static struct iscsi_chap *chap_server_open(
	char *aic_str,
	unsigned int *aic_len)
{
	int ret;
	struct iscsi_chap *chap;

	if (!(auth->naf_flags & NAF_USERID_SET) ||
@@ -93,13 +128,9 @@ static struct iscsi_chap *chap_server_open(
		return NULL;

	chap = conn->auth_protocol;
	/*
	 * We only support MD5 MDA presently.
	 */
	if (strncmp(a_str, "CHAP_A=5", 8)) {
		pr_err("CHAP_A is not MD5.\n");
		return NULL;
	}
	ret = chap_check_algorithm(a_str);
	switch (ret) {
	case CHAP_DIGEST_MD5:
		pr_debug("[server] Got CHAP_A=5\n");
		/*
		 * Send back CHAP_A set to MD5.
@@ -108,6 +139,13 @@ static struct iscsi_chap *chap_server_open(
		*aic_len += 1;
		chap->digest_type = CHAP_DIGEST_MD5;
		pr_debug("[server] Sending CHAP_A=%d\n", chap->digest_type);
		break;
	case CHAP_DIGEST_UNKNOWN:
	default:
		pr_err("Unsupported CHAP_A value\n");
		return NULL;
	}

	/*
	 * Set Identifier.
	 */
+1 −0
Original line number Diff line number Diff line
#ifndef _ISCSI_CHAP_H_
#define _ISCSI_CHAP_H_

#define CHAP_DIGEST_UNKNOWN	0
#define CHAP_DIGEST_MD5		5
#define CHAP_DIGEST_SHA		6