📄 tncs.c
字号:
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 + -