📄 iscsi-auth-client.c
字号:
return AUTH_STATUS_NO_ERROR;}static intacl_set_option_list(struct iscsi_acl *client, unsigned int opt_count, const int *opt_list, unsigned int *clnt_optn_count, int *clnt_optn_list, unsigned int optn_max_count, int (*chk_option)(int), int (*chk_list)(unsigned int opt_count, const int *opt_list)){ unsigned int i, j; if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_CONFIGURE || opt_count > optn_max_count) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } for (i = 0; i < opt_count; i++) if (chk_option(opt_list[i])) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } /* Check for duplicate entries. */ for (i = 0; i < opt_count; i++) for (j = 0; j < opt_count; j++) { if (j == i) continue; if (opt_list[i] == opt_list[j]) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } } /* Check for key specific constraints. */ if (chk_list) if (chk_list(opt_count, opt_list)) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } for (i = 0; i < opt_count; i++) clnt_optn_list[i] = opt_list[i]; *clnt_optn_count = opt_count; return AUTH_STATUS_NO_ERROR;}static intacl_chk_auth_method_list(unsigned int option_count, const int *option_list){ unsigned int i; if (!option_list || option_count < 2) return 1; if (option_list[option_count - 1] != AUTH_OPTION_NONE) return 1; for (i = 0; i < (option_count - 1); i++) if (option_list[i] != AUTH_OPTION_NONE) return 0; return 0;}static voidacl_set_auth_method_valid(struct iscsi_acl *client){ unsigned int i, j = 0; int option = 0; /* * Following checks may need to be revised if * authentication options other than CHAP and none * are supported. */ if (client->node_type == TYPE_INITIATOR) { if (client->auth_rmt) /* * If initiator doing authentication, * don't offer authentication option none. */ option = 1; else if (!client->passwd_present) /* * If initiator password not set, * only offer authentication option none. */ option = 2; } if (client->node_type == TYPE_TARGET) { if (client->auth_rmt) /* * If target doing authentication, * don't accept authentication option none. */ option = 1; else /* * If target not doing authentication, * only accept authentication option none. */ option = 2; } for (i = 0; i < client->auth_method_count; i++) { if (option == 1) { if (client->auth_method_list[i] == AUTH_OPTION_NONE) continue; } else if (option == 2) if (client->auth_method_list[i] != AUTH_OPTION_NONE) continue; client->auth_method_valid_list[j++] = client->auth_method_list[i]; } client->auth_method_valid_count = j; acl_init_key_blk(&client->send_key_block); if (client->node_type == TYPE_INITIATOR) { if (client->auth_rmt) { /* * Initiator wants to authenticate target, * always send AuthMethod key. */ client->send_key_block.transit_bit = 0; client->auth_method_valid_neg_role = AUTH_NEG_ROLE_ORIGINATOR; } else { client->send_key_block.transit_bit = 1; client->auth_method_valid_neg_role = client->auth_method_neg_role; } } else { client->send_key_block.transit_bit = 0; client->auth_method_valid_neg_role = AUTH_NEG_ROLE_RESPONDER; } if (client->auth_method_valid_neg_role == AUTH_NEG_ROLE_ORIGINATOR) acl_set_auth_method_key(client, client->auth_method_valid_count, client->auth_method_valid_list); else { int value = AUTH_OPTION_NOT_PRESENT; acl_set_auth_method_key(client, 1, &value); }}static intacl_set_auth_method_list(struct iscsi_acl *client, unsigned int option_count, const int *option_list){ int status; status = acl_set_option_list(client, option_count, option_list, &client->auth_method_count, client->auth_method_list, AUTH_METHOD_MAX_COUNT, acl_chk_auth_mthd_optn, acl_chk_auth_method_list); if (status != AUTH_STATUS_NO_ERROR) return status; /* Setting authMethod affects auth_method_valid. */ acl_set_auth_method_valid(client); return AUTH_STATUS_NO_ERROR;}static intacl_chk_chap_alg_list(unsigned int option_count, const int *option_list){ if (!option_list || option_count < 1) return 1; return 0;}static intacl_set_chap_alg_list(struct iscsi_acl *client, unsigned int option_count, const int *option_list){ return acl_set_option_list(client, option_count, option_list, &client->chap_alg_count, client->chap_alg_list, AUTH_CHAP_ALG_MAX_COUNT, acl_chk_chap_alg_optn, acl_chk_chap_alg_list);}intacl_init(int node_type, struct iscsi_session *session){ struct iscsi_acl *client; struct auth_str_block *rcv_str_blk; struct auth_str_block *snd_str_blk; struct auth_large_binary *rcv_chap_chlng; struct auth_large_binary *snd_chap_chlng; int value_list[2]; if (!session->auth_client_block) return AUTH_STATUS_ERROR; client = session->auth_client_block; if (!session->auth_recv_string_block) return AUTH_STATUS_ERROR; rcv_str_blk = session->auth_recv_string_block; if (!session->auth_send_string_block) return AUTH_STATUS_ERROR; snd_str_blk = session->auth_send_string_block; if (!session->auth_recv_binary_block) return AUTH_STATUS_ERROR; rcv_chap_chlng = session->auth_recv_binary_block; if (!session->auth_send_binary_block) return AUTH_STATUS_ERROR; snd_chap_chlng = session->auth_send_binary_block; memset(client, 0, sizeof(*client)); memset(rcv_str_blk, 0, sizeof(*rcv_str_blk)); memset(snd_str_blk, 0, sizeof(*snd_str_blk)); memset(rcv_chap_chlng, 0, sizeof(*rcv_chap_chlng)); memset(snd_chap_chlng, 0, sizeof(*snd_chap_chlng)); client->recv_key_block.str_block = rcv_str_blk->str_block; client->send_key_block.str_block = snd_str_blk->str_block; client->recv_chap_challenge.large_binary = rcv_chap_chlng->large_binary; client->send_chap_challenge.large_binary = snd_chap_chlng->large_binary; if (node_type != TYPE_INITIATOR && node_type != TYPE_TARGET) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } client->signature = ACL_SIGNATURE; client->node_type = (enum auth_node_type) node_type; client->auth_rmt = 1; client->passwd_present = 0; client->chap_challenge_len = AUTH_CHAP_RSP_LEN; client->ip_sec = 0; client->session_handle = session; client->phase = AUTH_PHASE_CONFIGURE; client->negotiated_auth_method = AUTH_OPTION_NOT_PRESENT; client->negotiated_chap_alg = AUTH_OPTION_NOT_PRESENT; if (client->node_type == TYPE_INITIATOR) client->auth_method_neg_role = AUTH_NEG_ROLE_ORIGINATOR; else /* Initial value ignored for Target. */ client->auth_method_neg_role = AUTH_NEG_ROLE_RESPONDER; value_list[0] = AUTH_METHOD_CHAP; value_list[1] = AUTH_OPTION_NONE; /* * Must call after setting auth_rmt, password, * and auth_method_neg_role */ if (acl_set_auth_method_list(client, 2, value_list) != AUTH_STATUS_NO_ERROR) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } value_list[0] = AUTH_CHAP_ALG_MD5; if (acl_set_chap_alg_list(client, 1, value_list) != AUTH_STATUS_NO_ERROR) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } return AUTH_STATUS_NO_ERROR;}intacl_finish(struct iscsi_acl *client){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; memset(client, 0, sizeof(*client)); return AUTH_STATUS_NO_ERROR;}intacl_set_user_name(struct iscsi_acl *client, const char *username){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_CONFIGURE || acl_chk_string(username, AUTH_STR_MAX_LEN, 0)) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } if (strlcpy(client->username, username, AUTH_STR_MAX_LEN) >= AUTH_STR_MAX_LEN) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } return AUTH_STATUS_NO_ERROR;}intacl_set_passwd(struct iscsi_acl *client, const unsigned char *passwd_data, unsigned int passwd_length){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_CONFIGURE || passwd_length > AUTH_STR_MAX_LEN) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } memcpy(client->passwd_data, passwd_data, passwd_length); client->passwd_length = passwd_length; client->passwd_present = 1; /* Setting password may affect auth_method_valid. */ acl_set_auth_method_valid(client); return AUTH_STATUS_NO_ERROR;}intacl_set_auth_rmt(struct iscsi_acl *client, int auth_rmt){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_CONFIGURE) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } client->auth_rmt = auth_rmt; /* Setting auth_rmt may affect auth_method_valid. */ acl_set_auth_method_valid(client); return AUTH_STATUS_NO_ERROR;}intacl_set_ip_sec(struct iscsi_acl *client, int ip_sec){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_CONFIGURE) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } client->ip_sec = ip_sec; return AUTH_STATUS_NO_ERROR;}intacl_get_dbg_status(struct iscsi_acl *client, int *value){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_DONE) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } *value = client->dbg_status; return AUTH_STATUS_NO_ERROR;}const char *acl_dbg_status_to_text(int dbg_status){ /* * Note: The ordering of this table must match the order * defined by enum auth_dbg_status in iscsi-auth-client.h. */ static char *const dbg_text[AUTH_DBG_STATUS_MAX_COUNT] = { "Debug status not set", "Authentication request passed", "Authentication not enabled", "Authentication request failed", "AuthMethod bad", "CHAP algorithm bad", "Decrypt password failed", "Local password too short with no IPSec", "Unexpected error from authentication server", "Authentication request status bad", "Authentication pass status not valid", "Same key set more than once on send", "Key value too long on send", "Too much data on send", "AuthMethod key expected", "CHAP algorithm key expected", "CHAP identifier expected", "CHAP challenge expected", "CHAP response expected", "CHAP username expected", "AuthMethod key not present", "AuthMethod negotiation failed", "AuthMethod negotiated to none", "CHAP algorithm negotiation failed", "CHAP challange reflected", "Local password same as remote", "Local password not set", "CHAP identifier bad", "CHAP challenge bad", "CHAP response bad", "Unexpected key present", "T bit set on response, but not on previous message", "T bit set on response, but authenticaton not complete", "Message count limit reached on receive", "Same key set more than once on receive", "Key value too long on receive", "Too much data on receive" }; if (dbg_status < 0 || dbg_status >= AUTH_DBG_STATUS_MAX_COUNT) return "Unknown error"; return dbg_text[dbg_status];}intacl_data(unsigned char *out_data, unsigned int *out_length, unsigned char *in_data, unsigned int in_length){ if (*out_length < in_length) return 1; /* error */ memcpy(out_data, in_data, in_length); *out_length = in_length; return 0; /* no error */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -