2.6.27 kernel compat patch
[open-iscsi.git] / usr / auth.c
blobcc232a0efe070fe7d97bcb3694d10db11fd199a5
1 /*
2 * iSCSI Authorization Library
4 * maintained by open-iscsi@@googlegroups.com
6 * Originally based on:
7 * Copyright (C) 2001 Cisco Systems, Inc.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * This file implements the iSCSI CHAP authentication method based on
20 * RFC 3720. The code in this file is meant to be common for both kernel and
21 * user level and makes use of only limited library functions, presently only
22 * string.h. Routines specific to kernel, user level are implemented in
23 * seperate files under the appropriate directories.
24 * This code in this files assumes a single thread of execution
25 * for each iscsi_acl structure, and does no locking.
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <fcntl.h>
34 #include "sysdeps.h"
35 #include "auth.h"
36 #include "initiator.h"
37 #include "md5.h"
38 #include "log.h"
40 static const char acl_hexstring[] = "0123456789abcdefABCDEF";
41 static const char acl_base64_string[] =
42 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
43 static const char acl_authmethod_set_chap_alg_list[] = "CHAP";
44 static const char acl_reject_option_name[] = "Reject";
46 void auth_md5_init(struct MD5Context *);
47 void auth_md5_update(struct MD5Context *, unsigned char *, unsigned int);
48 void auth_md5_final(unsigned char *, struct MD5Context *);
49 void get_random_bytes(unsigned char *data, unsigned int length);
50 size_t strlcpy(char *, const char *, size_t);
51 size_t strlcat(char *, const char *, size_t);
53 enum auth_dbg_status
54 acl_chap_compute_rsp(struct iscsi_acl *client, int rmt_auth, unsigned int id,
55 unsigned char *challenge_data,
56 unsigned int challenge_length,
57 unsigned char *response_data)
59 unsigned char id_data[1];
60 struct MD5Context context;
61 unsigned char out_data[AUTH_STR_MAX_LEN];
62 unsigned int out_length = AUTH_STR_MAX_LEN;
64 if (!client->passwd_present)
65 return AUTH_DBG_STATUS_LOCAL_PASSWD_NOT_SET;
67 auth_md5_init(&context);
69 /* id byte */
70 id_data[0] = id;
71 auth_md5_update(&context, id_data, 1);
73 /* decrypt password */
74 if (acl_data(out_data, &out_length, client->passwd_data,
75 client->passwd_length))
76 return AUTH_DBG_STATUS_PASSWD_DECRYPT_FAILED;
78 if (!rmt_auth && !client->ip_sec && out_length < 12)
79 return AUTH_DBG_STATUS_PASSWD_TOO_SHORT_WITH_NO_IPSEC;
81 /* shared secret */
82 auth_md5_update(&context, out_data, out_length);
84 /* clear decrypted password */
85 memset(out_data, 0, AUTH_STR_MAX_LEN);
87 /* challenge value */
88 auth_md5_update(&context, challenge_data, challenge_length);
90 auth_md5_final(response_data, &context);
92 return AUTH_DBG_STATUS_NOT_SET; /* no error */
96 * Authenticate a target's CHAP response.
98 int
99 acl_chap_auth_request(struct iscsi_acl *client, char *username, unsigned int id,
100 unsigned char *challenge_data,
101 unsigned int challenge_length,
102 unsigned char *response_data,
103 unsigned int rsp_length)
105 iscsi_session_t *session = client->session_handle;
106 struct MD5Context context;
107 unsigned char verify_data[16];
109 /* the expected credentials are in the session */
110 if (session->username_in == NULL) {
111 log_error("failing authentication, no incoming username "
112 "configured to authenticate target %s\n",
113 session->target_name);
114 return AUTH_STATUS_FAIL;
116 if (strcmp(username, session->username_in) != 0) {
117 log_error("failing authentication, received incorrect "
118 "username from target %s\n", session->target_name);
119 return AUTH_STATUS_FAIL;
122 if ((session->password_in_length < 1) ||
123 (session->password_in == NULL) ||
124 (session->password_in[0] == '\0')) {
125 log_error("failing authentication, no incoming password "
126 "configured to authenticate target %s\n",
127 session->target_name);
128 return AUTH_STATUS_FAIL;
131 /* challenge length is I->T, and shouldn't need to be checked */
133 if (rsp_length != sizeof(verify_data)) {
134 log_error("failing authentication, received incorrect "
135 "CHAP response length %u from target %s\n",
136 rsp_length, session->target_name);
137 return AUTH_STATUS_FAIL;
140 auth_md5_init(&context);
142 /* id byte */
143 verify_data[0] = id;
144 auth_md5_update(&context, verify_data, 1);
146 /* shared secret */
147 auth_md5_update(&context, (unsigned char *)session->password_in,
148 session->password_in_length);
150 /* challenge value */
151 auth_md5_update(&context, (unsigned char *)challenge_data,
152 challenge_length);
154 auth_md5_final(verify_data, &context);
156 if (memcmp(response_data, verify_data, sizeof(verify_data)) == 0) {
157 log_debug(1, "initiator authenticated target %s\n",
158 session->target_name);
159 return AUTH_STATUS_PASS;
162 log_error("failing authentication, received incorrect CHAP "
163 "response from target %s\n", session->target_name);
164 return AUTH_STATUS_FAIL;
167 void
168 auth_md5_init(struct MD5Context *context)
170 MD5Init(context);
173 void
174 auth_md5_update(struct MD5Context *context, unsigned char *data,
175 unsigned int length)
177 MD5Update(context, data, length);
180 void
181 auth_md5_final(unsigned char *hash, struct MD5Context *context)
183 MD5Final(hash, context);
186 void
187 get_random_bytes(unsigned char *data, unsigned int length)
190 long r;
191 unsigned n;
192 int fd;
194 fd = open("/dev/urandom", O_RDONLY);
195 while (length > 0) {
197 if (fd)
198 read(fd, &r, sizeof(long));
199 else
200 r = rand();
201 r = r ^ (r >> 8);
202 r = r ^ (r >> 4);
203 n = r & 0x7;
205 if (fd)
206 read(fd, &r, sizeof(long));
207 else
208 r = rand();
209 r = r ^ (r >> 8);
210 r = r ^ (r >> 5);
211 n = (n << 3) | (r & 0x7);
213 if (fd)
214 read(fd, &r, sizeof(long));
215 else
216 r = rand();
218 r = r ^ (r >> 8);
219 r = r ^ (r >> 5);
220 n = (n << 2) | (r & 0x3);
222 *data++ = n;
223 length--;
225 if (fd)
226 close(fd);
229 static const char acl_none_option_name[] = "None";
231 static int
232 acl_text_to_number(const char *text, unsigned long *num)
234 char *end;
235 unsigned long number = *num;
237 if (text[0] == '0' && (text[1] == 'x' || text[1] == 'X'))
238 number = strtoul(text + 2, &end, 16);
239 else
240 number = strtoul(text, &end, 10);
242 if (*text != '\0' && *end == '\0') {
243 *num = number;
244 return 0; /* No error */
245 } else
246 return 1; /* Error */
249 static int
250 acl_chk_string(const char *s, unsigned int max_len, unsigned int *out_len)
252 unsigned int len;
254 if (!s)
255 return 1;
257 for (len = 0; len < max_len; len++)
258 if (*s++ == '\0') {
259 if (out_len)
260 *out_len = len;
261 return 0;
264 return 1;
267 static int
268 acl_str_index(const char *s, int c)
270 char *str = strchr(s, c);
272 if (str)
273 return (str - s);
274 else
275 return -1;
278 static int
279 acl_chk_auth_mthd_optn(int val)
281 if (val == AUTH_OPTION_NONE || val == AUTH_METHOD_CHAP)
282 return 0;
284 return 1;
287 static const char *
288 acl_authmethod_optn_to_text(int value)
290 const char *s;
291 switch (value) {
292 case AUTH_OPTION_REJECT:
293 s = acl_reject_option_name;
294 break;
295 case AUTH_OPTION_NONE:
296 s = acl_none_option_name;
297 break;
298 case AUTH_METHOD_CHAP:
299 s = acl_authmethod_set_chap_alg_list;
300 break;
301 default:
302 s = NULL;
304 return s;
307 static int
308 acl_chk_chap_alg_optn(int chap_algorithm)
310 if (chap_algorithm == AUTH_OPTION_NONE ||
311 chap_algorithm == AUTH_CHAP_ALG_MD5)
312 return 0;
314 return 1;
317 static int
318 acl_data_to_text(unsigned char *data, unsigned int data_length, char *text,
319 unsigned int text_length)
321 unsigned long n;
323 if (!text || text_length == 0)
324 return 1;
326 if (!data || data_length == 0) {
327 *text = '\0';
328 return 1;
331 if (text_length < 3) {
332 *text = '\0';
333 return 1;
336 *text++ = '0';
337 *text++ = 'x';
339 text_length -= 2;
341 while (data_length > 0) {
343 if (text_length < 3) {
344 *text = '\0';
345 return 1;
348 n = *data++;
349 data_length--;
351 *text++ = acl_hexstring[(n >> 4) & 0xf];
352 *text++ = acl_hexstring[n & 0xf];
354 text_length -= 2;
357 *text = '\0';
359 return 0;
362 static int
363 acl_hex_to_data(const char *text, unsigned int text_length, unsigned char *data,
364 unsigned int *data_lenp)
366 int i;
367 unsigned int n1;
368 unsigned int n2;
369 unsigned int data_length = *data_lenp;
371 if ((text_length % 2) == 1) {
373 i = acl_str_index(acl_hexstring, *text++);
374 if (i < 0)
375 return 1; /* error, bad character */
377 if (i > 15)
378 i -= 6;
379 n2 = i;
381 if (data_length < 1)
382 return 1; /* error, too much data */
384 *data++ = n2;
385 data_length--;
388 while (*text != '\0') {
389 i = acl_str_index(acl_hexstring, *text++);
390 if (i < 0)
391 return 1; /* error, bad character */
393 if (i > 15)
394 i -= 6;
395 n1 = i;
397 if (*text == '\0')
398 return 1; /* error, odd string length */
400 i = acl_str_index(acl_hexstring, *text++);
401 if (i < 0)
402 return 1; /* error, bad character */
404 if (i > 15)
405 i -= 6;
406 n2 = i;
408 if (data_length < 1)
409 return 1; /* error, too much data */
411 *data++ = (n1 << 4) | n2;
412 data_length--;
415 if (data_length >= *data_lenp)
416 return 1; /* error, no data */
418 *data_lenp = *data_lenp - data_length;
420 return 0; /* no error */
423 static int
424 acl_base64_to_data(const char *text, unsigned char *data,
425 unsigned int *data_lenp)
427 int i;
428 unsigned int n;
429 unsigned int count;
430 unsigned int data_length = *data_lenp;
432 n = 0;
433 count = 0;
435 while (*text != '\0' && *text != '=') {
437 i = acl_str_index(acl_base64_string, *text++);
438 if (i < 0)
439 return 1; /* error, bad character */
441 n = (n << 6 | (unsigned int)i);
442 count++;
444 if (count >= 4) {
445 if (data_length < 3)
446 return 1; /* error, too much data */
447 *data++ = n >> 16;
448 *data++ = n >> 8;
449 *data++ = n;
450 data_length -= 3;
451 n = 0;
452 count = 0;
456 while (*text != '\0')
457 if (*text++ != '=')
458 return 1; /* error, bad pad */
460 if (count == 0) {
461 /* do nothing */
462 } else if (count == 2) {
463 if (data_length < 1)
464 return 1; /* error, too much data */
465 n = n >> 4;
466 *data++ = n;
467 data_length--;
468 } else if (count == 3) {
469 if (data_length < 2)
470 return 1; /* error, too much data */
471 n = n >> 2;
472 *data++ = n >> 8;
473 *data++ = n;
474 data_length -= 2;
475 } else
476 return 1; /* bad encoding */
478 if (data_length >= *data_lenp)
479 return 1; /* error, no data */
481 *data_lenp = *data_lenp - data_length;
483 return 0; /* no error */
486 static int
487 acl_text_to_data(const char *text, unsigned char *data,
488 unsigned int *data_length)
490 int status;
491 unsigned int text_length;
493 status = acl_chk_string(text, 2 + 2 * AUTH_LARGE_BINARY_MAX_LEN + 1,
494 &text_length);
495 if (status)
496 return status;
498 if (text[0] == '0' && (text[1] == 'x' || text[1] == 'X')) {
499 /* skip prefix */
500 text += 2;
501 text_length -= 2;
502 status = acl_hex_to_data(text, text_length, data, data_length);
503 } else if (text[0] == '0' && (text[1] == 'b' || text[1] == 'B')) {
504 /* skip prefix */
505 text += 2;
506 text_length -= 2;
507 status = acl_base64_to_data(text, data, data_length);
508 } else
509 status = 1; /* prefix not recognized. */
511 return status;
514 static void
515 acl_init_key_blk(struct auth_key_block *key_blk)
517 char *str_block = key_blk->str_block;
519 memset(key_blk, 0, sizeof(*key_blk));
520 key_blk->str_block = str_block;
523 static void
524 acl_set_key_value(struct auth_key_block *key_blk, int key_type,
525 const char *key_val)
527 unsigned int length;
528 char *string;
530 if (key_blk->key[key_type].value_set) {
531 key_blk->dup_set = 1;
532 return;
535 key_blk->key[key_type].value_set = 1;
537 if (!key_val)
538 return;
540 if (acl_chk_string(key_val, AUTH_STR_MAX_LEN, &length)) {
541 key_blk->str_too_long = 1;
542 return;
545 length += 1;
547 if ((key_blk->blk_length + length) > AUTH_STR_BLOCK_MAX_LEN) {
548 key_blk->too_much_data = 1;
549 return;
552 string = &key_blk->str_block[key_blk->blk_length];
554 if (strlcpy(string, key_val, length) >= length) {
555 key_blk->too_much_data = 1;
556 return;
558 key_blk->blk_length += length;
560 key_blk->key[key_type].string = string;
561 key_blk->key[key_type].present = 1;
564 static const char *
565 acl_get_key_val(struct auth_key_block *key_blk, int key_type)
567 key_blk->key[key_type].processed = 1;
569 if (!key_blk->key[key_type].present)
570 return NULL;
572 return key_blk->key[key_type].string;
575 static void
576 acl_chk_key(struct iscsi_acl *client, int key_type, int *negotiated_option,
577 unsigned int option_count, int *option_list,
578 const char *(*value_to_text) (int))
580 const char *key_val;
581 int length;
582 unsigned int i;
584 key_val = acl_get_key_val(&client->recv_key_block, key_type);
585 if (!key_val) {
586 *negotiated_option = AUTH_OPTION_NOT_PRESENT;
587 return;
590 while (*key_val != '\0') {
592 length = 0;
594 while (*key_val != '\0' && *key_val != ',')
595 client->scratch_key_value[length++] = *key_val++;
597 if (*key_val == ',')
598 key_val++;
599 client->scratch_key_value[length++] = '\0';
601 for (i = 0; i < option_count; i++) {
602 const char *s = (*value_to_text)(option_list[i]);
604 if (!s)
605 continue;
607 if (strcmp(client->scratch_key_value, s) == 0) {
608 *negotiated_option = option_list[i];
609 return;
614 *negotiated_option = AUTH_OPTION_REJECT;
617 static void
618 acl_set_key(struct iscsi_acl *client, int key_type, unsigned int option_count,
619 int *option_list, const char *(*value_to_text)(int))
621 unsigned int i;
623 if (option_count == 0) {
625 * No valid options to send, but we always want to
626 * send something.
628 acl_set_key_value(&client->send_key_block, key_type,
629 acl_none_option_name);
630 return;
633 if (option_count == 1 && option_list[0] == AUTH_OPTION_NOT_PRESENT) {
634 acl_set_key_value(&client->send_key_block, key_type, NULL);
635 return;
638 for (i = 0; i < option_count; i++) {
639 const char *s = (*value_to_text)(option_list[i]);
641 if (!s)
642 continue;
644 if (i == 0)
645 strlcpy(client->scratch_key_value, s,
646 AUTH_STR_MAX_LEN);
647 else {
648 strlcat(client->scratch_key_value, ",",
649 AUTH_STR_MAX_LEN);
650 strlcat(client->scratch_key_value, s,
651 AUTH_STR_MAX_LEN);
655 acl_set_key_value(&client->send_key_block, key_type,
656 client->scratch_key_value);
659 static void
660 acl_chk_auth_method_key(struct iscsi_acl *client)
662 acl_chk_key(client, AUTH_KEY_TYPE_AUTH_METHOD,
663 &client->negotiated_auth_method,
664 client->auth_method_valid_count,
665 client->auth_method_valid_list,
666 acl_authmethod_optn_to_text);
669 static void
670 acl_set_auth_method_key(struct iscsi_acl *client,
671 unsigned int auth_method_count, int *auth_method_list)
673 acl_set_key(client, AUTH_KEY_TYPE_AUTH_METHOD, auth_method_count,
674 auth_method_list, acl_authmethod_optn_to_text);
677 static void
678 acl_chk_chap_alg_key(struct iscsi_acl *client)
680 const char *key_val;
681 int length;
682 unsigned long number;
683 unsigned int i;
685 key_val = acl_get_key_val(&client->recv_key_block,
686 AUTH_KEY_TYPE_CHAP_ALG);
687 if (!key_val) {
688 client->negotiated_chap_alg = AUTH_OPTION_NOT_PRESENT;
689 return;
692 while (*key_val != '\0') {
694 length = 0;
696 while (*key_val != '\0' && *key_val != ',')
697 client->scratch_key_value[length++] = *key_val++;
699 if (*key_val == ',')
700 key_val++;
701 client->scratch_key_value[length++] = '\0';
703 if (acl_text_to_number(client->scratch_key_value, &number))
704 continue;
707 for (i = 0; i < client->chap_alg_count; i++)
708 if (number == (unsigned long)client->chap_alg_list[i])
710 client->negotiated_chap_alg = number;
711 return;
715 client->negotiated_chap_alg = AUTH_OPTION_REJECT;
718 static void
719 acl_set_chap_alg_key(struct iscsi_acl *client, unsigned int chap_alg_count,
720 int *chap_alg_list)
722 unsigned int i;
724 if (chap_alg_count == 0) {
725 acl_set_key_value(&client->send_key_block,
726 AUTH_KEY_TYPE_CHAP_ALG, NULL);
727 return;
730 if (chap_alg_count == 1 &&
731 chap_alg_list[0] == AUTH_OPTION_NOT_PRESENT) {
732 acl_set_key_value(&client->send_key_block,
733 AUTH_KEY_TYPE_CHAP_ALG, NULL);
734 return;
737 if (chap_alg_count == 1 && chap_alg_list[0] == AUTH_OPTION_REJECT) {
738 acl_set_key_value(&client->send_key_block,
739 AUTH_KEY_TYPE_CHAP_ALG,
740 acl_reject_option_name);
741 return;
744 for (i = 0; i < chap_alg_count; i++) {
745 char s[20];
747 snprintf(s, sizeof(s), "%lu",(unsigned long)chap_alg_list[i]);
749 if (i == 0)
750 strlcpy(client->scratch_key_value, s,
751 AUTH_STR_MAX_LEN);
752 else {
753 strlcat(client->scratch_key_value, ",",
754 AUTH_STR_MAX_LEN);
755 strlcat(client->scratch_key_value, s,
756 AUTH_STR_MAX_LEN);
760 acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_ALG,
761 client->scratch_key_value);
764 static void
765 acl_next_phase(struct iscsi_acl *client)
767 switch (client->phase) {
768 case AUTH_PHASE_CONFIGURE:
769 client->phase = AUTH_PHASE_NEGOTIATE;
770 break;
771 case AUTH_PHASE_NEGOTIATE:
772 client->phase = AUTH_PHASE_AUTHENTICATE;
774 if (client->negotiated_auth_method == AUTH_OPTION_REJECT ||
775 client->negotiated_auth_method == AUTH_OPTION_NOT_PRESENT ||
776 client->negotiated_auth_method == AUTH_OPTION_NONE) {
778 client->local_state = AUTH_LOCAL_STATE_DONE;
779 client->rmt_state = AUTH_RMT_STATE_DONE;
781 if (client->auth_rmt) {
782 client->rmt_auth_status = AUTH_STATUS_FAIL;
783 client->phase = AUTH_PHASE_DONE;
784 } else
785 client->rmt_auth_status = AUTH_STATUS_PASS;
787 switch (client->negotiated_auth_method) {
788 case AUTH_OPTION_REJECT:
789 client->dbg_status =
790 AUTH_DBG_STATUS_AUTH_METHOD_REJECT;
791 break;
792 case AUTH_OPTION_NOT_PRESENT:
793 client->dbg_status =
794 AUTH_DBG_STATUS_AUTH_METHOD_NOT_PRESENT;
795 break;
796 case AUTH_OPTION_NONE:
797 client->dbg_status =
798 AUTH_DBG_STATUS_AUTH_METHOD_NONE;
801 } else if (client->negotiated_auth_method == AUTH_METHOD_CHAP) {
802 client->local_state = AUTH_LOCAL_STATE_SEND_ALG;
803 client->rmt_state = AUTH_RMT_STATE_SEND_ALG;
804 } else {
806 client->local_state = AUTH_LOCAL_STATE_DONE;
807 client->rmt_state = AUTH_RMT_STATE_DONE;
808 client->rmt_auth_status = AUTH_STATUS_FAIL;
809 client->dbg_status = AUTH_DBG_STATUS_AUTH_METHOD_BAD;
811 break;
812 case AUTH_PHASE_AUTHENTICATE:
813 client->phase = AUTH_PHASE_DONE;
814 break;
815 case AUTH_PHASE_DONE:
816 case AUTH_PHASE_ERROR:
817 default:
818 client->phase = AUTH_PHASE_ERROR;
822 static void
823 acl_local_auth(struct iscsi_acl *client)
825 unsigned int chap_identifier;
826 unsigned char response_data[AUTH_CHAP_RSP_LEN];
827 unsigned long number;
828 int status;
829 enum auth_dbg_status dbg_status;
830 const char *chap_identifier_key_val;
831 const char *chap_challenge_key_val;
833 switch (client->local_state) {
834 case AUTH_LOCAL_STATE_SEND_ALG:
835 if (client->node_type == TYPE_INITIATOR) {
836 acl_set_chap_alg_key(client, client->chap_alg_count,
837 client->chap_alg_list);
838 client->local_state = AUTH_LOCAL_STATE_RECV_ALG;
839 break;
841 /* Fall through */
842 case AUTH_LOCAL_STATE_RECV_ALG:
843 acl_chk_chap_alg_key(client);
845 if (client->node_type == TYPE_TARGET)
846 acl_set_chap_alg_key(client, 1,
847 &client->negotiated_chap_alg);
849 /* Make sure only supported CHAP algorithm is used. */
850 if (client->negotiated_chap_alg == AUTH_OPTION_NOT_PRESENT) {
851 client->local_state = AUTH_LOCAL_STATE_ERROR;
852 client->dbg_status = AUTH_DBG_STATUS_CHAP_ALG_EXPECTED;
853 break;
854 } else if (client->negotiated_chap_alg == AUTH_OPTION_REJECT) {
855 client->local_state = AUTH_LOCAL_STATE_ERROR;
856 client->dbg_status = AUTH_DBG_STATUS_CHAP_ALG_REJECT;
857 break;
858 } else if (client->negotiated_chap_alg != AUTH_CHAP_ALG_MD5) {
859 client->local_state = AUTH_LOCAL_STATE_ERROR;
860 client->dbg_status = AUTH_DBG_STATUS_CHAP_ALG_BAD;
861 break;
863 if (client->node_type == TYPE_TARGET) {
864 client->local_state = AUTH_LOCAL_STATE_RECV_CHALLENGE;
865 break;
867 /* Fall through */
868 case AUTH_LOCAL_STATE_RECV_CHALLENGE:
869 chap_identifier_key_val = acl_get_key_val(&client->recv_key_block,
870 AUTH_KEY_TYPE_CHAP_IDENTIFIER);
871 chap_challenge_key_val = acl_get_key_val(&client->recv_key_block,
872 AUTH_KEY_TYPE_CHAP_CHALLENGE);
873 if (client->node_type == TYPE_TARGET) {
874 if (!chap_identifier_key_val &&
875 !chap_challenge_key_val) {
876 client->local_state = AUTH_LOCAL_STATE_DONE;
877 break;
881 if (!chap_identifier_key_val) {
882 client->local_state = AUTH_LOCAL_STATE_ERROR;
883 client->dbg_status =
884 AUTH_DBG_STATUS_CHAP_IDENTIFIER_EXPECTED;
885 break;
888 if (!chap_challenge_key_val) {
889 client->local_state = AUTH_LOCAL_STATE_ERROR;
890 client->dbg_status =
891 AUTH_DBG_STATUS_CHAP_CHALLENGE_EXPECTED;
892 break;
895 status = acl_text_to_number(chap_identifier_key_val, &number);
896 if (status || (255 < number)) {
897 client->local_state = AUTH_LOCAL_STATE_ERROR;
898 client->dbg_status = AUTH_DBG_STATUS_CHAP_IDENTIFIER_BAD;
899 break;
901 chap_identifier = number;
903 if (client->recv_chap_challenge_status) {
904 client->local_state = AUTH_LOCAL_STATE_ERROR;
905 client->dbg_status = AUTH_DBG_STATUS_CHALLENGE_BAD;
906 break;
909 if (client->node_type == TYPE_TARGET &&
910 client->recv_chap_challenge.length ==
911 client->send_chap_challenge.length &&
912 memcmp(client->recv_chap_challenge.large_binary,
913 client->send_chap_challenge.large_binary,
914 client->send_chap_challenge.length) == 0) {
915 client->local_state = AUTH_LOCAL_STATE_ERROR;
916 client->dbg_status =
917 AUTH_DBG_STATUS_CHAP_CHALLENGE_REFLECTED;
918 break;
921 dbg_status = acl_chap_compute_rsp(client, 0,
922 chap_identifier,
923 client->recv_chap_challenge.large_binary,
924 client->recv_chap_challenge.length,
925 response_data);
927 if (dbg_status != AUTH_DBG_STATUS_NOT_SET) {
928 client->local_state = AUTH_LOCAL_STATE_ERROR;
929 client->dbg_status = dbg_status;
930 break;
933 acl_data_to_text(response_data,
934 AUTH_CHAP_RSP_LEN, client->scratch_key_value,
935 AUTH_STR_MAX_LEN);
936 acl_set_key_value(&client->send_key_block,
937 AUTH_KEY_TYPE_CHAP_RSP,
938 client->scratch_key_value);
939 acl_set_key_value(&client->send_key_block,
940 AUTH_KEY_TYPE_CHAP_USERNAME,
941 client->username);
943 client->local_state = AUTH_LOCAL_STATE_DONE;
944 break;
945 case AUTH_LOCAL_STATE_DONE:
946 break;
947 case AUTH_LOCAL_STATE_ERROR:
948 default:
949 client->phase = AUTH_PHASE_ERROR;
953 static void
954 acl_rmt_auth(struct iscsi_acl *client)
956 unsigned char id_data[1];
957 unsigned char response_data[AUTH_STR_MAX_LEN];
958 unsigned int rsp_len = AUTH_STR_MAX_LEN;
959 unsigned char my_rsp_data[AUTH_CHAP_RSP_LEN];
960 int status;
961 enum auth_dbg_status dbg_status;
962 const char *chap_rsp_key_val;
963 const char *chap_username_key_val;
965 switch (client->rmt_state) {
966 case AUTH_RMT_STATE_SEND_ALG:
967 if (client->node_type == TYPE_INITIATOR) {
968 client->rmt_state = AUTH_RMT_STATE_SEND_CHALLENGE;
969 break;
971 /* Fall through */
972 case AUTH_RMT_STATE_SEND_CHALLENGE:
973 if (!client->auth_rmt) {
974 client->rmt_auth_status = AUTH_STATUS_PASS;
975 client->dbg_status = AUTH_DBG_STATUS_AUTH_RMT_FALSE;
976 client->rmt_state = AUTH_RMT_STATE_DONE;
977 break;
979 get_random_bytes(id_data, 1);
980 client->send_chap_identifier = id_data[0];
981 snprintf(client->scratch_key_value, AUTH_STR_MAX_LEN, "%lu",
982 (unsigned long)client->send_chap_identifier);
983 acl_set_key_value(&client->send_key_block,
984 AUTH_KEY_TYPE_CHAP_IDENTIFIER,
985 client->scratch_key_value);
987 client->send_chap_challenge.length = client->chap_challenge_len;
988 get_random_bytes(client->send_chap_challenge.large_binary,
989 client->send_chap_challenge.length);
990 acl_set_key_value(&client->send_key_block,
991 AUTH_KEY_TYPE_CHAP_CHALLENGE, "");
993 client->rmt_state = AUTH_RMT_STATE_RECV_RSP;
994 break;
995 case AUTH_RMT_STATE_RECV_RSP:
996 chap_rsp_key_val = acl_get_key_val(&client->recv_key_block,
997 AUTH_KEY_TYPE_CHAP_RSP);
998 chap_username_key_val = acl_get_key_val(&client->recv_key_block,
999 AUTH_KEY_TYPE_CHAP_USERNAME);
1001 if (!chap_rsp_key_val) {
1002 client->rmt_state = AUTH_RMT_STATE_ERROR;
1003 client->dbg_status = AUTH_DBG_STATUS_CHAP_RSP_EXPECTED;
1004 break;
1007 if (!chap_username_key_val) {
1008 client->rmt_state = AUTH_RMT_STATE_ERROR;
1009 client->dbg_status = AUTH_DBG_STATUS_CHAP_USERNAME_EXPECTED;
1010 break;
1013 status = acl_text_to_data(chap_rsp_key_val, response_data,
1014 &rsp_len);
1016 if (status) {
1017 client->rmt_state = AUTH_RMT_STATE_ERROR;
1018 client->dbg_status = AUTH_DBG_STATUS_CHAP_RSP_BAD;
1019 break;
1022 if (rsp_len == AUTH_CHAP_RSP_LEN) {
1023 dbg_status = acl_chap_compute_rsp(client, 1,
1024 client->send_chap_identifier,
1025 client->send_chap_challenge.large_binary,
1026 client->send_chap_challenge.length,
1027 my_rsp_data);
1029 if (dbg_status == AUTH_DBG_STATUS_NOT_SET &&
1030 memcmp(my_rsp_data, response_data,
1031 AUTH_CHAP_RSP_LEN) == 0) {
1032 client->rmt_state = AUTH_RMT_STATE_ERROR;
1033 client->dbg_status = AUTH_DBG_STATUS_PASSWD_IDENTICAL;
1034 break;
1038 strlcpy(client->chap_username, chap_username_key_val,
1039 AUTH_STR_MAX_LEN);
1041 status = acl_chap_auth_request(client, client->chap_username,
1042 client->send_chap_identifier,
1043 client->send_chap_challenge.
1044 large_binary,
1045 client->send_chap_challenge.
1046 length, response_data,
1047 rsp_len);
1049 client->rmt_auth_status = (enum auth_status) status;
1050 client->auth_rsp_flag = 1;
1052 if (client->auth_server_error_flag) {
1053 client->rmt_auth_status = AUTH_STATUS_FAIL;
1054 client->dbg_status = AUTH_DBG_STATUS_AUTH_SERVER_ERROR;
1055 } else if (client->rmt_auth_status == AUTH_STATUS_PASS)
1056 client->dbg_status = AUTH_DBG_STATUS_AUTH_PASS;
1057 else if (client->rmt_auth_status == AUTH_STATUS_FAIL)
1058 client->dbg_status = AUTH_DBG_STATUS_AUTH_FAIL;
1059 else {
1060 client->rmt_auth_status = AUTH_STATUS_FAIL;
1061 client->dbg_status = AUTH_DBG_STATUS_AUTH_STATUS_BAD;
1063 client->rmt_state = AUTH_RMT_STATE_DONE;
1065 /* Fall through */
1066 case AUTH_RMT_STATE_DONE:
1067 break;
1068 case AUTH_RMT_STATE_ERROR:
1069 default:
1070 client->phase = AUTH_PHASE_ERROR;
1074 static void
1075 acl_hand_shake(struct iscsi_acl *client)
1077 if (client->phase == AUTH_PHASE_DONE)
1080 * Should only happen if authentication
1081 * protocol error occured.
1083 return;
1085 if (client->node_type == TYPE_INITIATOR)
1088 * Target should only have set T bit on response if
1089 * initiator set it on previous message.
1091 if (client->recv_key_block.transit_bit &&
1092 !client->transit_bit_sent_flag) {
1093 client->rmt_auth_status = AUTH_STATUS_FAIL;
1094 client->phase = AUTH_PHASE_DONE;
1095 client->dbg_status =
1096 AUTH_DBG_STATUS_T_BIT_SET_ILLEGAL;
1097 return;
1100 if (client->phase == AUTH_PHASE_NEGOTIATE) {
1102 * Should only happen if waiting for peer
1103 * to send AuthMethod key or set Transit Bit.
1105 if (client->node_type == TYPE_INITIATOR)
1106 client->send_key_block.transit_bit = 1;
1107 return;
1110 if (client->rmt_state == AUTH_RMT_STATE_RECV_RSP ||
1111 client->rmt_state == AUTH_RMT_STATE_DONE) {
1112 if (client->node_type == TYPE_INITIATOR) {
1113 if (client->recv_key_block.transit_bit) {
1114 if (client->rmt_state !=
1115 AUTH_RMT_STATE_DONE)
1116 goto recv_transit_bit_err;
1117 acl_next_phase(client);
1118 } else
1119 client->send_key_block.transit_bit = 1;
1120 } else {
1121 if (client->rmt_state == AUTH_RMT_STATE_DONE &&
1122 client->rmt_auth_status != AUTH_STATUS_PASS)
1124 * Authentication failed, don't do T bit
1125 * handshake.
1127 acl_next_phase(client);
1128 else {
1130 * Target can only set T bit on response if
1131 * initiator set it on current message.
1133 if (client->recv_key_block.transit_bit) {
1134 client->send_key_block.transit_bit = 1;
1135 acl_next_phase(client);
1139 } else
1140 if (client->node_type == TYPE_INITIATOR)
1141 if (client->recv_key_block.transit_bit)
1142 goto recv_transit_bit_err;
1143 return;
1145 recv_transit_bit_err:
1147 * Target set T bit on response but
1148 * initiator was not done with authentication.
1150 client->rmt_auth_status = AUTH_STATUS_FAIL;
1151 client->phase = AUTH_PHASE_DONE;
1152 client->dbg_status = AUTH_DBG_STATUS_T_BIT_SET_PREMATURE;
1155 static int
1156 acl_rcv_end_status(struct iscsi_acl *client)
1158 int auth_status;
1159 int key_type;
1161 if (client->phase == AUTH_PHASE_ERROR)
1162 return AUTH_STATUS_ERROR;
1164 if (client->phase == AUTH_PHASE_DONE) {
1166 /* Perform sanity check against configured parameters. */
1167 if (client->auth_rmt && !client->auth_rsp_flag &&
1168 client->rmt_auth_status == AUTH_STATUS_PASS) {
1169 client->rmt_auth_status = AUTH_STATUS_FAIL;
1170 client->dbg_status = AUTH_DBG_STATUS_AUTHPASS_NOT_VALID;
1173 auth_status = client->rmt_auth_status;
1175 } else
1176 auth_status = AUTH_STATUS_CONTINUE;
1178 if (auth_status == AUTH_STATUS_CONTINUE ||
1179 auth_status == AUTH_STATUS_PASS) {
1180 if (client->send_key_block.dup_set) {
1181 client->rmt_auth_status = AUTH_STATUS_FAIL;
1182 client->phase = AUTH_PHASE_DONE;
1183 client->dbg_status =
1184 AUTH_DBG_STATUS_SEND_DUP_SET_KEY_VALUE;
1185 auth_status = AUTH_STATUS_FAIL;
1186 } else if (client->send_key_block.str_too_long) {
1187 client->rmt_auth_status = AUTH_STATUS_FAIL;
1188 client->phase = AUTH_PHASE_DONE;
1189 client->dbg_status =
1190 AUTH_DBG_STATUS_SEND_STR_TOO_LONG;
1191 auth_status = AUTH_STATUS_FAIL;
1192 } else if (client->send_key_block.too_much_data) {
1193 client->rmt_auth_status = AUTH_STATUS_FAIL;
1194 client->phase = AUTH_PHASE_DONE;
1195 client->dbg_status =
1196 AUTH_DBG_STATUS_SEND_TOO_MUCH_DATA;
1197 auth_status = AUTH_STATUS_FAIL;
1198 } else {
1199 /* Check that all incoming keys have been processed. */
1201 for (key_type = AUTH_KEY_TYPE_FIRST;
1202 key_type < AUTH_KEY_TYPE_MAX_COUNT; key_type++)
1203 if (client->recv_key_block.key[key_type].present &&
1204 !client->recv_key_block.key[key_type].
1205 processed)
1206 break;
1208 if (key_type < AUTH_KEY_TYPE_MAX_COUNT) {
1209 client->rmt_auth_status = AUTH_STATUS_FAIL;
1210 client->phase = AUTH_PHASE_DONE;
1211 client->dbg_status =
1212 AUTH_DBG_STATUS_UNEXPECTED_KEY_PRESENT;
1213 auth_status = AUTH_STATUS_FAIL;
1218 if (auth_status != AUTH_STATUS_PASS &&
1219 auth_status != AUTH_STATUS_CONTINUE) {
1220 int auth_method_key_present = 0;
1221 int chap_alg_key_present = 0;
1224 * Suppress send keys on error,
1225 * except for AuthMethod and CHAP_A.
1227 if (client->node_type == TYPE_TARGET) {
1228 if (acl_get_key_val(&client->send_key_block,
1229 AUTH_KEY_TYPE_AUTH_METHOD))
1230 auth_method_key_present = 1;
1231 else if (acl_get_key_val(&client->send_key_block,
1232 AUTH_KEY_TYPE_CHAP_ALG))
1233 chap_alg_key_present = 1;
1236 acl_init_key_blk(&client->send_key_block);
1238 if (client->node_type == TYPE_TARGET) {
1239 if (auth_method_key_present &&
1240 client->negotiated_auth_method ==
1241 AUTH_OPTION_REJECT)
1242 acl_set_key_value(&client->send_key_block,
1243 AUTH_KEY_TYPE_AUTH_METHOD,
1244 acl_reject_option_name);
1245 else if (chap_alg_key_present &&
1246 client->negotiated_chap_alg ==
1247 AUTH_OPTION_REJECT)
1248 acl_set_key_value(&client->send_key_block,
1249 AUTH_KEY_TYPE_CHAP_ALG,
1250 acl_reject_option_name);
1253 client->recv_in_progress_flag = 0;
1255 return auth_status;
1259 acl_recv_begin(struct iscsi_acl *client)
1261 if (!client || client->signature != ACL_SIGNATURE)
1262 return AUTH_STATUS_ERROR;
1264 if (client->phase == AUTH_PHASE_ERROR)
1265 return AUTH_STATUS_ERROR;
1267 if (client->phase == AUTH_PHASE_DONE) {
1268 client->phase = AUTH_PHASE_ERROR;
1269 return AUTH_STATUS_ERROR;
1272 if (client->recv_in_progress_flag) {
1273 client->phase = AUTH_PHASE_ERROR;
1274 return AUTH_STATUS_ERROR;
1277 client->recv_in_progress_flag = 1;
1279 if (client->phase == AUTH_PHASE_CONFIGURE)
1280 acl_next_phase(client);
1282 client->transit_bit_sent_flag = client->send_key_block.transit_bit;
1284 acl_init_key_blk(&client->recv_key_block);
1285 acl_init_key_blk(&client->send_key_block);
1287 return AUTH_STATUS_NO_ERROR;
1291 acl_recv_end(struct iscsi_acl *client, iscsi_session_t *session_handle)
1293 int next_phase_flag = 0;
1295 if (!client || client->signature != ACL_SIGNATURE)
1296 return AUTH_STATUS_ERROR;
1298 if (client->phase == AUTH_PHASE_ERROR)
1299 return AUTH_STATUS_ERROR;
1301 if (!client->recv_in_progress_flag) {
1302 client->phase = AUTH_PHASE_ERROR;
1303 return AUTH_STATUS_ERROR;
1306 if (client->recv_end_count > AUTH_RECV_END_MAX_COUNT) {
1307 client->rmt_auth_status = AUTH_STATUS_FAIL;
1308 client->phase = AUTH_PHASE_DONE;
1309 client->dbg_status = AUTH_DBG_STATUS_RECV_MSG_COUNT_LIMIT;
1310 } else if (client->recv_key_block.dup_set) {
1311 client->rmt_auth_status = AUTH_STATUS_FAIL;
1312 client->phase = AUTH_PHASE_DONE;
1313 client->dbg_status = AUTH_DBG_STATUS_RECV_DUP_SET_KEY_VALUE;
1314 } else if (client->recv_key_block.str_too_long) {
1315 client->rmt_auth_status = AUTH_STATUS_FAIL;
1316 client->phase = AUTH_PHASE_DONE;
1317 client->dbg_status = AUTH_DBG_STATUS_RECV_STR_TOO_LONG;
1318 } else if (client->recv_key_block.too_much_data) {
1319 client->rmt_auth_status = AUTH_STATUS_FAIL;
1320 client->phase = AUTH_PHASE_DONE;
1321 client->dbg_status = AUTH_DBG_STATUS_RECV_TOO_MUCH_DATA;
1324 client->recv_end_count++;
1325 client->session_handle = session_handle;
1327 switch (client->phase) {
1328 case AUTH_PHASE_NEGOTIATE:
1329 acl_chk_auth_method_key(client);
1330 if (client->auth_method_valid_neg_role ==
1331 AUTH_NEG_ROLE_RESPONDER) {
1332 if (client->negotiated_auth_method ==
1333 AUTH_OPTION_NOT_PRESENT) {
1334 if (client->auth_rmt ||
1335 !client->recv_key_block.transit_bit) {
1337 * No AuthMethod key from peer on
1338 * first message, try moving the
1339 * process along by sending the
1340 * AuthMethod key.
1343 client->auth_method_valid_neg_role =
1344 AUTH_NEG_ROLE_ORIGINATOR;
1345 acl_set_auth_method_key(client,
1346 client->auth_method_valid_count,
1347 client->auth_method_valid_list);
1348 break;
1352 * Special case if peer sent no AuthMethod key,
1353 * but did set Transit Bit, allowing this side
1354 * to do a null authentication, and compelete
1355 * the iSCSI security phase without either side
1356 * sending the AuthMethod key.
1358 } else
1359 /* Send response to AuthMethod key. */
1360 acl_set_auth_method_key(client, 1,
1361 &client->negotiated_auth_method);
1363 if (client->node_type == TYPE_INITIATOR)
1364 acl_next_phase(client);
1365 else
1366 next_phase_flag = 1;
1367 } else {
1369 if (client->negotiated_auth_method ==
1370 AUTH_OPTION_NOT_PRESENT) {
1371 client->rmt_auth_status = AUTH_STATUS_FAIL;
1372 client->phase = AUTH_PHASE_DONE;
1373 client->dbg_status =
1374 AUTH_DBG_STATUS_AUTH_METHOD_EXPECTED;
1375 break;
1378 acl_next_phase(client);
1380 break;
1381 case AUTH_PHASE_AUTHENTICATE:
1382 case AUTH_PHASE_DONE:
1383 break;
1384 default:
1385 client->phase = AUTH_PHASE_ERROR;
1386 return AUTH_STATUS_ERROR;
1389 switch (client->phase) {
1390 case AUTH_PHASE_NEGOTIATE:
1391 if (next_phase_flag)
1392 acl_next_phase(client);
1393 break;
1394 case AUTH_PHASE_AUTHENTICATE:
1396 * Must call acl_local_auth()
1397 * before acl_rmt_auth()
1398 * to insure processing of the CHAP algorithm key,
1399 * and to avoid leaving an in progress request to the
1400 * authentication service.
1402 acl_local_auth(client);
1404 if (client->local_state != AUTH_LOCAL_STATE_ERROR)
1405 acl_rmt_auth(client);
1407 if (client->local_state == AUTH_LOCAL_STATE_ERROR ||
1408 client->rmt_state == AUTH_RMT_STATE_ERROR) {
1410 client->rmt_auth_status = AUTH_STATUS_FAIL;
1411 client->phase = AUTH_PHASE_DONE;
1412 /* client->dbg_status should already be set. */
1414 break;
1415 case AUTH_PHASE_DONE:
1416 break;
1417 default:
1418 client->phase = AUTH_PHASE_ERROR;
1419 return AUTH_STATUS_ERROR;
1422 acl_hand_shake(client);
1424 return acl_rcv_end_status(client);
1427 const char *
1428 acl_get_key_name(int key_type)
1431 * Note: The ordering of this table must match the order
1432 * defined by enum auth_key_type in iscsi-auth-client.h.
1434 static char *const key_names[AUTH_KEY_TYPE_MAX_COUNT] = {
1435 "AuthMethod",
1436 "CHAP_A",
1437 "CHAP_N",
1438 "CHAP_R",
1439 "CHAP_I",
1440 "CHAP_C"
1443 if (key_type < AUTH_KEY_TYPE_FIRST || key_type > AUTH_KEY_TYPE_LAST)
1444 return NULL;
1446 return key_names[key_type];
1450 acl_get_next_key_type(int *key_type)
1452 if (*key_type >= AUTH_KEY_TYPE_LAST)
1453 return AUTH_STATUS_ERROR;
1455 if (*key_type < AUTH_KEY_TYPE_FIRST)
1456 *key_type = AUTH_KEY_TYPE_FIRST;
1457 else
1458 (*key_type)++;
1460 return AUTH_STATUS_NO_ERROR;
1464 acl_recv_key_value(struct iscsi_acl *client, int key_type,
1465 const char *user_key_val)
1467 if (!client || client->signature != ACL_SIGNATURE)
1468 return AUTH_STATUS_ERROR;
1470 if (client->phase != AUTH_PHASE_NEGOTIATE &&
1471 client->phase != AUTH_PHASE_AUTHENTICATE) {
1472 client->phase = AUTH_PHASE_ERROR;
1473 return AUTH_STATUS_ERROR;
1476 if (key_type < AUTH_KEY_TYPE_FIRST || key_type > AUTH_KEY_TYPE_LAST) {
1477 client->phase = AUTH_PHASE_ERROR;
1478 return AUTH_STATUS_ERROR;
1481 if (key_type == AUTH_KEY_TYPE_CHAP_CHALLENGE) {
1482 client->recv_chap_challenge.length =
1483 AUTH_LARGE_BINARY_MAX_LEN;
1484 client->recv_chap_challenge_status =
1485 acl_text_to_data(user_key_val,
1486 client->recv_chap_challenge.large_binary,
1487 &client->recv_chap_challenge.length);
1488 user_key_val = "";
1491 acl_set_key_value(&client->recv_key_block, key_type, user_key_val);
1493 return AUTH_STATUS_NO_ERROR;
1497 acl_send_key_val(struct iscsi_acl *client, int key_type, int *key_present,
1498 char *user_key_val, unsigned int max_length)
1500 const char *key_val;
1502 if (!client || client->signature != ACL_SIGNATURE)
1503 return AUTH_STATUS_ERROR;
1505 if (client->phase != AUTH_PHASE_CONFIGURE &&
1506 client->phase != AUTH_PHASE_NEGOTIATE &&
1507 client->phase != AUTH_PHASE_AUTHENTICATE &&
1508 client->phase != AUTH_PHASE_DONE) {
1509 client->phase = AUTH_PHASE_ERROR;
1510 return AUTH_STATUS_ERROR;
1513 if (key_type < AUTH_KEY_TYPE_FIRST || key_type > AUTH_KEY_TYPE_LAST) {
1514 client->phase = AUTH_PHASE_ERROR;
1515 return AUTH_STATUS_ERROR;
1518 key_val = acl_get_key_val(&client->send_key_block, key_type);
1519 if (key_val) {
1520 if (key_type == AUTH_KEY_TYPE_CHAP_CHALLENGE) {
1521 if (acl_data_to_text(client->send_chap_challenge.large_binary,
1522 client->send_chap_challenge.length, user_key_val,
1523 max_length)) {
1524 client->phase = AUTH_PHASE_ERROR;
1525 return AUTH_STATUS_ERROR;
1527 } else if (strlcpy(user_key_val, key_val, max_length) >=
1528 max_length) {
1529 client->phase = AUTH_PHASE_ERROR;
1530 return AUTH_STATUS_ERROR;
1532 *key_present = 1;
1533 } else
1534 *key_present = 0;
1536 return AUTH_STATUS_NO_ERROR;
1540 acl_recv_transit_bit(struct iscsi_acl *client, int value)
1542 if (!client || client->signature != ACL_SIGNATURE)
1543 return AUTH_STATUS_ERROR;
1545 if (client->phase != AUTH_PHASE_NEGOTIATE &&
1546 client->phase != AUTH_PHASE_AUTHENTICATE) {
1548 client->phase = AUTH_PHASE_ERROR;
1549 return AUTH_STATUS_ERROR;
1552 if (value)
1553 client->recv_key_block.transit_bit = 1;
1554 else
1555 client->recv_key_block.transit_bit = 0;
1557 return AUTH_STATUS_NO_ERROR;
1561 acl_send_transit_bit(struct iscsi_acl *client, int *value)
1563 if (!client || client->signature != ACL_SIGNATURE)
1564 return AUTH_STATUS_ERROR;
1566 if (client->phase != AUTH_PHASE_CONFIGURE &&
1567 client->phase != AUTH_PHASE_NEGOTIATE &&
1568 client->phase != AUTH_PHASE_AUTHENTICATE &&
1569 client->phase != AUTH_PHASE_DONE) {
1571 client->phase = AUTH_PHASE_ERROR;
1572 return AUTH_STATUS_ERROR;
1575 *value = client->send_key_block.transit_bit;
1577 return AUTH_STATUS_NO_ERROR;
1580 static int
1581 acl_set_option_list(struct iscsi_acl *client, unsigned int opt_count,
1582 const int *opt_list, unsigned int *clnt_optn_count,
1583 int *clnt_optn_list, unsigned int optn_max_count,
1584 int (*chk_option)(int),
1585 int (*chk_list)(unsigned int opt_count, const int *opt_list))
1587 unsigned int i, j;
1589 if (!client || client->signature != ACL_SIGNATURE)
1590 return AUTH_STATUS_ERROR;
1592 if (client->phase != AUTH_PHASE_CONFIGURE ||
1593 opt_count > optn_max_count) {
1594 client->phase = AUTH_PHASE_ERROR;
1595 return AUTH_STATUS_ERROR;
1598 for (i = 0; i < opt_count; i++)
1599 if (chk_option(opt_list[i])) {
1600 client->phase = AUTH_PHASE_ERROR;
1601 return AUTH_STATUS_ERROR;
1604 /* Check for duplicate entries. */
1605 for (i = 0; i < opt_count; i++)
1606 for (j = 0; j < opt_count; j++) {
1607 if (j == i)
1608 continue;
1609 if (opt_list[i] == opt_list[j]) {
1610 client->phase = AUTH_PHASE_ERROR;
1611 return AUTH_STATUS_ERROR;
1615 /* Check for key specific constraints. */
1616 if (chk_list)
1617 if (chk_list(opt_count, opt_list)) {
1618 client->phase = AUTH_PHASE_ERROR;
1619 return AUTH_STATUS_ERROR;
1622 for (i = 0; i < opt_count; i++)
1623 clnt_optn_list[i] = opt_list[i];
1625 *clnt_optn_count = opt_count;
1627 return AUTH_STATUS_NO_ERROR;
1630 static int
1631 acl_chk_auth_method_list(unsigned int option_count, const int *option_list)
1633 unsigned int i;
1635 if (!option_list || option_count < 2)
1636 return 1;
1638 if (option_list[option_count - 1] != AUTH_OPTION_NONE)
1639 return 1;
1641 for (i = 0; i < (option_count - 1); i++)
1642 if (option_list[i] != AUTH_OPTION_NONE)
1643 return 0;
1645 return 0;
1648 static void
1649 acl_set_auth_method_valid(struct iscsi_acl *client)
1651 unsigned int i, j = 0;
1652 int option = 0;
1655 * Following checks may need to be revised if
1656 * authentication options other than CHAP and none
1657 * are supported.
1659 if (client->node_type == TYPE_INITIATOR) {
1660 if (client->auth_rmt)
1662 * If initiator doing authentication,
1663 * don't offer authentication option none.
1665 option = 1;
1666 else if (!client->passwd_present)
1668 * If initiator password not set,
1669 * only offer authentication option none.
1671 option = 2;
1674 if (client->node_type == TYPE_TARGET) {
1675 if (client->auth_rmt)
1677 * If target doing authentication,
1678 * don't accept authentication option none.
1680 option = 1;
1681 else
1683 * If target not doing authentication,
1684 * only accept authentication option none.
1686 option = 2;
1689 for (i = 0; i < client->auth_method_count; i++) {
1690 if (option == 1) {
1691 if (client->auth_method_list[i] == AUTH_OPTION_NONE)
1692 continue;
1693 } else if (option == 2)
1694 if (client->auth_method_list[i] != AUTH_OPTION_NONE)
1695 continue;
1696 client->auth_method_valid_list[j++] = client->auth_method_list[i];
1699 client->auth_method_valid_count = j;
1701 acl_init_key_blk(&client->send_key_block);
1703 if (client->node_type == TYPE_INITIATOR) {
1704 if (client->auth_rmt) {
1706 * Initiator wants to authenticate target,
1707 * always send AuthMethod key.
1709 client->send_key_block.transit_bit = 0;
1710 client->auth_method_valid_neg_role =
1711 AUTH_NEG_ROLE_ORIGINATOR;
1712 } else {
1713 client->send_key_block.transit_bit = 1;
1714 client->auth_method_valid_neg_role =
1715 client->auth_method_neg_role;
1717 } else {
1718 client->send_key_block.transit_bit = 0;
1719 client->auth_method_valid_neg_role = AUTH_NEG_ROLE_RESPONDER;
1722 if (client->auth_method_valid_neg_role == AUTH_NEG_ROLE_ORIGINATOR)
1723 acl_set_auth_method_key(client, client->auth_method_valid_count,
1724 client->auth_method_valid_list);
1725 else {
1726 int value = AUTH_OPTION_NOT_PRESENT;
1727 acl_set_auth_method_key(client, 1, &value);
1731 static int
1732 acl_set_auth_method_list(struct iscsi_acl *client, unsigned int option_count,
1733 const int *option_list)
1735 int status;
1737 status = acl_set_option_list(client, option_count, option_list,
1738 &client->auth_method_count,
1739 client->auth_method_list,
1740 AUTH_METHOD_MAX_COUNT,
1741 acl_chk_auth_mthd_optn,
1742 acl_chk_auth_method_list);
1744 if (status != AUTH_STATUS_NO_ERROR)
1745 return status;
1747 /* Setting authMethod affects auth_method_valid. */
1748 acl_set_auth_method_valid(client);
1750 return AUTH_STATUS_NO_ERROR;
1753 static int
1754 acl_chk_chap_alg_list(unsigned int option_count, const int *option_list)
1756 if (!option_list || option_count < 1)
1757 return 1;
1759 return 0;
1762 static int
1763 acl_set_chap_alg_list(struct iscsi_acl *client, unsigned int option_count,
1764 const int *option_list)
1766 return acl_set_option_list(client, option_count, option_list,
1767 &client->chap_alg_count,
1768 client->chap_alg_list,
1769 AUTH_CHAP_ALG_MAX_COUNT,
1770 acl_chk_chap_alg_optn,
1771 acl_chk_chap_alg_list);
1775 acl_init(int node_type, int buf_desc_count, struct auth_buffer_desc *buff_desc)
1777 struct iscsi_acl *client;
1778 struct auth_str_block *recv_str_blk;
1779 struct auth_str_block *send_str_blk;
1780 struct auth_large_binary *recv_chap_challenge;
1781 struct auth_large_binary *send_chap_challenge;
1782 int value_list[2];
1784 if (buf_desc_count != 5 || !buff_desc)
1785 return AUTH_STATUS_ERROR;
1787 if (!buff_desc[0].address ||
1788 buff_desc[0].length != sizeof(*client))
1789 return AUTH_STATUS_ERROR;
1790 client = (struct iscsi_acl *)buff_desc[0].address;
1792 if (!buff_desc[1].address ||
1793 buff_desc[1].length != sizeof(*recv_str_blk))
1794 return AUTH_STATUS_ERROR;
1795 recv_str_blk = (struct auth_str_block *)buff_desc[1].address;
1797 if (!buff_desc[2].address ||
1798 buff_desc[2].length != sizeof(*send_str_blk))
1799 return AUTH_STATUS_ERROR;
1801 send_str_blk = (struct auth_str_block *)buff_desc[2].address;
1803 if (!buff_desc[3].address ||
1804 buff_desc[3].length != sizeof(*recv_chap_challenge))
1805 return AUTH_STATUS_ERROR;
1807 recv_chap_challenge = (struct auth_large_binary *)
1808 buff_desc[3].address;
1810 if (!buff_desc[4].address ||
1811 buff_desc[4].length != sizeof(*send_chap_challenge))
1812 return AUTH_STATUS_ERROR;
1813 send_chap_challenge = (struct auth_large_binary *)
1814 buff_desc[4].address;
1815 memset(client, 0, sizeof(*client));
1816 memset(recv_str_blk, 0, sizeof(*recv_str_blk));
1817 memset(send_str_blk, 0, sizeof(*send_str_blk));
1818 memset(recv_chap_challenge, 0, sizeof(*recv_chap_challenge));
1819 memset(send_chap_challenge, 0, sizeof(*send_chap_challenge));
1821 client->recv_key_block.str_block = recv_str_blk->str_block;
1822 client->send_key_block.str_block = send_str_blk->str_block;
1823 client->recv_chap_challenge.large_binary = recv_chap_challenge->large_binary;
1824 client->send_chap_challenge.large_binary = send_chap_challenge->large_binary;
1826 if (node_type != TYPE_INITIATOR && node_type != TYPE_TARGET) {
1827 client->phase = AUTH_PHASE_ERROR;
1828 return AUTH_STATUS_ERROR;
1831 client->signature = ACL_SIGNATURE;
1832 client->node_type = (enum auth_node_type) node_type;
1833 client->auth_rmt = 1;
1834 client->passwd_present = 0;
1835 client->chap_challenge_len = AUTH_CHAP_RSP_LEN;
1836 client->ip_sec = 0;
1838 client->phase = AUTH_PHASE_CONFIGURE;
1839 client->negotiated_auth_method = AUTH_OPTION_NOT_PRESENT;
1840 client->negotiated_chap_alg = AUTH_OPTION_NOT_PRESENT;
1842 if (client->node_type == TYPE_INITIATOR)
1843 client->auth_method_neg_role = AUTH_NEG_ROLE_ORIGINATOR;
1844 else
1845 /* Initial value ignored for Target. */
1846 client->auth_method_neg_role = AUTH_NEG_ROLE_RESPONDER;
1848 value_list[0] = AUTH_METHOD_CHAP;
1849 value_list[1] = AUTH_OPTION_NONE;
1852 * Must call after setting auth_rmt, password,
1853 * and auth_method_neg_role
1855 if (acl_set_auth_method_list(client, 2, value_list) !=
1856 AUTH_STATUS_NO_ERROR) {
1857 client->phase = AUTH_PHASE_ERROR;
1858 return AUTH_STATUS_ERROR;
1861 value_list[0] = AUTH_CHAP_ALG_MD5;
1863 if (acl_set_chap_alg_list(client, 1, value_list) !=
1864 AUTH_STATUS_NO_ERROR) {
1865 client->phase = AUTH_PHASE_ERROR;
1866 return AUTH_STATUS_ERROR;
1869 return AUTH_STATUS_NO_ERROR;
1873 acl_finish(struct iscsi_acl *client)
1875 if (!client || client->signature != ACL_SIGNATURE)
1876 return AUTH_STATUS_ERROR;
1878 memset(client, 0, sizeof(*client));
1880 return AUTH_STATUS_NO_ERROR;
1884 acl_set_user_name(struct iscsi_acl *client, const char *username)
1886 if (!client || client->signature != ACL_SIGNATURE)
1887 return AUTH_STATUS_ERROR;
1889 if (client->phase != AUTH_PHASE_CONFIGURE ||
1890 acl_chk_string(username, AUTH_STR_MAX_LEN, NULL)) {
1891 client->phase = AUTH_PHASE_ERROR;
1892 return AUTH_STATUS_ERROR;
1895 if (!username)
1896 client->username[0] = '\0';
1897 else if (strlcpy(client->username, username, AUTH_STR_MAX_LEN) >=
1898 AUTH_STR_MAX_LEN) {
1899 client->phase = AUTH_PHASE_ERROR;
1900 return AUTH_STATUS_ERROR;
1903 return AUTH_STATUS_NO_ERROR;
1907 acl_set_passwd(struct iscsi_acl *client, const unsigned char *passwd_data,
1908 unsigned int passwd_length)
1910 if (!client || client->signature != ACL_SIGNATURE)
1911 return AUTH_STATUS_ERROR;
1913 if (client->phase != AUTH_PHASE_CONFIGURE ||
1914 passwd_length > AUTH_STR_MAX_LEN) {
1915 client->phase = AUTH_PHASE_ERROR;
1916 return AUTH_STATUS_ERROR;
1919 memcpy(client->passwd_data, passwd_data, passwd_length);
1920 client->passwd_length = passwd_length;
1921 client->passwd_present = 1;
1923 /* Setting password may affect auth_method_valid. */
1924 acl_set_auth_method_valid(client);
1926 return AUTH_STATUS_NO_ERROR;
1930 acl_set_auth_rmt(struct iscsi_acl *client, int auth_rmt)
1932 if (!client || client->signature != ACL_SIGNATURE)
1933 return AUTH_STATUS_ERROR;
1935 if (client->phase != AUTH_PHASE_CONFIGURE) {
1936 client->phase = AUTH_PHASE_ERROR;
1937 return AUTH_STATUS_ERROR;
1940 client->auth_rmt = auth_rmt;
1942 /* Setting auth_rmt may affect auth_method_valid. */
1943 acl_set_auth_method_valid(client);
1945 return AUTH_STATUS_NO_ERROR;
1949 acl_set_ip_sec(struct iscsi_acl *client, int ip_sec)
1951 if (!client || client->signature != ACL_SIGNATURE)
1952 return AUTH_STATUS_ERROR;
1954 if (client->phase != AUTH_PHASE_CONFIGURE) {
1955 client->phase = AUTH_PHASE_ERROR;
1956 return AUTH_STATUS_ERROR;
1959 client->ip_sec = ip_sec;
1961 return AUTH_STATUS_NO_ERROR;
1965 acl_get_dbg_status(struct iscsi_acl *client, int *value)
1967 if (!client || client->signature != ACL_SIGNATURE)
1968 return AUTH_STATUS_ERROR;
1970 if (client->phase != AUTH_PHASE_DONE) {
1971 client->phase = AUTH_PHASE_ERROR;
1972 return AUTH_STATUS_ERROR;
1975 *value = client->dbg_status;
1977 return AUTH_STATUS_NO_ERROR;
1980 const char *
1981 acl_dbg_status_to_text(int dbg_status)
1984 * Note: The ordering of this table must match the order
1985 * defined by enum auth_dbg_status in iscsi-auth-client.h.
1987 static char *const dbg_text[AUTH_DBG_STATUS_MAX_COUNT] = {
1988 "Debug status not set",
1989 "Authentication request passed",
1990 "Authentication not enabled",
1991 "Authentication request failed",
1992 "AuthMethod bad",
1993 "CHAP algorithm bad",
1994 "Decrypt password failed",
1995 "Local password too short with no IPSec",
1996 "Unexpected error from authentication server",
1997 "Authentication request status bad",
1998 "Authentication pass status not valid",
1999 "Same key set more than once on send",
2000 "Key value too long on send",
2001 "Too much data on send",
2002 "AuthMethod key expected",
2003 "CHAP algorithm key expected",
2004 "CHAP identifier expected",
2005 "CHAP challenge expected",
2006 "CHAP response expected",
2007 "CHAP username expected",
2008 "AuthMethod key not present",
2009 "AuthMethod negotiation failed",
2010 "AuthMethod negotiated to none",
2011 "CHAP algorithm negotiation failed",
2012 "CHAP challange reflected",
2013 "Local password same as remote",
2014 "Local password not set",
2015 "CHAP identifier bad",
2016 "CHAP challenge bad",
2017 "CHAP response bad",
2018 "Unexpected key present",
2019 "T bit set on response, but not on previous message",
2020 "T bit set on response, but authenticaton not complete",
2021 "Message count limit reached on receive",
2022 "Same key set more than once on receive",
2023 "Key value too long on receive",
2024 "Too much data on receive"
2027 if (dbg_status < 0 || dbg_status >= AUTH_DBG_STATUS_MAX_COUNT)
2028 return "Unknown error";
2030 return dbg_text[dbg_status];
2034 acl_data(unsigned char *out_data, unsigned int *out_length,
2035 unsigned char *in_data, unsigned int in_length)
2037 if (*out_length < in_length)
2038 return 1; /* error */
2040 memcpy(out_data, in_data, in_length);
2041 *out_length = in_length;
2043 return 0; /* no error */