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

📄 iscsi-auth-client.c

📁 ISCSI user client software.Client would be used to access the IPSAN server.
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	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 + -