diff options
author | Tejas Vaykole <tejas.vaykole@calsoftinc.com> | 2014-05-30 01:43:47 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-06-05 22:44:02 -0400 |
commit | 3160723c49605965628c3ee7699e5e956c4f8f51 (patch) | |
tree | fcba72fafb5e7e4e6908cb6238962585a60189a0 /drivers/target/iscsi | |
parent | cee6029ecfc2494e7869da20e3ff5aa7f5c4368e (diff) |
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>
Diffstat (limited to 'drivers/target/iscsi')
-rw-r--r-- | drivers/target/iscsi/iscsi_target_auth.c | 64 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_auth.h | 1 |
2 files changed, 52 insertions, 13 deletions
diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c index de77d9aa22c6..155f33848aa6 100644 --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c | |||
@@ -71,6 +71,40 @@ static void chap_gen_challenge( | |||
71 | challenge_asciihex); | 71 | challenge_asciihex); |
72 | } | 72 | } |
73 | 73 | ||
74 | static int chap_check_algorithm(const char *a_str) | ||
75 | { | ||
76 | char *tmp, *orig, *token; | ||
77 | |||
78 | tmp = kstrdup(a_str, GFP_KERNEL); | ||
79 | if (!tmp) { | ||
80 | pr_err("Memory allocation failed for CHAP_A temporary buffer\n"); | ||
81 | return CHAP_DIGEST_UNKNOWN; | ||
82 | } | ||
83 | orig = tmp; | ||
84 | |||
85 | token = strsep(&tmp, "="); | ||
86 | if (!token) | ||
87 | goto out; | ||
88 | |||
89 | if (strcmp(token, "CHAP_A")) { | ||
90 | pr_err("Unable to locate CHAP_A key\n"); | ||
91 | goto out; | ||
92 | } | ||
93 | while (token) { | ||
94 | token = strsep(&tmp, ","); | ||
95 | if (!token) | ||
96 | goto out; | ||
97 | |||
98 | if (!strncmp(token, "5", 1)) { | ||
99 | pr_debug("Selected MD5 Algorithm\n"); | ||
100 | kfree(orig); | ||
101 | return CHAP_DIGEST_MD5; | ||
102 | } | ||
103 | } | ||
104 | out: | ||
105 | kfree(orig); | ||
106 | return CHAP_DIGEST_UNKNOWN; | ||
107 | } | ||
74 | 108 | ||
75 | static struct iscsi_chap *chap_server_open( | 109 | static struct iscsi_chap *chap_server_open( |
76 | struct iscsi_conn *conn, | 110 | struct iscsi_conn *conn, |
@@ -79,6 +113,7 @@ static struct iscsi_chap *chap_server_open( | |||
79 | char *aic_str, | 113 | char *aic_str, |
80 | unsigned int *aic_len) | 114 | unsigned int *aic_len) |
81 | { | 115 | { |
116 | int ret; | ||
82 | struct iscsi_chap *chap; | 117 | struct iscsi_chap *chap; |
83 | 118 | ||
84 | if (!(auth->naf_flags & NAF_USERID_SET) || | 119 | if (!(auth->naf_flags & NAF_USERID_SET) || |
@@ -93,21 +128,24 @@ static struct iscsi_chap *chap_server_open( | |||
93 | return NULL; | 128 | return NULL; |
94 | 129 | ||
95 | chap = conn->auth_protocol; | 130 | chap = conn->auth_protocol; |
96 | /* | 131 | ret = chap_check_algorithm(a_str); |
97 | * We only support MD5 MDA presently. | 132 | switch (ret) { |
98 | */ | 133 | case CHAP_DIGEST_MD5: |
99 | if (strncmp(a_str, "CHAP_A=5", 8)) { | 134 | pr_debug("[server] Got CHAP_A=5\n"); |
100 | pr_err("CHAP_A is not MD5.\n"); | 135 | /* |
136 | * Send back CHAP_A set to MD5. | ||
137 | */ | ||
138 | *aic_len = sprintf(aic_str, "CHAP_A=5"); | ||
139 | *aic_len += 1; | ||
140 | chap->digest_type = CHAP_DIGEST_MD5; | ||
141 | pr_debug("[server] Sending CHAP_A=%d\n", chap->digest_type); | ||
142 | break; | ||
143 | case CHAP_DIGEST_UNKNOWN: | ||
144 | default: | ||
145 | pr_err("Unsupported CHAP_A value\n"); | ||
101 | return NULL; | 146 | return NULL; |
102 | } | 147 | } |
103 | pr_debug("[server] Got CHAP_A=5\n"); | 148 | |
104 | /* | ||
105 | * Send back CHAP_A set to MD5. | ||
106 | */ | ||
107 | *aic_len = sprintf(aic_str, "CHAP_A=5"); | ||
108 | *aic_len += 1; | ||
109 | chap->digest_type = CHAP_DIGEST_MD5; | ||
110 | pr_debug("[server] Sending CHAP_A=%d\n", chap->digest_type); | ||
111 | /* | 149 | /* |
112 | * Set Identifier. | 150 | * Set Identifier. |
113 | */ | 151 | */ |
diff --git a/drivers/target/iscsi/iscsi_target_auth.h b/drivers/target/iscsi/iscsi_target_auth.h index 2f463c09626d..d22f7b96a06c 100644 --- a/drivers/target/iscsi/iscsi_target_auth.h +++ b/drivers/target/iscsi/iscsi_target_auth.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _ISCSI_CHAP_H_ | 1 | #ifndef _ISCSI_CHAP_H_ |
2 | #define _ISCSI_CHAP_H_ | 2 | #define _ISCSI_CHAP_H_ |
3 | 3 | ||
4 | #define CHAP_DIGEST_UNKNOWN 0 | ||
4 | #define CHAP_DIGEST_MD5 5 | 5 | #define CHAP_DIGEST_MD5 5 |
5 | #define CHAP_DIGEST_SHA 6 | 6 | #define CHAP_DIGEST_SHA 6 |
6 | 7 | ||