📄 iscsi-auth-client.c
字号:
if (client->rmt_state != AUTH_RMT_STATE_DONE) goto recv_transit_bit_err; acl_next_phase(client); } else client->send_key_block.transit_bit = 1; } else { if (client->rmt_state == AUTH_RMT_STATE_DONE && client->rmt_auth_status != AUTH_STATUS_PASS) /* * Authentication failed, don't do T bit * handshake. */ acl_next_phase(client); else { /* * Target can only set T bit on response if * initiator set it on current message. */ if (client->recv_key_block.transit_bit) { client->send_key_block.transit_bit = 1; acl_next_phase(client); } } } } else if (client->node_type == TYPE_INITIATOR) if (client->recv_key_block.transit_bit) goto recv_transit_bit_err; return; recv_transit_bit_err: /* * Target set T bit on response but * initiator was not done with authentication. */ client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_T_BIT_SET_PREMATURE;}static intacl_rcv_end_status(struct iscsi_acl *client){ int auth_status; int key_type; if (client->phase == AUTH_PHASE_ERROR) return AUTH_STATUS_ERROR; if (client->phase == AUTH_PHASE_DONE) { /* Perform sanity check against configured parameters. */ if (client->auth_rmt && !client->auth_rsp_flag && client->rmt_auth_status == AUTH_STATUS_PASS) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->dbg_status = AUTH_DBG_STATUS_AUTHPASS_NOT_VALID; } auth_status = client->rmt_auth_status; } else auth_status = AUTH_STATUS_CONTINUE; if (auth_status == AUTH_STATUS_CONTINUE || auth_status == AUTH_STATUS_PASS) { if (client->send_key_block.dup_set) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_SEND_DUP_SET_KEY_VALUE; auth_status = AUTH_STATUS_FAIL; } else if (client->send_key_block.str_too_long) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_SEND_STR_TOO_LONG; auth_status = AUTH_STATUS_FAIL; } else if (client->send_key_block.too_much_data) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_SEND_TOO_MUCH_DATA; auth_status = AUTH_STATUS_FAIL; } else { /* Check that all incoming keys have been processed. */ for (key_type = AUTH_KEY_TYPE_FIRST; key_type < AUTH_KEY_TYPE_MAX_COUNT; key_type++) if (client->recv_key_block.key[key_type].present && !client->recv_key_block.key[key_type]. processed) break; if (key_type < AUTH_KEY_TYPE_MAX_COUNT) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_UNEXPECTED_KEY_PRESENT; auth_status = AUTH_STATUS_FAIL; } } } if (auth_status != AUTH_STATUS_PASS && auth_status != AUTH_STATUS_CONTINUE) { int auth_method_key_present = 0; int chap_alg_key_present = 0; /* * Suppress send keys on error, * except for AuthMethod and CHAP_A. */ if (client->node_type == TYPE_TARGET) { if (acl_get_key_val(&client->send_key_block, AUTH_KEY_TYPE_AUTH_METHOD)) auth_method_key_present = 1; else if (acl_get_key_val(&client->send_key_block, AUTH_KEY_TYPE_CHAP_ALG)) chap_alg_key_present = 1; } acl_init_key_blk(&client->send_key_block); if (client->node_type == TYPE_TARGET) { if (auth_method_key_present && client->negotiated_auth_method == AUTH_OPTION_REJECT) acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_AUTH_METHOD, acl_reject_option_name); else if (chap_alg_key_present && client->negotiated_chap_alg == AUTH_OPTION_REJECT) acl_set_key_value(&client->send_key_block, AUTH_KEY_TYPE_CHAP_ALG, acl_reject_option_name); } } client->recv_in_progress_flag = 0; return auth_status;}intacl_recv_begin(struct iscsi_acl *client){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase == AUTH_PHASE_ERROR) return AUTH_STATUS_ERROR; if (client->phase == AUTH_PHASE_DONE) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } if (client->recv_in_progress_flag) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } client->recv_in_progress_flag = 1; if (client->phase == AUTH_PHASE_CONFIGURE) acl_next_phase(client); client->transit_bit_sent_flag = client->send_key_block.transit_bit; acl_init_key_blk(&client->recv_key_block); acl_init_key_blk(&client->send_key_block); return AUTH_STATUS_NO_ERROR;}intacl_recv_end(struct iscsi_acl *client){ int next_phase_flag = 0; if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase == AUTH_PHASE_ERROR) return AUTH_STATUS_ERROR; if (!client->recv_in_progress_flag) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } if (client->recv_end_count > AUTH_RECV_END_MAX_COUNT) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_RECV_MSG_COUNT_LIMIT; } else if (client->recv_key_block.dup_set) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_RECV_DUP_SET_KEY_VALUE; } else if (client->recv_key_block.str_too_long) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_RECV_STR_TOO_LONG; } else if (client->recv_key_block.too_much_data) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_RECV_TOO_MUCH_DATA; } client->recv_end_count++; switch (client->phase) { case AUTH_PHASE_NEGOTIATE: acl_chk_auth_method_key(client); if (client->auth_method_valid_neg_role == AUTH_NEG_ROLE_RESPONDER) { if (client->negotiated_auth_method == AUTH_OPTION_NOT_PRESENT) { if (client->auth_rmt || !client->recv_key_block.transit_bit) { /* * No AuthMethod key from peer on * first message, try moving the * process along by sending the * AuthMethod key. */ 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); break; } /* * Special case if peer sent no AuthMethod key, * but did set Transit Bit, allowing this side * to do a null authentication, and compelete * the iSCSI security phase without either side * sending the AuthMethod key. */ } else /* Send response to AuthMethod key. */ acl_set_auth_method_key(client, 1, &client->negotiated_auth_method); if (client->node_type == TYPE_INITIATOR) acl_next_phase(client); else next_phase_flag = 1; } else { if (client->negotiated_auth_method == AUTH_OPTION_NOT_PRESENT) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; client->dbg_status = AUTH_DBG_STATUS_AUTH_METHOD_EXPECTED; break; } acl_next_phase(client); } break; case AUTH_PHASE_AUTHENTICATE: case AUTH_PHASE_DONE: break; default: client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } switch (client->phase) { case AUTH_PHASE_NEGOTIATE: if (next_phase_flag) acl_next_phase(client); break; case AUTH_PHASE_AUTHENTICATE: /* * Must call acl_local_auth() * before acl_rmt_auth() * to insure processing of the CHAP algorithm key, * and to avoid leaving an in progress request to the * authentication service. */ acl_local_auth(client); if (client->local_state != AUTH_LOCAL_STATE_ERROR) acl_rmt_auth(client); if (client->local_state == AUTH_LOCAL_STATE_ERROR || client->rmt_state == AUTH_RMT_STATE_ERROR) { client->rmt_auth_status = AUTH_STATUS_FAIL; client->phase = AUTH_PHASE_DONE; /* client->dbg_status should already be set. */ } break; case AUTH_PHASE_DONE: break; default: client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } acl_hand_shake(client); return acl_rcv_end_status(client);}const char *acl_get_key_name(int key_type){ /* * Note: The ordering of this table must match the order * defined by enum auth_key_type in iscsi-auth-client.h. */ static char *const key_names[AUTH_KEY_TYPE_MAX_COUNT] = { "AuthMethod", "CHAP_A", "CHAP_N", "CHAP_R", "CHAP_I", "CHAP_C" }; if (key_type < AUTH_KEY_TYPE_FIRST || key_type > AUTH_KEY_TYPE_LAST) return 0; return key_names[key_type];}intacl_get_next_key_type(int *key_type){ if (*key_type >= AUTH_KEY_TYPE_LAST) return AUTH_STATUS_ERROR; if (*key_type < AUTH_KEY_TYPE_FIRST) *key_type = AUTH_KEY_TYPE_FIRST; else (*key_type)++; return AUTH_STATUS_NO_ERROR;}intacl_recv_key_value(struct iscsi_acl *client, int key_type, const char *user_key_val){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_NEGOTIATE && client->phase != AUTH_PHASE_AUTHENTICATE) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } if (key_type < AUTH_KEY_TYPE_FIRST || key_type > AUTH_KEY_TYPE_LAST) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } if (key_type == AUTH_KEY_TYPE_CHAP_CHALLENGE) { client->recv_chap_challenge.length = AUTH_LARGE_BINARY_MAX_LEN; client->recv_chap_challenge_status = acl_text_to_data(user_key_val, client->recv_chap_challenge.large_binary, &client->recv_chap_challenge.length); user_key_val = ""; } acl_set_key_value(&client->recv_key_block, key_type, user_key_val); return AUTH_STATUS_NO_ERROR;}intacl_send_key_val(struct iscsi_acl *client, int key_type, int *key_present, char *user_key_val, unsigned int max_length){ const char *key_val; if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_CONFIGURE && client->phase != AUTH_PHASE_NEGOTIATE && client->phase != AUTH_PHASE_AUTHENTICATE && client->phase != AUTH_PHASE_DONE) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } if (key_type < AUTH_KEY_TYPE_FIRST || key_type > AUTH_KEY_TYPE_LAST) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } key_val = acl_get_key_val(&client->send_key_block, key_type); if (key_val) { if (key_type == AUTH_KEY_TYPE_CHAP_CHALLENGE) { if (acl_data_to_text(client->send_chap_challenge.large_binary, client->send_chap_challenge.length, user_key_val, max_length)) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } } else if (strlcpy(user_key_val, key_val, max_length) >= max_length) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } *key_present = 1; } else *key_present = 0; return AUTH_STATUS_NO_ERROR;}intacl_recv_transit_bit(struct iscsi_acl *client, int value){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_NEGOTIATE && client->phase != AUTH_PHASE_AUTHENTICATE) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } if (value) client->recv_key_block.transit_bit = 1; else client->recv_key_block.transit_bit = 0; return AUTH_STATUS_NO_ERROR;}intacl_send_transit_bit(struct iscsi_acl *client, int *value){ if (!client || client->signature != ACL_SIGNATURE) return AUTH_STATUS_ERROR; if (client->phase != AUTH_PHASE_CONFIGURE && client->phase != AUTH_PHASE_NEGOTIATE && client->phase != AUTH_PHASE_AUTHENTICATE && client->phase != AUTH_PHASE_DONE) { client->phase = AUTH_PHASE_ERROR; return AUTH_STATUS_ERROR; } *value = client->send_key_block.transit_bit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -