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: Tejas Vaykole <tejas.vaykole@calsoftinc.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
cee6029ecf
commit
3160723c49
@ -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,21 +128,24 @@ 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");
|
||||
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.
|
||||
*/
|
||||
*aic_len = sprintf(aic_str, "CHAP_A=5");
|
||||
*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;
|
||||
}
|
||||
pr_debug("[server] Got CHAP_A=5\n");
|
||||
/*
|
||||
* Send back CHAP_A set to MD5.
|
||||
*/
|
||||
*aic_len = sprintf(aic_str, "CHAP_A=5");
|
||||
*aic_len += 1;
|
||||
chap->digest_type = CHAP_DIGEST_MD5;
|
||||
pr_debug("[server] Sending CHAP_A=%d\n", chap->digest_type);
|
||||
|
||||
/*
|
||||
* Set Identifier.
|
||||
*/
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef _ISCSI_CHAP_H_
|
||||
#define _ISCSI_CHAP_H_
|
||||
|
||||
#define CHAP_DIGEST_UNKNOWN 0
|
||||
#define CHAP_DIGEST_MD5 5
|
||||
#define CHAP_DIGEST_SHA 6
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user