📄 iscsi-auth-client.c
字号:
} acl_set_key_value(&client->send_key_block, key_type, client->scratch_key_value);}static voidacl_chk_auth_method_key(struct iscsi_acl *client){ acl_chk_key(client, AUTH_KEY_TYPE_AUTH_METHOD, &client->negotiated_auth_method, client->auth_method_valid_count, client->auth_method_valid_list, acl_authmethod_optn_to_text);}static voidacl_set_auth_method_key(struct iscsi_acl *client, unsigned int auth_method_count, int *auth_method_list){ acl_set_key(client, AUTH_KEY_TYPE_AUTH_METHOD, auth_method_count, auth_method_list, acl_authmethod_optn_to_text);}static voidacl_chk_chap_alg_key(struct iscsi_acl *client){ const char *key_val; int length; unsigned long number; unsigned int i; key_val = acl_get_key_val(&client->recv_key_block, AUTH_KEY_TYPE_CHAP_ALG); if (!key_val) { client->negotiated_chap_alg = AUTH_OPTION_NOT_PRESENT; return; } while (*key_val != '\0') { length = 0; while (*key_val != '\0' && *key_val != ',') client->scratch_key_value[length++] = *key_val++; if (*key_val == ',') key_val++; client->scratch_key_value[length++] = '\0'; if (acl_text_to_number(client->scratch_key_value, &number)) continue; for (i = 0; i < client->chap_alg_count; i++) if (number == (unsigned long)client->chap_alg_list[i]) { client->negotiated_chap_alg = number; return; } } client->negotiated_chap_alg = AUTH_OPTION_REJECT;}static voidacl_set_chap_alg_key(struct iscsi_acl *client, unsigned int chap_alg_count, int *chap_alg_list){ unsigned int i; if (chap_alg_count == 0) { acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_ALG, 0); return; } if (chap_alg_count == 1 && chap_alg_list[0] == AUTH_OPTION_NOT_PRESENT) { acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_ALG, 0); return; } if (chap_alg_count == 1 && chap_alg_list[0] == AUTH_OPTION_REJECT) { acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_ALG, acl_reject_option_name); return; } for (i = 0; i < chap_alg_count; i++) { char s[20]; snprintf(s, sizeof(s), "%lu",(unsigned long)chap_alg_list[i]); if (i == 0) strlcpy(client->scratch_key_value, s, AUTH_STR_MAX_LEN); else { strlcat(client->scratch_key_value, ",", AUTH_STR_MAX_LEN); strlcat(client->scratch_key_value, s, AUTH_STR_MAX_LEN); } } acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_ALG, client->scratch_key_value);}static voidacl_next_phase(struct iscsi_acl *client){ switch (client->phase) { case AUTH_PHASE_CONFIGURE: client->phase = AUTH_PHASE_NEGOTIATE; break; case AUTH_PHASE_NEGOTIATE: client->phase = AUTH_PHASE_AUTHENTICATE; if (client->negotiated_auth_method == AUTH_OPTION_REJECT || client->negotiated_auth_method == AUTH_OPTION_NOT_PRESENT || client->negotiated_auth_method == AUTH_OPTION_NONE) { client->local_state = AUTH_LOCAL_STATE_DONE; client->rmt_state = AUTH_RMT_STATE_DONE; if (client->auth_rmt) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; } else client->rmt_auth_status = AUTH_STATUS_PASS; switch (client->negotiated_auth_method) { case AUTH_OPTION_REJECT: client->dbg_status = AUTH_DBG_STATUS_AUTH_METHOD_REJECT; break; case AUTH_OPTION_NOT_PRESENT: client->dbg_status = AUTH_DBG_STATUS_AUTH_METHOD_NOT_PRESENT; break; case AUTH_OPTION_NONE: client->dbg_status = AUTH_DBG_STATUS_AUTH_METHOD_NONE; } } else if (client->negotiated_auth_method == AUTH_METHOD_CHAP) { client->local_state = AUTH_LOCAL_STATE_SEND_ALG; client->rmt_state = AUTH_RMT_STATE_SEND_ALG; } else { client->local_state = AUTH_LOCAL_STATE_DONE; client->rmt_state = AUTH_RMT_STATE_DONE; client->rmt_auth_status = AUTH_STATUS_FAIL; client->dbg_status = AUTH_DBG_STATUS_AUTH_METHOD_BAD; } break; case AUTH_PHASE_AUTHENTICATE: client->phase = AUTH_PHASE_DONE; break; case AUTH_PHASE_DONE: case AUTH_PHASE_ERROR: default: client->phase = AUTH_PHASE_ERROR; }}static voidacl_local_auth(struct iscsi_acl *client){ unsigned int chap_identifier; unsigned char response_data[AUTH_CHAP_RSP_LEN]; unsigned long number; int status; enum auth_dbg_status dbg_status; const char *chap_identifier_key_val; const char *chap_challenge_key_val; switch (client->local_state) { case AUTH_LOCAL_STATE_SEND_ALG: if (client->node_type == TYPE_INITIATOR) { acl_set_chap_alg_key(client, client->chap_alg_count, client->chap_alg_list); client->local_state = AUTH_LOCAL_STATE_RECV_ALG; break; } /* Fall through */ case AUTH_LOCAL_STATE_RECV_ALG: acl_chk_chap_alg_key(client); if (client->node_type == TYPE_TARGET) acl_set_chap_alg_key(client, 1, &client->negotiated_chap_alg); /* Make sure only supported CHAP algorithm is used. */ if (client->negotiated_chap_alg == AUTH_OPTION_NOT_PRESENT) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_ALG_EXPECTED; break; } else if (client->negotiated_chap_alg == AUTH_OPTION_REJECT) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_ALG_REJECT; break; } else if (client->negotiated_chap_alg != AUTH_CHAP_ALG_MD5) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_ALG_BAD; break; } if (client->node_type == TYPE_TARGET) { client->local_state = AUTH_LOCAL_STATE_RECV_CHALLENGE; break; } /* Fall through */ case AUTH_LOCAL_STATE_RECV_CHALLENGE: chap_identifier_key_val = acl_get_key_val(&client->recv_key_block, AUTH_KEY_TYPE_CHAP_IDENTIFIER); chap_challenge_key_val = acl_get_key_val(&client->recv_key_block, AUTH_KEY_TYPE_CHAP_CHALLENGE); if (client->node_type == TYPE_TARGET) { if (!chap_identifier_key_val && !chap_challenge_key_val) { client->local_state = AUTH_LOCAL_STATE_DONE; break; } } if (!chap_identifier_key_val) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_IDENTIFIER_EXPECTED; break; } if (!chap_challenge_key_val) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_CHALLENGE_EXPECTED; break; } status = acl_text_to_number(chap_identifier_key_val, &number); if (status || (255 < number)) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_IDENTIFIER_BAD; break; } chap_identifier = number; if (client->recv_chap_challenge_status) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHALLENGE_BAD; break; } if (client->node_type == TYPE_TARGET && client->recv_chap_challenge.length == client->send_chap_challenge.length && memcmp(client->recv_chap_challenge.large_binary, client->send_chap_challenge.large_binary, client->send_chap_challenge.length) == 0) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_CHALLENGE_REFLECTED; break; } dbg_status = acl_chap_compute_rsp(client, 0, chap_identifier, client->recv_chap_challenge.large_binary, client->recv_chap_challenge.length, response_data); if (dbg_status != AUTH_DBG_STATUS_NOT_SET) { client->local_state = AUTH_LOCAL_STATE_ERROR; client->dbg_status = dbg_status; break; } acl_data_to_text(response_data, AUTH_CHAP_RSP_LEN, client->scratch_key_value, AUTH_STR_MAX_LEN); acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_RSP, client->scratch_key_value); acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_USERNAME, client->username); client->local_state = AUTH_LOCAL_STATE_DONE; break; case AUTH_LOCAL_STATE_DONE: break; case AUTH_LOCAL_STATE_ERROR: default: client->phase = AUTH_PHASE_ERROR; }}static voidacl_rmt_auth(struct iscsi_acl *client){ unsigned char id_data[1]; unsigned char response_data[AUTH_STR_MAX_LEN]; unsigned int rsp_len = AUTH_STR_MAX_LEN; unsigned char my_rsp_data[AUTH_CHAP_RSP_LEN]; int status; enum auth_dbg_status dbg_status; const char *chap_rsp_key_val; const char *chap_username_key_val; switch (client->rmt_state) { case AUTH_RMT_STATE_SEND_ALG: if (client->node_type == TYPE_INITIATOR) { client->rmt_state = AUTH_RMT_STATE_SEND_CHALLENGE; break; } /* Fall through */ case AUTH_RMT_STATE_SEND_CHALLENGE: if (!client->auth_rmt) { client->rmt_auth_status = AUTH_STATUS_PASS; client->dbg_status = AUTH_DBG_STATUS_AUTH_RMT_FALSE; client->rmt_state = AUTH_RMT_STATE_DONE; break; } get_random_bytes(id_data, 1); client->send_chap_identifier = id_data[0]; snprintf(client->scratch_key_value, AUTH_STR_MAX_LEN, "%lu", (unsigned long)client->send_chap_identifier); acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_IDENTIFIER, client->scratch_key_value); client->send_chap_challenge.length = client->chap_challenge_len; get_random_bytes(client->send_chap_challenge.large_binary, client->send_chap_challenge.length); acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_CHALLENGE, ""); client->rmt_state = AUTH_RMT_STATE_RECV_RSP; break; case AUTH_RMT_STATE_RECV_RSP: chap_rsp_key_val = acl_get_key_val(&client->recv_key_block, AUTH_KEY_TYPE_CHAP_RSP); chap_username_key_val = acl_get_key_val(&client->recv_key_block, AUTH_KEY_TYPE_CHAP_USERNAME); if (!chap_rsp_key_val) { client->rmt_state = AUTH_RMT_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_RSP_EXPECTED; break; } if (!chap_username_key_val) { client->rmt_state = AUTH_RMT_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_USERNAME_EXPECTED; break; } status = acl_text_to_data(chap_rsp_key_val, response_data, &rsp_len); if (status) { client->rmt_state = AUTH_RMT_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_CHAP_RSP_BAD; break; } if (rsp_len == AUTH_CHAP_RSP_LEN) { dbg_status = acl_chap_compute_rsp(client, 1, client->send_chap_identifier, client->send_chap_challenge.large_binary, client->send_chap_challenge.length, my_rsp_data); if (dbg_status == AUTH_DBG_STATUS_NOT_SET && memcmp(my_rsp_data, response_data, AUTH_CHAP_RSP_LEN) == 0) { client->rmt_state = AUTH_RMT_STATE_ERROR; client->dbg_status = AUTH_DBG_STATUS_PASSWD_IDENTICAL; break; } } strlcpy(client->chap_username, chap_username_key_val, AUTH_STR_MAX_LEN); status = acl_chap_auth_request(client, client->chap_username, client->send_chap_identifier, client->send_chap_challenge. large_binary, client->send_chap_challenge. length, response_data, rsp_len); client->rmt_auth_status = (enum auth_status) status; client->auth_rsp_flag = 1; if (client->auth_server_error_flag) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->dbg_status = AUTH_DBG_STATUS_AUTH_SERVER_ERROR; } else if (client->rmt_auth_status == AUTH_STATUS_PASS) client->dbg_status = AUTH_DBG_STATUS_AUTH_PASS; else if (client->rmt_auth_status == AUTH_STATUS_FAIL) client->dbg_status = AUTH_DBG_STATUS_AUTH_FAIL; else { client->rmt_auth_status = AUTH_STATUS_FAIL; client->dbg_status = AUTH_DBG_STATUS_AUTH_STATUS_BAD; } client->rmt_state = AUTH_RMT_STATE_DONE; /* Fall through */ case AUTH_RMT_STATE_DONE: break; case AUTH_RMT_STATE_ERROR: default: client->phase = AUTH_PHASE_ERROR; }}static voidacl_hand_shake(struct iscsi_acl *client){ if (client->phase == AUTH_PHASE_DONE) /* * Should only happen if authentication * protocol error occured. */ return; if (client->node_type == TYPE_INITIATOR) /* * Target should only have set T bit on response if * initiator set it on previous message. */ if (client->recv_key_block.transit_bit && !client->transit_bit_sent_flag) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_T_BIT_SET_ILLEGAL; return; } if (client->phase == AUTH_PHASE_NEGOTIATE) { /* * Should only happen if waiting for peer * to send AuthMethod key or set Transit Bit. */ if (client->node_type == TYPE_INITIATOR) client->send_key_block.transit_bit = 1; return; } if (client->rmt_state == AUTH_RMT_STATE_RECV_RSP || client->rmt_state == AUTH_RMT_STATE_DONE) { if (client->node_type == TYPE_INITIATOR) { if (client->recv_key_block.transit_bit) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -