📄 initiator_negotiate.c
字号:
int *count);/* When called, 1st login PDU is set up in outputpdu except for T, * NSG, CSG. Returns 1 for redirection, 0 for all other successes, * -1 for any error*/static intinitiator_security_phase(struct socket *sock, struct parameter_type p_param_tbl[MAX_CONFIG_PARAMS], struct auth_parameter_type p_auth_param, __u32 * cur_cmd_sn, int *exp_stat_sn, int *max_send_length, int noperational, __u32 who_called, struct generic_pdu *inputpdu, struct generic_pdu *outputpdu, int *target_version_max, int *target_version_active, __u32 connection_flags, __u64 * login_flags, struct unknown_key **unknown_key_list){ int add_length = 0; int retval = -1; /* assume we will fail */ struct parameter_type *auth_p = NULL; int count; __u32 got_value ; __u32 got_keys = 0; enum security_steps security_step = ss_initial; int result ; TRACE(TRACE_ENTER_LEAVE, "Enter initiator_security_phase\n"); /* offer no transition on first login pdu sent to target */ outputpdu->flags &= ~(CSG | NSG | T_BIT); add_length = scan_table_and_process(sock, p_param_tbl, SECURITY_PARAM | INFORMATIONAL_PARAM, 0, INITIATOR, inputpdu, outputpdu, connection_flags, login_flags); if (add_length < 0) { retval = add_length; goto out; } outputpdu->text_length = add_length; for (count = 0; count < LOOP_TIMES; count++) { TRACE(TRACE_DEBUG, "Send security login, key length %d\n", add_length); outputpdu->cmd_sn = cpu_to_be32(*cur_cmd_sn); TRACE(TRACE_ISCSI, "Send Login, ITT %u\n", ntohl(outputpdu->init_task_tag)); if (write_and_read (sock, inputpdu, outputpdu, target_version_max, target_version_active, connection_flags) < 0) { goto out; } if (inputpdu->status_class != 0x00) { TRACE_ERROR ("Login Reject from target, Class 0x%02x, Detail 0x%02x\n", inputpdu->status_class, inputpdu->status_detail); goto out; } *exp_stat_sn = be32_to_cpu(((struct iscsi_targ_login_rsp *) inputpdu)->stat_sn) + 1; outputpdu->exp_stat_sn = cpu_to_be32(*exp_stat_sn); /* assume we will want no transition on our next output pdu */ outputpdu->flags &= ~(CSG | NSG | T_BIT); /* Build next transmission PDU */ add_length = scan_input_and_process(sock, p_param_tbl, SECURITY_PARAM | INFORMATIONAL_PARAM, TARGETPORTALGROUPTAG_FLAG, INITIATOR, max_send_length, who_called, inputpdu, outputpdu, connection_flags, login_flags, unknown_key_list); if (add_length < 0) { retval = add_length; goto out; } outputpdu->text_length = add_length; TRACE(TRACE_ISCSI_FULL, "Initiator switch on security_step %d\n", security_step); switch (security_step) { case ss_initial: { TRACE(TRACE_ISCSI_FULL, "security_step %d\n", security_step); if ((result = ss_initial_func(&security_step, unknown_key_list, p_param_tbl, p_auth_param, noperational, auth_p, inputpdu, outputpdu )) < 0 ) { TRACE_ERROR("ss_initial_func -1\n"); goto out; } else if (result == 1) continue; else break; } break; case ss_find_chap_a_i_c: { // 718 /* previously sent CHAP_A list, * expecting CHAP_A, * CHAP_I, CHAP_C */ TRACE(TRACE_ISCSI_FULL, "security_step %d\n", security_step); if(ss_find_chap_a_i_c_func(&security_step, unknown_key_list, p_param_tbl, p_auth_param, noperational, auth_p, inputpdu, outputpdu, &got_keys, &got_value) < 0 ){ goto out; } } break ; case ss_find_chap_n_r: { /* expecting target to reply to * our previously sent challenge */ TRACE(TRACE_ISCSI_FULL, "security_step %d\n", security_step); if(ss_find_chap_n_r_func(&security_step, unknown_key_list, p_param_tbl, p_auth_param, noperational, inputpdu, outputpdu, &got_keys, &got_value, &count) < 0 ) { goto out; } } break; case ss_find_srp_g_s: { /* previously sent SRP_U, * expecting SRP_GROUP, SRP_s */ TRACE(TRACE_ISCSI_FULL, "security_step %d\n", security_step); if(ss_find_srp_g_s_func(&security_step, unknown_key_list, p_param_tbl, p_auth_param, noperational, inputpdu, outputpdu, &got_keys) < 0 ) { goto out; } } break; case ss_find_srp_b: { /* previously sent SRP_A and SRP_GROUP, * expecting SRP_B */ TRACE(TRACE_ISCSI_FULL, "security_step %d\n", security_step); if (ss_find_srp_b_func( &security_step, unknown_key_list, p_param_tbl, p_auth_param, noperational, inputpdu, outputpdu, &got_keys) < 0 ) { goto out; } } break; case ss_find_srp_h: { /* expecting target to send SRP_HM */ TRACE(TRACE_ISCSI_FULL, "security_step %d\n", security_step); if (ss_find_srp_h_func( &security_step, unknown_key_list, p_param_tbl, p_auth_param, noperational, inputpdu, outputpdu, &got_keys, &count) < 0 ) { goto out; } } break; case ss_done: { /* done with authentication * (may never have done any) */ TRACE(TRACE_ISCSI_FULL, "security_step %d\n", security_step); if (ss_done_func( &security_step, unknown_key_list, p_param_tbl, p_auth_param, noperational, inputpdu, outputpdu, &got_keys, &count) < 0 ) { goto out; } } break; default: /* should NEVER happen */ TRACE_ERROR("unknown security step %d\n", security_step); goto out; } /* switch */ } /* loop */ if (count == LOOP_TIMES) { TRACE_ERROR("infinite loop in security phase negotiations\n"); } else retval = 0; /* our pessimism was unjustified, we succeeded ! */ out: TRACE(TRACE_ENTER_LEAVE, "Leave initiator_security_phase, retval %d\n", retval); return retval;}/* * Setup up outgoing PDU to send AuthMethod */intss_initial_func(enum security_steps *security_step, struct unknown_key ** unknown_key_list, struct parameter_type *p_param_tbl, struct auth_parameter_type p_auth_param, int noperational, struct parameter_type *auth_p, struct generic_pdu *inputpdu, struct generic_pdu *outputpdu){ char *dummy_string; int got_bitmask; struct unknown_key *key; int temp_len; char *srp_u = NULL; struct SRP_Context *srp_ctx = NULL; struct CHAP_Context *init_ctx = NULL; struct CHAP_Context *targ_ctx = NULL; TRACE(TRACE_ENTER_LEAVE, "Enter ss_initial_func() \n"); ALLOCATE_MAX_TEXT_LEN(dummy_string); /* looking to find AuthMethod=CHAP or * AuthMethod=SRP * Also deal with unknown keys: CHAP, SRP * keys illegal in this state */ for (key = *unknown_key_list; key != NULL; key = key->next) { if (!key->processed) { key->processed = 1; if ((got_bitmask = print_bad_security_key(key))) { print_not_allowed_security_key(key); } goto out; } } if ((auth_p = find_flag_parameter(AUTHMETHOD_FLAG, p_param_tbl)) == NULL) { /* should NEVER happen */ TRACE_ERROR("AuthMethod parameter not found\n"); goto out; } if (!IS_KEY_GOT_FROM_OTHER_SIDE(auth_p->neg_info)) { /* Target did not send us an AuthMethod key, find out why */ if (!IS_KEY_SENT_TO_OTHER_SIDE(auth_p->neg_info)) { /* AuthMethod key not going to be negotiated */ *security_step = ss_done; if (noperational == 0) outputpdu->flags |= (NSG3 | T_BIT); else outputpdu->flags |= (NSG1 | T_BIT); } else { /* AuthMethod key sent but reply not received yet, stay in ss_initial state */ goto out_cont; } } else if (!strcmp(auth_p->str_value, NONE)) { /* not going to do authentication, offer transition */ *security_step = ss_done; if (noperational == 0) outputpdu->flags |= (NSG3 | T_BIT); else outputpdu->flags |= (NSG1 | T_BIT); } else if (!strcmp(auth_p->str_value, CHAP)) { /* start CHAP authentication */ TRACE(TRACE_DEBUG, "Start initiator chap authentication\n"); init_ctx = p_auth_param.chap_local_ctx; targ_ctx = p_auth_param.chap_peer_ctx; if (init_ctx == NULL || targ_ctx == NULL) { TRACE_ERROR("CHAP context not initialized yet\n"); goto out; } CHAP_SetAlgorithm(MD5_ALGORITHM, targ_ctx); CHAP_SetAlgorithm(MD5_ALGORITHM, init_ctx); temp_len = sprintf(dummy_string, "CHAP_A="); temp_len += CHAP_GetAlgorithmList(dummy_string + temp_len); TRACE(TRACE_ISCSI, "Attach key: %s\n", dummy_string); strcpy(outputpdu->text + outputpdu->text_length, dummy_string); outputpdu->text_length += temp_len + 1; *security_step = ss_find_chap_a_i_c; } else if (!strcmp(auth_p->str_value, SRP)) { /* start SRP authentication */ TRACE(TRACE_DEBUG, "Start initiator srp authentication\n"); srp_ctx = p_auth_param.srp_ctx; if (srp_ctx == NULL) { TRACE_ERROR("SRP context not initialized yet\n"); goto out; } /* look up SRP user name, error if none */ if ((srp_u = SRP_Initiator_GetUsername(srp_ctx)) == NULL) { TRACE_ERROR("uo User Name in SRP database\n"); goto out; } /* generate and attach key SRP_U=value */ temp_len = sprintf(dummy_string, "%s=%s", SRP_U, srp_u); TRACE(TRACE_ISCSI, "Attach key: %s\n", dummy_string); strcpy(outputpdu->text + outputpdu->text_length, dummy_string); outputpdu->text_length += temp_len + 1; my_kfree((void **) &srp_u, "SRP_U"); /* generate and attach key SRP_TargetAuth=value */ temp_len = sprintf(dummy_string, "%s=%s", SRP_TARGETAUTH, p_auth_param. auth_flags & USE_TARGET_CONFIRMATION ? YES : NO); TRACE(TRACE_ISCSI, "Attach key: %s\n", dummy_string); strcpy(outputpdu->text + outputpdu->text_length, dummy_string); outputpdu->text_length += temp_len + 1; *security_step = ss_find_srp_g_s; } else { /* should NEVER happen */ TRACE_ERROR ("unknown AuthMethod value \"%s\"\n", auth_p->str_value); goto out; } TRACE(TRACE_ENTER_LEAVE, "Leaving ss_initial_func() Success Next %d\n", *security_step); FREE_STRING(dummy_string); return 1;out_cont: TRACE(TRACE_ENTER_LEAVE, "Leaving ss_initial_func() Continue Next %d\n", *security_step); FREE_STRING(dummy_string); return 0;out: TRACE(TRACE_ENTER_LEAVE, "Leaving ss_initial_func() Failure Next %d\n", *security_step); FREE_STRING(dummy_string); return -1;}intss_find_chap_a_i_c_func(enum security_steps *security_step, struct unknown_key ** unknown_key_list, struct parameter_type *p_param_tbl, struct auth_parameter_type p_auth_param, int noperational, struct parameter_type *auth_p, struct generic_pdu *inputpdu, struct generic_pdu *outputpdu, __u32 * got_keys, __u32 * got_value){ char *dummy_string; int got_bitmask; int add_length; struct unknown_key *key; int temp_len; char *our_chap_n = NULL; char *our_chap_c = NULL; char *our_chap_r = NULL; char *his_chap_c = NULL; __u8 chap_i = 0; struct CHAP_Context *init_ctx ; struct CHAP_Context *targ_ctx ; init_ctx = p_auth_param.chap_local_ctx; targ_ctx = p_auth_param.chap_peer_ctx; TRACE(TRACE_ENTER_LEAVE, "Enter ss_find_chap_a_i_c() \n"); ALLOCATE_MAX_TEXT_LEN(dummy_string); /* previously sent CHAP_A list, expecting CHAP_A, * CHAP_I, CHAP_C */ for (key = *unknown_key_list; key != NULL; key = key->next) { if (!key->processed) { key->processed = 1; got_bitmask = print_bad_security_key(key); if (got_bitmask == GOT_CHAP_A) { if (check_step_key_number (key, got_keys, GOT_CHAP_A, UINT_MAX, got_value)) goto out; if (!CHAP_SetAlgorithm(*got_value, targ_ctx) || !CHAP_SetAlgorithm(*got_value, init_ctx)) { TRACE_ERROR ("illegal %s algorithm \"%s\"\n", key->keyname, key->keyvalue); goto out; } } else if (got_bitmask == GOT_CHAP_I) { if (check_step_key_number (key, got_keys, GOT_CHAP_I, 255, got_value)) goto out; chap_i = *got_value; } else if (got_bitmask == GOT_CHAP_C) { if (check_step_key(key, got_keys, GOT_CHAP_C)) goto out; his_chap_c = key->keyvalue; } else { if (got_bitmask) { print_not_allowed_security_key(key); } goto out; } } } if ((*got_keys & (GOT_CHAP_A | GOT_CHAP_I | GOT_CHAP_C)) == (GOT_CHAP_A | GOT_CHAP_I | GOT_CHAP_C)) { /* have all target keys needed to respond
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -