2 * iSCSI Authorization Library
4 * maintained by open-iscsi@@googlegroups.com
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.
36 #include "initiator.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);
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
);
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
;
82 auth_md5_update(&context
, out_data
, out_length
);
84 /* clear decrypted password */
85 memset(out_data
, 0, AUTH_STR_MAX_LEN
);
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.
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
);
144 auth_md5_update(&context
, verify_data
, 1);
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
,
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
;
168 auth_md5_init(struct MD5Context
*context
)
174 auth_md5_update(struct MD5Context
*context
, unsigned char *data
,
177 MD5Update(context
, data
, length
);
181 auth_md5_final(unsigned char *hash
, struct MD5Context
*context
)
183 MD5Final(hash
, context
);
187 get_random_bytes(unsigned char *data
, unsigned int length
)
194 fd
= open("/dev/urandom", O_RDONLY
);
197 if (!fd
|| read(fd
, &r
, sizeof(long)) != -1)
203 if (!fd
|| read(fd
, &r
, sizeof(long)) != -1)
207 n
= (n
<< 3) | (r
& 0x7);
209 if (!fd
|| read(fd
, &r
, sizeof(long)) != -1)
213 n
= (n
<< 2) | (r
& 0x3);
222 static const char acl_none_option_name
[] = "None";
225 acl_text_to_number(const char *text
, unsigned long *num
)
228 unsigned long number
= *num
;
230 if (text
[0] == '0' && (text
[1] == 'x' || text
[1] == 'X'))
231 number
= strtoul(text
+ 2, &end
, 16);
233 number
= strtoul(text
, &end
, 10);
235 if (*text
!= '\0' && *end
== '\0') {
237 return 0; /* No error */
239 return 1; /* Error */
243 acl_chk_string(const char *s
, unsigned int max_len
, unsigned int *out_len
)
250 for (len
= 0; len
< max_len
; len
++)
261 acl_str_index(const char *s
, int c
)
263 char *str
= strchr(s
, c
);
272 acl_chk_auth_mthd_optn(int val
)
274 if (val
== AUTH_OPTION_NONE
|| val
== AUTH_METHOD_CHAP
)
281 acl_authmethod_optn_to_text(int value
)
285 case AUTH_OPTION_REJECT
:
286 s
= acl_reject_option_name
;
288 case AUTH_OPTION_NONE
:
289 s
= acl_none_option_name
;
291 case AUTH_METHOD_CHAP
:
292 s
= acl_authmethod_set_chap_alg_list
;
301 acl_chk_chap_alg_optn(int chap_algorithm
)
303 if (chap_algorithm
== AUTH_OPTION_NONE
||
304 chap_algorithm
== AUTH_CHAP_ALG_MD5
)
311 acl_data_to_text(unsigned char *data
, unsigned int data_length
, char *text
,
312 unsigned int text_length
)
316 if (!text
|| text_length
== 0)
319 if (!data
|| data_length
== 0) {
324 if (text_length
< 3) {
334 while (data_length
> 0) {
336 if (text_length
< 3) {
344 *text
++ = acl_hexstring
[(n
>> 4) & 0xf];
345 *text
++ = acl_hexstring
[n
& 0xf];
356 acl_hex_to_data(const char *text
, unsigned int text_length
, unsigned char *data
,
357 unsigned int *data_lenp
)
362 unsigned int data_length
= *data_lenp
;
364 if ((text_length
% 2) == 1) {
366 i
= acl_str_index(acl_hexstring
, *text
++);
368 return 1; /* error, bad character */
375 return 1; /* error, too much data */
381 while (*text
!= '\0') {
382 i
= acl_str_index(acl_hexstring
, *text
++);
384 return 1; /* error, bad character */
391 return 1; /* error, odd string length */
393 i
= acl_str_index(acl_hexstring
, *text
++);
395 return 1; /* error, bad character */
402 return 1; /* error, too much data */
404 *data
++ = (n1
<< 4) | n2
;
408 if (data_length
>= *data_lenp
)
409 return 1; /* error, no data */
411 *data_lenp
= *data_lenp
- data_length
;
413 return 0; /* no error */
417 acl_base64_to_data(const char *text
, unsigned char *data
,
418 unsigned int *data_lenp
)
423 unsigned int data_length
= *data_lenp
;
428 while (*text
!= '\0' && *text
!= '=') {
430 i
= acl_str_index(acl_base64_string
, *text
++);
432 return 1; /* error, bad character */
434 n
= (n
<< 6 | (unsigned int)i
);
439 return 1; /* error, too much data */
449 while (*text
!= '\0')
451 return 1; /* error, bad pad */
455 } else if (count
== 2) {
457 return 1; /* error, too much data */
461 } else if (count
== 3) {
463 return 1; /* error, too much data */
469 return 1; /* bad encoding */
471 if (data_length
>= *data_lenp
)
472 return 1; /* error, no data */
474 *data_lenp
= *data_lenp
- data_length
;
476 return 0; /* no error */
480 acl_text_to_data(const char *text
, unsigned char *data
,
481 unsigned int *data_length
)
484 unsigned int text_length
;
486 status
= acl_chk_string(text
, 2 + 2 * AUTH_LARGE_BINARY_MAX_LEN
+ 1,
491 if (text
[0] == '0' && (text
[1] == 'x' || text
[1] == 'X')) {
495 status
= acl_hex_to_data(text
, text_length
, data
, data_length
);
496 } else if (text
[0] == '0' && (text
[1] == 'b' || text
[1] == 'B')) {
500 status
= acl_base64_to_data(text
, data
, data_length
);
502 status
= 1; /* prefix not recognized. */
508 acl_init_key_blk(struct auth_key_block
*key_blk
)
510 char *str_block
= key_blk
->str_block
;
512 memset(key_blk
, 0, sizeof(*key_blk
));
513 key_blk
->str_block
= str_block
;
517 acl_set_key_value(struct auth_key_block
*key_blk
, int key_type
,
523 if (key_blk
->key
[key_type
].value_set
) {
524 key_blk
->dup_set
= 1;
528 key_blk
->key
[key_type
].value_set
= 1;
533 if (acl_chk_string(key_val
, AUTH_STR_MAX_LEN
, &length
)) {
534 key_blk
->str_too_long
= 1;
540 if ((key_blk
->blk_length
+ length
) > AUTH_STR_BLOCK_MAX_LEN
) {
541 key_blk
->too_much_data
= 1;
545 string
= &key_blk
->str_block
[key_blk
->blk_length
];
547 if (strlcpy(string
, key_val
, length
) >= length
) {
548 key_blk
->too_much_data
= 1;
551 key_blk
->blk_length
+= length
;
553 key_blk
->key
[key_type
].string
= string
;
554 key_blk
->key
[key_type
].present
= 1;
558 acl_get_key_val(struct auth_key_block
*key_blk
, int key_type
)
560 key_blk
->key
[key_type
].processed
= 1;
562 if (!key_blk
->key
[key_type
].present
)
565 return key_blk
->key
[key_type
].string
;
569 acl_chk_key(struct iscsi_acl
*client
, int key_type
, int *negotiated_option
,
570 unsigned int option_count
, int *option_list
,
571 const char *(*value_to_text
) (int))
577 key_val
= acl_get_key_val(&client
->recv_key_block
, key_type
);
579 *negotiated_option
= AUTH_OPTION_NOT_PRESENT
;
583 while (*key_val
!= '\0') {
587 while (*key_val
!= '\0' && *key_val
!= ',')
588 client
->scratch_key_value
[length
++] = *key_val
++;
592 client
->scratch_key_value
[length
++] = '\0';
594 for (i
= 0; i
< option_count
; i
++) {
595 const char *s
= (*value_to_text
)(option_list
[i
]);
600 if (strcmp(client
->scratch_key_value
, s
) == 0) {
601 *negotiated_option
= option_list
[i
];
607 *negotiated_option
= AUTH_OPTION_REJECT
;
611 acl_set_key(struct iscsi_acl
*client
, int key_type
, unsigned int option_count
,
612 int *option_list
, const char *(*value_to_text
)(int))
616 if (option_count
== 0) {
618 * No valid options to send, but we always want to
621 acl_set_key_value(&client
->send_key_block
, key_type
,
622 acl_none_option_name
);
626 if (option_count
== 1 && option_list
[0] == AUTH_OPTION_NOT_PRESENT
) {
627 acl_set_key_value(&client
->send_key_block
, key_type
, NULL
);
631 for (i
= 0; i
< option_count
; i
++) {
632 const char *s
= (*value_to_text
)(option_list
[i
]);
638 strlcpy(client
->scratch_key_value
, s
,
641 strlcat(client
->scratch_key_value
, ",",
643 strlcat(client
->scratch_key_value
, s
,
648 acl_set_key_value(&client
->send_key_block
, key_type
,
649 client
->scratch_key_value
);
653 acl_chk_auth_method_key(struct iscsi_acl
*client
)
655 acl_chk_key(client
, AUTH_KEY_TYPE_AUTH_METHOD
,
656 &client
->negotiated_auth_method
,
657 client
->auth_method_valid_count
,
658 client
->auth_method_valid_list
,
659 acl_authmethod_optn_to_text
);
663 acl_set_auth_method_key(struct iscsi_acl
*client
,
664 unsigned int auth_method_count
, int *auth_method_list
)
666 acl_set_key(client
, AUTH_KEY_TYPE_AUTH_METHOD
, auth_method_count
,
667 auth_method_list
, acl_authmethod_optn_to_text
);
671 acl_chk_chap_alg_key(struct iscsi_acl
*client
)
675 unsigned long number
;
678 key_val
= acl_get_key_val(&client
->recv_key_block
,
679 AUTH_KEY_TYPE_CHAP_ALG
);
681 client
->negotiated_chap_alg
= AUTH_OPTION_NOT_PRESENT
;
685 while (*key_val
!= '\0') {
689 while (*key_val
!= '\0' && *key_val
!= ',')
690 client
->scratch_key_value
[length
++] = *key_val
++;
694 client
->scratch_key_value
[length
++] = '\0';
696 if (acl_text_to_number(client
->scratch_key_value
, &number
))
700 for (i
= 0; i
< client
->chap_alg_count
; i
++)
701 if (number
== (unsigned long)client
->chap_alg_list
[i
])
703 client
->negotiated_chap_alg
= number
;
708 client
->negotiated_chap_alg
= AUTH_OPTION_REJECT
;
712 acl_set_chap_alg_key(struct iscsi_acl
*client
, unsigned int chap_alg_count
,
717 if (chap_alg_count
== 0) {
718 acl_set_key_value(&client
->send_key_block
,
719 AUTH_KEY_TYPE_CHAP_ALG
, NULL
);
723 if (chap_alg_count
== 1 &&
724 chap_alg_list
[0] == AUTH_OPTION_NOT_PRESENT
) {
725 acl_set_key_value(&client
->send_key_block
,
726 AUTH_KEY_TYPE_CHAP_ALG
, NULL
);
730 if (chap_alg_count
== 1 && chap_alg_list
[0] == AUTH_OPTION_REJECT
) {
731 acl_set_key_value(&client
->send_key_block
,
732 AUTH_KEY_TYPE_CHAP_ALG
,
733 acl_reject_option_name
);
737 for (i
= 0; i
< chap_alg_count
; i
++) {
740 snprintf(s
, sizeof(s
), "%lu",(unsigned long)chap_alg_list
[i
]);
743 strlcpy(client
->scratch_key_value
, s
,
746 strlcat(client
->scratch_key_value
, ",",
748 strlcat(client
->scratch_key_value
, s
,
753 acl_set_key_value(&client
->send_key_block
, AUTH_KEY_TYPE_CHAP_ALG
,
754 client
->scratch_key_value
);
758 acl_next_phase(struct iscsi_acl
*client
)
760 switch (client
->phase
) {
761 case AUTH_PHASE_CONFIGURE
:
762 client
->phase
= AUTH_PHASE_NEGOTIATE
;
764 case AUTH_PHASE_NEGOTIATE
:
765 client
->phase
= AUTH_PHASE_AUTHENTICATE
;
767 if (client
->negotiated_auth_method
== AUTH_OPTION_REJECT
||
768 client
->negotiated_auth_method
== AUTH_OPTION_NOT_PRESENT
||
769 client
->negotiated_auth_method
== AUTH_OPTION_NONE
) {
771 client
->local_state
= AUTH_LOCAL_STATE_DONE
;
772 client
->rmt_state
= AUTH_RMT_STATE_DONE
;
774 if (client
->auth_rmt
) {
775 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
776 client
->phase
= AUTH_PHASE_DONE
;
778 client
->rmt_auth_status
= AUTH_STATUS_PASS
;
780 switch (client
->negotiated_auth_method
) {
781 case AUTH_OPTION_REJECT
:
783 AUTH_DBG_STATUS_AUTH_METHOD_REJECT
;
785 case AUTH_OPTION_NOT_PRESENT
:
787 AUTH_DBG_STATUS_AUTH_METHOD_NOT_PRESENT
;
789 case AUTH_OPTION_NONE
:
791 AUTH_DBG_STATUS_AUTH_METHOD_NONE
;
794 } else if (client
->negotiated_auth_method
== AUTH_METHOD_CHAP
) {
795 client
->local_state
= AUTH_LOCAL_STATE_SEND_ALG
;
796 client
->rmt_state
= AUTH_RMT_STATE_SEND_ALG
;
799 client
->local_state
= AUTH_LOCAL_STATE_DONE
;
800 client
->rmt_state
= AUTH_RMT_STATE_DONE
;
801 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
802 client
->dbg_status
= AUTH_DBG_STATUS_AUTH_METHOD_BAD
;
805 case AUTH_PHASE_AUTHENTICATE
:
806 client
->phase
= AUTH_PHASE_DONE
;
808 case AUTH_PHASE_DONE
:
809 case AUTH_PHASE_ERROR
:
811 client
->phase
= AUTH_PHASE_ERROR
;
816 acl_local_auth(struct iscsi_acl
*client
)
818 unsigned int chap_identifier
;
819 unsigned char response_data
[AUTH_CHAP_RSP_LEN
];
820 unsigned long number
;
822 enum auth_dbg_status dbg_status
;
823 const char *chap_identifier_key_val
;
824 const char *chap_challenge_key_val
;
826 switch (client
->local_state
) {
827 case AUTH_LOCAL_STATE_SEND_ALG
:
828 if (client
->node_type
== TYPE_INITIATOR
) {
829 acl_set_chap_alg_key(client
, client
->chap_alg_count
,
830 client
->chap_alg_list
);
831 client
->local_state
= AUTH_LOCAL_STATE_RECV_ALG
;
835 case AUTH_LOCAL_STATE_RECV_ALG
:
836 acl_chk_chap_alg_key(client
);
838 if (client
->node_type
== TYPE_TARGET
)
839 acl_set_chap_alg_key(client
, 1,
840 &client
->negotiated_chap_alg
);
842 /* Make sure only supported CHAP algorithm is used. */
843 if (client
->negotiated_chap_alg
== AUTH_OPTION_NOT_PRESENT
) {
844 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
845 client
->dbg_status
= AUTH_DBG_STATUS_CHAP_ALG_EXPECTED
;
847 } else if (client
->negotiated_chap_alg
== AUTH_OPTION_REJECT
) {
848 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
849 client
->dbg_status
= AUTH_DBG_STATUS_CHAP_ALG_REJECT
;
851 } else if (client
->negotiated_chap_alg
!= AUTH_CHAP_ALG_MD5
) {
852 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
853 client
->dbg_status
= AUTH_DBG_STATUS_CHAP_ALG_BAD
;
856 if (client
->node_type
== TYPE_TARGET
) {
857 client
->local_state
= AUTH_LOCAL_STATE_RECV_CHALLENGE
;
861 case AUTH_LOCAL_STATE_RECV_CHALLENGE
:
862 chap_identifier_key_val
= acl_get_key_val(&client
->recv_key_block
,
863 AUTH_KEY_TYPE_CHAP_IDENTIFIER
);
864 chap_challenge_key_val
= acl_get_key_val(&client
->recv_key_block
,
865 AUTH_KEY_TYPE_CHAP_CHALLENGE
);
866 if (client
->node_type
== TYPE_TARGET
) {
867 if (!chap_identifier_key_val
&&
868 !chap_challenge_key_val
) {
869 client
->local_state
= AUTH_LOCAL_STATE_DONE
;
874 if (!chap_identifier_key_val
) {
875 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
877 AUTH_DBG_STATUS_CHAP_IDENTIFIER_EXPECTED
;
881 if (!chap_challenge_key_val
) {
882 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
884 AUTH_DBG_STATUS_CHAP_CHALLENGE_EXPECTED
;
888 status
= acl_text_to_number(chap_identifier_key_val
, &number
);
889 if (status
|| (255 < number
)) {
890 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
891 client
->dbg_status
= AUTH_DBG_STATUS_CHAP_IDENTIFIER_BAD
;
894 chap_identifier
= number
;
896 if (client
->recv_chap_challenge_status
) {
897 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
898 client
->dbg_status
= AUTH_DBG_STATUS_CHALLENGE_BAD
;
902 if (client
->node_type
== TYPE_TARGET
&&
903 client
->recv_chap_challenge
.length
==
904 client
->send_chap_challenge
.length
&&
905 memcmp(client
->recv_chap_challenge
.large_binary
,
906 client
->send_chap_challenge
.large_binary
,
907 client
->send_chap_challenge
.length
) == 0) {
908 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
910 AUTH_DBG_STATUS_CHAP_CHALLENGE_REFLECTED
;
914 dbg_status
= acl_chap_compute_rsp(client
, 0,
916 client
->recv_chap_challenge
.large_binary
,
917 client
->recv_chap_challenge
.length
,
920 if (dbg_status
!= AUTH_DBG_STATUS_NOT_SET
) {
921 client
->local_state
= AUTH_LOCAL_STATE_ERROR
;
922 client
->dbg_status
= dbg_status
;
926 acl_data_to_text(response_data
,
927 AUTH_CHAP_RSP_LEN
, client
->scratch_key_value
,
929 acl_set_key_value(&client
->send_key_block
,
930 AUTH_KEY_TYPE_CHAP_RSP
,
931 client
->scratch_key_value
);
932 acl_set_key_value(&client
->send_key_block
,
933 AUTH_KEY_TYPE_CHAP_USERNAME
,
936 client
->local_state
= AUTH_LOCAL_STATE_DONE
;
938 case AUTH_LOCAL_STATE_DONE
:
940 case AUTH_LOCAL_STATE_ERROR
:
942 client
->phase
= AUTH_PHASE_ERROR
;
947 acl_rmt_auth(struct iscsi_acl
*client
)
949 unsigned char id_data
[1];
950 unsigned char response_data
[AUTH_STR_MAX_LEN
];
951 unsigned int rsp_len
= AUTH_STR_MAX_LEN
;
952 unsigned char my_rsp_data
[AUTH_CHAP_RSP_LEN
];
954 enum auth_dbg_status dbg_status
;
955 const char *chap_rsp_key_val
;
956 const char *chap_username_key_val
;
958 switch (client
->rmt_state
) {
959 case AUTH_RMT_STATE_SEND_ALG
:
960 if (client
->node_type
== TYPE_INITIATOR
) {
961 client
->rmt_state
= AUTH_RMT_STATE_SEND_CHALLENGE
;
965 case AUTH_RMT_STATE_SEND_CHALLENGE
:
966 if (!client
->auth_rmt
) {
967 client
->rmt_auth_status
= AUTH_STATUS_PASS
;
968 client
->dbg_status
= AUTH_DBG_STATUS_AUTH_RMT_FALSE
;
969 client
->rmt_state
= AUTH_RMT_STATE_DONE
;
972 get_random_bytes(id_data
, 1);
973 client
->send_chap_identifier
= id_data
[0];
974 snprintf(client
->scratch_key_value
, AUTH_STR_MAX_LEN
, "%lu",
975 (unsigned long)client
->send_chap_identifier
);
976 acl_set_key_value(&client
->send_key_block
,
977 AUTH_KEY_TYPE_CHAP_IDENTIFIER
,
978 client
->scratch_key_value
);
980 client
->send_chap_challenge
.length
= client
->chap_challenge_len
;
981 get_random_bytes(client
->send_chap_challenge
.large_binary
,
982 client
->send_chap_challenge
.length
);
983 acl_set_key_value(&client
->send_key_block
,
984 AUTH_KEY_TYPE_CHAP_CHALLENGE
, "");
986 client
->rmt_state
= AUTH_RMT_STATE_RECV_RSP
;
988 case AUTH_RMT_STATE_RECV_RSP
:
989 chap_rsp_key_val
= acl_get_key_val(&client
->recv_key_block
,
990 AUTH_KEY_TYPE_CHAP_RSP
);
991 chap_username_key_val
= acl_get_key_val(&client
->recv_key_block
,
992 AUTH_KEY_TYPE_CHAP_USERNAME
);
994 if (!chap_rsp_key_val
) {
995 client
->rmt_state
= AUTH_RMT_STATE_ERROR
;
996 client
->dbg_status
= AUTH_DBG_STATUS_CHAP_RSP_EXPECTED
;
1000 if (!chap_username_key_val
) {
1001 client
->rmt_state
= AUTH_RMT_STATE_ERROR
;
1002 client
->dbg_status
= AUTH_DBG_STATUS_CHAP_USERNAME_EXPECTED
;
1006 status
= acl_text_to_data(chap_rsp_key_val
, response_data
,
1010 client
->rmt_state
= AUTH_RMT_STATE_ERROR
;
1011 client
->dbg_status
= AUTH_DBG_STATUS_CHAP_RSP_BAD
;
1015 if (rsp_len
== AUTH_CHAP_RSP_LEN
) {
1016 dbg_status
= acl_chap_compute_rsp(client
, 1,
1017 client
->send_chap_identifier
,
1018 client
->send_chap_challenge
.large_binary
,
1019 client
->send_chap_challenge
.length
,
1022 if (dbg_status
== AUTH_DBG_STATUS_NOT_SET
&&
1023 memcmp(my_rsp_data
, response_data
,
1024 AUTH_CHAP_RSP_LEN
) == 0) {
1025 client
->rmt_state
= AUTH_RMT_STATE_ERROR
;
1026 client
->dbg_status
= AUTH_DBG_STATUS_PASSWD_IDENTICAL
;
1031 strlcpy(client
->chap_username
, chap_username_key_val
,
1034 status
= acl_chap_auth_request(client
, client
->chap_username
,
1035 client
->send_chap_identifier
,
1036 client
->send_chap_challenge
.
1038 client
->send_chap_challenge
.
1039 length
, response_data
,
1042 client
->rmt_auth_status
= (enum auth_status
) status
;
1043 client
->auth_rsp_flag
= 1;
1045 if (client
->auth_server_error_flag
) {
1046 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1047 client
->dbg_status
= AUTH_DBG_STATUS_AUTH_SERVER_ERROR
;
1048 } else if (client
->rmt_auth_status
== AUTH_STATUS_PASS
)
1049 client
->dbg_status
= AUTH_DBG_STATUS_AUTH_PASS
;
1050 else if (client
->rmt_auth_status
== AUTH_STATUS_FAIL
)
1051 client
->dbg_status
= AUTH_DBG_STATUS_AUTH_FAIL
;
1053 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1054 client
->dbg_status
= AUTH_DBG_STATUS_AUTH_STATUS_BAD
;
1056 client
->rmt_state
= AUTH_RMT_STATE_DONE
;
1059 case AUTH_RMT_STATE_DONE
:
1061 case AUTH_RMT_STATE_ERROR
:
1063 client
->phase
= AUTH_PHASE_ERROR
;
1068 acl_hand_shake(struct iscsi_acl
*client
)
1070 if (client
->phase
== AUTH_PHASE_DONE
)
1073 * Should only happen if authentication
1074 * protocol error occured.
1078 if (client
->node_type
== TYPE_INITIATOR
)
1081 * Target should only have set T bit on response if
1082 * initiator set it on previous message.
1084 if (client
->recv_key_block
.transit_bit
&&
1085 !client
->transit_bit_sent_flag
) {
1086 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1087 client
->phase
= AUTH_PHASE_DONE
;
1088 client
->dbg_status
=
1089 AUTH_DBG_STATUS_T_BIT_SET_ILLEGAL
;
1093 if (client
->phase
== AUTH_PHASE_NEGOTIATE
) {
1095 * Should only happen if waiting for peer
1096 * to send AuthMethod key or set Transit Bit.
1098 if (client
->node_type
== TYPE_INITIATOR
)
1099 client
->send_key_block
.transit_bit
= 1;
1103 if (client
->rmt_state
== AUTH_RMT_STATE_RECV_RSP
||
1104 client
->rmt_state
== AUTH_RMT_STATE_DONE
) {
1105 if (client
->node_type
== TYPE_INITIATOR
) {
1106 if (client
->recv_key_block
.transit_bit
) {
1107 if (client
->rmt_state
!=
1108 AUTH_RMT_STATE_DONE
)
1109 goto recv_transit_bit_err
;
1110 acl_next_phase(client
);
1112 client
->send_key_block
.transit_bit
= 1;
1114 if (client
->rmt_state
== AUTH_RMT_STATE_DONE
&&
1115 client
->rmt_auth_status
!= AUTH_STATUS_PASS
)
1117 * Authentication failed, don't do T bit
1120 acl_next_phase(client
);
1123 * Target can only set T bit on response if
1124 * initiator set it on current message.
1126 if (client
->recv_key_block
.transit_bit
) {
1127 client
->send_key_block
.transit_bit
= 1;
1128 acl_next_phase(client
);
1133 if (client
->node_type
== TYPE_INITIATOR
)
1134 if (client
->recv_key_block
.transit_bit
)
1135 goto recv_transit_bit_err
;
1138 recv_transit_bit_err
:
1140 * Target set T bit on response but
1141 * initiator was not done with authentication.
1143 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1144 client
->phase
= AUTH_PHASE_DONE
;
1145 client
->dbg_status
= AUTH_DBG_STATUS_T_BIT_SET_PREMATURE
;
1149 acl_rcv_end_status(struct iscsi_acl
*client
)
1154 if (client
->phase
== AUTH_PHASE_ERROR
)
1155 return AUTH_STATUS_ERROR
;
1157 if (client
->phase
== AUTH_PHASE_DONE
) {
1159 /* Perform sanity check against configured parameters. */
1160 if (client
->auth_rmt
&& !client
->auth_rsp_flag
&&
1161 client
->rmt_auth_status
== AUTH_STATUS_PASS
) {
1162 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1163 client
->dbg_status
= AUTH_DBG_STATUS_AUTHPASS_NOT_VALID
;
1166 auth_status
= client
->rmt_auth_status
;
1169 auth_status
= AUTH_STATUS_CONTINUE
;
1171 if (auth_status
== AUTH_STATUS_CONTINUE
||
1172 auth_status
== AUTH_STATUS_PASS
) {
1173 if (client
->send_key_block
.dup_set
) {
1174 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1175 client
->phase
= AUTH_PHASE_DONE
;
1176 client
->dbg_status
=
1177 AUTH_DBG_STATUS_SEND_DUP_SET_KEY_VALUE
;
1178 auth_status
= AUTH_STATUS_FAIL
;
1179 } else if (client
->send_key_block
.str_too_long
) {
1180 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1181 client
->phase
= AUTH_PHASE_DONE
;
1182 client
->dbg_status
=
1183 AUTH_DBG_STATUS_SEND_STR_TOO_LONG
;
1184 auth_status
= AUTH_STATUS_FAIL
;
1185 } else if (client
->send_key_block
.too_much_data
) {
1186 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1187 client
->phase
= AUTH_PHASE_DONE
;
1188 client
->dbg_status
=
1189 AUTH_DBG_STATUS_SEND_TOO_MUCH_DATA
;
1190 auth_status
= AUTH_STATUS_FAIL
;
1192 /* Check that all incoming keys have been processed. */
1194 for (key_type
= AUTH_KEY_TYPE_FIRST
;
1195 key_type
< AUTH_KEY_TYPE_MAX_COUNT
; key_type
++)
1196 if (client
->recv_key_block
.key
[key_type
].present
&&
1197 !client
->recv_key_block
.key
[key_type
].
1201 if (key_type
< AUTH_KEY_TYPE_MAX_COUNT
) {
1202 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1203 client
->phase
= AUTH_PHASE_DONE
;
1204 client
->dbg_status
=
1205 AUTH_DBG_STATUS_UNEXPECTED_KEY_PRESENT
;
1206 auth_status
= AUTH_STATUS_FAIL
;
1211 if (auth_status
!= AUTH_STATUS_PASS
&&
1212 auth_status
!= AUTH_STATUS_CONTINUE
) {
1213 int auth_method_key_present
= 0;
1214 int chap_alg_key_present
= 0;
1217 * Suppress send keys on error,
1218 * except for AuthMethod and CHAP_A.
1220 if (client
->node_type
== TYPE_TARGET
) {
1221 if (acl_get_key_val(&client
->send_key_block
,
1222 AUTH_KEY_TYPE_AUTH_METHOD
))
1223 auth_method_key_present
= 1;
1224 else if (acl_get_key_val(&client
->send_key_block
,
1225 AUTH_KEY_TYPE_CHAP_ALG
))
1226 chap_alg_key_present
= 1;
1229 acl_init_key_blk(&client
->send_key_block
);
1231 if (client
->node_type
== TYPE_TARGET
) {
1232 if (auth_method_key_present
&&
1233 client
->negotiated_auth_method
==
1235 acl_set_key_value(&client
->send_key_block
,
1236 AUTH_KEY_TYPE_AUTH_METHOD
,
1237 acl_reject_option_name
);
1238 else if (chap_alg_key_present
&&
1239 client
->negotiated_chap_alg
==
1241 acl_set_key_value(&client
->send_key_block
,
1242 AUTH_KEY_TYPE_CHAP_ALG
,
1243 acl_reject_option_name
);
1246 client
->recv_in_progress_flag
= 0;
1252 acl_recv_begin(struct iscsi_acl
*client
)
1254 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1255 return AUTH_STATUS_ERROR
;
1257 if (client
->phase
== AUTH_PHASE_ERROR
)
1258 return AUTH_STATUS_ERROR
;
1260 if (client
->phase
== AUTH_PHASE_DONE
) {
1261 client
->phase
= AUTH_PHASE_ERROR
;
1262 return AUTH_STATUS_ERROR
;
1265 if (client
->recv_in_progress_flag
) {
1266 client
->phase
= AUTH_PHASE_ERROR
;
1267 return AUTH_STATUS_ERROR
;
1270 client
->recv_in_progress_flag
= 1;
1272 if (client
->phase
== AUTH_PHASE_CONFIGURE
)
1273 acl_next_phase(client
);
1275 client
->transit_bit_sent_flag
= client
->send_key_block
.transit_bit
;
1277 acl_init_key_blk(&client
->recv_key_block
);
1278 acl_init_key_blk(&client
->send_key_block
);
1280 return AUTH_STATUS_NO_ERROR
;
1284 acl_recv_end(struct iscsi_acl
*client
, iscsi_session_t
*session_handle
)
1286 int next_phase_flag
= 0;
1288 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1289 return AUTH_STATUS_ERROR
;
1291 if (client
->phase
== AUTH_PHASE_ERROR
)
1292 return AUTH_STATUS_ERROR
;
1294 if (!client
->recv_in_progress_flag
) {
1295 client
->phase
= AUTH_PHASE_ERROR
;
1296 return AUTH_STATUS_ERROR
;
1299 if (client
->recv_end_count
> AUTH_RECV_END_MAX_COUNT
) {
1300 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1301 client
->phase
= AUTH_PHASE_DONE
;
1302 client
->dbg_status
= AUTH_DBG_STATUS_RECV_MSG_COUNT_LIMIT
;
1303 } else if (client
->recv_key_block
.dup_set
) {
1304 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1305 client
->phase
= AUTH_PHASE_DONE
;
1306 client
->dbg_status
= AUTH_DBG_STATUS_RECV_DUP_SET_KEY_VALUE
;
1307 } else if (client
->recv_key_block
.str_too_long
) {
1308 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1309 client
->phase
= AUTH_PHASE_DONE
;
1310 client
->dbg_status
= AUTH_DBG_STATUS_RECV_STR_TOO_LONG
;
1311 } else if (client
->recv_key_block
.too_much_data
) {
1312 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1313 client
->phase
= AUTH_PHASE_DONE
;
1314 client
->dbg_status
= AUTH_DBG_STATUS_RECV_TOO_MUCH_DATA
;
1317 client
->recv_end_count
++;
1318 client
->session_handle
= session_handle
;
1320 switch (client
->phase
) {
1321 case AUTH_PHASE_NEGOTIATE
:
1322 acl_chk_auth_method_key(client
);
1323 if (client
->auth_method_valid_neg_role
==
1324 AUTH_NEG_ROLE_RESPONDER
) {
1325 if (client
->negotiated_auth_method
==
1326 AUTH_OPTION_NOT_PRESENT
) {
1327 if (client
->auth_rmt
||
1328 !client
->recv_key_block
.transit_bit
) {
1330 * No AuthMethod key from peer on
1331 * first message, try moving the
1332 * process along by sending the
1336 client
->auth_method_valid_neg_role
=
1337 AUTH_NEG_ROLE_ORIGINATOR
;
1338 acl_set_auth_method_key(client
,
1339 client
->auth_method_valid_count
,
1340 client
->auth_method_valid_list
);
1345 * Special case if peer sent no AuthMethod key,
1346 * but did set Transit Bit, allowing this side
1347 * to do a null authentication, and compelete
1348 * the iSCSI security phase without either side
1349 * sending the AuthMethod key.
1352 /* Send response to AuthMethod key. */
1353 acl_set_auth_method_key(client
, 1,
1354 &client
->negotiated_auth_method
);
1356 if (client
->node_type
== TYPE_INITIATOR
)
1357 acl_next_phase(client
);
1359 next_phase_flag
= 1;
1362 if (client
->negotiated_auth_method
==
1363 AUTH_OPTION_NOT_PRESENT
) {
1364 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1365 client
->phase
= AUTH_PHASE_DONE
;
1366 client
->dbg_status
=
1367 AUTH_DBG_STATUS_AUTH_METHOD_EXPECTED
;
1371 acl_next_phase(client
);
1374 case AUTH_PHASE_AUTHENTICATE
:
1375 case AUTH_PHASE_DONE
:
1378 client
->phase
= AUTH_PHASE_ERROR
;
1379 return AUTH_STATUS_ERROR
;
1382 switch (client
->phase
) {
1383 case AUTH_PHASE_NEGOTIATE
:
1384 if (next_phase_flag
)
1385 acl_next_phase(client
);
1387 case AUTH_PHASE_AUTHENTICATE
:
1389 * Must call acl_local_auth()
1390 * before acl_rmt_auth()
1391 * to insure processing of the CHAP algorithm key,
1392 * and to avoid leaving an in progress request to the
1393 * authentication service.
1395 acl_local_auth(client
);
1397 if (client
->local_state
!= AUTH_LOCAL_STATE_ERROR
)
1398 acl_rmt_auth(client
);
1400 if (client
->local_state
== AUTH_LOCAL_STATE_ERROR
||
1401 client
->rmt_state
== AUTH_RMT_STATE_ERROR
) {
1403 client
->rmt_auth_status
= AUTH_STATUS_FAIL
;
1404 client
->phase
= AUTH_PHASE_DONE
;
1405 /* client->dbg_status should already be set. */
1408 case AUTH_PHASE_DONE
:
1411 client
->phase
= AUTH_PHASE_ERROR
;
1412 return AUTH_STATUS_ERROR
;
1415 acl_hand_shake(client
);
1417 return acl_rcv_end_status(client
);
1421 acl_get_key_name(int key_type
)
1424 * Note: The ordering of this table must match the order
1425 * defined by enum auth_key_type in iscsi-auth-client.h.
1427 static char *const key_names
[AUTH_KEY_TYPE_MAX_COUNT
] = {
1436 if (key_type
< AUTH_KEY_TYPE_FIRST
|| key_type
> AUTH_KEY_TYPE_LAST
)
1439 return key_names
[key_type
];
1443 acl_get_next_key_type(int *key_type
)
1445 if (*key_type
>= AUTH_KEY_TYPE_LAST
)
1446 return AUTH_STATUS_ERROR
;
1448 if (*key_type
< AUTH_KEY_TYPE_FIRST
)
1449 *key_type
= AUTH_KEY_TYPE_FIRST
;
1453 return AUTH_STATUS_NO_ERROR
;
1457 acl_recv_key_value(struct iscsi_acl
*client
, int key_type
,
1458 const char *user_key_val
)
1460 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1461 return AUTH_STATUS_ERROR
;
1463 if (client
->phase
!= AUTH_PHASE_NEGOTIATE
&&
1464 client
->phase
!= AUTH_PHASE_AUTHENTICATE
) {
1465 client
->phase
= AUTH_PHASE_ERROR
;
1466 return AUTH_STATUS_ERROR
;
1469 if (key_type
< AUTH_KEY_TYPE_FIRST
|| key_type
> AUTH_KEY_TYPE_LAST
) {
1470 client
->phase
= AUTH_PHASE_ERROR
;
1471 return AUTH_STATUS_ERROR
;
1474 if (key_type
== AUTH_KEY_TYPE_CHAP_CHALLENGE
) {
1475 client
->recv_chap_challenge
.length
=
1476 AUTH_LARGE_BINARY_MAX_LEN
;
1477 client
->recv_chap_challenge_status
=
1478 acl_text_to_data(user_key_val
,
1479 client
->recv_chap_challenge
.large_binary
,
1480 &client
->recv_chap_challenge
.length
);
1484 acl_set_key_value(&client
->recv_key_block
, key_type
, user_key_val
);
1486 return AUTH_STATUS_NO_ERROR
;
1490 acl_send_key_val(struct iscsi_acl
*client
, int key_type
, int *key_present
,
1491 char *user_key_val
, unsigned int max_length
)
1493 const char *key_val
;
1495 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1496 return AUTH_STATUS_ERROR
;
1498 if (client
->phase
!= AUTH_PHASE_CONFIGURE
&&
1499 client
->phase
!= AUTH_PHASE_NEGOTIATE
&&
1500 client
->phase
!= AUTH_PHASE_AUTHENTICATE
&&
1501 client
->phase
!= AUTH_PHASE_DONE
) {
1502 client
->phase
= AUTH_PHASE_ERROR
;
1503 return AUTH_STATUS_ERROR
;
1506 if (key_type
< AUTH_KEY_TYPE_FIRST
|| key_type
> AUTH_KEY_TYPE_LAST
) {
1507 client
->phase
= AUTH_PHASE_ERROR
;
1508 return AUTH_STATUS_ERROR
;
1511 key_val
= acl_get_key_val(&client
->send_key_block
, key_type
);
1513 if (key_type
== AUTH_KEY_TYPE_CHAP_CHALLENGE
) {
1514 if (acl_data_to_text(client
->send_chap_challenge
.large_binary
,
1515 client
->send_chap_challenge
.length
, user_key_val
,
1517 client
->phase
= AUTH_PHASE_ERROR
;
1518 return AUTH_STATUS_ERROR
;
1520 } else if (strlcpy(user_key_val
, key_val
, max_length
) >=
1522 client
->phase
= AUTH_PHASE_ERROR
;
1523 return AUTH_STATUS_ERROR
;
1529 return AUTH_STATUS_NO_ERROR
;
1533 acl_recv_transit_bit(struct iscsi_acl
*client
, int value
)
1535 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1536 return AUTH_STATUS_ERROR
;
1538 if (client
->phase
!= AUTH_PHASE_NEGOTIATE
&&
1539 client
->phase
!= AUTH_PHASE_AUTHENTICATE
) {
1541 client
->phase
= AUTH_PHASE_ERROR
;
1542 return AUTH_STATUS_ERROR
;
1546 client
->recv_key_block
.transit_bit
= 1;
1548 client
->recv_key_block
.transit_bit
= 0;
1550 return AUTH_STATUS_NO_ERROR
;
1554 acl_send_transit_bit(struct iscsi_acl
*client
, int *value
)
1556 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1557 return AUTH_STATUS_ERROR
;
1559 if (client
->phase
!= AUTH_PHASE_CONFIGURE
&&
1560 client
->phase
!= AUTH_PHASE_NEGOTIATE
&&
1561 client
->phase
!= AUTH_PHASE_AUTHENTICATE
&&
1562 client
->phase
!= AUTH_PHASE_DONE
) {
1564 client
->phase
= AUTH_PHASE_ERROR
;
1565 return AUTH_STATUS_ERROR
;
1568 *value
= client
->send_key_block
.transit_bit
;
1570 return AUTH_STATUS_NO_ERROR
;
1574 acl_set_option_list(struct iscsi_acl
*client
, unsigned int opt_count
,
1575 const int *opt_list
, unsigned int *clnt_optn_count
,
1576 int *clnt_optn_list
, unsigned int optn_max_count
,
1577 int (*chk_option
)(int),
1578 int (*chk_list
)(unsigned int opt_count
, const int *opt_list
))
1582 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1583 return AUTH_STATUS_ERROR
;
1585 if (client
->phase
!= AUTH_PHASE_CONFIGURE
||
1586 opt_count
> optn_max_count
) {
1587 client
->phase
= AUTH_PHASE_ERROR
;
1588 return AUTH_STATUS_ERROR
;
1591 for (i
= 0; i
< opt_count
; i
++)
1592 if (chk_option(opt_list
[i
])) {
1593 client
->phase
= AUTH_PHASE_ERROR
;
1594 return AUTH_STATUS_ERROR
;
1597 /* Check for duplicate entries. */
1598 for (i
= 0; i
< opt_count
; i
++)
1599 for (j
= 0; j
< opt_count
; j
++) {
1602 if (opt_list
[i
] == opt_list
[j
]) {
1603 client
->phase
= AUTH_PHASE_ERROR
;
1604 return AUTH_STATUS_ERROR
;
1608 /* Check for key specific constraints. */
1610 if (chk_list(opt_count
, opt_list
)) {
1611 client
->phase
= AUTH_PHASE_ERROR
;
1612 return AUTH_STATUS_ERROR
;
1615 for (i
= 0; i
< opt_count
; i
++)
1616 clnt_optn_list
[i
] = opt_list
[i
];
1618 *clnt_optn_count
= opt_count
;
1620 return AUTH_STATUS_NO_ERROR
;
1624 acl_chk_auth_method_list(unsigned int option_count
, const int *option_list
)
1628 if (!option_list
|| option_count
< 2)
1631 if (option_list
[option_count
- 1] != AUTH_OPTION_NONE
)
1634 for (i
= 0; i
< (option_count
- 1); i
++)
1635 if (option_list
[i
] != AUTH_OPTION_NONE
)
1642 acl_set_auth_method_valid(struct iscsi_acl
*client
)
1644 unsigned int i
, j
= 0;
1648 * Following checks may need to be revised if
1649 * authentication options other than CHAP and none
1652 if (client
->node_type
== TYPE_INITIATOR
) {
1653 if (client
->auth_rmt
)
1655 * If initiator doing authentication,
1656 * don't offer authentication option none.
1659 else if (!client
->passwd_present
)
1661 * If initiator password not set,
1662 * only offer authentication option none.
1667 if (client
->node_type
== TYPE_TARGET
) {
1668 if (client
->auth_rmt
)
1670 * If target doing authentication,
1671 * don't accept authentication option none.
1676 * If target not doing authentication,
1677 * only accept authentication option none.
1682 for (i
= 0; i
< client
->auth_method_count
; i
++) {
1684 if (client
->auth_method_list
[i
] == AUTH_OPTION_NONE
)
1686 } else if (option
== 2)
1687 if (client
->auth_method_list
[i
] != AUTH_OPTION_NONE
)
1689 client
->auth_method_valid_list
[j
++] = client
->auth_method_list
[i
];
1692 client
->auth_method_valid_count
= j
;
1694 acl_init_key_blk(&client
->send_key_block
);
1696 if (client
->node_type
== TYPE_INITIATOR
) {
1697 if (client
->auth_rmt
) {
1699 * Initiator wants to authenticate target,
1700 * always send AuthMethod key.
1702 client
->send_key_block
.transit_bit
= 0;
1703 client
->auth_method_valid_neg_role
=
1704 AUTH_NEG_ROLE_ORIGINATOR
;
1706 client
->send_key_block
.transit_bit
= 1;
1707 client
->auth_method_valid_neg_role
=
1708 client
->auth_method_neg_role
;
1711 client
->send_key_block
.transit_bit
= 0;
1712 client
->auth_method_valid_neg_role
= AUTH_NEG_ROLE_RESPONDER
;
1715 if (client
->auth_method_valid_neg_role
== AUTH_NEG_ROLE_ORIGINATOR
)
1716 acl_set_auth_method_key(client
, client
->auth_method_valid_count
,
1717 client
->auth_method_valid_list
);
1719 int value
= AUTH_OPTION_NOT_PRESENT
;
1720 acl_set_auth_method_key(client
, 1, &value
);
1725 acl_set_auth_method_list(struct iscsi_acl
*client
, unsigned int option_count
,
1726 const int *option_list
)
1730 status
= acl_set_option_list(client
, option_count
, option_list
,
1731 &client
->auth_method_count
,
1732 client
->auth_method_list
,
1733 AUTH_METHOD_MAX_COUNT
,
1734 acl_chk_auth_mthd_optn
,
1735 acl_chk_auth_method_list
);
1737 if (status
!= AUTH_STATUS_NO_ERROR
)
1740 /* Setting authMethod affects auth_method_valid. */
1741 acl_set_auth_method_valid(client
);
1743 return AUTH_STATUS_NO_ERROR
;
1747 acl_chk_chap_alg_list(unsigned int option_count
, const int *option_list
)
1749 if (!option_list
|| option_count
< 1)
1756 acl_set_chap_alg_list(struct iscsi_acl
*client
, unsigned int option_count
,
1757 const int *option_list
)
1759 return acl_set_option_list(client
, option_count
, option_list
,
1760 &client
->chap_alg_count
,
1761 client
->chap_alg_list
,
1762 AUTH_CHAP_ALG_MAX_COUNT
,
1763 acl_chk_chap_alg_optn
,
1764 acl_chk_chap_alg_list
);
1768 acl_init(int node_type
, int buf_desc_count
, struct auth_buffer_desc
*buff_desc
)
1770 struct iscsi_acl
*client
;
1771 struct auth_str_block
*recv_str_blk
;
1772 struct auth_str_block
*send_str_blk
;
1773 struct auth_large_binary
*recv_chap_challenge
;
1774 struct auth_large_binary
*send_chap_challenge
;
1777 if (buf_desc_count
!= 5 || !buff_desc
)
1778 return AUTH_STATUS_ERROR
;
1780 if (!buff_desc
[0].address
||
1781 buff_desc
[0].length
!= sizeof(*client
))
1782 return AUTH_STATUS_ERROR
;
1783 client
= (struct iscsi_acl
*)buff_desc
[0].address
;
1785 if (!buff_desc
[1].address
||
1786 buff_desc
[1].length
!= sizeof(*recv_str_blk
))
1787 return AUTH_STATUS_ERROR
;
1788 recv_str_blk
= (struct auth_str_block
*)buff_desc
[1].address
;
1790 if (!buff_desc
[2].address
||
1791 buff_desc
[2].length
!= sizeof(*send_str_blk
))
1792 return AUTH_STATUS_ERROR
;
1794 send_str_blk
= (struct auth_str_block
*)buff_desc
[2].address
;
1796 if (!buff_desc
[3].address
||
1797 buff_desc
[3].length
!= sizeof(*recv_chap_challenge
))
1798 return AUTH_STATUS_ERROR
;
1800 recv_chap_challenge
= (struct auth_large_binary
*)
1801 buff_desc
[3].address
;
1803 if (!buff_desc
[4].address
||
1804 buff_desc
[4].length
!= sizeof(*send_chap_challenge
))
1805 return AUTH_STATUS_ERROR
;
1806 send_chap_challenge
= (struct auth_large_binary
*)
1807 buff_desc
[4].address
;
1808 memset(client
, 0, sizeof(*client
));
1809 memset(recv_str_blk
, 0, sizeof(*recv_str_blk
));
1810 memset(send_str_blk
, 0, sizeof(*send_str_blk
));
1811 memset(recv_chap_challenge
, 0, sizeof(*recv_chap_challenge
));
1812 memset(send_chap_challenge
, 0, sizeof(*send_chap_challenge
));
1814 client
->recv_key_block
.str_block
= recv_str_blk
->str_block
;
1815 client
->send_key_block
.str_block
= send_str_blk
->str_block
;
1816 client
->recv_chap_challenge
.large_binary
= recv_chap_challenge
->large_binary
;
1817 client
->send_chap_challenge
.large_binary
= send_chap_challenge
->large_binary
;
1819 if (node_type
!= TYPE_INITIATOR
&& node_type
!= TYPE_TARGET
) {
1820 client
->phase
= AUTH_PHASE_ERROR
;
1821 return AUTH_STATUS_ERROR
;
1824 client
->signature
= ACL_SIGNATURE
;
1825 client
->node_type
= (enum auth_node_type
) node_type
;
1826 client
->auth_rmt
= 1;
1827 client
->passwd_present
= 0;
1828 client
->chap_challenge_len
= AUTH_CHAP_RSP_LEN
;
1831 client
->phase
= AUTH_PHASE_CONFIGURE
;
1832 client
->negotiated_auth_method
= AUTH_OPTION_NOT_PRESENT
;
1833 client
->negotiated_chap_alg
= AUTH_OPTION_NOT_PRESENT
;
1835 if (client
->node_type
== TYPE_INITIATOR
)
1836 client
->auth_method_neg_role
= AUTH_NEG_ROLE_ORIGINATOR
;
1838 /* Initial value ignored for Target. */
1839 client
->auth_method_neg_role
= AUTH_NEG_ROLE_RESPONDER
;
1841 value_list
[0] = AUTH_METHOD_CHAP
;
1842 value_list
[1] = AUTH_OPTION_NONE
;
1845 * Must call after setting auth_rmt, password,
1846 * and auth_method_neg_role
1848 if (acl_set_auth_method_list(client
, 2, value_list
) !=
1849 AUTH_STATUS_NO_ERROR
) {
1850 client
->phase
= AUTH_PHASE_ERROR
;
1851 return AUTH_STATUS_ERROR
;
1854 value_list
[0] = AUTH_CHAP_ALG_MD5
;
1856 if (acl_set_chap_alg_list(client
, 1, value_list
) !=
1857 AUTH_STATUS_NO_ERROR
) {
1858 client
->phase
= AUTH_PHASE_ERROR
;
1859 return AUTH_STATUS_ERROR
;
1862 return AUTH_STATUS_NO_ERROR
;
1866 acl_finish(struct iscsi_acl
*client
)
1868 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1869 return AUTH_STATUS_ERROR
;
1871 memset(client
, 0, sizeof(*client
));
1873 return AUTH_STATUS_NO_ERROR
;
1877 acl_set_user_name(struct iscsi_acl
*client
, const char *username
)
1879 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1880 return AUTH_STATUS_ERROR
;
1882 if (client
->phase
!= AUTH_PHASE_CONFIGURE
||
1883 acl_chk_string(username
, AUTH_STR_MAX_LEN
, NULL
)) {
1884 client
->phase
= AUTH_PHASE_ERROR
;
1885 return AUTH_STATUS_ERROR
;
1889 client
->username
[0] = '\0';
1890 else if (strlcpy(client
->username
, username
, AUTH_STR_MAX_LEN
) >=
1892 client
->phase
= AUTH_PHASE_ERROR
;
1893 return AUTH_STATUS_ERROR
;
1896 return AUTH_STATUS_NO_ERROR
;
1900 acl_set_passwd(struct iscsi_acl
*client
, const unsigned char *passwd_data
,
1901 unsigned int passwd_length
)
1903 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1904 return AUTH_STATUS_ERROR
;
1906 if (client
->phase
!= AUTH_PHASE_CONFIGURE
||
1907 passwd_length
> AUTH_STR_MAX_LEN
) {
1908 client
->phase
= AUTH_PHASE_ERROR
;
1909 return AUTH_STATUS_ERROR
;
1912 memcpy(client
->passwd_data
, passwd_data
, passwd_length
);
1913 client
->passwd_length
= passwd_length
;
1914 client
->passwd_present
= 1;
1916 /* Setting password may affect auth_method_valid. */
1917 acl_set_auth_method_valid(client
);
1919 return AUTH_STATUS_NO_ERROR
;
1923 acl_set_auth_rmt(struct iscsi_acl
*client
, int auth_rmt
)
1925 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1926 return AUTH_STATUS_ERROR
;
1928 if (client
->phase
!= AUTH_PHASE_CONFIGURE
) {
1929 client
->phase
= AUTH_PHASE_ERROR
;
1930 return AUTH_STATUS_ERROR
;
1933 client
->auth_rmt
= auth_rmt
;
1935 /* Setting auth_rmt may affect auth_method_valid. */
1936 acl_set_auth_method_valid(client
);
1938 return AUTH_STATUS_NO_ERROR
;
1942 acl_set_ip_sec(struct iscsi_acl
*client
, int ip_sec
)
1944 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1945 return AUTH_STATUS_ERROR
;
1947 if (client
->phase
!= AUTH_PHASE_CONFIGURE
) {
1948 client
->phase
= AUTH_PHASE_ERROR
;
1949 return AUTH_STATUS_ERROR
;
1952 client
->ip_sec
= ip_sec
;
1954 return AUTH_STATUS_NO_ERROR
;
1958 acl_get_dbg_status(struct iscsi_acl
*client
, int *value
)
1960 if (!client
|| client
->signature
!= ACL_SIGNATURE
)
1961 return AUTH_STATUS_ERROR
;
1963 if (client
->phase
!= AUTH_PHASE_DONE
) {
1964 client
->phase
= AUTH_PHASE_ERROR
;
1965 return AUTH_STATUS_ERROR
;
1968 *value
= client
->dbg_status
;
1970 return AUTH_STATUS_NO_ERROR
;
1974 acl_dbg_status_to_text(int dbg_status
)
1977 * Note: The ordering of this table must match the order
1978 * defined by enum auth_dbg_status in iscsi-auth-client.h.
1980 static char *const dbg_text
[AUTH_DBG_STATUS_MAX_COUNT
] = {
1981 "Debug status not set",
1982 "Authentication request passed",
1983 "Authentication not enabled",
1984 "Authentication request failed",
1986 "CHAP algorithm bad",
1987 "Decrypt password failed",
1988 "Local password too short with no IPSec",
1989 "Unexpected error from authentication server",
1990 "Authentication request status bad",
1991 "Authentication pass status not valid",
1992 "Same key set more than once on send",
1993 "Key value too long on send",
1994 "Too much data on send",
1995 "AuthMethod key expected",
1996 "CHAP algorithm key expected",
1997 "CHAP identifier expected",
1998 "CHAP challenge expected",
1999 "CHAP response expected",
2000 "CHAP username expected",
2001 "AuthMethod key not present",
2002 "AuthMethod negotiation failed",
2003 "AuthMethod negotiated to none",
2004 "CHAP algorithm negotiation failed",
2005 "CHAP challange reflected",
2006 "Local password same as remote",
2007 "Local password not set",
2008 "CHAP identifier bad",
2009 "CHAP challenge bad",
2010 "CHAP response bad",
2011 "Unexpected key present",
2012 "T bit set on response, but not on previous message",
2013 "T bit set on response, but authenticaton not complete",
2014 "Message count limit reached on receive",
2015 "Same key set more than once on receive",
2016 "Key value too long on receive",
2017 "Too much data on receive"
2020 if (dbg_status
< 0 || dbg_status
>= AUTH_DBG_STATUS_MAX_COUNT
)
2021 return "Unknown error";
2023 return dbg_text
[dbg_status
];
2027 acl_data(unsigned char *out_data
, unsigned int *out_length
,
2028 unsigned char *in_data
, unsigned int in_length
)
2030 if (*out_length
< in_length
)
2031 return 1; /* error */
2033 memcpy(out_data
, in_data
, in_length
);
2034 *out_length
= in_length
;
2036 return 0; /* no error */