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

📄 tncc.c

📁 IEEE802.11 a/b/g 客户端应用程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 tncc_process_res tncc_get_recommendation(char *start){	char *pos, *pos2, saved;	int recom;	pos = os_strstr(start, "<TNCCS-Recommendation ");	if (pos == NULL)		return TNCCS_RECOMMENDATION_ERROR;	pos += 21;	pos = os_strstr(pos, " type=");	if (pos == NULL)		return TNCCS_RECOMMENDATION_ERROR;	pos += 6;	if (*pos == '"')		pos++;	pos2 = pos;	while (*pos2 != '\0' && *pos2 != '"' && *pos2 != '>')		pos2++;	if (*pos2 == '\0')		return TNCCS_RECOMMENDATION_ERROR;	saved = *pos2;	*pos2 = '\0';	wpa_printf(MSG_DEBUG, "TNC: TNCCS-Recommendation: '%s'", pos);	recom = TNCCS_RECOMMENDATION_ERROR;	if (os_strcmp(pos, "allow") == 0)		recom = TNCCS_RECOMMENDATION_ALLOW;	else if (os_strcmp(pos, "none") == 0)		recom = TNCCS_RECOMMENDATION_NONE;	else if (os_strcmp(pos, "isolate") == 0)		recom = TNCCS_RECOMMENDATION_ISOLATE;	*pos2 = saved;	return recom;}enum tncc_process_res tncc_process_if_tnccs(struct tncc_data *tncc,					    const u8 *msg, size_t len){	char *buf, *start, *end, *pos, *pos2, *payload;	unsigned int batch_id;	unsigned char *decoded;	size_t decoded_len;	enum tncc_process_res res = TNCCS_PROCESS_OK_NO_RECOMMENDATION;	int recommendation_msg = 0;	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 != tncc->last_batchid + 1) {		wpa_printf(MSG_DEBUG, "TNC: Unexpected IF-TNCCS BatchId "			   "%u (expected %u)",			   batch_id, tncc->last_batchid + 1);		os_free(buf);		return TNCCS_PROCESS_ERROR;	}	tncc->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 (tncc_get_type(start, &type) < 0) {			*endpos = '<';			start = end;			continue;		}		wpa_printf(MSG_DEBUG, "TNC: IMC-IMV-Message Type 0x%x", type);		decoded = tncc_get_base64(start, &decoded_len);		if (decoded == NULL) {			*endpos = '<';			start = end;			continue;		}		tncc_send_to_imcs(tncc, 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 (tncc_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 = tncc_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);		}		if (type == TNC_TNCCS_RECOMMENDATION && xml) {			/*			 * <TNCCS-Recommendation type="allow">			 * </TNCCS-Recommendation>			 */			*xmlend = '\0';			res = tncc_get_recommendation(xml);			*xmlend = '<';			recommendation_msg = 1;		}		start = end;	}	os_free(buf);	if (recommendation_msg)		tncc_notify_recommendation(tncc, res);	return res;}#ifdef CONFIG_NATIVE_WINDOWSstatic int tncc_read_config_reg(struct tncc_data *tncc, HKEY hive){	HKEY hk, hk2;	LONG ret;	DWORD i;	struct tnc_if_imc *imc, *last;	int j;	last = tncc->imc;	while (last && last->next)		last = last->next;	ret = RegOpenKeyEx(hive, TNC_WINREG_PATH, 0, KEY_ENUMERATE_SUB_KEYS,			   &hk);	if (ret != ERROR_SUCCESS)		return 0;	for (i = 0; ; i++) {		TCHAR name[255], *val;		DWORD namelen, buflen;		namelen = 255;		ret = RegEnumKeyEx(hk, i, name, &namelen, NULL, NULL, NULL,				   NULL);		if (ret == ERROR_NO_MORE_ITEMS)			break;		if (ret != ERROR_SUCCESS) {			wpa_printf(MSG_DEBUG, "TNC: RegEnumKeyEx failed: 0x%x",				   (unsigned int) ret);			break;		}		if (namelen >= 255)			namelen = 255 - 1;		name[namelen] = '\0';		wpa_printf(MSG_DEBUG, "TNC: IMC '" TSTR "'", name);		ret = RegOpenKeyEx(hk, name, 0, KEY_QUERY_VALUE, &hk2);		if (ret != ERROR_SUCCESS) {			wpa_printf(MSG_DEBUG, "Could not open IMC key '" TSTR				   "'", name);			continue;		}		ret = RegQueryValueEx(hk2, TEXT("Path"), NULL, NULL, NULL,				      &buflen);		if (ret != ERROR_SUCCESS) {			wpa_printf(MSG_DEBUG, "TNC: Could not read Path from "				   "IMC key '" TSTR "'", name);			RegCloseKey(hk2);			continue;		}		val = os_malloc(buflen);		if (val == NULL) {			RegCloseKey(hk2);			continue;		}		ret = RegQueryValueEx(hk2, TEXT("Path"), NULL, NULL,				      (LPBYTE) val, &buflen);		if (ret != ERROR_SUCCESS) {			os_free(val);			RegCloseKey(hk2);			continue;		}		RegCloseKey(hk2);		wpa_unicode2ascii_inplace(val);		wpa_printf(MSG_DEBUG, "TNC: IMC Path '%s'", (char *) val);		for (j = 0; j < TNC_MAX_IMC_ID; j++) {			if (tnc_imc[j] == NULL)				break;		}		if (j >= TNC_MAX_IMC_ID) {			wpa_printf(MSG_DEBUG, "TNC: Too many IMCs");			os_free(val);			continue;		}		imc = os_zalloc(sizeof(*imc));		if (imc == NULL) {			os_free(val);			break;		}		imc->imcID = j;		wpa_unicode2ascii_inplace(name);		imc->name = os_strdup((char *) name);		imc->path = os_strdup((char *) val);		os_free(val);		if (last == NULL)			tncc->imc = imc;		else			last->next = imc;		last = imc;		tnc_imc[imc->imcID] = imc;	}	RegCloseKey(hk);	return 0;}static int tncc_read_config(struct tncc_data *tncc){	if (tncc_read_config_reg(tncc, HKEY_LOCAL_MACHINE) < 0 ||	    tncc_read_config_reg(tncc, HKEY_CURRENT_USER) < 0)		return -1;	return 0;}#else /* CONFIG_NATIVE_WINDOWS */static struct tnc_if_imc * tncc_parse_imc(char *start, char *end, int *error){	struct tnc_if_imc *imc;	char *pos, *pos2;	int i;	for (i = 0; i < TNC_MAX_IMC_ID; i++) {		if (tnc_imc[i] == NULL)			break;	}	if (i >= TNC_MAX_IMC_ID) {		wpa_printf(MSG_DEBUG, "TNC: Too many IMCs");		return NULL;	}	imc = os_zalloc(sizeof(*imc));	if (imc == NULL) {		*error = 1;		return NULL;	}	imc->imcID = i;	pos = start;	wpa_printf(MSG_DEBUG, "TNC: Configured IMC: %s", pos);	if (pos + 1 >= end || *pos != '"') {		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMC line '%s' "			   "(no starting quotation mark)", start);		os_free(imc);		return NULL;	}	pos++;	pos2 = pos;	while (pos2 < end && *pos2 != '"')		pos2++;	if (pos2 >= end) {		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMC line '%s' "			   "(no ending quotation mark)", start);		os_free(imc);		return NULL;	}	*pos2 = '\0';	wpa_printf(MSG_DEBUG, "TNC: Name: '%s'", pos);	imc->name = os_strdup(pos);	pos = pos2 + 1;	if (pos >= end || *pos != ' ') {		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMC line '%s' "			   "(no space after name)", start);		os_free(imc);		return NULL;	}	pos++;	wpa_printf(MSG_DEBUG, "TNC: IMC file: '%s'", pos);	imc->path = os_strdup(pos);	tnc_imc[imc->imcID] = imc;	return imc;}static int tncc_read_config(struct tncc_data *tncc){	char *config, *end, *pos, *line_end;	size_t config_len;	struct tnc_if_imc *imc, *last;	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, "IMC ", 4) == 0) {			int error = 0;			imc = tncc_parse_imc(pos + 4, line_end, &error);			if (error)				return -1;			if (imc) {				if (last == NULL)					tncc->imc = imc;				else					last->next = imc;				last = imc;			}		}	}	os_free(config);	return 0;}#endif /* CONFIG_NATIVE_WINDOWS */struct tncc_data * tncc_init(void){	struct tncc_data *tncc;	struct tnc_if_imc *imc;	tncc = os_zalloc(sizeof(*tncc));	if (tncc == NULL)		return NULL;	/* TODO:	 * move loading and Initialize() to a location that is not	 *    re-initialized for every EAP-TNC session (?)	 */	if (tncc_read_config(tncc) < 0) {		wpa_printf(MSG_ERROR, "TNC: Failed to read TNC configuration");		goto failed;	}	for (imc = tncc->imc; imc; imc = imc->next) {		if (tncc_load_imc(imc)) {			wpa_printf(MSG_ERROR, "TNC: Failed to load IMC '%s'",				   imc->name);			goto failed;		}	}	return tncc;failed:	tncc_deinit(tncc);	return NULL;}void tncc_deinit(struct tncc_data *tncc){	struct tnc_if_imc *imc, *prev;	imc = tncc->imc;	while (imc) {		tncc_unload_imc(imc);		prev = imc;		imc = imc->next;		os_free(prev);	}	os_free(tncc);}static struct wpabuf * tncc_build_soh(void){	struct wpabuf *buf;	u8 *tlv_len, *tlv_len2, *outer_len, *inner_len, *ssoh_len, *end;	u8 correlation_id[24];	int ver = 2;	if (os_get_random(correlation_id, sizeof(correlation_id)))		return NULL;	wpa_hexdump(MSG_DEBUG, "TNC: SoH Correlation ID",		    correlation_id, sizeof(correlation_id));	buf = wpabuf_alloc(200);	if (buf == NULL)		return NULL;	/* Vendor-Specific TLV (Microsoft) - SoH */	wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* TLV Type */	tlv_len = wpabuf_put(buf, 2); /* Length */	wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* Vendor_Id */	wpabuf_put_be16(buf, 0x01); /* TLV Type - SoH TLV */	tlv_len2 = wpabuf_put(buf, 2); /* Length */	/* SoH Header */	wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* Outer Type */	outer_len = wpabuf_put(buf, 2);	wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */	wpabuf_put_be16(buf, ver); /* Inner Type */	inner_len = wpabuf_put(buf, 2);	if (ver == 2) {		/* SoH Mode Sub-Header */		/* Outer Type */		wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV);		wpabuf_put_be16(buf, 4 + 24 + 1 + 1); /* Length */		wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */		/* Value: */		wpabuf_put_data(buf, correlation_id, sizeof(correlation_id));		wpabuf_put_u8(buf, 0x01); /* Intent Flag - Request */		wpabuf_put_u8(buf, 0x00); /* Content-Type Flag */	}	/* SSoH TLV */	/* System-Health-Id */	wpabuf_put_be16(buf, 0x0002); /* Type */	wpabuf_put_be16(buf, 4); /* Length */	wpabuf_put_be32(buf, 79616);	/* Vendor-Specific Attribute */	wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV);	ssoh_len = wpabuf_put(buf, 2);	wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */	/* TODO: MS-Machine-Inventory */	/* TODO: MS-Quarantine-State */	/* MS-Packet-Info */	wpabuf_put_u8(buf, 0x03);	wpabuf_put_u8(buf, 0x11); /* r=request, vers=1 */	/* TODO: MS-MachineName */	/* MS-CorrelationId */	wpabuf_put_u8(buf, 0x06);	wpabuf_put_data(buf, correlation_id, sizeof(correlation_id));	end = wpabuf_put(buf, 0);	WPA_PUT_BE16(ssoh_len, end - ssoh_len - 2);	/* TODO: SoHReportEntry TLV (zero or more) */	/* Update length fields */	end = wpabuf_put(buf, 0);	WPA_PUT_BE16(tlv_len, end - tlv_len - 2);	WPA_PUT_BE16(tlv_len2, end - tlv_len2 - 2);	WPA_PUT_BE16(outer_len, end - outer_len - 2);	WPA_PUT_BE16(inner_len, end - inner_len - 2);	return buf;}struct wpabuf * tncc_process_soh_request(const u8 *data, size_t len){	const u8 *pos;	wpa_hexdump(MSG_DEBUG, "TNC: SoH Request", data, len);	if (len < 12)		return NULL;	/* SoH Request */	pos = data;	/* TLV Type */	if (WPA_GET_BE16(pos) != EAP_TLV_VENDOR_SPECIFIC_TLV)		return NULL;	pos += 2;	/* Length */	if (WPA_GET_BE16(pos) < 8)		return NULL;	pos += 2;	/* Vendor_Id */	if (WPA_GET_BE32(pos) != EAP_VENDOR_MICROSOFT)		return NULL;	pos += 4;	/* TLV Type */	if (WPA_GET_BE16(pos) != 0x02 /* SoH request TLV */)		return NULL;	wpa_printf(MSG_DEBUG, "TNC: SoH Request TLV received");	return tncc_build_soh();}

⌨️ 快捷键说明

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