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

📄 iscsid.c

📁 iscsi企业级target.很好用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com> * * Released under the terms of the GNU GPL v2.0. */#include <ctype.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include "iscsid.h"static struct iscsi_key login_keys[] = {	{"InitiatorName",},	{"InitiatorAlias",},	{"SessionType",},	{"TargetName",},	{NULL, 0, 0, 0, NULL},};char *text_key_find(struct connection *conn, char *searchKey){	char *data, *key, *value;	int keylen, datasize;	keylen = strlen(searchKey);	data = conn->req.data;	datasize = conn->req.datasize;	while (1) {		for (key = data; datasize > 0 && *data != '='; data++, datasize--)			;		if (!datasize)			return NULL;		data++;		datasize--;		for (value = data; datasize > 0 && *data != 0; data++, datasize--)			;		if (!datasize)			return NULL;		data++;		datasize--;		if (keylen == value - key - 1		     && !strncmp(key, searchKey, keylen))			return value;	}}static char *next_key(char **data, int *datasize, char **value){	char *key, *p, *q;	int size = *datasize;	key = p = *data;	for (; size > 0 && *p != '='; p++, size--)		;	if (!size)		return NULL;	*p++ = 0;	size--;	for (q = p; size > 0 && *p != 0; p++, size--)		;	if (!size)		return NULL;	p++;	size--;	*data = p;	*value = q;	*datasize = size;	return key;}void text_key_add(struct connection *conn, char *key, char *value){	int keylen = strlen(key);	int valuelen = strlen(value);	int len = keylen + valuelen + 2;	char *buffer;	if (!conn->rsp.datasize) {		if (!conn->rsp_buffer)			conn->rsp_buffer = malloc(INCOMING_BUFSIZE);		conn->rsp.data = conn->rsp_buffer;	}	if (conn->rwsize + len > INCOMING_BUFSIZE) {		log_warning("Dropping key (%s=%s)", key, value);		return;	}	buffer = conn->rsp_buffer;	buffer += conn->rsp.datasize;	conn->rsp.datasize += len;	strcpy(buffer, key);	buffer += keylen;	*buffer++ = '=';	strcpy(buffer, value);}static void text_key_add_reject(struct connection *conn, char *key){	text_key_add(conn, key, "Reject");}static int account_empty(u32 tid, int dir){	char pass[ISCSI_NAME_LEN];	memset(pass, 0, sizeof(pass));	return cops->account_query(tid, dir, pass, pass) < 0 ? 1 : 0;}static void text_scan_security(struct connection *conn){	struct iscsi_login_rsp_hdr *rsp = (struct iscsi_login_rsp_hdr *)&conn->rsp.bhs;	char *key, *value, *data, *nextValue;	int datasize;	data = conn->req.data;	datasize = conn->req.datasize;	while ((key = next_key(&data, &datasize, &value))) {		if (!(param_index_by_name(key, login_keys) < 0))			;		else if (!strcmp(key, "AuthMethod")) {			do {				nextValue = strchr(value, ',');				if (nextValue)					*nextValue++ = 0;				if (!strcmp(value, "None")) {					if (!account_empty(conn->tid, AUTH_DIR_INCOMING))						continue;					conn->auth_method = AUTH_NONE;					text_key_add(conn, key, "None");					break;				} else if (!strcmp(value, "CHAP")) {					if (account_empty(conn->tid, AUTH_DIR_INCOMING))						continue;					conn->auth_method = AUTH_CHAP;					text_key_add(conn, key, "CHAP");					break;				}			} while ((value = nextValue));			if (conn->auth_method == AUTH_UNKNOWN)				text_key_add_reject(conn, key);		} else			text_key_add(conn, key, "NotUnderstood");	}	if (conn->auth_method == AUTH_UNKNOWN) {		rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;		rsp->status_detail = ISCSI_STATUS_AUTH_FAILED;		conn->state = STATE_EXIT;	}}static void login_security_done(struct connection *conn){	int err;	struct iscsi_login_req_hdr *req = (struct iscsi_login_req_hdr *)&conn->req.bhs;	struct iscsi_login_rsp_hdr *rsp = (struct iscsi_login_rsp_hdr *)&conn->rsp.bhs;	struct session *session;	if (!conn->tid)		return;	if ((session = session_find_name(conn->tid, conn->initiator, req->sid))) {		if (!req->sid.id.tsih) {			/* do session reinstatement */			session_conns_close(conn->tid, session->sid.id64);			session = NULL;		} else if (req->sid.id.tsih != session->sid.id.tsih) {			/* fail the login */			rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;			rsp->status_detail = ISCSI_STATUS_SESSION_NOT_FOUND;			conn->state = STATE_EXIT;			return;		} else if ((err = conn_test(conn)) == -ENOENT) {			/* do connection reinstatement */		}		/* add a new connection to the session */		conn->session = session;	} else {		if (req->sid.id.tsih) {			/* fail the login */			rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;			rsp->status_detail = ISCSI_STATUS_SESSION_NOT_FOUND;			conn->state = STATE_EXIT;			return;		}		/* instantiate a new session */	}}static void text_scan_login(struct connection *conn){	char *key, *value, *data;	int datasize, idx;	struct iscsi_login_rsp_hdr *rsp = (struct iscsi_login_rsp_hdr *)&conn->rsp.bhs;	data = conn->req.data;	datasize = conn->req.datasize;	while ((key = next_key(&data, &datasize, &value))) {		if (!(param_index_by_name(key, login_keys) < 0))			;		else if (!strcmp(key, "AuthMethod"))			;		else if (!((idx = param_index_by_name(key, session_keys)) < 0)) {			int err;			unsigned int val;			char buf[32];			if (idx == key_max_xmit_data_length) {				text_key_add(conn, key, "NotUnderstood");				continue;			}			if (idx == key_max_recv_data_length)				idx = key_max_xmit_data_length;			if (param_str_to_val(session_keys, idx, value, &val) < 0) {				if (conn->session_param[idx].state				    == KEY_STATE_START) {					text_key_add_reject(conn, key);					continue;				} else {					rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;					rsp->status_detail = ISCSI_STATUS_INIT_ERR;					conn->state = STATE_EXIT;					goto out;				}			}			err = param_check_val(session_keys, idx, &val);			err = param_set_val(session_keys, conn->session_param, idx, &val);			switch (conn->session_param[idx].state) {			case KEY_STATE_START:				if (idx == key_max_xmit_data_length)					break;				memset(buf, 0, sizeof(buf));				param_val_to_str(session_keys, idx, val, buf);				text_key_add(conn, key, buf);				break;			case KEY_STATE_REQUEST:				if (val != conn->session_param[idx].val) {					rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;					rsp->status_detail = ISCSI_STATUS_INIT_ERR;					conn->state = STATE_EXIT;					log_warning("%s %u %u\n", key,					val, conn->session_param[idx].val);					goto out;				}				break;			case KEY_STATE_DONE:				break;			}			conn->session_param[idx].state = KEY_STATE_DONE;		} else			text_key_add(conn, key, "NotUnderstood");	}out:	return;}static int text_check_param(struct connection *conn){	struct iscsi_param *p = conn->session_param;	char buf[32];	int i, cnt;	for (i = 0, cnt = 0; session_keys[i].name; i++) {		if (p[i].state == KEY_STATE_START && p[i].val != session_keys[i].def) {			switch (conn->state) {			case STATE_LOGIN_FULL:			case STATE_SECURITY_FULL:				if (i == key_max_xmit_data_length) {					if (p[i].val > session_keys[i].def)						p[i].val = session_keys[i].def;					p[i].state = KEY_STATE_DONE;					continue;				}				break;			case STATE_LOGIN:				if (i == key_max_xmit_data_length)					continue;				memset(buf, 0, sizeof(buf));				param_val_to_str(session_keys, i, p[i].val,						 buf);				text_key_add(conn, session_keys[i].name, buf);				p[i].state = KEY_STATE_REQUEST;				break;			default:				if (i == key_max_xmit_data_length)					continue;			}			cnt++;		}	}	return cnt;}static void login_start(struct connection *conn){	struct iscsi_login_req_hdr *req = (struct iscsi_login_req_hdr *)&conn->req.bhs;	struct iscsi_login_rsp_hdr *rsp = (struct iscsi_login_rsp_hdr *)&conn->rsp.bhs;	char *name, *alias, *session_type, *target_name;	conn->cid = be16_to_cpu(req->cid);	conn->sid.id64 = req->sid.id64;	if (!conn->sid.id64) {		rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;		rsp->status_detail = ISCSI_STATUS_MISSING_FIELDS;		conn->state = STATE_EXIT;		return;	}	name = text_key_find(conn, "InitiatorName");	if (!name) {		rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;		rsp->status_detail = ISCSI_STATUS_MISSING_FIELDS;		conn->state = STATE_EXIT;		return;	}	conn->initiator = strdup(name);	alias = text_key_find(conn, "InitiatorAlias");	session_type = text_key_find(conn, "SessionType");	target_name = text_key_find(conn, "TargetName");	conn->auth_method = -1;	conn->session_type = SESSION_NORMAL;	if (session_type) {		if (!strcmp(session_type, "Discovery"))			conn->session_type = SESSION_DISCOVERY;		else if (strcmp(session_type, "Normal")) {			rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;			rsp->status_detail = ISCSI_STATUS_INV_SESSION_TYPE;			conn->state = STATE_EXIT;			return;		}	}	if (conn->session_type == SESSION_NORMAL) {		if (!target_name) {			rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;			rsp->status_detail = ISCSI_STATUS_MISSING_FIELDS;			conn->state = STATE_EXIT;			return;		}		if (!(conn->tid = target_find_by_name(target_name)) ||		    cops->initiator_access(conn->tid, conn->fd) < 0) {			rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;			rsp->status_detail = ISCSI_STATUS_TGT_NOT_FOUND;

⌨️ 快捷键说明

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