mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 20:14:06 +02:00
scsi: target: iscsi: Support base64 in CHAP
RFC7143 allows both Base64 and Hex encoding for CHAP binary entities like Challenge and Response. Currently the Linux iSCSI target supports only Hex encoding. Add support for Base64 encoded CHAP Challenge and CHAP Response required for CHAP tests in Windows HLK. Link: https://lore.kernel.org/r/20220718152555.17084-3-d.bogdanov@yadro.com Reviewed-by: Mike Christie <michael.christie@oracle.com> Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
8f1f7d297b
commit
1e57338834
|
|
@ -205,6 +205,38 @@ static struct iscsi_chap *chap_server_open(
|
||||||
return chap;
|
return chap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char base64_lookup_table[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
static int chap_base64_decode(u8 *dst, const char *src, size_t len)
|
||||||
|
{
|
||||||
|
int i, bits = 0, ac = 0;
|
||||||
|
const char *p;
|
||||||
|
u8 *cp = dst;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (src[i] == '=')
|
||||||
|
return cp - dst;
|
||||||
|
|
||||||
|
p = strchr(base64_lookup_table, src[i]);
|
||||||
|
if (p == NULL || src[i] == 0)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
ac <<= 6;
|
||||||
|
ac += (p - base64_lookup_table);
|
||||||
|
bits += 6;
|
||||||
|
if (bits >= 8) {
|
||||||
|
*cp++ = (ac >> (bits - 8)) & 0xff;
|
||||||
|
ac &= ~(BIT(16) - BIT(bits - 8));
|
||||||
|
bits -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ac)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return cp - dst;
|
||||||
|
}
|
||||||
|
|
||||||
static int chap_server_compute_hash(
|
static int chap_server_compute_hash(
|
||||||
struct iscsit_conn *conn,
|
struct iscsit_conn *conn,
|
||||||
struct iscsi_node_auth *auth,
|
struct iscsi_node_auth *auth,
|
||||||
|
|
@ -295,16 +327,27 @@ static int chap_server_compute_hash(
|
||||||
pr_err("Could not find CHAP_R.\n");
|
pr_err("Could not find CHAP_R.\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (type != HEX) {
|
|
||||||
pr_err("Could not find CHAP_R.\n");
|
switch (type) {
|
||||||
goto out;
|
case HEX:
|
||||||
}
|
|
||||||
if (strlen(chap_r) != chap->digest_size * 2) {
|
if (strlen(chap_r) != chap->digest_size * 2) {
|
||||||
pr_err("Malformed CHAP_R\n");
|
pr_err("Malformed CHAP_R\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (hex2bin(client_digest, chap_r, chap->digest_size) < 0) {
|
if (hex2bin(client_digest, chap_r, chap->digest_size) < 0) {
|
||||||
pr_err("Malformed CHAP_R\n");
|
pr_err("Malformed CHAP_R: invalid HEX\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BASE64:
|
||||||
|
if (chap_base64_decode(client_digest, chap_r, strlen(chap_r)) !=
|
||||||
|
chap->digest_size) {
|
||||||
|
pr_err("Malformed CHAP_R: invalid BASE64\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("Could not find CHAP_R\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -404,10 +447,8 @@ static int chap_server_compute_hash(
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != HEX) {
|
switch (type) {
|
||||||
pr_err("Could not find CHAP_C.\n");
|
case HEX:
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
initiatorchg_len = DIV_ROUND_UP(strlen(initiatorchg), 2);
|
initiatorchg_len = DIV_ROUND_UP(strlen(initiatorchg), 2);
|
||||||
if (!initiatorchg_len) {
|
if (!initiatorchg_len) {
|
||||||
pr_err("Unable to convert incoming challenge\n");
|
pr_err("Unable to convert incoming challenge\n");
|
||||||
|
|
@ -417,10 +458,35 @@ static int chap_server_compute_hash(
|
||||||
pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
|
pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (hex2bin(initiatorchg_binhex, initiatorchg, initiatorchg_len) < 0) {
|
|
||||||
pr_err("Malformed CHAP_C\n");
|
if (hex2bin(initiatorchg_binhex, initiatorchg,
|
||||||
|
initiatorchg_len) < 0) {
|
||||||
|
pr_err("Malformed CHAP_C: invalid HEX\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case BASE64:
|
||||||
|
initiatorchg_len = chap_base64_decode(initiatorchg_binhex,
|
||||||
|
initiatorchg,
|
||||||
|
strlen(initiatorchg));
|
||||||
|
if (initiatorchg_len < 0) {
|
||||||
|
pr_err("Malformed CHAP_C: invalid BASE64\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (!initiatorchg_len) {
|
||||||
|
pr_err("Unable to convert incoming challenge\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (initiatorchg_len > 1024) {
|
||||||
|
pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("Could not find CHAP_C.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
pr_debug("[server] Got CHAP_C=%s\n", initiatorchg);
|
pr_debug("[server] Got CHAP_C=%s\n", initiatorchg);
|
||||||
/*
|
/*
|
||||||
* During mutual authentication, the CHAP_C generated by the
|
* During mutual authentication, the CHAP_C generated by the
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,9 @@ int extract_param(
|
||||||
if (*ptr == '0' && (*(ptr+1) == 'x' || *(ptr+1) == 'X')) {
|
if (*ptr == '0' && (*(ptr+1) == 'x' || *(ptr+1) == 'X')) {
|
||||||
ptr += 2; /* skip 0x */
|
ptr += 2; /* skip 0x */
|
||||||
*type = HEX;
|
*type = HEX;
|
||||||
|
} else if (*ptr == '0' && (*(ptr+1) == 'b' || *(ptr+1) == 'B')) {
|
||||||
|
ptr += 2; /* skip 0b */
|
||||||
|
*type = BASE64;
|
||||||
} else
|
} else
|
||||||
*type = DECIMAL;
|
*type = DECIMAL;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#define DECIMAL 0
|
#define DECIMAL 0
|
||||||
#define HEX 1
|
#define HEX 1
|
||||||
|
#define BASE64 2
|
||||||
|
|
||||||
struct iscsit_conn;
|
struct iscsit_conn;
|
||||||
struct iscsi_login;
|
struct iscsi_login;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user