18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-TNC - TNCS (IF-IMV, IF-TNCCS, and IF-TNCCS-SOH) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2007-2008, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <dlfcn.h> 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "base64.h" 1450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#include "common/tnc.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tncs.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_tlv_common.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_common/eap_defs.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TODO: TNCS must be thread-safe; review the code and add locking etc. if 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * needed.. */ 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#ifndef TNC_CONFIG_FILE 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TNC_CONFIG_FILE "/etc/tnc_config" 2550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#endif /* TNC_CONFIG_FILE */ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IF_TNCCS_START \ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"<?xml version=\"1.0\"?>\n" \ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"<TNCCS-Batch BatchId=\"%d\" Recipient=\"TNCS\" " \ 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"xmlns=\"http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#\" " \ 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \ 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"xsi:schemaLocation=\"http://www.trustedcomputinggroup.org/IWG/TNC/1_0/" \ 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"IF_TNCCS# https://www.trustedcomputinggroup.org/XML/SCHEMA/TNCCS_1.0.xsd\">\n" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IF_TNCCS_END "\n</TNCCS-Batch>" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TNC IF-IMV */ 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tnc_if_imv { 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *next; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *name; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *path; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *dlhandle; /* from dlopen() */ 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_MessageTypeList supported_types; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_supported_types; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Functions implemented by IMVs (with TNC_IMV_ prefix) */ 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result (*Initialize)( 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Version minVersion, 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Version maxVersion, 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Version *pOutActualVersion); 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result (*NotifyConnectionChange)( 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID, 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionState newState); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result (*ReceiveMessage)( 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID, 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_BufferReference message, 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_UInt32 messageLength, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_MessageType messageType); 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result (*SolicitRecommendation)( 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result (*BatchEnding)( 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result (*Terminate)(TNC_IMVID imvID); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result (*ProvideBindFunction)( 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_TNCS_BindFunctionPointer bindFunction); 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define TNC_MAX_IMV_ID 10 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tncs_data { 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tncs_data *next; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; /* local copy of tncs_global_data->imv */ 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int last_batchid; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum IMV_Action_Recommendation recommendation; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int done; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct conn_imv { 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *imv_send; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t imv_send_len; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum IMV_Action_Recommendation recommendation; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int recommendation_set; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } imv_data[TNC_MAX_IMV_ID]; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *tncs_message; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tncs_global { 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID next_conn_id; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tncs_data *connections; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct tncs_global *tncs_global_data = NULL; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct tnc_if_imv * tncs_get_imv(TNC_IMVID imvID) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imvID >= TNC_MAX_IMV_ID || tncs_global_data == NULL) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv = tncs_global_data->imv; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (imv) { 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->imvID == imvID) 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return imv; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv = imv->next; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct tncs_data * tncs_get_conn(TNC_ConnectionID connectionID) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tncs_data *tncs; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_global_data == NULL) 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs = tncs_global_data->connections; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (tncs) { 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs->connectionID == connectionID) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tncs; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs = tncs->next; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Connection ID %lu not found", 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) connectionID); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TNCS functions that IMVs can call */ 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTNC_Result TNC_TNCS_ReportMessageTypes( 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_MessageTypeList supportedTypes, 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_UInt32 typeCount) 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_UInt32 i; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_ReportMessageTypes(imvID=%lu " 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "typeCount=%lu)", 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) imvID, (unsigned long) typeCount); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < typeCount; i++) { 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: supportedTypes[%lu] = %lu", 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i, supportedTypes[i]); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv = tncs_get_imv(imvID); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv == NULL) 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_INVALID_PARAMETER; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(imv->supported_types); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->supported_types = 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_malloc(typeCount * sizeof(TNC_MessageType)); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->supported_types == NULL) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_FATAL; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(imv->supported_types, supportedTypes, 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt typeCount * sizeof(TNC_MessageType)); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->num_supported_types = typeCount; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_SUCCESS; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTNC_Result TNC_TNCS_SendMessage( 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID, 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_BufferReference message, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_UInt32 messageLength, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_MessageType messageType) 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tncs_data *tncs; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *b64; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t b64len; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_SendMessage(imvID=%lu " 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connectionID=%lu messageType=%lu)", 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imvID, connectionID, messageType); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "TNC: TNC_TNCS_SendMessage", 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt message, messageLength); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_get_imv(imvID) == NULL) 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_INVALID_PARAMETER; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs = tncs_get_conn(connectionID); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs == NULL) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_INVALID_PARAMETER; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b64 = base64_encode(message, messageLength, &b64len); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b64 == NULL) 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_FATAL; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs->imv_data[imvID].imv_send); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[imvID].imv_send_len = 0; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[imvID].imv_send = os_zalloc(b64len + 100); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs->imv_data[imvID].imv_send == NULL) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b64); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_OTHER; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[imvID].imv_send_len = 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf((char *) tncs->imv_data[imvID].imv_send, 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b64len + 100, 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "<IMC-IMV-Message><Type>%08X</Type>" 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "<Base64>%s</Base64></IMC-IMV-Message>", 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) messageType, b64); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b64); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_SUCCESS; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTNC_Result TNC_TNCS_RequestHandshakeRetry( 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID, 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_RetryReason reason) 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_RequestHandshakeRetry"); 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_SUCCESS; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTNC_Result TNC_TNCS_ProvideRecommendation( 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID, 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMV_Action_Recommendation recommendation, 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMV_Evaluation_Result evaluation) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tncs_data *tncs; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_ProvideRecommendation(imvID=%lu " 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connectionID=%lu recommendation=%lu evaluation=%lu)", 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) imvID, (unsigned long) connectionID, 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) recommendation, (unsigned long) evaluation); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_get_imv(imvID) == NULL) 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_INVALID_PARAMETER; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs = tncs_get_conn(connectionID); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs == NULL) 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_INVALID_PARAMETER; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[imvID].recommendation = recommendation; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[imvID].recommendation_set = 1; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_SUCCESS; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTNC_Result TNC_TNCS_GetAttribute( 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID, 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_AttributeID attribureID, 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_UInt32 bufferLength, 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_BufferReference buffer, 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_UInt32 *pOutValueLength) 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_GetAttribute"); 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_SUCCESS; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTNC_Result TNC_TNCS_SetAttribute( 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID connectionID, 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_AttributeID attribureID, 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_UInt32 bufferLength, 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_BufferReference buffer) 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_SetAttribute"); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_SUCCESS; 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTNC_Result TNC_TNCS_BindFunction( 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMVID imvID, 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *functionName, 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void **pOutFunctionPointer) 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_BindFunction(imcID=%lu, " 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "functionName='%s')", (unsigned long) imvID, functionName); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_get_imv(imvID) == NULL) 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_INVALID_PARAMETER; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pOutFunctionPointer == NULL) 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_INVALID_PARAMETER; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(functionName, "TNC_TNCS_ReportMessageTypes") == 0) 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pOutFunctionPointer = TNC_TNCS_ReportMessageTypes; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strcmp(functionName, "TNC_TNCS_SendMessage") == 0) 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pOutFunctionPointer = TNC_TNCS_SendMessage; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strcmp(functionName, "TNC_TNCS_RequestHandshakeRetry") == 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pOutFunctionPointer = TNC_TNCS_RequestHandshakeRetry; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strcmp(functionName, "TNC_TNCS_ProvideRecommendation") == 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pOutFunctionPointer = TNC_TNCS_ProvideRecommendation; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strcmp(functionName, "TNC_TNCS_GetAttribute") == 0) 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pOutFunctionPointer = TNC_TNCS_GetAttribute; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strcmp(functionName, "TNC_TNCS_SetAttribute") == 0) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pOutFunctionPointer = TNC_TNCS_SetAttribute; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pOutFunctionPointer = NULL; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNC_RESULT_SUCCESS; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * tncs_get_sym(void *handle, char *func) 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *fptr; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fptr = dlsym(handle, func); 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return fptr; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_imv_resolve_funcs(struct tnc_if_imv *imv) 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *handle = imv->dlhandle; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Mandatory IMV functions */ 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->Initialize = tncs_get_sym(handle, "TNC_IMV_Initialize"); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->Initialize == NULL) { 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: IMV does not export " 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TNC_IMV_Initialize"); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->SolicitRecommendation = tncs_get_sym( 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle, "TNC_IMV_SolicitRecommendation"); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->SolicitRecommendation == NULL) { 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: IMV does not export " 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TNC_IMV_SolicitRecommendation"); 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->ProvideBindFunction = 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_get_sym(handle, "TNC_IMV_ProvideBindFunction"); 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->ProvideBindFunction == NULL) { 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: IMV does not export " 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TNC_IMV_ProvideBindFunction"); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Optional IMV functions */ 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->NotifyConnectionChange = 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_get_sym(handle, "TNC_IMV_NotifyConnectionChange"); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->ReceiveMessage = tncs_get_sym(handle, "TNC_IMV_ReceiveMessage"); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->BatchEnding = tncs_get_sym(handle, "TNC_IMV_BatchEnding"); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->Terminate = tncs_get_sym(handle, "TNC_IMV_Terminate"); 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_imv_initialize(struct tnc_if_imv *imv) 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result res; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Version imv_ver; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMV_Initialize for IMV '%s'", 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->name); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = imv->Initialize(imv->imvID, TNC_IFIMV_VERSION_1, 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IFIMV_VERSION_1, &imv_ver); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_IMV_Initialize: res=%lu imv_ver=%lu", 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) res, (unsigned long) imv_ver); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res == TNC_RESULT_SUCCESS ? 0 : -1; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_imv_terminate(struct tnc_if_imv *imv) 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result res; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->Terminate == NULL) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMV_Terminate for IMV '%s'", 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->name); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = imv->Terminate(imv->imvID); 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_IMV_Terminate: %lu", 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) res); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res == TNC_RESULT_SUCCESS ? 0 : -1; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_imv_provide_bind_function(struct tnc_if_imv *imv) 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result res; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMV_ProvideBindFunction for " 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IMV '%s'", imv->name); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = imv->ProvideBindFunction(imv->imvID, TNC_TNCS_BindFunction); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_IMV_ProvideBindFunction: res=%lu", 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) res); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res == TNC_RESULT_SUCCESS ? 0 : -1; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_imv_notify_connection_change(struct tnc_if_imv *imv, 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionID conn, 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionState state) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result res; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->NotifyConnectionChange == NULL) 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMV_NotifyConnectionChange(%d)" 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for IMV '%s'", (int) state, imv->name); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = imv->NotifyConnectionChange(imv->imvID, conn, state); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNC_IMC_NotifyConnectionChange: %lu", 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) res); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res == TNC_RESULT_SUCCESS ? 0 : -1; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_load_imv(struct tnc_if_imv *imv) 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->path == NULL) { 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: No IMV configured"); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Opening IMV: %s (%s)", 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->name, imv->path); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->dlhandle = dlopen(imv->path, RTLD_LAZY); 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->dlhandle == NULL) { 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Failed to open IMV '%s' (%s): %s", 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->name, imv->path, dlerror()); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_imv_resolve_funcs(imv) < 0) { 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Failed to resolve IMV functions"); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_imv_initialize(imv) < 0 || 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_imv_provide_bind_function(imv) < 0) { 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Failed to initialize IMV"); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tncs_free_imv(struct tnc_if_imv *imv) 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(imv->name); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(imv->path); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(imv->supported_types); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tncs_unload_imv(struct tnc_if_imv *imv) 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_imv_terminate(imv); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->dlhandle) 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlclose(imv->dlhandle); 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_free_imv(imv); 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_supported_type(struct tnc_if_imv *imv, unsigned int type) 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int vendor, subtype; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv == NULL || imv->supported_types == NULL) 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor = type >> 8; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt subtype = type & 0xff; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < imv->num_supported_types; i++) { 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int svendor, ssubtype; 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt svendor = imv->supported_types[i] >> 8; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssubtype = imv->supported_types[i] & 0xff; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((vendor == svendor || svendor == TNC_VENDORID_ANY) && 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (subtype == ssubtype || ssubtype == TNC_SUBTYPE_ANY)) 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tncs_send_to_imvs(struct tncs_data *tncs, unsigned int type, 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *msg, size_t len) 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result res; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, "TNC: Message to IMV(s)", msg, len); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (imv = tncs->imv; imv; imv = imv->next) { 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->ReceiveMessage == NULL || 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !tncs_supported_type(imv, type)) 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Call ReceiveMessage for IMV '%s'", 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->name); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = imv->ReceiveMessage(imv->imvID, tncs->connectionID, 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (TNC_BufferReference) msg, len, 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type); 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: ReceiveMessage: %lu", 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) res); 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tncs_batch_ending(struct tncs_data *tncs) 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result res; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (imv = tncs->imv; imv; imv = imv->next) { 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv->BatchEnding == NULL) 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Call BatchEnding for IMV '%s'", 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->name); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = imv->BatchEnding(imv->imvID, tncs->connectionID); 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: BatchEnding: %lu", 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) res); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tncs_solicit_recommendation(struct tncs_data *tncs) 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_Result res; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (imv = tncs->imv; imv; imv = imv->next) { 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs->imv_data[imv->imvID].recommendation_set) 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Call SolicitRecommendation for " 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IMV '%s'", imv->name); 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = imv->SolicitRecommendation(imv->imvID, 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->connectionID); 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: SolicitRecommendation: %lu", 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) res); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tncs_init_connection(struct tncs_data *tncs) 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (imv = tncs->imv; imv; imv = imv->next) { 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_imv_notify_connection_change( 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv, tncs->connectionID, TNC_CONNECTION_STATE_CREATE); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_imv_notify_connection_change( 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv, tncs->connectionID, 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_CONNECTION_STATE_HANDSHAKE); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < TNC_MAX_IMV_ID; i++) { 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs->imv_data[i].imv_send); 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[i].imv_send = NULL; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[i].imv_send_len = 0; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsize_t tncs_total_send_len(struct tncs_data *tncs) 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = 0; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < TNC_MAX_IMV_ID; i++) 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += tncs->imv_data[i].imv_send_len; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs->tncs_message) 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += os_strlen(tncs->tncs_message); 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * tncs_copy_send_buf(struct tncs_data *tncs, u8 *pos) 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < TNC_MAX_IMV_ID; i++) { 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs->imv_data[i].imv_send == NULL) 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, tncs->imv_data[i].imv_send, 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[i].imv_send_len); 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += tncs->imv_data[i].imv_send_len; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs->imv_data[i].imv_send); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[i].imv_send = NULL; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv_data[i].imv_send_len = 0; 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs->tncs_message) { 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len = os_strlen(tncs->tncs_message); 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, tncs->tncs_message, len); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += len; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs->tncs_message); 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->tncs_message = NULL; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar * tncs_if_tnccs_start(struct tncs_data *tncs) 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf = os_malloc(1000); 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->last_batchid++; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, 1000, IF_TNCCS_START, tncs->last_batchid); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar * tncs_if_tnccs_end(void) 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf = os_malloc(100); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(buf, 100, IF_TNCCS_END); 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_get_type(char *start, unsigned int *type) 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = os_strstr(start, "<Type>"); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 6; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *type = strtoul(pos, NULL, 16); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned char * tncs_get_base64(char *start, size_t *decoded_len) 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos, *pos2; 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *decoded; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(start, "<Base64>"); 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 8; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = os_strstr(pos, "</Base64>"); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt decoded = base64_decode((unsigned char *) pos, os_strlen(pos), 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt decoded_len); 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '<'; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (decoded == NULL) { 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Failed to decode Base64 data"); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return decoded; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum tncs_process_res tncs_derive_recommendation(struct tncs_data *tncs) 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum IMV_Action_Recommendation rec; 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_ConnectionState state; 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *txt; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: No more messages from IMVs"); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs->done) 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_PROCESS_OK_NO_RECOMMENDATION; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_solicit_recommendation(tncs); 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Select the most restrictive recommendation */ 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (imv = tncs->imv; imv; imv = imv->next) { 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_IMV_Action_Recommendation irec; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt irec = tncs->imv_data[imv->imvID].recommendation; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (irec == TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS) 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (irec == TNC_IMV_ACTION_RECOMMENDATION_ISOLATE && 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rec != TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS) 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (irec == TNC_IMV_ACTION_RECOMMENDATION_ALLOW && 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rec == TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION) 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Recommendation: %d", rec); 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->recommendation = rec; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->done = 1; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt = NULL; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (rec) { 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION: 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt = "allow"; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = TNC_CONNECTION_STATE_ACCESS_ALLOWED; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt = "isolate"; 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = TNC_CONNECTION_STATE_ACCESS_ISOLATED; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt txt = "none"; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = TNC_CONNECTION_STATE_ACCESS_NONE; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state = TNC_CONNECTION_STATE_ACCESS_ALLOWED; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (txt) { 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs->tncs_message); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->tncs_message = os_zalloc(200); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs->tncs_message) { 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(tncs->tncs_message, 199, 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "<TNCC-TNCS-Message><Type>%08X</Type>" 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "<XML><TNCCS-Recommendation type=\"%s\">" 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "</TNCCS-Recommendation></XML>" 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "</TNCC-TNCS-Message>", 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TNC_TNCCS_RECOMMENDATION, txt); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (imv = tncs->imv; imv; imv = imv->next) { 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_imv_notify_connection_change(imv, tncs->connectionID, 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt state); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (rec) { 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_RECOMMENDATION_ALLOW; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_RECOMMENDATION_NO_ACCESS; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_RECOMMENDATION_ISOLATE; 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION: 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_RECOMMENDATION_NO_RECOMMENDATION; 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_PROCESS_ERROR; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum tncs_process_res tncs_process_if_tnccs(struct tncs_data *tncs, 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *msg, size_t len) 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, *start, *end, *pos, *pos2, *payload; 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int batch_id; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned char *decoded; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t decoded_len; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7884b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt buf = dup_binstr(msg, len); 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_PROCESS_ERROR; 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = os_strstr(buf, "<TNCCS-Batch "); 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strstr(buf, "</TNCCS-Batch>"); 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (start == NULL || end == NULL || start > end) { 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_PROCESS_ERROR; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start += 13; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*start == ' ') 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start++; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(start, "BatchId="); 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) { 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_PROCESS_ERROR; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 8; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '"') 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt batch_id = atoi(pos); 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Received IF-TNCCS BatchId=%u", 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt batch_id); 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (batch_id != tncs->last_batchid + 1) { 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Unexpected IF-TNCCS BatchId " 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%u (expected %u)", 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt batch_id, tncs->last_batchid + 1); 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_PROCESS_ERROR; 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->last_batchid = batch_id; 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos != '\0' && *pos != '>') 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_PROCESS_ERROR; 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt payload = start; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * <IMC-IMV-Message> 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * <Type>01234567</Type> 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * <Base64>foo==</Base64> 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * </IMC-IMV-Message> 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*start) { 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *endpos; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int type; 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(start, "<IMC-IMV-Message>"); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + 17; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strstr(start, "</IMC-IMV-Message>"); 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt endpos = end; 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end += 18; 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_get_type(start, &type) < 0) { 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *endpos = '<'; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: IMC-IMV-Message Type 0x%x", type); 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt decoded = tncs_get_base64(start, &decoded_len); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (decoded == NULL) { 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *endpos = '<'; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_send_to_imvs(tncs, type, decoded, decoded_len); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(decoded); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end; 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * <TNCC-TNCS-Message> 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * <Type>01234567</Type> 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * <XML><TNCCS-Foo type="foo"></TNCCS-Foo></XML> 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * <Base64>foo==</Base64> 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * </TNCC-TNCS-Message> 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = payload; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*start) { 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int type; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *xml, *xmlend, *endpos; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(start, "<TNCC-TNCS-Message>"); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + 19; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = os_strstr(start, "</TNCC-TNCS-Message>"); 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end == NULL) 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *end = '\0'; 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt endpos = end; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end += 20; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_get_type(start, &type) < 0) { 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *endpos = '<'; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: TNCC-TNCS-Message Type 0x%x", 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt type); 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Base64 OR XML */ 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt decoded = NULL; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xml = NULL; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xmlend = NULL; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(start, "<XML>"); 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 5; 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = os_strstr(pos, "</XML>"); 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == NULL) { 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *endpos = '<'; 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end; 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xmlend = pos2; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xml = pos; 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt decoded = tncs_get_base64(start, &decoded_len); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (decoded == NULL) { 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *endpos = '<'; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end; 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (decoded) { 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TNC: TNCC-TNCS-Message Base64", 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt decoded, decoded_len); 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(decoded); 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (xml) { 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TNC: TNCC-TNCS-Message XML", 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned char *) xml, 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt xmlend - xml); 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = end; 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_batch_ending(tncs); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_total_send_len(tncs) == 0) 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tncs_derive_recommendation(tncs); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TNCCS_PROCESS_OK_NO_RECOMMENDATION; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct tnc_if_imv * tncs_parse_imv(int id, char *start, char *end, 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int *error) 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos, *pos2; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (id >= TNC_MAX_IMV_ID) { 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Too many IMVs"); 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv = os_zalloc(sizeof(*imv)); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv == NULL) { 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *error = 1; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->imvID = id; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = start; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Configured IMV: %s", pos); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= end || *pos != '"') { 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMV line '%s' " 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(no starting quotation mark)", start); 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(imv); 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = pos; 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos2 < end && *pos2 != '"') 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2++; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 >= end) { 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMV line '%s' " 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(no ending quotation mark)", start); 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(imv); 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos2 = '\0'; 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: Name: '%s'", pos); 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->name = os_strdup(pos); 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos >= end || *pos != ' ') { 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMV line '%s' " 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(no space after name)", start); 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(imv); 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TNC: IMV file: '%s'", pos); 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->path = os_strdup(pos); 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return imv; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tncs_read_config(struct tncs_global *global) 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *config, *end, *pos, *line_end; 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t config_len; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv, *last; 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int id = 0; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = NULL; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config = os_readfile(TNC_CONFIG_FILE, &config_len); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) { 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Could not open TNC configuration " 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "file '%s'", TNC_CONFIG_FILE); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = config + config_len; 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (pos = config; pos < end; pos = line_end + 1) { 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line_end = pos; 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*line_end != '\n' && *line_end != '\r' && 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line_end < end) 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt line_end++; 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *line_end = '\0'; 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(pos, "IMV ", 4) == 0) { 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int error = 0; 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv = tncs_parse_imv(id++, pos + 4, line_end, &error); 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (error) 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (imv) { 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (last == NULL) 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->imv = imv; 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last->next = imv; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt last = imv; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(config); 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tncs_data * tncs_init(void) 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tncs_data *tncs; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_global_data == NULL) 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs = os_zalloc(sizeof(*tncs)); 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs == NULL) 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->imv = tncs_global_data->imv; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->connectionID = tncs_global_data->next_conn_id++; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs->next = tncs_global_data->connections; 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_global_data->connections = tncs; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tncs; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tncs_deinit(struct tncs_data *tncs) 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tncs_data *prev, *conn; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs == NULL) 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < TNC_MAX_IMV_ID; i++) 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs->imv_data[i].imv_send); 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = tncs_global_data->connections; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (conn) { 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == tncs) { 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = tncs->next; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_global_data->connections = tncs->next; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = conn; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = conn->next; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs->tncs_message); 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tncs_global_init(void) 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv; 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 111850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (tncs_global_data) 111950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return 0; 112050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_global_data = os_zalloc(sizeof(*tncs_global_data)); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_global_data == NULL) 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_read_config(tncs_global_data) < 0) { 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Failed to read TNC configuration"); 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (imv = tncs_global_data->imv; imv; imv = imv->next) { 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_load_imv(imv)) { 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TNC: Failed to load IMV '%s'", 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv->name); 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfailed: 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_global_deinit(); 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tncs_global_deinit(void) 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tnc_if_imv *imv, *prev; 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tncs_global_data == NULL) 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv = tncs_global_data->imv; 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (imv) { 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_unload_imv(imv); 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = imv; 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt imv = imv->next; 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tncs_global_data); 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_global_data = NULL; 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tncs_build_soh_request(void) 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Build a SoH Request TLV (to be used inside SoH EAP Extensions 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Method) 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(8 + 4); 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Vendor-Specific TLV (Microsoft) - SoH Request */ 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* TLV Type */ 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be16(buf, 8); /* Length */ 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* Vendor_Id */ 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be16(buf, 0x02); /* TLV Type - SoH Request TLV */ 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be16(buf, 0); /* Length */ 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tncs_process_soh(const u8 *soh_tlv, size_t soh_tlv_len, 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int *failure) 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TNC: SoH TLV", soh_tlv, soh_tlv_len); 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *failure = 0; 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: return MS-SoH Response TLV */ 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1203