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

📄 tncs.c

📁 IEEE 802.11a/b/g 服务器端AP
💻 C
📖 第 1 页 / 共 2 页
字号:
		res = imv->SolicitRecommendation(imv->imvID,						 tncs->connectionID);		wpa_printf(MSG_DEBUG, "TNC: SolicitRecommendation: %lu",			   (unsigned long) res);	}}void tncs_init_connection(struct tncs_data *tncs){	struct tnc_if_imv *imv;	int i;	for (imv = tncs->imv; imv; imv = imv->next) {		tncs_imv_notify_connection_change(			imv, tncs->connectionID, TNC_CONNECTION_STATE_CREATE);		tncs_imv_notify_connection_change(			imv, tncs->connectionID,			TNC_CONNECTION_STATE_HANDSHAKE);	}	for (i = 0; i < TNC_MAX_IMV_ID; i++) {		os_free(tncs->imv_data[i].imv_send);		tncs->imv_data[i].imv_send = NULL;		tncs->imv_data[i].imv_send_len = 0;	}}size_t tncs_total_send_len(struct tncs_data *tncs){	int i;	size_t len = 0;	for (i = 0; i < TNC_MAX_IMV_ID; i++)		len += tncs->imv_data[i].imv_send_len;	if (tncs->tncs_message)		len += os_strlen(tncs->tncs_message);	return len;}u8 * tncs_copy_send_buf(struct tncs_data *tncs, u8 *pos){	int i;	for (i = 0; i < TNC_MAX_IMV_ID; i++) {		if (tncs->imv_data[i].imv_send == NULL)			continue;		os_memcpy(pos, tncs->imv_data[i].imv_send,			  tncs->imv_data[i].imv_send_len);		pos += tncs->imv_data[i].imv_send_len;		os_free(tncs->imv_data[i].imv_send);		tncs->imv_data[i].imv_send = NULL;		tncs->imv_data[i].imv_send_len = 0;	}	if (tncs->tncs_message) {		size_t len = os_strlen(tncs->tncs_message);		os_memcpy(pos, tncs->tncs_message, len);		pos += len;		os_free(tncs->tncs_message);		tncs->tncs_message = NULL;	}	return pos;}char * tncs_if_tnccs_start(struct tncs_data *tncs){	char *buf = os_malloc(1000);	if (buf == NULL)		return NULL;	tncs->last_batchid++;	os_snprintf(buf, 1000, IF_TNCCS_START, tncs->last_batchid);	return buf;}char * tncs_if_tnccs_end(void){	char *buf = os_malloc(100);	if (buf == NULL)		return NULL;	os_snprintf(buf, 100, IF_TNCCS_END);	return buf;}static int tncs_get_type(char *start, unsigned int *type){	char *pos = os_strstr(start, "<Type>");	if (pos == NULL)		return -1;	pos += 6;	*type = strtoul(pos, NULL, 16);	return 0;}static unsigned char * tncs_get_base64(char *start, size_t *decoded_len){	char *pos, *pos2;	unsigned char *decoded;	pos = os_strstr(start, "<Base64>");	if (pos == NULL)		return NULL;	pos += 8;	pos2 = os_strstr(pos, "</Base64>");	if (pos2 == NULL)		return NULL;	*pos2 = '\0';	decoded = base64_decode((unsigned char *) pos, os_strlen(pos),				decoded_len);	*pos2 = '<';	if (decoded == NULL) {		wpa_printf(MSG_DEBUG, "TNC: Failed to decode Base64 data");	}	return decoded;}static enum tncs_process_res tncs_derive_recommendation(struct tncs_data *tncs){	enum IMV_Action_Recommendation rec;	struct tnc_if_imv *imv;	TNC_ConnectionState state;	char *txt;	wpa_printf(MSG_DEBUG, "TNC: No more messages from IMVs");	if (tncs->done)		return TNCCS_PROCESS_OK_NO_RECOMMENDATION;	tncs_solicit_recommendation(tncs);	/* Select the most restrictive recommendation */	rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;	for (imv = tncs->imv; imv; imv = imv->next) {		TNC_IMV_Action_Recommendation irec;		irec = tncs->imv_data[imv->imvID].recommendation;		if (irec == TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS)			rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS;		if (irec == TNC_IMV_ACTION_RECOMMENDATION_ISOLATE &&		    rec != TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS)			rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE;		if (irec == TNC_IMV_ACTION_RECOMMENDATION_ALLOW &&		    rec == TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION)			rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;	}	wpa_printf(MSG_DEBUG, "TNC: Recommendation: %d", rec);	tncs->recommendation = rec;	tncs->done = 1;	txt = NULL;	switch (rec) {	case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:	case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:		txt = "allow";		state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;		break;	case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:		txt = "isolate";		state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;		break;	case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:		txt = "none";		state = TNC_CONNECTION_STATE_ACCESS_NONE;		break;	default:		state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;		break;	}	if (txt) {		os_free(tncs->tncs_message);		tncs->tncs_message = os_zalloc(200);		if (tncs->tncs_message) {			os_snprintf(tncs->tncs_message, 199,				    "<TNCC-TNCS-Message><Type>%08X</Type>"				    "<XML><TNCCS-Recommendation type=\"%s\">"				    "</TNCCS-Recommendation></XML>"				    "</TNCC-TNCS-Message>",				    TNC_TNCCS_RECOMMENDATION, txt);		}	}	for (imv = tncs->imv; imv; imv = imv->next) {		tncs_imv_notify_connection_change(imv, tncs->connectionID,						  state);	}	switch (rec) {	case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:		return TNCCS_RECOMMENDATION_ALLOW;	case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:		return TNCCS_RECOMMENDATION_NO_ACCESS;	case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:		return TNCCS_RECOMMENDATION_ISOLATE;	case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:		return TNCCS_RECOMMENDATION_NO_RECOMMENDATION;	default:		return TNCCS_PROCESS_ERROR;	}}enum tncs_process_res tncs_process_if_tnccs(struct tncs_data *tncs,					    const u8 *msg, size_t len){	char *buf, *start, *end, *pos, *pos2, *payload;	unsigned int batch_id;	unsigned char *decoded;	size_t decoded_len;	buf = os_malloc(len + 1);	if (buf == NULL)		return TNCCS_PROCESS_ERROR;	os_memcpy(buf, msg, len);	buf[len] = '\0';	start = os_strstr(buf, "<TNCCS-Batch ");	end = os_strstr(buf, "</TNCCS-Batch>");	if (start == NULL || end == NULL || start > end) {		os_free(buf);		return TNCCS_PROCESS_ERROR;	}	start += 13;	while (*start == ' ')		start++;	*end = '\0';	pos = os_strstr(start, "BatchId=");	if (pos == NULL) {		os_free(buf);		return TNCCS_PROCESS_ERROR;	}	pos += 8;	if (*pos == '"')		pos++;	batch_id = atoi(pos);	wpa_printf(MSG_DEBUG, "TNC: Received IF-TNCCS BatchId=%u",		   batch_id);	if (batch_id != tncs->last_batchid + 1) {		wpa_printf(MSG_DEBUG, "TNC: Unexpected IF-TNCCS BatchId "			   "%u (expected %u)",			   batch_id, tncs->last_batchid + 1);		os_free(buf);		return TNCCS_PROCESS_ERROR;	}	tncs->last_batchid = batch_id;	while (*pos != '\0' && *pos != '>')		pos++;	if (*pos == '\0') {		os_free(buf);		return TNCCS_PROCESS_ERROR;	}	pos++;	payload = start;	/*	 * <IMC-IMV-Message>	 * <Type>01234567</Type>	 * <Base64>foo==</Base64>	 * </IMC-IMV-Message>	 */	while (*start) {		char *endpos;		unsigned int type;		pos = os_strstr(start, "<IMC-IMV-Message>");		if (pos == NULL)			break;		start = pos + 17;		end = os_strstr(start, "</IMC-IMV-Message>");		if (end == NULL)			break;		*end = '\0';		endpos = end;		end += 18;		if (tncs_get_type(start, &type) < 0) {			*endpos = '<';			start = end;			continue;		}		wpa_printf(MSG_DEBUG, "TNC: IMC-IMV-Message Type 0x%x", type);		decoded = tncs_get_base64(start, &decoded_len);		if (decoded == NULL) {			*endpos = '<';			start = end;			continue;		}		tncs_send_to_imvs(tncs, type, decoded, decoded_len);		os_free(decoded);		start = end;	}	/*	 * <TNCC-TNCS-Message>	 * <Type>01234567</Type>	 * <XML><TNCCS-Foo type="foo"></TNCCS-Foo></XML>	 * <Base64>foo==</Base64>	 * </TNCC-TNCS-Message>	 */	start = payload;	while (*start) {		unsigned int type;		char *xml, *xmlend, *endpos;		pos = os_strstr(start, "<TNCC-TNCS-Message>");		if (pos == NULL)			break;		start = pos + 19;		end = os_strstr(start, "</TNCC-TNCS-Message>");		if (end == NULL)			break;		*end = '\0';		endpos = end;		end += 20;		if (tncs_get_type(start, &type) < 0) {			*endpos = '<';			start = end;			continue;		}		wpa_printf(MSG_DEBUG, "TNC: TNCC-TNCS-Message Type 0x%x",			   type);		/* Base64 OR XML */		decoded = NULL;		xml = NULL;		xmlend = NULL;		pos = os_strstr(start, "<XML>");		if (pos) {			pos += 5;			pos2 = os_strstr(pos, "</XML>");			if (pos2 == NULL) {				*endpos = '<';				start = end;				continue;			}			xmlend = pos2;			xml = pos;		} else {			decoded = tncs_get_base64(start, &decoded_len);			if (decoded == NULL) {				*endpos = '<';				start = end;				continue;			}		}		if (decoded) {			wpa_hexdump_ascii(MSG_MSGDUMP,					  "TNC: TNCC-TNCS-Message Base64",					  decoded, decoded_len);			os_free(decoded);		}		if (xml) {			wpa_hexdump_ascii(MSG_MSGDUMP,					  "TNC: TNCC-TNCS-Message XML",					  (unsigned char *) xml,					  xmlend - xml);		}		start = end;	}	os_free(buf);	tncs_batch_ending(tncs);	if (tncs_total_send_len(tncs) == 0)		return tncs_derive_recommendation(tncs);	return TNCCS_PROCESS_OK_NO_RECOMMENDATION;}static struct tnc_if_imv * tncs_parse_imv(int id, char *start, char *end,					  int *error){	struct tnc_if_imv *imv;	char *pos, *pos2;	if (id >= TNC_MAX_IMV_ID) {		wpa_printf(MSG_DEBUG, "TNC: Too many IMVs");		return NULL;	}	imv = os_zalloc(sizeof(*imv));	if (imv == NULL) {		*error = 1;		return NULL;	}	imv->imvID = id;	pos = start;	wpa_printf(MSG_DEBUG, "TNC: Configured IMV: %s", pos);	if (pos + 1 >= end || *pos != '"') {		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMV line '%s' "			   "(no starting quotation mark)", start);		os_free(imv);		return NULL;	}	pos++;	pos2 = pos;	while (pos2 < end && *pos2 != '"')		pos2++;	if (pos2 >= end) {		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMV line '%s' "			   "(no ending quotation mark)", start);		os_free(imv);		return NULL;	}	*pos2 = '\0';	wpa_printf(MSG_DEBUG, "TNC: Name: '%s'", pos);	imv->name = os_strdup(pos);	pos = pos2 + 1;	if (pos >= end || *pos != ' ') {		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMV line '%s' "			   "(no space after name)", start);		os_free(imv);		return NULL;	}	pos++;	wpa_printf(MSG_DEBUG, "TNC: IMV file: '%s'", pos);	imv->path = os_strdup(pos);	return imv;}static int tncs_read_config(struct tncs_global *global){	char *config, *end, *pos, *line_end;	size_t config_len;	struct tnc_if_imv *imv, *last;	int id = 0;	last = NULL;	config = os_readfile(TNC_CONFIG_FILE, &config_len);	if (config == NULL) {		wpa_printf(MSG_ERROR, "TNC: Could not open TNC configuration "			   "file '%s'", TNC_CONFIG_FILE);		return -1;	}	end = config + config_len;	for (pos = config; pos < end; pos = line_end + 1) {		line_end = pos;		while (*line_end != '\n' && *line_end != '\r' &&		       line_end < end)			line_end++;		*line_end = '\0';		if (os_strncmp(pos, "IMV ", 4) == 0) {			int error = 0;			imv = tncs_parse_imv(id++, pos + 4, line_end, &error);			if (error)				return -1;			if (imv) {				if (last == NULL)					global->imv = imv;				else					last->next = imv;				last = imv;			}		}	}	os_free(config);	return 0;}struct tncs_data * tncs_init(void){	struct tncs_data *tncs;	if (tncs_global_data == NULL)		return NULL;	tncs = os_zalloc(sizeof(*tncs));	if (tncs == NULL)		return NULL;	tncs->imv = tncs_global_data->imv;	tncs->connectionID = tncs_global_data->next_conn_id++;	tncs->next = tncs_global_data->connections;	tncs_global_data->connections = tncs;	return tncs;}void tncs_deinit(struct tncs_data *tncs){	int i;	struct tncs_data *prev, *conn;	if (tncs == NULL)		return;	for (i = 0; i < TNC_MAX_IMV_ID; i++)		os_free(tncs->imv_data[i].imv_send);	prev = NULL;	conn = tncs_global_data->connections;	while (conn) {		if (conn == tncs) {			if (prev)				prev->next = tncs->next;			else				tncs_global_data->connections = tncs->next;			break;		}		prev = conn;		conn = conn->next;	}	os_free(tncs->tncs_message);	os_free(tncs);}int tncs_global_init(void){	struct tnc_if_imv *imv;	tncs_global_data = os_zalloc(sizeof(*tncs_global_data));	if (tncs_global_data == NULL)		return -1;	if (tncs_read_config(tncs_global_data) < 0) {		wpa_printf(MSG_ERROR, "TNC: Failed to read TNC configuration");		goto failed;	}	for (imv = tncs_global_data->imv; imv; imv = imv->next) {		if (tncs_load_imv(imv)) {			wpa_printf(MSG_ERROR, "TNC: Failed to load IMV '%s'",				   imv->name);			goto failed;		}	}	return 0;failed:	tncs_global_deinit();	return -1;}void tncs_global_deinit(void){	struct tnc_if_imv *imv, *prev;	if (tncs_global_data == NULL)		return;	imv = tncs_global_data->imv;	while (imv) {		tncs_unload_imv(imv);		prev = imv;		imv = imv->next;		os_free(prev);	}	os_free(tncs_global_data);}struct wpabuf * tncs_build_soh_request(void){	struct wpabuf *buf;	/*	 * Build a SoH Request TLV (to be used inside SoH EAP Extensions	 * Method)	 */	buf = wpabuf_alloc(8 + 4);	if (buf == NULL)		return NULL;	/* Vendor-Specific TLV (Microsoft) - SoH Request */	wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* TLV Type */	wpabuf_put_be16(buf, 8); /* Length */	wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* Vendor_Id */	wpabuf_put_be16(buf, 0x02); /* TLV Type - SoH Request TLV */	wpabuf_put_be16(buf, 0); /* Length */	return buf;}struct wpabuf * tncs_process_soh(const u8 *soh_tlv, size_t soh_tlv_len,				 int *failure){	wpa_hexdump(MSG_DEBUG, "TNC: SoH TLV", soh_tlv, soh_tlv_len);	*failure = 0;	/* TODO: return MS-SoH Response TLV */	return NULL;}

⌨️ 快捷键说明

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