⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 target_negotiate.c

📁 iscsi源代码 UNH的progect 有initiator端和target端的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	/* ok to use this tsih, it is unique */	session->tsih = new_tsih;	print_isid_tsih_message(session, "Created session with ");	up(&host->session_sem);out:	return;}static inttarget_check_login(struct iscsi_conn *conn,				   struct parameter_type p_param_tbl[MAX_CONFIG_PARAMS],				   struct generic_pdu *inputpdu,				   struct generic_pdu *outputpdu,				   __u32 when_called,				   int noperational,				   __u64 *login_flags,				   int *count, struct unknown_key **unknown_key_list){	int *max_send_length = &conn->max_send_length;	struct socket *sock = conn->conn_socket;	int retval = 0;	int correct_CSG = (inputpdu->flags & CSG) >> CSG_SHIFT;	int add_length;	int what_to_process;	TRACE(TRACE_DEBUG, "Enter target_check_login\n");	if ((inputpdu->opcode & ISCSI_OPCODE) != ISCSI_INIT_LOGIN_CMND) {		/* opcode just received is not a Login, but is should be! */		TRACE_ERROR("invalid opcode 0x%02x during login\n",					inputpdu->opcode & ISCSI_OPCODE);		login_reject(conn, STAT_CLASS_INITIATOR,					 STAT_DETAIL_INVALID_DURING_LOGIN, outputpdu);		retval = -1;		goto out;	}	TRACE(TRACE_ISCSI, "Got Login command, CSG %d, NSG %d, T %d\n",		  (inputpdu->flags & CSG) >> CSG_SHIFT, inputpdu->flags & NSG,		  (inputpdu->flags & T_BIT) >> 7);	if (TRACE_TEST(TRACE_ISCSI_FULL))		print_init_login_cmnd((struct iscsi_init_login_cmnd *)inputpdu);	/* check if the login has I bit set */	if (!(inputpdu->opcode & I_BIT)) {		/* protocol error  */		TRACE_ERROR("login request I bit not set!\n");		login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu);		retval = -1;		goto out;	}	/* check if the input CSG is valid */	if ((inputpdu->flags & CSG) >= CSG2) {		TRACE_ERROR("Invalid CSG %d should be 0 or 1\n",					(inputpdu->flags & CSG) >> CSG_SHIFT);		login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu);		retval = -1;		goto out;	}	/* check that initiator and target agree on the current stage */	if (((inputpdu->flags & CSG) >> CSG_SHIFT) != correct_CSG) {		/* protocol error */		TRACE_ERROR("Initiator state is %d, expected %d\n",					(inputpdu->flags & CSG) >> CSG_SHIFT, correct_CSG);		login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu);		retval = -1;		goto out;	}	/* check if the input NSG is valid:	   NSG can never be 2,	   NSG must be 0 if the T bit is 0,	   NSG must be greater than CSG if T bit is 1.	 */	if (inputpdu->flags & T_BIT) {		/* T bit is set, NSG must be valid */		if ((inputpdu->flags & NSG) == NSG2 ||		    (inputpdu->flags & NSG) <= ((inputpdu->flags & CSG) >> CSG_SHIFT)) {			TRACE_ERROR("invalid NSG %d\n", inputpdu->flags & NSG);			login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu);			retval = -1;			goto out;		}	} else {		/* T bit is not set, NSG should be 0 */		if (inputpdu->flags & NSG) {			TRACE_WARNING("T bit is 0 but NSG = %d, should be 0 (ignored)\n",							inputpdu->flags & NSG);		}	}	outputpdu->flags &= ~(CSG | NSG | T_BIT);	outputpdu->flags |= (inputpdu->flags & CSG);	/* RFC 3720 Section 10.12.3 CSG and NSG	 * "The next stage value is only valid when the T bit is 1;	 * otherwise, it is reserved."	 */	if (inputpdu->flags & T_BIT) {		outputpdu->flags |= (inputpdu->flags & NSG) | T_BIT;	}	if (*login_flags & FIRST_FLAG) {			/* this is the first login pdu of this login phase */		retval = check_first_login(conn, inputpdu, outputpdu);	} else {		/* this is not the first login pdu of this login phase */		retval = check_other_login(conn, correct_CSG, inputpdu, outputpdu);	}	if (retval < 0)		goto out;	if ((outputpdu->flags & CSG) == 0) {		/* now in security parameter negotiation stage */		what_to_process = SECURITY_PARAM | INFORMATIONAL_PARAM;		if (noperational > 0) {			/* we want to offer operational keys, force next stage to 1 */			inputpdu->flags &= ~NSG;			inputpdu->flags |= NSG1;		}	} else {							/* now in operational parameter negotiation stage */		what_to_process = OPERATIONAL_PARAM | INFORMATIONAL_PARAM;	}	*count += 1;				/* to avoid infinite loops */	if (*count >= LOOP_TIMES) {		TRACE_ERROR("Infinite loop in parameter negotiations\n");		login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu);		retval = -1;		goto out;	}	/* process each key attached to input */	add_length = scan_input_and_process(sock, p_param_tbl,										what_to_process,										TARGETNAME_FLAG | INITIATORNAME_FLAG |										SESSIONTYPE_FLAG, TARGET,										max_send_length, when_called, inputpdu,										outputpdu, conn->connection_flags,										login_flags, unknown_key_list);	if (add_length < 0) {		login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu);		retval = add_length;		goto out;	}	/* check that initial login includes initiator name, target name */	if ((*login_flags) & FIRST_FLAG) {		if (check_flags(conn, *login_flags, outputpdu, p_param_tbl) < 0) {			retval = -1;			goto out;		}	}	outputpdu->text_length = add_length;	/* scan through our table and make any offers */	add_length = scan_table_and_process(sock, p_param_tbl,										what_to_process, 0,										TARGET,										inputpdu, outputpdu,										conn->connection_flags, login_flags);	if (add_length < 0) {		login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR, outputpdu);		retval = add_length;		goto out;	}	outputpdu->text_length += add_length;	/*  after finishing attaching all keys to output */	if (outputpdu->flags & T_BIT) {			/* check whether all parameters that were sent in this stage		 * have received their responses 		 */		if (check_neg_responses(p_param_tbl, 0) < 0) {			if (*count < LOOP_TIMES - 1) {					/* reset the T bit to be 0 for more negotiations */				outputpdu->flags &= (~T_BIT);				outputpdu->flags &= (~NSG);			} else {							/* It seems the initiator doesn't reply the key */				/* error */				TRACE_ERROR("Target didn't receive all the responses\n");				login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR,							 outputpdu);				retval = -1;				goto out;			}		} else {			/* output.NSG = input.NSG, we will change to the next state now */			outputpdu->flags &= (~NSG);			outputpdu->flags |= inputpdu->flags & NSG;		}	} else {		/* not changing the state */		outputpdu->flags &= (~NSG);	}	outputpdu->status_class = 0;	outputpdu->status_detail = 0;	outputpdu->cmd_sn = cpu_to_be32(conn->stat_sn + 1);	outputpdu->exp_stat_sn = cpu_to_be32(conn->session->exp_cmd_sn);	outputpdu->max_cmd_sn = cpu_to_be32(conn->session->max_cmd_sn);	/* For a new session TSIH MUST be set by the target in the final	   response and MUST be 0 otherwise */	if (((inputpdu->tsih) == 0) && (!(inputpdu->flags & T_BIT)									|| (inputpdu->flags & NSG) != NSG3									|| !(outputpdu->flags & T_BIT)									|| (outputpdu->flags & NSG) != NSG3)) {		outputpdu->tsih = 0;	} else {		/* last LoginResponse in new session,		 * check for session reinstatement and assign a new tsih to session		 */		if (inputpdu->tsih == 0)			finalize_new_session(conn->session);		outputpdu->tsih = cpu_to_be16(conn->session->tsih);	}out:	TRACE(TRACE_DEBUG, "Leave target_check_login, retval %d\n", retval);	return retval;}/*	states to drive authentication steps during security phase */enum security_steps {	ss_initial,	ss_find_chap_a, 	ss_find_chap_n_r, 	ss_find_chap_i_c,	ss_find_srp_u, 	ss_find_srp_a_g, 	ss_find_srp_m,	ss_done, 	ss_leave,	ss_error};/*	returns 0 on success, -1 on error */intno_security_key_allowed(struct iscsi_conn *conn,						struct generic_pdu *outputpdu,						struct unknown_key *unknown_key_list){	int retval = 0;	struct unknown_key *key;	for (key = unknown_key_list; key != NULL; key = key->next) {		if (is_securitykey(key->keyname)) {			print_not_allowed_security_key(key);			retval = -1;			login_reject(conn, STAT_CLASS_INITIATOR, STAT_DETAIL_ERR,						 outputpdu);			goto out;		}	}  out:	return retval;}voidattach_key_int(struct generic_pdu *outputpdu, char *key_name, int key_int){	int tmp_len;	tmp_len = sprintf(outputpdu->text + outputpdu->text_length, "%s=%d",					  key_name, key_int);	TRACE(TRACE_ISCSI, "attach key %s\n",		  outputpdu->text + outputpdu->text_length);	outputpdu->text_length += tmp_len + 1;}voidattach_key_string(struct generic_pdu *outputpdu, char *key_name,				  char *key_string){	int tmp_len;	tmp_len = sprintf(outputpdu->text + outputpdu->text_length, "%s=%s",					  key_name, key_string);	TRACE(TRACE_ISCSI, "attach key %s\n",		  outputpdu->text + outputpdu->text_length);	outputpdu->text_length += tmp_len + 1;}voidcheck_authmethod(struct parameter_type *auth_p,				 struct generic_pdu *outputpdu,				 enum security_steps *security_step){	if (IS_KEY_GOT_FROM_OTHER_SIDE(auth_p->neg_info)) {			/* initiator has sent AuthMethod offer/reply, check it */		if (!strcmp(auth_p->str_value, CHAP))			*security_step = ss_find_chap_a;		else if (!strcmp(auth_p->str_value, SRP))			*security_step = ss_find_srp_u;		else if (outputpdu->flags & T_BIT)			*security_step = ss_leave;		else			*security_step = ss_done;	} else if (outputpdu->flags & T_BIT)		*security_step = ss_leave;	/* else leave security_step value unchanged */}static inttarget_security_negotiate(struct iscsi_conn *conn,						  struct parameter_type p_param_tbl[MAX_CONFIG_PARAMS],						  struct generic_pdu *inputpdu,						  struct generic_pdu *outputpdu,						  __u32 when_called,						  __u64 *login_flags,						  int noperational,						  struct auth_parameter_type auth_param,						  struct unknown_key **unknown_key_list){	struct socket *sock = conn->conn_socket;	int retval = 0;	int padding = 0;	struct parameter_type *auth_p;	char *dummy_string;	struct unknown_key *key, *key_next, **key_prev;	int count = 0;	__u32 neg_flags = 0, got_bitmask;	char *chap_r = NULL;	char *chap_c = NULL;	int chap_a = 0;	int chap_i = 0;	char *chap_n;	__u32 value;	enum security_steps security_step = ss_initial;	int target_auth = 0;	char *srp_grouplist = NULL;	char *srp_s = NULL;	char *srp_b = NULL;	char *srp_u = NULL;	char *srp_hm;	ALLOCATE_MAX_TEXT_LEN(dummy_string);	TRACE(TRACE_DEBUG, "Entering target security negotiate\n");	if ((auth_p = find_flag_parameter(AUTHMETHOD_FLAG, p_param_tbl)) == NULL) {		/* should NEVER happen */		TRACE_ERROR("AuthMethod parameter not found\n");		retval = -1;		goto out;	}	if (target_check_login(conn,						   p_param_tbl,						   inputpdu,						   outputpdu,						   when_called,						   noperational,						   login_flags,						   &count, unknown_key_list) < 0) {		TRACE_ERROR("check login failed\n");		retval = -1;		goto out;	}	if (no_security_key_allowed(conn, outputpdu, *unknown_key_list))		goto out;	if (iscsi_send_msg(sock, outputpdu, conn->connection_flags) < 0) {		TRACE(TRACE_DEBUG, "iscsi_send_msg failed\n");		retval = -1;		goto out;	} else {		conn->stat_sn++;	}	outputpdu->text_length = 0;	*login_flags &= ~FIRST_FLAG;	check_authmethod(auth_p, outputpdu, &security_step);	while ((outputpdu->flags & NSG) != NSG3) {		if (iscsi_recv_msg(sock, ISCSI_HDR_LEN, (char *) inputpdu,						   conn->connection_flags) < 0) {			TRACE(TRACE_DEBUG, "iscsi_recv_msg failed\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -