Moved tnc-tnccs, tnc-imc, tnccs-11, tnccs-20 and tnccs-dynamic libcharon plugins to libtnccs
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libhydra \
|
||||
-I$(top_srcdir)/src/libcharon \
|
||||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libtnccs \
|
||||
-I$(top_srcdir)/src/libtls
|
||||
|
||||
AM_CFLAGS = \
|
||||
-rdynamic
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
|
||||
libstrongswan_tnc_imc_la_LIBADD = \
|
||||
$(top_builddir)/src/libtncif/libtncif.la \
|
||||
$(top_builddir)/src/libtnccs/libtnccs.la
|
||||
endif
|
||||
|
||||
libstrongswan_tnc_imc_la_SOURCES = \
|
||||
tnc_imc_plugin.h tnc_imc_plugin.c tnc_imc.h tnc_imc.c \
|
||||
tnc_imc_manager.h tnc_imc_manager.c tnc_imc_bind_function.c
|
||||
|
||||
libstrongswan_tnc_imc_la_LDFLAGS = -module -avoid-version
|
||||
@@ -1,428 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley
|
||||
* Copyright (C) 2010-2011 Andreas Steffen,
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnc_imc.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <tncif_pa_subtypes.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <library.h>
|
||||
#include <collections/linked_list.h>
|
||||
#include <threading/mutex.h>
|
||||
|
||||
typedef struct private_tnc_imc_t private_tnc_imc_t;
|
||||
|
||||
/**
|
||||
* Private data of an imc_t object.
|
||||
*/
|
||||
struct private_tnc_imc_t {
|
||||
|
||||
/**
|
||||
* Public members of imc_t.
|
||||
*/
|
||||
imc_t public;
|
||||
|
||||
/**
|
||||
* Name of loaded IMC
|
||||
*/
|
||||
char *name;
|
||||
|
||||
/**
|
||||
* Handle of loaded IMC
|
||||
*/
|
||||
void *handle;
|
||||
|
||||
/**
|
||||
* ID of loaded IMC
|
||||
*/
|
||||
TNC_IMCID id;
|
||||
|
||||
/**
|
||||
* list of additional IMC IDs
|
||||
*/
|
||||
linked_list_t *additional_ids;
|
||||
|
||||
/**
|
||||
* List of message types supported by IMC - Vendor ID part
|
||||
*/
|
||||
TNC_VendorIDList supported_vids;
|
||||
|
||||
/**
|
||||
* List of message types supported by IMC - Subtype part
|
||||
*/
|
||||
TNC_MessageSubtypeList supported_subtypes;
|
||||
|
||||
/**
|
||||
* Number of supported message types
|
||||
*/
|
||||
TNC_UInt32 type_count;
|
||||
|
||||
/**
|
||||
* mutex to lock the imc_t object
|
||||
*/
|
||||
mutex_t *mutex;
|
||||
};
|
||||
|
||||
METHOD(imc_t, set_id, void,
|
||||
private_tnc_imc_t *this, TNC_IMCID id)
|
||||
{
|
||||
this->id = id;
|
||||
}
|
||||
|
||||
METHOD(imc_t, get_id, TNC_IMCID,
|
||||
private_tnc_imc_t *this)
|
||||
{
|
||||
return this->id;
|
||||
}
|
||||
|
||||
METHOD(imc_t, add_id, void,
|
||||
private_tnc_imc_t *this, TNC_IMCID id)
|
||||
{
|
||||
void *pointer;
|
||||
|
||||
/* store the scalar value in the pointer */
|
||||
pointer = (void*)id;
|
||||
this->additional_ids->insert_last(this->additional_ids, pointer);
|
||||
}
|
||||
|
||||
METHOD(imc_t, has_id, bool,
|
||||
private_tnc_imc_t *this, TNC_IMCID id)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
TNC_IMCID additional_id;
|
||||
void *pointer;
|
||||
bool found = FALSE;
|
||||
|
||||
/* check primary IMC ID */
|
||||
if (id == this->id)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* return if there are no additional IMC IDs */
|
||||
if (this->additional_ids->get_count(this->additional_ids) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check additional IMC IDs */
|
||||
enumerator = this->additional_ids->create_enumerator(this->additional_ids);
|
||||
while (enumerator->enumerate(enumerator, &pointer))
|
||||
{
|
||||
/* interpret pointer as scalar value */
|
||||
additional_id = (TNC_UInt32)pointer;
|
||||
|
||||
if (id == additional_id)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(imc_t, get_name, char*,
|
||||
private_tnc_imc_t *this)
|
||||
{
|
||||
return this->name;
|
||||
}
|
||||
|
||||
METHOD(imc_t, set_message_types, void,
|
||||
private_tnc_imc_t *this, TNC_MessageTypeList supported_types,
|
||||
TNC_UInt32 type_count)
|
||||
{
|
||||
char buf[BUF_LEN];
|
||||
char *pos = buf;
|
||||
int len = sizeof(buf);
|
||||
int i, written;
|
||||
size_t size;
|
||||
TNC_VendorID vid;
|
||||
TNC_MessageSubtype subtype;
|
||||
enum_name_t *pa_subtype_names;
|
||||
|
||||
/* lock the imc_t instance */
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
/* Free existing VendorID and MessageSubtype lists */
|
||||
free(this->supported_vids);
|
||||
this->supported_vids = NULL;
|
||||
free(this->supported_subtypes);
|
||||
this->supported_subtypes = NULL;
|
||||
|
||||
/* Store the new MessageType list */
|
||||
this->type_count = type_count;
|
||||
if (type_count && supported_types)
|
||||
{
|
||||
size = type_count * sizeof(TNC_VendorID);
|
||||
this->supported_vids = malloc(size);
|
||||
size = type_count * sizeof(TNC_MessageSubtype);
|
||||
this->supported_subtypes = malloc(size);
|
||||
|
||||
for (i = 0; i < type_count; i++)
|
||||
{
|
||||
vid = (supported_types[i] >> 8) & TNC_VENDORID_ANY;
|
||||
subtype = supported_types[i] & TNC_SUBTYPE_ANY;
|
||||
|
||||
pa_subtype_names = get_pa_subtype_names(vid);
|
||||
if (pa_subtype_names)
|
||||
{
|
||||
written = snprintf(pos, len," '%N/%N' 0x%06x/0x%02x",
|
||||
pen_names, vid, pa_subtype_names, subtype,
|
||||
vid, subtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
written = snprintf(pos, len," '%N' 0x%06x/0x%02x",
|
||||
pen_names, vid, vid, subtype);
|
||||
}
|
||||
if (written >= len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += written;
|
||||
len -= written;
|
||||
|
||||
this->supported_vids[i] = vid;
|
||||
this->supported_subtypes[i] = subtype;
|
||||
}
|
||||
}
|
||||
*pos = '\0';
|
||||
DBG2(DBG_TNC, "IMC %u supports %u message type%s:%s",
|
||||
this->id, type_count, (type_count == 1) ? "":"s", buf);
|
||||
|
||||
/* unlock the imc_t instance */
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
METHOD(imc_t, set_message_types_long, void,
|
||||
private_tnc_imc_t *this, TNC_VendorIDList supported_vids,
|
||||
TNC_MessageSubtypeList supported_subtypes, TNC_UInt32 type_count)
|
||||
{
|
||||
char buf[BUF_LEN];
|
||||
char *pos = buf;
|
||||
int len = sizeof(buf);
|
||||
int i, written;
|
||||
size_t size;
|
||||
TNC_VendorID vid;
|
||||
TNC_MessageSubtype subtype;
|
||||
enum_name_t *pa_subtype_names;
|
||||
|
||||
/* lock the imc_t instance */
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
/* Free existing VendorID and MessageSubtype lists */
|
||||
free(this->supported_vids);
|
||||
this->supported_vids = NULL;
|
||||
free(this->supported_subtypes);
|
||||
this->supported_subtypes = NULL;
|
||||
|
||||
/* Store the new MessageType list */
|
||||
this->type_count = type_count;
|
||||
if (type_count && supported_vids && supported_subtypes)
|
||||
{
|
||||
size = type_count * sizeof(TNC_VendorID);
|
||||
this->supported_vids = malloc(size);
|
||||
memcpy(this->supported_vids, supported_vids, size);
|
||||
size = type_count * sizeof(TNC_MessageSubtype);
|
||||
this->supported_subtypes = malloc(size);
|
||||
memcpy(this->supported_subtypes, supported_subtypes, size);
|
||||
|
||||
for (i = 0; i < type_count; i++)
|
||||
{
|
||||
vid = supported_vids[i];
|
||||
subtype = supported_subtypes[i];
|
||||
|
||||
pa_subtype_names = get_pa_subtype_names(vid);
|
||||
if (pa_subtype_names)
|
||||
{
|
||||
written = snprintf(pos, len," '%N/%N' 0x%06x/0x%08x",
|
||||
pen_names, vid, pa_subtype_names, subtype,
|
||||
vid, subtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
written = snprintf(pos, len," '%N' 0x%06x/0x%08x",
|
||||
pen_names, vid, vid, subtype);
|
||||
}
|
||||
if (written >= len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += written;
|
||||
len -= written;
|
||||
}
|
||||
}
|
||||
*pos = '\0';
|
||||
DBG2(DBG_TNC, "IMC %u supports %u message type%s:%s",
|
||||
this->id, type_count, (type_count == 1) ? "":"s", buf);
|
||||
|
||||
/* unlock the imc_t instance */
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
|
||||
METHOD(imc_t, type_supported, bool,
|
||||
private_tnc_imc_t *this, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype)
|
||||
{
|
||||
TNC_VendorID vid;
|
||||
TNC_MessageSubtype subtype;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < this->type_count; i++)
|
||||
{
|
||||
vid = this->supported_vids[i];
|
||||
subtype = this->supported_subtypes[i];
|
||||
|
||||
if ((vid == TNC_VENDORID_ANY && subtype == TNC_SUBTYPE_ANY) ||
|
||||
(vid == msg_vid && (subtype == TNC_SUBTYPE_ANY ||
|
||||
subtype == msg_subtype)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(imc_t, destroy, void,
|
||||
private_tnc_imc_t *this)
|
||||
{
|
||||
if (this->handle && lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.tnc-imc.dlclose", TRUE, "charon"))
|
||||
{
|
||||
dlclose(this->handle);
|
||||
}
|
||||
this->mutex->destroy(this->mutex);
|
||||
this->additional_ids->destroy(this->additional_ids);
|
||||
free(this->supported_vids);
|
||||
free(this->supported_subtypes);
|
||||
free(this->name);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic constructor
|
||||
*/
|
||||
static private_tnc_imc_t* tnc_imc_create_empty(char *name)
|
||||
{
|
||||
private_tnc_imc_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.set_id = _set_id,
|
||||
.get_id = _get_id,
|
||||
.add_id = _add_id,
|
||||
.has_id = _has_id,
|
||||
.get_name = _get_name,
|
||||
.set_message_types = _set_message_types,
|
||||
.set_message_types_long = _set_message_types_long,
|
||||
.type_supported = _type_supported,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.name = strdup(name),
|
||||
.additional_ids = linked_list_create(),
|
||||
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
imc_t* tnc_imc_create(char *name, char *path)
|
||||
{
|
||||
private_tnc_imc_t *this;
|
||||
|
||||
this = tnc_imc_create_empty(name);
|
||||
|
||||
this->handle = dlopen(path, RTLD_LAZY);
|
||||
if (!this->handle)
|
||||
{
|
||||
DBG1(DBG_TNC, "IMC \"%s\" failed to load: %s", name, dlerror());
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->public.initialize = dlsym(this->handle, "TNC_IMC_Initialize");
|
||||
if (!this->public.initialize)
|
||||
{
|
||||
DBG1(DBG_TNC, "could not resolve TNC_IMC_Initialize in %s: %s\n",
|
||||
path, dlerror());
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
this->public.notify_connection_change =
|
||||
dlsym(this->handle, "TNC_IMC_NotifyConnectionChange");
|
||||
this->public.begin_handshake = dlsym(this->handle, "TNC_IMC_BeginHandshake");
|
||||
if (!this->public.begin_handshake)
|
||||
{
|
||||
DBG1(DBG_TNC, "could not resolve TNC_IMC_BeginHandshake in %s: %s\n",
|
||||
path, dlerror());
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
this->public.receive_message =
|
||||
dlsym(this->handle, "TNC_IMC_ReceiveMessage");
|
||||
this->public.receive_message_long =
|
||||
dlsym(this->handle, "TNC_IMC_ReceiveMessageLong");
|
||||
this->public.batch_ending =
|
||||
dlsym(this->handle, "TNC_IMC_BatchEnding");
|
||||
this->public.terminate =
|
||||
dlsym(this->handle, "TNC_IMC_Terminate");
|
||||
this->public.provide_bind_function =
|
||||
dlsym(this->handle, "TNC_IMC_ProvideBindFunction");
|
||||
if (!this->public.provide_bind_function)
|
||||
{
|
||||
DBG1(DBG_TNC, "could not resolve TNC_IMC_ProvideBindFunction in %s: %s\n",
|
||||
path, dlerror());
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
imc_t* tnc_imc_create_from_functions(char *name,
|
||||
TNC_IMC_InitializePointer initialize,
|
||||
TNC_IMC_NotifyConnectionChangePointer notify_connection_change,
|
||||
TNC_IMC_BeginHandshakePointer begin_handshake,
|
||||
TNC_IMC_ReceiveMessagePointer receive_message,
|
||||
TNC_IMC_ReceiveMessageLongPointer receive_message_long,
|
||||
TNC_IMC_BatchEndingPointer batch_ending,
|
||||
TNC_IMC_TerminatePointer terminate,
|
||||
TNC_IMC_ProvideBindFunctionPointer provide_bind_function)
|
||||
{
|
||||
private_tnc_imc_t *this;
|
||||
|
||||
this = tnc_imc_create_empty(name);
|
||||
|
||||
this->public.initialize = initialize;
|
||||
this->public.notify_connection_change = notify_connection_change;
|
||||
this->public.begin_handshake = begin_handshake;
|
||||
this->public.receive_message = receive_message;
|
||||
this->public.receive_message_long = receive_message_long;
|
||||
this->public.batch_ending = batch_ending;
|
||||
this->public.terminate = terminate;
|
||||
this->public.provide_bind_function = provide_bind_function;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @defgroup tnc_imc_t tnc_imc
|
||||
* @{ @ingroup tnc_imc
|
||||
*/
|
||||
|
||||
#ifndef TNC_IMC_H_
|
||||
#define TNC_IMC_H_
|
||||
|
||||
#include <tnc/imc/imc.h>
|
||||
|
||||
/**
|
||||
* Create an Integrity Measurement Collector loaded from a library.
|
||||
*
|
||||
* @param name name of the IMC
|
||||
* @param filename path to the dynamic IMC library
|
||||
* @return instance of the imc_t interface
|
||||
*/
|
||||
imc_t* tnc_imc_create(char *name, char *filename);
|
||||
|
||||
/**
|
||||
* Create an Integrity Measurement Collector from a set of IMC functions.
|
||||
*
|
||||
* @param name name of the IMC
|
||||
* @param initialize TNC_IMC_InitializePointer
|
||||
* @param notify_connection_change TNC_IMC_NotifyConnectionChangePointer
|
||||
* @param begin_handshake TNC_IMC_BeginHandshakePointer
|
||||
* @param receive_message TNC_IMC_ReceiveMessagePointer
|
||||
* @param receive_message_long TNC_IMC_ReceiveMessageLongPointer
|
||||
* @param batch_ending TNC_IMC_BatchEndingPointer
|
||||
* @param terminate TNC_IMC_TerminatePointer
|
||||
* @param provide_bind_function TNC_IMC_ProvideBindFunctionPointer
|
||||
* @return instance of the imc_t interface
|
||||
*/
|
||||
imc_t* tnc_imc_create_from_functions(char *name,
|
||||
TNC_IMC_InitializePointer initialize,
|
||||
TNC_IMC_NotifyConnectionChangePointer notify_connection_change,
|
||||
TNC_IMC_BeginHandshakePointer begin_handshake,
|
||||
TNC_IMC_ReceiveMessagePointer receive_message,
|
||||
TNC_IMC_ReceiveMessageLongPointer receive_message_long,
|
||||
TNC_IMC_BatchEndingPointer batch_ending,
|
||||
TNC_IMC_TerminatePointer terminate,
|
||||
TNC_IMC_ProvideBindFunctionPointer provide_bind_function);
|
||||
|
||||
#endif /** TNC_IMC_H_ @}*/
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
#include <tnc/imc/imc_manager.h>
|
||||
#include <tnc/tnccs/tnccs_manager.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
/**
|
||||
* Called by the IMC to inform a TNCC about the set of message types the IMC
|
||||
* is able to receive
|
||||
*/
|
||||
TNC_Result TNC_TNCC_ReportMessageTypes(TNC_IMCID imc_id,
|
||||
TNC_MessageTypeList supported_types,
|
||||
TNC_UInt32 type_count)
|
||||
{
|
||||
if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMC %u",
|
||||
imc_id);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return tnc->imcs->set_message_types(tnc->imcs, imc_id, supported_types,
|
||||
type_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the IMC to inform a TNCC about the set of message types the IMC
|
||||
* is able to receive. This function supports long message types.
|
||||
*/
|
||||
TNC_Result TNC_TNCC_ReportMessageTypesLong(TNC_IMCID imc_id,
|
||||
TNC_VendorIDList supported_vids,
|
||||
TNC_MessageSubtypeList supported_subtypes,
|
||||
TNC_UInt32 type_count)
|
||||
{
|
||||
if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring ReportMessageTypesLong() from unregistered IMC %u",
|
||||
imc_id);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return tnc->imcs->set_message_types_long(tnc->imcs, imc_id, supported_vids,
|
||||
supported_subtypes, type_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the IMC to ask a TNCC to retry an Integrity Check Handshake
|
||||
*/
|
||||
TNC_Result TNC_TNCC_RequestHandshakeRetry(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_RetryReason reason)
|
||||
{
|
||||
if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMC %u",
|
||||
imc_id);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return tnc->tnccs->request_handshake_retry(tnc->tnccs, TRUE, imc_id,
|
||||
connection_id, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the IMC when an IMC-IMV message is to be sent
|
||||
*/
|
||||
TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_MessageType msg_type)
|
||||
{
|
||||
TNC_VendorID msg_vid;
|
||||
TNC_MessageSubtype msg_subtype;
|
||||
|
||||
if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u",
|
||||
imc_id);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
|
||||
msg_subtype = msg_type & TNC_SUBTYPE_ANY;
|
||||
|
||||
return tnc->tnccs->send_message(tnc->tnccs, imc_id, TNC_IMVID_ANY,
|
||||
connection_id, 0, msg, msg_len, msg_vid, msg_subtype);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the IMC when an IMC-IMV message is to be sent over IF-TNCCS 2.0
|
||||
*/
|
||||
TNC_Result TNC_TNCC_SendMessageLong(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_UInt32 msg_flags,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_VendorID msg_vid,
|
||||
TNC_MessageSubtype msg_subtype,
|
||||
TNC_UInt32 imv_id)
|
||||
{
|
||||
if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u",
|
||||
imc_id);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return tnc->tnccs->send_message(tnc->tnccs, imc_id, imv_id, connection_id,
|
||||
msg_flags, msg, msg_len, msg_vid, msg_subtype);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the IMC to get the value of an attribute associated with a
|
||||
* connection or with the TNCC as a whole.
|
||||
*/
|
||||
TNC_Result TNC_TNCC_GetAttribute(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_AttributeID attribute_id,
|
||||
TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer,
|
||||
TNC_UInt32 *out_value_len)
|
||||
{
|
||||
if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMC %u",
|
||||
imc_id);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return tnc->tnccs->get_attribute(tnc->tnccs, TRUE, imc_id, connection_id,
|
||||
attribute_id, buffer_len, buffer, out_value_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the IMC to set the value of an attribute associated with a
|
||||
* connection or with the TNCC as a whole.
|
||||
*/
|
||||
TNC_Result TNC_TNCC_SetAttribute(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_AttributeID attribute_id,
|
||||
TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer)
|
||||
{
|
||||
if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMC %u",
|
||||
imc_id);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return tnc->tnccs->set_attribute(tnc->tnccs, TRUE, imc_id, connection_id,
|
||||
attribute_id, buffer_len, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the IMC when it wants to reserve an additional IMC ID for itself
|
||||
*/
|
||||
TNC_Result TNC_TNCC_ReserveAdditionalIMCID(TNC_IMCID imc_id, TNC_UInt32 *new_id)
|
||||
{
|
||||
if (tnc->imcs->reserve_id(tnc->imcs, imc_id, new_id))
|
||||
{
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
DBG1(DBG_TNC, "ignoring ReserveAdditionalIMCID() from unregistered IMC %u",
|
||||
imc_id);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the IMC when it needs a function pointer
|
||||
*/
|
||||
TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id,
|
||||
char *function_name,
|
||||
void **function_pointer)
|
||||
{
|
||||
if (streq(function_name, "TNC_TNCC_ReportMessageTypes"))
|
||||
{
|
||||
*function_pointer = (void*)TNC_TNCC_ReportMessageTypes;
|
||||
}
|
||||
else if (streq(function_name, "TNC_TNCC_ReportMessageTypesLong"))
|
||||
{
|
||||
*function_pointer = (void*)TNC_TNCC_ReportMessageTypesLong;
|
||||
}
|
||||
else if (streq(function_name, "TNC_TNCC_RequestHandshakeRetry"))
|
||||
{
|
||||
*function_pointer = (void*)TNC_TNCC_RequestHandshakeRetry;
|
||||
}
|
||||
else if (streq(function_name, "TNC_TNCC_SendMessage"))
|
||||
{
|
||||
*function_pointer = (void*)TNC_TNCC_SendMessage;
|
||||
}
|
||||
else if (streq(function_name, "TNC_TNCC_SendMessageLong"))
|
||||
{
|
||||
*function_pointer = (void*)TNC_TNCC_SendMessageLong;
|
||||
}
|
||||
else if (streq(function_name, "TNC_TNCC_GetAttribute"))
|
||||
{
|
||||
*function_pointer = (void*)TNC_TNCC_GetAttribute;
|
||||
}
|
||||
else if (streq(function_name, "TNC_TNCC_SetAttribute"))
|
||||
{
|
||||
*function_pointer = (void*)TNC_TNCC_SetAttribute;
|
||||
}
|
||||
else if (streq(function_name, "TNC_TNCC_ReserveAdditionalIMCID"))
|
||||
{
|
||||
*function_pointer = (void*)TNC_TNCC_ReserveAdditionalIMCID;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
@@ -1,441 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley
|
||||
* Copyright (C) 2010-2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnc_imc_manager.h"
|
||||
#include "tnc_imc.h"
|
||||
|
||||
#include <tncifimc.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <threading/rwlock.h>
|
||||
#include <threading/mutex.h>
|
||||
#include <collections/linked_list.h>
|
||||
|
||||
typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t;
|
||||
|
||||
/**
|
||||
* Private data of an imc_manager_t object.
|
||||
*/
|
||||
struct private_tnc_imc_manager_t {
|
||||
|
||||
/**
|
||||
* Public members of imc_manager_t.
|
||||
*/
|
||||
imc_manager_t public;
|
||||
|
||||
/**
|
||||
* Linked list of IMCs
|
||||
*/
|
||||
linked_list_t *imcs;
|
||||
|
||||
/**
|
||||
* Lock to access IMC list
|
||||
*/
|
||||
rwlock_t *lock;
|
||||
|
||||
/**
|
||||
* Next IMC ID to be assigned
|
||||
*/
|
||||
TNC_IMCID next_imc_id;
|
||||
|
||||
/**
|
||||
* Mutex to access next IMC ID
|
||||
*/
|
||||
mutex_t *id_mutex;
|
||||
};
|
||||
|
||||
METHOD(imc_manager_t, add, bool,
|
||||
private_tnc_imc_manager_t *this, imc_t *imc)
|
||||
{
|
||||
TNC_Version version;
|
||||
TNC_IMCID imc_id;
|
||||
|
||||
this->id_mutex->lock(this->id_mutex);
|
||||
imc_id = this->next_imc_id++;
|
||||
this->id_mutex->unlock(this->id_mutex);
|
||||
|
||||
imc->set_id(imc, imc_id);
|
||||
if (imc->initialize(imc_id, TNC_IFIMC_VERSION_1,
|
||||
TNC_IFIMC_VERSION_1, &version) != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_TNC, "IMC \"%s\" failed to initialize", imc->get_name(imc));
|
||||
return FALSE;
|
||||
}
|
||||
this->lock->write_lock(this->lock);
|
||||
this->imcs->insert_last(this->imcs, imc);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
if (imc->provide_bind_function(imc->get_id(imc),
|
||||
TNC_TNCC_BindFunction) != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
if (imc->terminate)
|
||||
{
|
||||
imc->terminate(imc->get_id(imc));
|
||||
}
|
||||
DBG1(DBG_TNC, "IMC \"%s\" failed to obtain bind function",
|
||||
imc->get_name(imc));
|
||||
this->lock->write_lock(this->lock);
|
||||
this->imcs->remove_last(this->imcs, (void**)&imc);
|
||||
this->lock->unlock(this->lock);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, remove_, imc_t*,
|
||||
private_tnc_imc_manager_t *this, TNC_IMCID id)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc, *removed_imc = NULL;
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
if (id == imc->get_id(imc))
|
||||
{
|
||||
this->imcs->remove_at(this->imcs, enumerator);
|
||||
removed_imc = imc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
return removed_imc;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, load, bool,
|
||||
private_tnc_imc_manager_t *this, char *name, char *path)
|
||||
{
|
||||
imc_t *imc;
|
||||
|
||||
imc = tnc_imc_create(name, path);
|
||||
if (!imc)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!add(this, imc))
|
||||
{
|
||||
imc->destroy(imc);
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc), name, path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, load_from_functions, bool,
|
||||
private_tnc_imc_manager_t *this, char *name,
|
||||
TNC_IMC_InitializePointer initialize,
|
||||
TNC_IMC_NotifyConnectionChangePointer notify_connection_change,
|
||||
TNC_IMC_BeginHandshakePointer begin_handshake,
|
||||
TNC_IMC_ReceiveMessagePointer receive_message,
|
||||
TNC_IMC_ReceiveMessageLongPointer receive_message_long,
|
||||
TNC_IMC_BatchEndingPointer batch_ending,
|
||||
TNC_IMC_TerminatePointer terminate,
|
||||
TNC_IMC_ProvideBindFunctionPointer provide_bind_function)
|
||||
{
|
||||
imc_t *imc;
|
||||
|
||||
imc = tnc_imc_create_from_functions(name,
|
||||
initialize, notify_connection_change,
|
||||
begin_handshake, receive_message,
|
||||
receive_message_long, batch_ending,
|
||||
terminate, provide_bind_function);
|
||||
if (!imc)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!add(this, imc))
|
||||
{
|
||||
imc->destroy(imc);
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_TNC, "IMC %u \"%s\" loaded", imc->get_id(imc), name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, is_registered, bool,
|
||||
private_tnc_imc_manager_t *this, TNC_IMCID id)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc;
|
||||
bool found = FALSE;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
if (imc->has_id(imc, id))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, reserve_id, bool,
|
||||
private_tnc_imc_manager_t *this, TNC_IMCID id, TNC_UInt32 *new_id)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc;
|
||||
bool found = FALSE;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
if (id == imc->get_id(imc))
|
||||
{
|
||||
found = TRUE;
|
||||
this->id_mutex->lock(this->id_mutex);
|
||||
*new_id = this->next_imc_id++;
|
||||
this->id_mutex->unlock(this->id_mutex);
|
||||
imc->add_id(imc, *new_id);
|
||||
DBG2(DBG_TNC, "additional ID %u reserved for IMC with primary ID %u",
|
||||
*new_id, id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, get_preferred_language, char*,
|
||||
private_tnc_imc_manager_t *this)
|
||||
{
|
||||
return lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.tnc-imc.preferred_language", "en", "charon");
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, notify_connection_change, void,
|
||||
private_tnc_imc_manager_t *this, TNC_ConnectionID id,
|
||||
TNC_ConnectionState state)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
if (imc->notify_connection_change)
|
||||
{
|
||||
imc->notify_connection_change(imc->get_id(imc), id, state);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, begin_handshake, void,
|
||||
private_tnc_imc_manager_t *this, TNC_ConnectionID id)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
imc->begin_handshake(imc->get_id(imc), id);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, set_message_types, TNC_Result,
|
||||
private_tnc_imc_manager_t *this, TNC_IMCID id,
|
||||
TNC_MessageTypeList supported_types,
|
||||
TNC_UInt32 type_count)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc;
|
||||
TNC_Result result = TNC_RESULT_FATAL;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
if (id == imc->get_id(imc))
|
||||
{
|
||||
imc->set_message_types(imc, supported_types, type_count);
|
||||
result = TNC_RESULT_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, set_message_types_long, TNC_Result,
|
||||
private_tnc_imc_manager_t *this, TNC_IMCID id,
|
||||
TNC_VendorIDList supported_vids,
|
||||
TNC_MessageSubtypeList supported_subtypes,
|
||||
TNC_UInt32 type_count)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc;
|
||||
TNC_Result result = TNC_RESULT_FATAL;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
if (id == imc->get_id(imc))
|
||||
{
|
||||
imc->set_message_types_long(imc, supported_vids, supported_subtypes,
|
||||
type_count);
|
||||
result = TNC_RESULT_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, receive_message, void,
|
||||
private_tnc_imc_manager_t *this, TNC_ConnectionID connection_id,
|
||||
bool excl,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_VendorID msg_vid,
|
||||
TNC_MessageSubtype msg_subtype,
|
||||
TNC_UInt32 src_imv_id,
|
||||
TNC_UInt32 dst_imc_id)
|
||||
{
|
||||
bool type_supported = FALSE;
|
||||
TNC_MessageType msg_type;
|
||||
TNC_UInt32 msg_flags;
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
if (imc->type_supported(imc, msg_vid, msg_subtype) &&
|
||||
(!excl || (excl && imc->has_id(imc, dst_imc_id))))
|
||||
{
|
||||
if (imc->receive_message_long && src_imv_id)
|
||||
{
|
||||
type_supported = TRUE;
|
||||
msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
|
||||
imc->receive_message_long(imc->get_id(imc), connection_id,
|
||||
msg_flags, msg, msg_len, msg_vid, msg_subtype,
|
||||
src_imv_id, dst_imc_id);
|
||||
|
||||
}
|
||||
else if (imc->receive_message && msg_vid <= TNC_VENDORID_ANY &&
|
||||
msg_subtype <= TNC_SUBTYPE_ANY)
|
||||
{
|
||||
type_supported = TRUE;
|
||||
msg_type = (msg_vid << 8) | msg_subtype;
|
||||
imc->receive_message(imc->get_id(imc), connection_id,
|
||||
msg, msg_len, msg_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
if (!type_supported)
|
||||
{
|
||||
DBG2(DBG_TNC, "message type 0x%06x/0x%08x not supported by any IMC",
|
||||
msg_vid, msg_subtype);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, batch_ending, void,
|
||||
private_tnc_imc_manager_t *this, TNC_ConnectionID id)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_t *imc;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc))
|
||||
{
|
||||
if (imc->batch_ending)
|
||||
{
|
||||
imc->batch_ending(imc->get_id(imc), id);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, destroy, void,
|
||||
private_tnc_imc_manager_t *this)
|
||||
{
|
||||
imc_t *imc;
|
||||
|
||||
while (this->imcs->remove_last(this->imcs, (void**)&imc) == SUCCESS)
|
||||
{
|
||||
if (imc->terminate &&
|
||||
imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
|
||||
imc->get_name(imc));
|
||||
}
|
||||
imc->destroy(imc);
|
||||
}
|
||||
this->imcs->destroy(this->imcs);
|
||||
this->lock->destroy(this->lock);
|
||||
this->id_mutex->destroy(this->id_mutex);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
imc_manager_t* tnc_imc_manager_create(void)
|
||||
{
|
||||
private_tnc_imc_manager_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.add = _add,
|
||||
.remove = _remove_, /* avoid name conflict with stdio.h */
|
||||
.load = _load,
|
||||
.load_from_functions = _load_from_functions,
|
||||
.is_registered = _is_registered,
|
||||
.reserve_id = _reserve_id,
|
||||
.get_preferred_language = _get_preferred_language,
|
||||
.notify_connection_change = _notify_connection_change,
|
||||
.begin_handshake = _begin_handshake,
|
||||
.set_message_types = _set_message_types,
|
||||
.set_message_types_long = _set_message_types_long,
|
||||
.receive_message = _receive_message,
|
||||
.batch_ending = _batch_ending,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.imcs = linked_list_create(),
|
||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
.id_mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||
.next_imc_id = 1,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @defgroup tnc_imc_manager tnc_imc_manager
|
||||
* @{ @ingroup tnc_imc
|
||||
*/
|
||||
|
||||
#ifndef TNC_IMC_MANAGER_H_
|
||||
#define TNC_IMC_MANAGER_H_
|
||||
|
||||
#include <tnc/imc/imc_manager.h>
|
||||
|
||||
/**
|
||||
* Create an IMC manager instance.
|
||||
*/
|
||||
imc_manager_t *tnc_imc_manager_create();
|
||||
|
||||
#endif /** TNC_IMC_MANAGER_H_ @}*/
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnc_imc_plugin.h"
|
||||
#include "tnc_imc_manager.h"
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
|
||||
typedef struct private_tnc_imc_plugin_t private_tnc_imc_plugin_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnc_imc_plugin_t object.
|
||||
*/
|
||||
struct private_tnc_imc_plugin_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
tnc_imc_plugin_t public;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_tnc_imc_plugin_t *this)
|
||||
{
|
||||
return "tnc-imc";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_tnc_imc_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(tnc_manager_register, tnc_imc_manager_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "imc-manager"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
|
||||
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
|
||||
PLUGIN_SDEPEND(CERT_DECODE, CERT_TRUSTED_PUBKEY),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_tnc_imc_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *tnc_imc_plugin_create(void)
|
||||
{
|
||||
private_tnc_imc_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnc_imc tnc_imc
|
||||
* @ingroup cplugins
|
||||
*
|
||||
* @defgroup tnc_imc_plugin tnc_imc_plugin
|
||||
* @{ @ingroup tnc_imc
|
||||
*/
|
||||
|
||||
#ifndef TNC_IMC_PLUGIN_H_
|
||||
#define TNC_IMC_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct tnc_imc_plugin_t tnc_imc_plugin_t;
|
||||
|
||||
/**
|
||||
* TNC IMC plugin
|
||||
*/
|
||||
struct tnc_imc_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** TNC_IMC_PLUGIN_H_ @}*/
|
||||
@@ -1,23 +0,0 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libtls \
|
||||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libtnccs
|
||||
|
||||
AM_CFLAGS = \
|
||||
-rdynamic
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-tnc-tnccs.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-tnc-tnccs.la
|
||||
libstrongswan_tnc_tnccs_la_LIBADD = \
|
||||
$(top_builddir)/src/libtncif/libtncif.la \
|
||||
$(top_builddir)/src/libtnccs/libtnccs.la
|
||||
endif
|
||||
|
||||
libstrongswan_tnc_tnccs_la_SOURCES = \
|
||||
tnc_tnccs_plugin.h tnc_tnccs_plugin.c \
|
||||
tnc_tnccs_manager.h tnc_tnccs_manager.c
|
||||
|
||||
libstrongswan_tnc_tnccs_la_LDFLAGS = -module -avoid-version
|
||||
@@ -1,866 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for asprintf() */
|
||||
|
||||
#include "tnc_tnccs_manager.h"
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
#include <tnc/imv/imv_manager.h>
|
||||
#include <tnc/imc/imc_manager.h>
|
||||
#include <tnc/imv/imv_manager.h>
|
||||
|
||||
#include <tncif_identity.h>
|
||||
|
||||
#include <tls.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <pen/pen.h>
|
||||
#include <bio/bio_writer.h>
|
||||
#include <collections/linked_list.h>
|
||||
#include <threading/rwlock.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct private_tnc_tnccs_manager_t private_tnc_tnccs_manager_t;
|
||||
typedef struct tnccs_entry_t tnccs_entry_t;
|
||||
typedef struct tnccs_connection_entry_t tnccs_connection_entry_t;
|
||||
|
||||
/**
|
||||
* TNCCS constructor entry
|
||||
*/
|
||||
struct tnccs_entry_t {
|
||||
|
||||
/**
|
||||
* TNCCS protocol type
|
||||
*/
|
||||
tnccs_type_t type;
|
||||
|
||||
/**
|
||||
* constructor function to create instance
|
||||
*/
|
||||
tnccs_constructor_t constructor;
|
||||
};
|
||||
|
||||
/**
|
||||
* TNCCS connection entry
|
||||
*/
|
||||
struct tnccs_connection_entry_t {
|
||||
|
||||
/**
|
||||
* TNCCS connection ID
|
||||
*/
|
||||
TNC_ConnectionID id;
|
||||
|
||||
/**
|
||||
* TNCCS protocol type
|
||||
*/
|
||||
tnccs_type_t type;
|
||||
|
||||
/**
|
||||
* TNCCS instance
|
||||
*/
|
||||
tnccs_t *tnccs;
|
||||
|
||||
/**
|
||||
* TNCCS send message function
|
||||
*/
|
||||
tnccs_send_message_t send_message;
|
||||
|
||||
/**
|
||||
* TNCCS request handshake retry flag
|
||||
*/
|
||||
bool *request_handshake_retry;
|
||||
|
||||
/**
|
||||
* Maximum size of a PA-TNC message
|
||||
*/
|
||||
u_int32_t max_msg_len;
|
||||
|
||||
/**
|
||||
* collection of IMV recommendations
|
||||
*/
|
||||
recommendations_t *recs;
|
||||
};
|
||||
|
||||
/**
|
||||
* private data of tnc_tnccs_manager
|
||||
*/
|
||||
struct private_tnc_tnccs_manager_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
tnccs_manager_t public;
|
||||
|
||||
/**
|
||||
* list of TNCCS protocol entries
|
||||
*/
|
||||
linked_list_t *protocols;
|
||||
|
||||
/**
|
||||
* rwlock to lock the TNCCS protocol entries
|
||||
*/
|
||||
rwlock_t *protocol_lock;
|
||||
|
||||
/**
|
||||
* connection ID counter
|
||||
*/
|
||||
TNC_ConnectionID connection_id;
|
||||
|
||||
/**
|
||||
* list of TNCCS connection entries
|
||||
*/
|
||||
linked_list_t *connections;
|
||||
|
||||
/**
|
||||
* rwlock to lock TNCCS connection entries
|
||||
*/
|
||||
rwlock_t *connection_lock;
|
||||
|
||||
};
|
||||
|
||||
METHOD(tnccs_manager_t, add_method, void,
|
||||
private_tnc_tnccs_manager_t *this, tnccs_type_t type,
|
||||
tnccs_constructor_t constructor)
|
||||
{
|
||||
tnccs_entry_t *entry;
|
||||
|
||||
entry = malloc_thing(tnccs_entry_t);
|
||||
entry->type = type;
|
||||
entry->constructor = constructor;
|
||||
|
||||
this->protocol_lock->write_lock(this->protocol_lock);
|
||||
this->protocols->insert_last(this->protocols, entry);
|
||||
this->protocol_lock->unlock(this->protocol_lock);
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, remove_method, void,
|
||||
private_tnc_tnccs_manager_t *this, tnccs_constructor_t constructor)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_entry_t *entry;
|
||||
|
||||
this->protocol_lock->write_lock(this->protocol_lock);
|
||||
enumerator = this->protocols->create_enumerator(this->protocols);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (constructor == entry->constructor)
|
||||
{
|
||||
this->protocols->remove_at(this->protocols, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->protocol_lock->unlock(this->protocol_lock);
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, create_instance, tnccs_t*,
|
||||
private_tnc_tnccs_manager_t *this, tnccs_type_t type, bool is_server,
|
||||
identification_t *server, identification_t *peer,
|
||||
tnc_ift_type_t transport)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_entry_t *entry;
|
||||
tnccs_t *protocol = NULL;
|
||||
|
||||
this->protocol_lock->read_lock(this->protocol_lock);
|
||||
enumerator = this->protocols->create_enumerator(this->protocols);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (type == entry->type)
|
||||
{
|
||||
protocol = entry->constructor(is_server, server, peer, transport);
|
||||
if (protocol)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->protocol_lock->unlock(this->protocol_lock);
|
||||
|
||||
return protocol;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID,
|
||||
private_tnc_tnccs_manager_t *this, tnccs_type_t type, tnccs_t *tnccs,
|
||||
tnccs_send_message_t send_message, bool* request_handshake_retry,
|
||||
u_int32_t max_msg_len, recommendations_t **recs)
|
||||
{
|
||||
tnccs_connection_entry_t *entry;
|
||||
|
||||
entry = malloc_thing(tnccs_connection_entry_t);
|
||||
entry->type = type;
|
||||
entry->tnccs = tnccs;
|
||||
entry->send_message = send_message;
|
||||
entry->request_handshake_retry = request_handshake_retry;
|
||||
entry->max_msg_len = max_msg_len;
|
||||
if (recs)
|
||||
{
|
||||
/* we assume a TNC Server needing recommendations from IMVs */
|
||||
if (!tnc->imvs)
|
||||
{
|
||||
DBG1(DBG_TNC, "no IMV manager available!");
|
||||
free(entry);
|
||||
return 0;
|
||||
}
|
||||
entry->recs = tnc->imvs->create_recommendations(tnc->imvs);
|
||||
*recs = entry->recs;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we assume a TNC Client */
|
||||
if (!tnc->imcs)
|
||||
{
|
||||
DBG1(DBG_TNC, "no IMC manager available!");
|
||||
free(entry);
|
||||
return 0;
|
||||
}
|
||||
entry->recs = NULL;
|
||||
}
|
||||
this->connection_lock->write_lock(this->connection_lock);
|
||||
entry->id = ++this->connection_id;
|
||||
this->connections->insert_last(this->connections, entry);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
DBG1(DBG_TNC, "assigned TNCCS Connection ID %u", entry->id);
|
||||
return entry->id;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, remove_connection, void,
|
||||
private_tnc_tnccs_manager_t *this, TNC_ConnectionID id, bool is_server)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
|
||||
if (is_server)
|
||||
{
|
||||
if (tnc->imvs)
|
||||
{
|
||||
tnc->imvs->notify_connection_change(tnc->imvs, id,
|
||||
TNC_CONNECTION_STATE_DELETE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tnc->imcs)
|
||||
{
|
||||
tnc->imcs->notify_connection_change(tnc->imcs, id,
|
||||
TNC_CONNECTION_STATE_DELETE);
|
||||
}
|
||||
}
|
||||
|
||||
this->connection_lock->write_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
this->connections->remove_at(this->connections, enumerator);
|
||||
if (entry->recs)
|
||||
{
|
||||
entry->recs->destroy(entry->recs);
|
||||
}
|
||||
free(entry);
|
||||
DBG1(DBG_TNC, "removed TNCCS Connection ID %u", id);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, request_handshake_retry, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, bool is_imc, TNC_UInt32 imcv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_RetryReason reason)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
|
||||
if (id == TNC_CONNECTIONID_ANY)
|
||||
{
|
||||
DBG2(DBG_TNC, "%s %u requests handshake retry for all connections "
|
||||
"(reason: %u)", is_imc ? "IMC":"IMV", reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_TNC, "%s %u requests handshake retry for Connection ID %u "
|
||||
"(reason: %u)", is_imc ? "IMC":"IMV", imcv_id, id, reason);
|
||||
}
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == TNC_CONNECTIONID_ANY || id == entry->id)
|
||||
{
|
||||
*entry->request_handshake_retry = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, send_message, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, TNC_IMCID imc_id, TNC_IMVID imv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_UInt32 msg_flags,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_VendorID msg_vid,
|
||||
TNC_MessageSubtype msg_subtype)
|
||||
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
tnccs_send_message_t send_message = NULL;
|
||||
tnccs_t *tnccs = NULL;
|
||||
|
||||
if (msg_vid == TNC_VENDORID_ANY || msg_subtype == TNC_SUBTYPE_ANY)
|
||||
{
|
||||
DBG1(DBG_TNC, "not sending message of invalid type 0x%02x/0x%08x",
|
||||
msg_vid, msg_subtype);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
tnccs = entry->tnccs;
|
||||
send_message = entry->send_message;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
if (tnccs && send_message)
|
||||
{
|
||||
return send_message(tnccs, imc_id, imv_id, msg_flags, msg, msg_len,
|
||||
msg_vid, msg_subtype);
|
||||
}
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, provide_recommendation, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, TNC_IMVID imv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_IMV_Action_Recommendation rec,
|
||||
TNC_IMV_Evaluation_Result eval)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
recommendations_t *recs = NULL;
|
||||
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
recs = entry->recs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
if (recs)
|
||||
{
|
||||
recs->provide_recommendation(recs, imv_id, rec, eval);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the value of a boolean attribute into the buffer
|
||||
*/
|
||||
static TNC_Result bool_attribute(TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer,
|
||||
TNC_UInt32 *value_len,
|
||||
bool value)
|
||||
{
|
||||
*value_len = 1;
|
||||
|
||||
if (buffer && buffer_len > 0)
|
||||
{
|
||||
*buffer = value ? 0x01 : 0x00;
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the value of an u_int32_t attribute into the buffer
|
||||
*/
|
||||
static TNC_Result uint_attribute(TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer,
|
||||
TNC_UInt32 *value_len,
|
||||
u_int32_t value)
|
||||
{
|
||||
*value_len = sizeof(u_int32_t);
|
||||
|
||||
if (buffer && buffer_len >= *value_len)
|
||||
{
|
||||
htoun32(buffer, value);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the value of string attribute into the buffer
|
||||
*/
|
||||
static TNC_Result str_attribute(TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer,
|
||||
TNC_UInt32 *value_len,
|
||||
char *value)
|
||||
{
|
||||
*value_len = 1 + strlen(value);
|
||||
|
||||
if (buffer && buffer_len >= *value_len)
|
||||
{
|
||||
snprintf(buffer, buffer_len, "%s", value);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the value of a TNC identity list into the buffer
|
||||
*/
|
||||
static TNC_Result identity_attribute(TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer,
|
||||
TNC_UInt32 *value_len,
|
||||
linked_list_t *list)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
enumerator_t *enumerator;
|
||||
u_int32_t count;
|
||||
chunk_t value;
|
||||
tncif_identity_t *tnc_id;
|
||||
TNC_Result result = TNC_RESULT_INVALID_PARAMETER;
|
||||
|
||||
count = list->get_count(list);
|
||||
writer = bio_writer_create(4 + TNCIF_IDENTITY_MIN_SIZE * count);
|
||||
writer->write_uint32(writer, count);
|
||||
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &tnc_id))
|
||||
{
|
||||
tnc_id->build(tnc_id, writer);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
value = writer->get_buf(writer);
|
||||
*value_len = value.len;
|
||||
if (buffer && buffer_len >= value.len)
|
||||
{
|
||||
memcpy(buffer, value.ptr, value.len);
|
||||
result = TNC_RESULT_SUCCESS;
|
||||
}
|
||||
writer->destroy(writer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, get_attribute, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, bool is_imc,
|
||||
TNC_UInt32 imcv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_AttributeID attribute_id,
|
||||
TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer,
|
||||
TNC_UInt32 *value_len)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
bool attribute_match = FALSE, entry_found = FALSE;
|
||||
|
||||
if (is_imc)
|
||||
{
|
||||
switch (attribute_id)
|
||||
{
|
||||
/* these attributes are unsupported */
|
||||
case TNC_ATTRIBUTEID_SOHR:
|
||||
case TNC_ATTRIBUTEID_SSOHR:
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
|
||||
/* these attributes are supported */
|
||||
case TNC_ATTRIBUTEID_PRIMARY_IMC_ID:
|
||||
attribute_match = TRUE;
|
||||
break;
|
||||
|
||||
/* these attributes are yet to be matched */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (attribute_id)
|
||||
{
|
||||
/* these attributes are unsupported or invalid */
|
||||
case TNC_ATTRIBUTEID_REASON_STRING:
|
||||
case TNC_ATTRIBUTEID_REASON_LANGUAGE:
|
||||
case TNC_ATTRIBUTEID_SOH:
|
||||
case TNC_ATTRIBUTEID_SSOH:
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
|
||||
/* these attributes are supported */
|
||||
case TNC_ATTRIBUTEID_PRIMARY_IMV_ID:
|
||||
case TNC_ATTRIBUTEID_AR_IDENTITIES:
|
||||
attribute_match = TRUE;
|
||||
break;
|
||||
|
||||
/* these attributes are yet to be matched */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!attribute_match)
|
||||
{
|
||||
switch (attribute_id)
|
||||
{
|
||||
/* these attributes are supported */
|
||||
case TNC_ATTRIBUTEID_PREFERRED_LANGUAGE:
|
||||
case TNC_ATTRIBUTEID_MAX_ROUND_TRIPS:
|
||||
case TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE:
|
||||
case TNC_ATTRIBUTEID_HAS_LONG_TYPES:
|
||||
case TNC_ATTRIBUTEID_HAS_EXCLUSIVE:
|
||||
case TNC_ATTRIBUTEID_HAS_SOH:
|
||||
case TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL:
|
||||
case TNC_ATTRIBUTEID_IFTNCCS_VERSION:
|
||||
case TNC_ATTRIBUTEID_IFT_PROTOCOL:
|
||||
case TNC_ATTRIBUTEID_IFT_VERSION:
|
||||
break;
|
||||
|
||||
/* these attributes are unsupported or unknown */
|
||||
case TNC_ATTRIBUTEID_DHPN:
|
||||
case TNC_ATTRIBUTEID_TLS_UNIQUE:
|
||||
default:
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/* attributes specific to the TNCC or TNCS are unsupported */
|
||||
if (id == TNC_CONNECTIONID_ANY)
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
entry_found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
if (!entry_found)
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (attribute_id)
|
||||
{
|
||||
case TNC_ATTRIBUTEID_PREFERRED_LANGUAGE:
|
||||
{
|
||||
recommendations_t *recs;
|
||||
chunk_t pref_lang;
|
||||
|
||||
recs = entry->recs;
|
||||
if (!recs)
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
pref_lang = recs->get_preferred_language(recs);
|
||||
if (pref_lang.len == 0)
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
*value_len = pref_lang.len;
|
||||
if (buffer && buffer_len >= pref_lang.len)
|
||||
{
|
||||
memcpy(buffer, pref_lang.ptr, pref_lang.len);
|
||||
}
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
case TNC_ATTRIBUTEID_MAX_ROUND_TRIPS:
|
||||
return uint_attribute(buffer_len, buffer, value_len,
|
||||
0xffffffff);
|
||||
case TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE:
|
||||
return uint_attribute(buffer_len, buffer, value_len,
|
||||
entry->max_msg_len);
|
||||
case TNC_ATTRIBUTEID_HAS_LONG_TYPES:
|
||||
case TNC_ATTRIBUTEID_HAS_EXCLUSIVE:
|
||||
return bool_attribute(buffer_len, buffer, value_len,
|
||||
entry->type == TNCCS_2_0);
|
||||
case TNC_ATTRIBUTEID_HAS_SOH:
|
||||
return bool_attribute(buffer_len, buffer, value_len,
|
||||
entry->type == TNCCS_SOH);
|
||||
case TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL:
|
||||
{
|
||||
char *protocol;
|
||||
|
||||
switch (entry->type)
|
||||
{
|
||||
case TNCCS_1_1:
|
||||
case TNCCS_2_0:
|
||||
protocol = "IF-TNCCS";
|
||||
break;
|
||||
case TNCCS_SOH:
|
||||
protocol = "IF-TNCCS-SOH";
|
||||
break;
|
||||
default:
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return str_attribute(buffer_len, buffer, value_len, protocol);
|
||||
}
|
||||
case TNC_ATTRIBUTEID_IFTNCCS_VERSION:
|
||||
{
|
||||
char *version;
|
||||
|
||||
switch (entry->type)
|
||||
{
|
||||
case TNCCS_1_1:
|
||||
version = "1.1";
|
||||
break;
|
||||
case TNCCS_2_0:
|
||||
version = "2.0";
|
||||
break;
|
||||
case TNCCS_SOH:
|
||||
version = "1.0";
|
||||
break;
|
||||
default:
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return str_attribute(buffer_len, buffer, value_len, version);
|
||||
}
|
||||
case TNC_ATTRIBUTEID_IFT_PROTOCOL:
|
||||
{
|
||||
char *protocol;
|
||||
|
||||
switch (entry->tnccs->get_transport(entry->tnccs))
|
||||
{
|
||||
case TNC_IFT_EAP_1_0:
|
||||
case TNC_IFT_EAP_1_1:
|
||||
case TNC_IFT_EAP_2_0:
|
||||
protocol = "IF-T for Tunneled EAP";
|
||||
break;
|
||||
case TNC_IFT_TLS_1_0:
|
||||
case TNC_IFT_TLS_2_0:
|
||||
protocol = "IF-T for TLS";
|
||||
break;
|
||||
default:
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return str_attribute(buffer_len, buffer, value_len, protocol);
|
||||
}
|
||||
case TNC_ATTRIBUTEID_IFT_VERSION:
|
||||
{
|
||||
char *version;
|
||||
|
||||
switch (entry->tnccs->get_transport(entry->tnccs))
|
||||
{
|
||||
case TNC_IFT_EAP_1_0:
|
||||
case TNC_IFT_TLS_1_0:
|
||||
version = "1.0";
|
||||
break;
|
||||
case TNC_IFT_EAP_1_1:
|
||||
version = "1.1";
|
||||
break;
|
||||
case TNC_IFT_EAP_2_0:
|
||||
case TNC_IFT_TLS_2_0:
|
||||
version = "2.0";
|
||||
break;
|
||||
default:
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
return str_attribute(buffer_len, buffer, value_len, version);
|
||||
}
|
||||
case TNC_ATTRIBUTEID_AR_IDENTITIES:
|
||||
{
|
||||
linked_list_t *list;
|
||||
identification_t *peer;
|
||||
tnccs_t *tnccs;
|
||||
tncif_identity_t *tnc_id;
|
||||
u_int32_t id_type, subject_type;
|
||||
chunk_t id_value;
|
||||
char *id_str;
|
||||
TNC_Result result;
|
||||
|
||||
list = linked_list_create();
|
||||
tnccs = entry->tnccs;
|
||||
peer = tnccs->tls.get_peer_id(&tnccs->tls);
|
||||
if (peer)
|
||||
{
|
||||
switch (peer->get_type(peer))
|
||||
{
|
||||
case ID_IPV4_ADDR:
|
||||
id_type = TNC_ID_IPV4_ADDR;
|
||||
subject_type = TNC_SUBJECT_MACHINE;
|
||||
break;
|
||||
case ID_IPV6_ADDR:
|
||||
id_type = TNC_ID_IPV6_ADDR;
|
||||
subject_type = TNC_SUBJECT_MACHINE;
|
||||
break;
|
||||
case ID_FQDN:
|
||||
id_type = TNC_ID_USERNAME;
|
||||
subject_type = TNC_SUBJECT_USER;
|
||||
break;
|
||||
case ID_RFC822_ADDR:
|
||||
id_type = TNC_ID_EMAIL_ADDR;
|
||||
subject_type = TNC_SUBJECT_USER;
|
||||
break;
|
||||
case ID_DER_ASN1_DN:
|
||||
id_type = TNC_ID_X500_DN;
|
||||
subject_type = TNC_SUBJECT_USER;
|
||||
break;
|
||||
default:
|
||||
id_type = TNC_ID_UNKNOWN;
|
||||
subject_type = TNC_SUBJECT_UNKNOWN;
|
||||
}
|
||||
if (id_type != TNC_ID_UNKNOWN &&
|
||||
asprintf(&id_str, "%Y", peer) >= 0)
|
||||
{
|
||||
id_value = chunk_from_str(id_str);
|
||||
tnc_id = tncif_identity_create(
|
||||
pen_type_create(PEN_TCG, id_type), id_value,
|
||||
pen_type_create(PEN_TCG, subject_type),
|
||||
pen_type_create(PEN_TCG,
|
||||
tnccs->get_auth_type(tnccs)));
|
||||
list->insert_last(list, tnc_id);
|
||||
}
|
||||
}
|
||||
result = identity_attribute(buffer_len, buffer, value_len, list);
|
||||
list->destroy_offset(list, offsetof(tncif_identity_t, destroy));
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, set_attribute, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, bool is_imc,
|
||||
TNC_UInt32 imcv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_AttributeID attribute_id,
|
||||
TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
recommendations_t *recs = NULL;
|
||||
|
||||
if (is_imc || id == TNC_CONNECTIONID_ANY ||
|
||||
(attribute_id != TNC_ATTRIBUTEID_REASON_STRING &&
|
||||
attribute_id != TNC_ATTRIBUTEID_REASON_LANGUAGE))
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
recs = entry->recs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
if (recs)
|
||||
{
|
||||
chunk_t attribute = { buffer, buffer_len };
|
||||
|
||||
if (attribute_id == TNC_ATTRIBUTEID_REASON_STRING)
|
||||
{
|
||||
return recs->set_reason_string(recs, imcv_id, attribute);
|
||||
}
|
||||
else
|
||||
{
|
||||
return recs->set_reason_language(recs, imcv_id, attribute);
|
||||
}
|
||||
}
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, destroy, void,
|
||||
private_tnc_tnccs_manager_t *this)
|
||||
{
|
||||
this->protocols->destroy_function(this->protocols, free);
|
||||
this->protocol_lock->destroy(this->protocol_lock);
|
||||
this->connections->destroy_function(this->connections, free);
|
||||
this->connection_lock->destroy(this->connection_lock);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* See header
|
||||
*/
|
||||
tnccs_manager_t *tnc_tnccs_manager_create()
|
||||
{
|
||||
private_tnc_tnccs_manager_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.add_method = _add_method,
|
||||
.remove_method = _remove_method,
|
||||
.create_instance = _create_instance,
|
||||
.create_connection = _create_connection,
|
||||
.remove_connection = _remove_connection,
|
||||
.request_handshake_retry = _request_handshake_retry,
|
||||
.send_message = _send_message,
|
||||
.provide_recommendation = _provide_recommendation,
|
||||
.get_attribute = _get_attribute,
|
||||
.set_attribute = _set_attribute,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.protocols = linked_list_create(),
|
||||
.connections = linked_list_create(),
|
||||
.protocol_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
.connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnc_tnccs_manager tnc_tnccs_manager
|
||||
* @{ @ingroup tnc_tnccs
|
||||
*/
|
||||
|
||||
#ifndef TNC_TNCCS_MANAGER_H_
|
||||
#define TNC_TNCCS_MANAGER_H_
|
||||
|
||||
#include <tnc/tnccs/tnccs_manager.h>
|
||||
|
||||
/**
|
||||
* Create a TNCCS manager instance.
|
||||
*/
|
||||
tnccs_manager_t *tnc_tnccs_manager_create();
|
||||
|
||||
#endif /** TNC_TNCCS_MANAGER_H_ @}*/
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnc_tnccs_plugin.h"
|
||||
#include "tnc_tnccs_manager.h"
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_tnc_tnccs_plugin_t private_tnc_tnccs_plugin_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnc_tnccs_plugin_t object.
|
||||
*/
|
||||
struct private_tnc_tnccs_plugin_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
tnc_tnccs_plugin_t public;
|
||||
|
||||
};
|
||||
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_tnc_tnccs_plugin_t *this)
|
||||
{
|
||||
return "tnc-tnccs";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_tnc_tnccs_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(tnc_manager_register, tnc_tnccs_manager_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "tnccs-manager"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_tnc_tnccs_plugin_t *this)
|
||||
{
|
||||
libtnccs_deinit();
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *tnc_tnccs_plugin_create(void)
|
||||
{
|
||||
private_tnc_tnccs_plugin_t *this;
|
||||
|
||||
if (lib->integrity)
|
||||
{
|
||||
if (lib->integrity->check(lib->integrity, "libtnccs", libtnccs_init))
|
||||
{
|
||||
DBG1(DBG_LIB,
|
||||
"lib 'libtnccs': passed file and segment integrity tests");
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_LIB,
|
||||
"lib 'libtnccs': failed integrity tests");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
libtnccs_init();
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnc_tnccs tnc_tnccs
|
||||
* @ingroup cplugins
|
||||
*
|
||||
* @defgroup tnc_tnccs_plugin tnc_tnccs_plugin
|
||||
* @{ @ingroup tnc_tnccs
|
||||
*/
|
||||
|
||||
#ifndef TNC_TNCCS_PLUGIN_H_
|
||||
#define TNC_TNCCS_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct tnc_tnccs_plugin_t tnc_tnccs_plugin_t;
|
||||
|
||||
/**
|
||||
* TNCCS manager plugin
|
||||
*/
|
||||
struct tnc_tnccs_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** TNC_TNCCS_PLUGIN_H_ @}*/
|
||||
@@ -1,35 +0,0 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libcharon \
|
||||
-I$(top_srcdir)/src/libhydra \
|
||||
-I$(top_srcdir)/src/libtls \
|
||||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libtnccs
|
||||
|
||||
AM_CFLAGS = \
|
||||
${xml_CFLAGS} \
|
||||
-rdynamic
|
||||
|
||||
libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS}
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-tnccs-11.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-tnccs-11.la
|
||||
libstrongswan_tnccs_11_la_LIBADD += \
|
||||
$(top_builddir)/src/libtncif/libtncif.la \
|
||||
$(top_builddir)/src/libtnccs/libtnccs.la
|
||||
endif
|
||||
|
||||
libstrongswan_tnccs_11_la_SOURCES = \
|
||||
tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c \
|
||||
batch/tnccs_batch.h batch/tnccs_batch.c \
|
||||
messages/tnccs_msg.h messages/tnccs_msg.c \
|
||||
messages/imc_imv_msg.h messages/imc_imv_msg.c \
|
||||
messages/tnccs_error_msg.h messages/tnccs_error_msg.c \
|
||||
messages/tnccs_preferred_language_msg.h messages/tnccs_preferred_language_msg.c \
|
||||
messages/tnccs_reason_strings_msg.h messages/tnccs_reason_strings_msg.c \
|
||||
messages/tnccs_recommendation_msg.h messages/tnccs_recommendation_msg.c \
|
||||
messages/tnccs_tncs_contact_info_msg.h messages/tnccs_tncs_contact_info_msg.c
|
||||
|
||||
libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version
|
||||
@@ -1,325 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley ([email protected])
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_batch.h"
|
||||
#include "messages/tnccs_error_msg.h"
|
||||
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
|
||||
#include <collections/linked_list.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <libxml/parser.h>
|
||||
|
||||
#define TNCCS_NS "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#"
|
||||
#define SCHEMA_NS "http://www.w3.org/2001/XMLSchema-instance"
|
||||
#define TNCCS_XSD "https://www.trustedcomputinggroup.org/XML/SCHEMA/TNCCS_1.0.xsd"
|
||||
|
||||
typedef struct private_tnccs_batch_t private_tnccs_batch_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_batch_t object.
|
||||
*
|
||||
*/
|
||||
struct private_tnccs_batch_t {
|
||||
/**
|
||||
* Public tnccs_batch_t interface.
|
||||
*/
|
||||
tnccs_batch_t public;
|
||||
|
||||
/**
|
||||
* Batch ID
|
||||
*/
|
||||
int batch_id;
|
||||
|
||||
/**
|
||||
* TNCC if TRUE, TNCS if FALSE
|
||||
*/
|
||||
bool is_server;
|
||||
|
||||
/**
|
||||
* linked list of TNCCS messages
|
||||
*/
|
||||
linked_list_t *messages;
|
||||
|
||||
/**
|
||||
* linked list of TNCCS error messages
|
||||
*/
|
||||
linked_list_t *errors;
|
||||
|
||||
/**
|
||||
* XML document
|
||||
*/
|
||||
xmlDocPtr doc;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
};
|
||||
|
||||
METHOD(tnccs_batch_t, get_encoding, chunk_t,
|
||||
private_tnccs_batch_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(tnccs_batch_t, add_msg, void,
|
||||
private_tnccs_batch_t *this, tnccs_msg_t* msg)
|
||||
{
|
||||
xmlNodePtr root;
|
||||
|
||||
DBG2(DBG_TNC, "adding %N message", tnccs_msg_type_names,
|
||||
msg->get_type(msg));
|
||||
this->messages->insert_last(this->messages, msg);
|
||||
root = xmlDocGetRootElement(this->doc);
|
||||
xmlAddChild(root, msg->get_node(msg));
|
||||
}
|
||||
|
||||
METHOD(tnccs_batch_t, build, void,
|
||||
private_tnccs_batch_t *this)
|
||||
{
|
||||
xmlChar *xmlbuf;
|
||||
int buf_size;
|
||||
|
||||
xmlDocDumpFormatMemory(this->doc, &xmlbuf, &buf_size, 1);
|
||||
this->encoding = chunk_create(xmlbuf, buf_size);
|
||||
this->encoding = chunk_clone(this->encoding);
|
||||
xmlFree(xmlbuf);
|
||||
}
|
||||
|
||||
METHOD(tnccs_batch_t, process, status_t,
|
||||
private_tnccs_batch_t *this)
|
||||
{
|
||||
tnccs_msg_t *tnccs_msg, *msg;
|
||||
tnccs_error_type_t error_type = TNCCS_ERROR_OTHER;
|
||||
char *error_msg, buf[BUF_LEN];
|
||||
xmlNodePtr cur;
|
||||
xmlNsPtr ns;
|
||||
xmlChar *batchid, *recipient;
|
||||
int batch_id;
|
||||
|
||||
this->doc = xmlParseMemory(this->encoding.ptr, this->encoding.len);
|
||||
if (!this->doc)
|
||||
{
|
||||
error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||
error_msg = "failed to parse XML message";
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* check out the XML document */
|
||||
cur = xmlDocGetRootElement(this->doc);
|
||||
if (!cur)
|
||||
{
|
||||
error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||
error_msg = "empty XML document";
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* check TNCCS namespace */
|
||||
ns = xmlSearchNsByHref(this->doc, cur, TNCCS_NS);
|
||||
if (!ns)
|
||||
{
|
||||
error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||
error_msg = "TNCCS namespace not found";
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* check XML document type */
|
||||
if (xmlStrcmp(cur->name, "TNCCS-Batch"))
|
||||
{
|
||||
error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||
error_msg = buf;
|
||||
snprintf(buf, BUF_LEN, "wrong XML document type '%s', expected TNCCS-Batch",
|
||||
cur->name);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* check presence of BatchID property */
|
||||
batchid = xmlGetProp(cur, "BatchId");
|
||||
if (!batchid)
|
||||
{
|
||||
error_type = TNCCS_ERROR_INVALID_BATCH_ID;
|
||||
error_msg = "BatchId is missing";
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* check BatchID */
|
||||
batch_id = atoi((char*)batchid);
|
||||
xmlFree(batchid);
|
||||
if (batch_id != this->batch_id)
|
||||
{
|
||||
error_type = TNCCS_ERROR_INVALID_BATCH_ID;
|
||||
error_msg = buf;
|
||||
snprintf(buf, BUF_LEN, "BatchId %d expected, got %d", this->batch_id,
|
||||
batch_id);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* check presence of Recipient property */
|
||||
recipient = xmlGetProp(cur, "Recipient");
|
||||
if (!recipient)
|
||||
{
|
||||
error_type = TNCCS_ERROR_INVALID_RECIPIENT_TYPE;
|
||||
error_msg = "Recipient is missing";
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* check recipient */
|
||||
if (!streq(recipient, this->is_server ? "TNCS" : "TNCC"))
|
||||
{
|
||||
error_type = TNCCS_ERROR_INVALID_RECIPIENT_TYPE;
|
||||
error_msg = buf;
|
||||
snprintf(buf, BUF_LEN, "message recipient expected '%s', got '%s'",
|
||||
this->is_server ? "TNCS" : "TNCC", recipient);
|
||||
xmlFree(recipient);
|
||||
goto fatal;
|
||||
}
|
||||
xmlFree(recipient);
|
||||
|
||||
DBG2(DBG_TNC, "processing TNCCS Batch #%d", batch_id);
|
||||
|
||||
/* Now walk the tree, handling message nodes as we go */
|
||||
for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next)
|
||||
{
|
||||
/* ignore empty or blank nodes */
|
||||
if (xmlIsBlankNode(cur))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ignore nodes with wrong namespace */
|
||||
if (cur->ns != ns)
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring message node '%s' having wrong namespace",
|
||||
cur->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
tnccs_msg = tnccs_msg_create_from_node(cur, this->errors);
|
||||
|
||||
/* exit if a message parsing error occurred */
|
||||
if (this->errors->get_count(this->errors) > 0)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* ignore unrecognized messages */
|
||||
if (!tnccs_msg)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
this->messages->insert_last(this->messages, tnccs_msg);
|
||||
}
|
||||
return SUCCESS;
|
||||
|
||||
fatal:
|
||||
msg = tnccs_error_msg_create(error_type, error_msg);
|
||||
this->errors->insert_last(this->errors, msg);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
METHOD(tnccs_batch_t, create_msg_enumerator, enumerator_t*,
|
||||
private_tnccs_batch_t *this)
|
||||
{
|
||||
return this->messages->create_enumerator(this->messages);
|
||||
}
|
||||
|
||||
METHOD(tnccs_batch_t, create_error_enumerator, enumerator_t*,
|
||||
private_tnccs_batch_t *this)
|
||||
{
|
||||
return this->errors->create_enumerator(this->errors);
|
||||
}
|
||||
|
||||
METHOD(tnccs_batch_t, destroy, void,
|
||||
private_tnccs_batch_t *this)
|
||||
{
|
||||
this->messages->destroy_offset(this->messages,
|
||||
offsetof(tnccs_msg_t, destroy));
|
||||
this->errors->destroy_offset(this->errors,
|
||||
offsetof(tnccs_msg_t, destroy));
|
||||
xmlFreeDoc(this->doc);
|
||||
free(this->encoding.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id)
|
||||
{
|
||||
private_tnccs_batch_t *this;
|
||||
xmlNodePtr n;
|
||||
xmlNsPtr ns_xsi;
|
||||
char buf[12];
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_encoding = _get_encoding,
|
||||
.add_msg = _add_msg,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.create_msg_enumerator = _create_msg_enumerator,
|
||||
.create_error_enumerator = _create_error_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.is_server = is_server,
|
||||
.messages = linked_list_create(),
|
||||
.errors = linked_list_create(),
|
||||
.batch_id = batch_id,
|
||||
.doc = xmlNewDoc("1.0"),
|
||||
);
|
||||
|
||||
DBG2(DBG_TNC, "creating TNCCS Batch #%d", this->batch_id);
|
||||
n = xmlNewNode(NULL, "TNCCS-Batch");
|
||||
xmlNewNs(n, TNCCS_NS, NULL);
|
||||
ns_xsi = xmlNewNs(n, SCHEMA_NS, "xsi");
|
||||
snprintf(buf, sizeof(buf), "%d", batch_id);
|
||||
xmlNewProp(n, "BatchId", buf);
|
||||
xmlNewProp(n, "Recipient", this->is_server ? "TNCC" : "TNCS");
|
||||
xmlNewNsProp(n, ns_xsi, "schemaLocation", TNCCS_NS " " TNCCS_XSD);
|
||||
xmlDocSetRootElement(this->doc, n);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id, chunk_t data)
|
||||
{
|
||||
private_tnccs_batch_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_encoding = _get_encoding,
|
||||
.add_msg = _add_msg,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.create_msg_enumerator = _create_msg_enumerator,
|
||||
.create_error_enumerator = _create_error_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.is_server = is_server,
|
||||
.batch_id = batch_id,
|
||||
.messages = linked_list_create(),
|
||||
.errors = linked_list_create(),
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_batch tnccs_batch
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_BATCH_H_
|
||||
#define TNCCS_BATCH_H_
|
||||
|
||||
typedef enum tnccs_batch_type_t tnccs_batch_type_t;
|
||||
typedef struct tnccs_batch_t tnccs_batch_t;
|
||||
|
||||
#include "messages/tnccs_msg.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Interface for a TNCCS 1.x Batch.
|
||||
*/
|
||||
struct tnccs_batch_t {
|
||||
|
||||
/**
|
||||
* Get the encoding of the TNCCS 1.x Batch
|
||||
*
|
||||
* @return encoded TNCCS 1.x batch
|
||||
*/
|
||||
chunk_t (*get_encoding)(tnccs_batch_t *this);
|
||||
|
||||
/**
|
||||
* Add TNCCS message
|
||||
*
|
||||
* @param msg TNCCS message to be addedd
|
||||
*/
|
||||
void (*add_msg)(tnccs_batch_t *this, tnccs_msg_t* msg);
|
||||
|
||||
/**
|
||||
* Build the TNCCS 1.x Batch
|
||||
*/
|
||||
void (*build)(tnccs_batch_t *this);
|
||||
|
||||
/**
|
||||
* Process the TNCCS 1.x Batch
|
||||
*
|
||||
* @return return processing status
|
||||
*/
|
||||
status_t (*process)(tnccs_batch_t *this);
|
||||
|
||||
/**
|
||||
* Enumerates over all TNCCS Messages
|
||||
*
|
||||
* @return return message enumerator
|
||||
*/
|
||||
enumerator_t* (*create_msg_enumerator)(tnccs_batch_t *this);
|
||||
|
||||
/**
|
||||
* Enumerates over all parsing errors
|
||||
*
|
||||
* @return return error enumerator
|
||||
*/
|
||||
enumerator_t* (*create_error_enumerator)(tnccs_batch_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a tnccs_batch_t object.
|
||||
*/
|
||||
void (*destroy)(tnccs_batch_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an empty TNCCS 1.x Batch
|
||||
*
|
||||
* @param is_server TRUE if server, FALSE if client
|
||||
* @param batch_id number of the batch to be sent
|
||||
*/
|
||||
tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id);
|
||||
|
||||
/**
|
||||
* Create an unprocessed TNCCS 1.x Batch from data
|
||||
*
|
||||
* @param is_server TRUE if server, FALSE if client
|
||||
* @param batch_id current Batch ID
|
||||
* @param data encoded PB-TNC batch
|
||||
*/
|
||||
tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id,
|
||||
chunk_t data);
|
||||
|
||||
#endif /** TNCCS_BATCH_H_ @}*/
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley ([email protected])
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "imc_imv_msg.h"
|
||||
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
|
||||
#include <utils/lexparser.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_imc_imv_msg_t private_imc_imv_msg_t;
|
||||
|
||||
#define BYTES_PER_LINE 57
|
||||
|
||||
/**
|
||||
* Private data of a imc_imv_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_imc_imv_msg_t {
|
||||
/**
|
||||
* Public imc_imv_msg_t interface.
|
||||
*/
|
||||
imc_imv_msg_t public;
|
||||
|
||||
/**
|
||||
* TNCCS message type
|
||||
*/
|
||||
tnccs_msg_type_t type;
|
||||
|
||||
/**
|
||||
* XML-encoded message node
|
||||
*/
|
||||
xmlNodePtr node;
|
||||
|
||||
/**
|
||||
* IMC-IMV message type
|
||||
*/
|
||||
TNC_MessageType msg_type;
|
||||
|
||||
/**
|
||||
* IMC-IMV message body
|
||||
*/
|
||||
chunk_t msg_body;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Encodes message data into multiple base64-encoded lines
|
||||
*/
|
||||
static chunk_t encode_base64(chunk_t data)
|
||||
{
|
||||
chunk_t encoding;
|
||||
u_char *pos;
|
||||
size_t b64_chars, b64_lines;
|
||||
|
||||
/* handle empty message data object */
|
||||
if (data.len == 0)
|
||||
{
|
||||
encoding = chunk_alloc(1);
|
||||
*encoding.ptr = '\0';
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/* compute and allocate maximum size of base64 object */
|
||||
b64_chars = 4 * ((data.len + 2) / 3);
|
||||
b64_lines = (data.len + BYTES_PER_LINE - 1) / BYTES_PER_LINE;
|
||||
encoding = chunk_alloc(b64_chars + b64_lines);
|
||||
pos = encoding.ptr;
|
||||
|
||||
/* encode lines */
|
||||
while (b64_lines--)
|
||||
{
|
||||
chunk_t data_line, b64_line;
|
||||
|
||||
data_line = chunk_create(data.ptr, min(data.len, BYTES_PER_LINE));
|
||||
data.ptr += data_line.len;
|
||||
data.len -= data_line.len;
|
||||
b64_line = chunk_to_base64(data_line, pos);
|
||||
pos += b64_line.len;
|
||||
*pos = '\n';
|
||||
pos++;
|
||||
}
|
||||
/* terminate last line with NULL character instead of newline */
|
||||
*(pos-1) = '\0';
|
||||
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes message data from multiple base64-encoded lines
|
||||
*/
|
||||
static chunk_t decode_base64(chunk_t data)
|
||||
{
|
||||
chunk_t decoding, data_line, b64_line;
|
||||
u_char *pos;
|
||||
|
||||
/* compute and allocate maximum size of decoded message data */
|
||||
decoding = chunk_alloc(3 * ((data.len + 3) / 4));
|
||||
pos = decoding.ptr;
|
||||
decoding.len = 0;
|
||||
|
||||
while (fetchline(&data, &b64_line))
|
||||
{
|
||||
data_line = chunk_from_base64(b64_line, pos);
|
||||
pos += data_line.len;
|
||||
decoding.len += data_line.len;
|
||||
}
|
||||
|
||||
return decoding;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
||||
private_imc_imv_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
||||
private_imc_imv_msg_t *this)
|
||||
{
|
||||
return this->node;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, destroy, void,
|
||||
private_imc_imv_msg_t *this)
|
||||
{
|
||||
free(this->msg_body.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(imc_imv_msg_t, get_msg_type, TNC_MessageType,
|
||||
private_imc_imv_msg_t *this)
|
||||
{
|
||||
return this->msg_type;
|
||||
}
|
||||
|
||||
METHOD(imc_imv_msg_t, get_msg_body, chunk_t,
|
||||
private_imc_imv_msg_t *this)
|
||||
{
|
||||
return this->msg_body;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node, linked_list_t *errors)
|
||||
{
|
||||
private_imc_imv_msg_t *this;
|
||||
xmlNsPtr ns;
|
||||
xmlNodePtr cur;
|
||||
xmlChar *content;
|
||||
chunk_t b64_body;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_msg_type = _get_msg_type,
|
||||
.get_msg_body = _get_msg_body,
|
||||
},
|
||||
.type = IMC_IMV_MSG,
|
||||
.node = node,
|
||||
);
|
||||
|
||||
ns = node->ns;
|
||||
cur = node->xmlChildrenNode;
|
||||
while (cur)
|
||||
{
|
||||
if (streq(cur->name, "Type") && cur->ns == ns)
|
||||
{
|
||||
content = xmlNodeGetContent(cur);
|
||||
this->msg_type = strtoul(content, NULL, 16);
|
||||
xmlFree(content);
|
||||
}
|
||||
else if (streq(cur->name, "Base64") && cur->ns == ns)
|
||||
{
|
||||
content = xmlNodeGetContent(cur);
|
||||
b64_body = chunk_create(content, strlen(content));
|
||||
this->msg_body = decode_base64(b64_body);
|
||||
xmlFree(content);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body)
|
||||
{
|
||||
private_imc_imv_msg_t *this;
|
||||
chunk_t b64_body;
|
||||
char buf[10]; /* big enough for hex-encoded message type */
|
||||
xmlNodePtr n;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_msg_type = _get_msg_type,
|
||||
.get_msg_body = _get_msg_body,
|
||||
},
|
||||
.type = IMC_IMV_MSG,
|
||||
.node = xmlNewNode(NULL, "IMC-IMV-Message"),
|
||||
.msg_type = msg_type,
|
||||
.msg_body = chunk_clone(msg_body),
|
||||
);
|
||||
|
||||
/* add the message type number in hex */
|
||||
n = xmlNewNode(NULL, "Type");
|
||||
snprintf(buf, 10, "%08x", this->msg_type);
|
||||
xmlNodeSetContent(n, buf);
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
/* encode the message as a Base64 node */
|
||||
n = xmlNewNode(NULL, "Base64");
|
||||
b64_body = encode_base64(this->msg_body);
|
||||
xmlNodeSetContent(n, b64_body.ptr);
|
||||
xmlAddChild(this->node, n);
|
||||
free(b64_body.ptr);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup imc_imv_msg imc_imv_msg
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef IMC_IMV_MSG_H_
|
||||
#define IMC_IMV_MSG_H_
|
||||
|
||||
typedef struct imc_imv_msg_t imc_imv_msg_t;
|
||||
|
||||
#include "tnccs_msg.h"
|
||||
|
||||
#include <tncif.h>
|
||||
|
||||
/**
|
||||
* Classs representing the PB-PA message type.
|
||||
*/
|
||||
struct imc_imv_msg_t {
|
||||
|
||||
/**
|
||||
* TNCCS Message interface
|
||||
*/
|
||||
tnccs_msg_t tnccs_msg_interface;
|
||||
|
||||
/**
|
||||
* Get IMC-IMV message type
|
||||
*
|
||||
* @return IMC-IMV message type
|
||||
*/
|
||||
TNC_MessageType (*get_msg_type)(imc_imv_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get IMC-IMV message body
|
||||
*
|
||||
* @return IMC-IMV message body
|
||||
*/
|
||||
chunk_t (*get_msg_body)(imc_imv_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an IMC-IMV message from XML-encoded message node
|
||||
*
|
||||
* @param node XML-encoded message node
|
||||
* @param errors linked list of TNCCS error messages
|
||||
*/
|
||||
tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node, linked_list_t *errors);
|
||||
|
||||
/**
|
||||
* Create an IMC-IMV message from parameters
|
||||
*
|
||||
* @param msg_type IMC-IMV message type
|
||||
* @param msg_body IMC-IMV message body
|
||||
*/
|
||||
tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body);
|
||||
|
||||
#endif /** IMC_IMV_MSG_H_ @}*/
|
||||
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley ([email protected])
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_error_msg.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
ENUM(tnccs_error_type_names, TNCCS_ERROR_BATCH_TOO_LONG, TNCCS_ERROR_OTHER,
|
||||
"batch-too-long",
|
||||
"malformed-batch",
|
||||
"invalid-batch-id",
|
||||
"invalid-recipient-type",
|
||||
"internal-error",
|
||||
"other"
|
||||
);
|
||||
|
||||
typedef struct private_tnccs_error_msg_t private_tnccs_error_msg_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_error_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_tnccs_error_msg_t {
|
||||
/**
|
||||
* Public tnccs_error_msg_t interface.
|
||||
*/
|
||||
tnccs_error_msg_t public;
|
||||
|
||||
/**
|
||||
* TNCCS message type
|
||||
*/
|
||||
tnccs_msg_type_t type;
|
||||
|
||||
/**
|
||||
* XML-encoded message node
|
||||
*/
|
||||
xmlNodePtr node;
|
||||
|
||||
/**
|
||||
* Error type
|
||||
*/
|
||||
tnccs_error_type_t error_type;
|
||||
|
||||
/**
|
||||
* Error message
|
||||
*/
|
||||
char *error_msg;
|
||||
|
||||
/**
|
||||
* reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
||||
private_tnccs_error_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
||||
private_tnccs_error_msg_t *this)
|
||||
{
|
||||
return this->node;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, get_ref, tnccs_msg_t*,
|
||||
private_tnccs_error_msg_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, destroy, void,
|
||||
private_tnccs_error_msg_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
free(this->error_msg);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tnccs_error_msg_t, get_message, char*,
|
||||
private_tnccs_error_msg_t *this, tnccs_error_type_t *type)
|
||||
{
|
||||
*type = this->error_type;
|
||||
|
||||
return this->error_msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node)
|
||||
{
|
||||
private_tnccs_error_msg_t *this;
|
||||
xmlChar *error_type_name, *error_msg;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_message = _get_message,
|
||||
},
|
||||
.type = TNCCS_MSG_ERROR,
|
||||
.ref = 1,
|
||||
.node = node,
|
||||
.error_type = TNCCS_ERROR_OTHER,
|
||||
);
|
||||
|
||||
error_type_name = xmlGetProp(node, "type");
|
||||
if (error_type_name)
|
||||
{
|
||||
this->error_type = enum_from_name(tnccs_error_type_names,
|
||||
error_type_name);
|
||||
if (this->error_type == -1)
|
||||
{
|
||||
this->error_type = TNCCS_ERROR_OTHER;
|
||||
}
|
||||
xmlFree(error_type_name);
|
||||
}
|
||||
|
||||
error_msg = xmlNodeGetContent(node);
|
||||
if (error_msg)
|
||||
{
|
||||
this->error_msg = strdup(error_msg);
|
||||
xmlFree(error_msg);
|
||||
}
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg)
|
||||
{
|
||||
private_tnccs_error_msg_t *this;
|
||||
xmlNodePtr n, n2;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_message = _get_message,
|
||||
},
|
||||
.type = TNCCS_MSG_ERROR,
|
||||
.ref = 1,
|
||||
.node = xmlNewNode(NULL, "TNCC-TNCS-Message"),
|
||||
.error_type = type,
|
||||
.error_msg = strdup(msg),
|
||||
);
|
||||
|
||||
DBG1(DBG_TNC, "%s", msg);
|
||||
|
||||
n = xmlNewNode(NULL, "Type");
|
||||
xmlNodeSetContent(n, "00000002");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
n = xmlNewNode(NULL, "XML");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
n2 = xmlNewNode(NULL, enum_to_name(tnccs_msg_type_names, this->type));
|
||||
xmlNewProp(n2, "type", enum_to_name(tnccs_error_type_names, type));
|
||||
xmlNodeSetContent(n2, msg);
|
||||
xmlAddChild(n, n2);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_error_msg tnccs_error_msg
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_ERROR_MSG_H_
|
||||
#define TNCCS_ERROR_MSG_H_
|
||||
|
||||
typedef enum tnccs_error_type_t tnccs_error_type_t;
|
||||
typedef struct tnccs_error_msg_t tnccs_error_msg_t;
|
||||
|
||||
#include "tnccs_msg.h"
|
||||
|
||||
/**
|
||||
* TNCCS error types as defined in section 8.1.4 of TCG TNC IF-TNCCS v1.2
|
||||
*/
|
||||
enum tnccs_error_type_t {
|
||||
TNCCS_ERROR_BATCH_TOO_LONG,
|
||||
TNCCS_ERROR_MALFORMED_BATCH,
|
||||
TNCCS_ERROR_INVALID_BATCH_ID,
|
||||
TNCCS_ERROR_INVALID_RECIPIENT_TYPE,
|
||||
TNCCS_ERROR_INTERNAL_ERROR,
|
||||
TNCCS_ERROR_OTHER
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for tnccs_error_type_t.
|
||||
*/
|
||||
extern enum_name_t *tnccs_error_type_names;
|
||||
|
||||
/**
|
||||
* Class representing the TNCCS-Error message type
|
||||
*/
|
||||
struct tnccs_error_msg_t {
|
||||
|
||||
/**
|
||||
* TNCCS Message interface
|
||||
*/
|
||||
tnccs_msg_t tnccs_msg_interface;
|
||||
|
||||
/**
|
||||
* Get error message and type
|
||||
*
|
||||
* @param type TNCCS error type
|
||||
* @return arbitrary error message
|
||||
*/
|
||||
char* (*get_message)(tnccs_error_msg_t *this, tnccs_error_type_t *type);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a TNCCS-Error message from XML-encoded message node
|
||||
*
|
||||
* @param node XML-encoded message node
|
||||
*/
|
||||
tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node);
|
||||
|
||||
/**
|
||||
* Create a TNCCS-Error message from parameters
|
||||
*
|
||||
* @param type TNCCS error type
|
||||
* @param msg arbitrary error message
|
||||
*/
|
||||
tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg);
|
||||
|
||||
#endif /** TNCCS_ERROR_MSG_H_ @}*/
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley ([email protected])
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_msg.h"
|
||||
#include "imc_imv_msg.h"
|
||||
#include "tnccs_error_msg.h"
|
||||
#include "tnccs_preferred_language_msg.h"
|
||||
#include "tnccs_reason_strings_msg.h"
|
||||
#include "tnccs_recommendation_msg.h"
|
||||
#include "tnccs_tncs_contact_info_msg.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
ENUM(tnccs_msg_type_names, IMC_IMV_MSG, TNCCS_MSG_ROOF,
|
||||
"IMC-IMV",
|
||||
"TNCCS-Recommendation",
|
||||
"TNCCS-Error",
|
||||
"TNCCS-PreferredLanguage",
|
||||
"TNCCS-ReasonStrings",
|
||||
"TNCCS-TNCSContactInfo"
|
||||
);
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors)
|
||||
{
|
||||
char *error_msg, buf[BUF_LEN];
|
||||
tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||
tnccs_msg_t *msg;
|
||||
tnccs_msg_type_t type = IMC_IMV_MSG;
|
||||
|
||||
if (streq((char*)node->name, "IMC-IMV-Message"))
|
||||
{
|
||||
DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names, type);
|
||||
return imc_imv_msg_create_from_node(node, errors);
|
||||
}
|
||||
else if (streq((char*)node->name, "TNCC-TNCS-Message"))
|
||||
{
|
||||
bool found = FALSE;
|
||||
xmlNsPtr ns = node->ns;
|
||||
xmlNodePtr cur = node->xmlChildrenNode;
|
||||
xmlNodePtr xml_msg_node = NULL;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
if (streq(cur->name, "Type") && cur->ns == ns)
|
||||
{
|
||||
xmlChar *content = xmlNodeGetContent(cur);
|
||||
|
||||
type = strtol(content, NULL, 16);
|
||||
xmlFree(content);
|
||||
found = TRUE;
|
||||
}
|
||||
else if (streq(cur->name, "XML") && cur->ns == ns)
|
||||
{
|
||||
xml_msg_node = cur->xmlChildrenNode;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
error_msg = "Type is missing in TNCC-TNCS-Message";
|
||||
goto fatal;
|
||||
}
|
||||
if (!xml_msg_node)
|
||||
{
|
||||
error_msg = "XML node is missing in TNCC-TNCS-Message";
|
||||
goto fatal;
|
||||
}
|
||||
cur = xml_msg_node;
|
||||
|
||||
/* skip empty and blank nodes */
|
||||
while (cur && xmlIsBlankNode(cur))
|
||||
{
|
||||
cur = cur->next;
|
||||
}
|
||||
if (!cur)
|
||||
{
|
||||
error_msg = "XML node is empty";
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* check if TNCCS message type and node name agree */
|
||||
if (type >= TNCCS_MSG_RECOMMENDATION && type <= TNCCS_MSG_ROOF)
|
||||
{
|
||||
DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names, type);
|
||||
if (cur->ns != ns)
|
||||
{
|
||||
error_msg = "node is not in the TNCCS message namespace";
|
||||
goto fatal;
|
||||
}
|
||||
if (type != enum_from_name(tnccs_msg_type_names, (char*)cur->name))
|
||||
{
|
||||
error_msg = buf;
|
||||
snprintf(buf, BUF_LEN, "expected '%N' node but was '%s'",
|
||||
tnccs_msg_type_names, type, (char*)cur->name);
|
||||
goto fatal;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TNCCS_MSG_RECOMMENDATION:
|
||||
return tnccs_recommendation_msg_create_from_node(cur, errors);
|
||||
case TNCCS_MSG_ERROR:
|
||||
return tnccs_error_msg_create_from_node(cur);
|
||||
case TNCCS_MSG_PREFERRED_LANGUAGE:
|
||||
return tnccs_preferred_language_msg_create_from_node(cur, errors);
|
||||
case TNCCS_MSG_REASON_STRINGS:
|
||||
return tnccs_reason_strings_msg_create_from_node(cur, errors);
|
||||
case TNCCS_MSG_TNCS_CONTACT_INFO:
|
||||
return tnccs_tncs_contact_info_msg_create_from_node(cur, errors);
|
||||
default:
|
||||
DBG1(DBG_TNC, "ignoring TNCC-TNCS-Message with type %d", type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
DBG1(DBG_TNC, "ignoring unknown message node '%s'", (char*)node->name);
|
||||
return NULL;
|
||||
|
||||
fatal:
|
||||
msg = tnccs_error_msg_create(error_type, error_msg);
|
||||
errors->insert_last(errors, msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_msg tnccs_msg
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_MSG_H_
|
||||
#define TNCCS_MSG_H_
|
||||
|
||||
typedef enum tnccs_msg_type_t tnccs_msg_type_t;
|
||||
typedef struct tnccs_msg_t tnccs_msg_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <collections/linked_list.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
/**
|
||||
* TNCC-TNCS messages as defined in section 2.8.5 of TCG TNC IF-TNCCS v1.2
|
||||
*/
|
||||
enum tnccs_msg_type_t {
|
||||
IMC_IMV_MSG = 0,
|
||||
TNCCS_MSG_RECOMMENDATION = 1,
|
||||
TNCCS_MSG_ERROR = 2,
|
||||
TNCCS_MSG_PREFERRED_LANGUAGE = 3,
|
||||
TNCCS_MSG_REASON_STRINGS = 4,
|
||||
TNCCS_MSG_TNCS_CONTACT_INFO = 5,
|
||||
TNCCS_MSG_ROOF = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for tnccs_msg_type_t.
|
||||
*/
|
||||
extern enum_name_t *tnccs_msg_type_names;
|
||||
|
||||
/**
|
||||
* Generic interface for all TNCCS message types.
|
||||
*
|
||||
* To handle all messages in a generic way, this interface
|
||||
* must be implemented by each message type.
|
||||
*/
|
||||
struct tnccs_msg_t {
|
||||
|
||||
/**
|
||||
* Get the TNCCS Message Type
|
||||
*
|
||||
* @return TNCCS Message Type
|
||||
*/
|
||||
tnccs_msg_type_t (*get_type)(tnccs_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the XML-encoded Message Node
|
||||
*
|
||||
* @return Message Node
|
||||
*/
|
||||
xmlNodePtr (*get_node)(tnccs_msg_t *this);
|
||||
|
||||
/**
|
||||
* Process the TNCCS Message
|
||||
*
|
||||
* @return return processing status
|
||||
*/
|
||||
status_t (*process)(tnccs_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get a new reference to the message.
|
||||
*
|
||||
* @return this, with an increased refcount
|
||||
*/
|
||||
tnccs_msg_t* (*get_ref)(tnccs_msg_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a tnccs_msg_t object.
|
||||
*/
|
||||
void (*destroy)(tnccs_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a pre-processed TNCCS message
|
||||
*
|
||||
* Useful for the parser which wants a generic constructor for all
|
||||
* tnccs_msg_t types.
|
||||
*
|
||||
* @param node TNCCS message node
|
||||
* @param errors linked list of TNCCS error messages
|
||||
*/
|
||||
tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors);
|
||||
|
||||
#endif /** TNCCS_MSG_H_ @}*/
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley ([email protected])
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_preferred_language_msg.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_tnccs_preferred_language_msg_t private_tnccs_preferred_language_msg_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_preferred_language_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_tnccs_preferred_language_msg_t {
|
||||
/**
|
||||
* Public tnccs_preferred_language_msg_t interface.
|
||||
*/
|
||||
tnccs_preferred_language_msg_t public;
|
||||
|
||||
/**
|
||||
* TNCCS message type
|
||||
*/
|
||||
tnccs_msg_type_t type;
|
||||
|
||||
/**
|
||||
* XML-encoded message node
|
||||
*/
|
||||
xmlNodePtr node;
|
||||
|
||||
/**
|
||||
* Preferred language
|
||||
*/
|
||||
char *preferred_language;
|
||||
};
|
||||
|
||||
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
||||
private_tnccs_preferred_language_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
||||
private_tnccs_preferred_language_msg_t *this)
|
||||
{
|
||||
return this->node;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, destroy, void,
|
||||
private_tnccs_preferred_language_msg_t *this)
|
||||
{
|
||||
free(this->preferred_language);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(tnccs_preferred_language_msg_t, get_preferred_language, char*,
|
||||
private_tnccs_preferred_language_msg_t *this)
|
||||
{
|
||||
return this->preferred_language;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node,
|
||||
linked_list_t *errors)
|
||||
{
|
||||
private_tnccs_preferred_language_msg_t *this;
|
||||
xmlChar *language;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_preferred_language = _get_preferred_language,
|
||||
},
|
||||
.type = TNCCS_MSG_PREFERRED_LANGUAGE,
|
||||
.node = node,
|
||||
);
|
||||
|
||||
language = xmlNodeGetContent(node);
|
||||
this->preferred_language = strdup(language);
|
||||
xmlFree(language);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_preferred_language_msg_create(char *language)
|
||||
{
|
||||
private_tnccs_preferred_language_msg_t *this;
|
||||
xmlNodePtr n, n2;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_preferred_language = _get_preferred_language,
|
||||
},
|
||||
.type = TNCCS_MSG_PREFERRED_LANGUAGE,
|
||||
.node = xmlNewNode(NULL, "TNCC-TNCS-Message"),
|
||||
.preferred_language = strdup(language),
|
||||
);
|
||||
|
||||
/* add the message type number in hex */
|
||||
n = xmlNewNode(NULL, "Type");
|
||||
xmlNodeSetContent(n, "00000003");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
n = xmlNewNode(NULL, "XML");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
n2 = xmlNewNode(NULL, enum_to_name(tnccs_msg_type_names, this->type));
|
||||
xmlNodeSetContent(n2, language);
|
||||
xmlAddChild(n, n2);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_preferred_language_msg tnccs_preferred_language_msg
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_PREFERRED_LANGUAGE_MSG_H_
|
||||
#define TNCCS_PREFERRED_LANGUAGE_MSG_H_
|
||||
|
||||
typedef struct tnccs_preferred_language_msg_t tnccs_preferred_language_msg_t;
|
||||
|
||||
#include "tnccs_msg.h"
|
||||
|
||||
#include <tncif.h>
|
||||
|
||||
/**
|
||||
* Class representing the TNCCS-PreferredLanguage message type
|
||||
*/
|
||||
struct tnccs_preferred_language_msg_t {
|
||||
|
||||
/**
|
||||
* TNCCS Message interface
|
||||
*/
|
||||
tnccs_msg_t tnccs_msg_interface;
|
||||
|
||||
/**
|
||||
* Get preferred language string
|
||||
*
|
||||
* @return preferred language string
|
||||
*/
|
||||
char* (*get_preferred_language)(tnccs_preferred_language_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a TNCCS-PreferredLanguage message from XML-encoded message node
|
||||
*
|
||||
* @param node XML-encoded message node
|
||||
* @param errors linked list of TNCCS error messages
|
||||
*/
|
||||
tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node,
|
||||
linked_list_t *errors);
|
||||
|
||||
/**
|
||||
* Create a TNCCS-PreferredLanguage message from parameters
|
||||
*
|
||||
* @param language preferred language string
|
||||
*/
|
||||
tnccs_msg_t *tnccs_preferred_language_msg_create(char *language);
|
||||
|
||||
#endif /** TNCCS_PREFERRED_LANGUAGE_MSG_H_ @}*/
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley ([email protected])
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_reason_strings_msg.h"
|
||||
#include "tnccs_error_msg.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_tnccs_reason_strings_msg_t private_tnccs_reason_strings_msg_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_reason_strings_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_tnccs_reason_strings_msg_t {
|
||||
/**
|
||||
* Public tnccs_reason_strings_msg_t interface.
|
||||
*/
|
||||
tnccs_reason_strings_msg_t public;
|
||||
|
||||
/**
|
||||
* TNCCS message type
|
||||
*/
|
||||
tnccs_msg_type_t type;
|
||||
|
||||
/**
|
||||
* XML-encoded message node
|
||||
*/
|
||||
xmlNodePtr node;
|
||||
|
||||
/**
|
||||
* Reason String
|
||||
*/
|
||||
chunk_t reason;
|
||||
|
||||
/**
|
||||
* Reason Language
|
||||
*/
|
||||
chunk_t language;
|
||||
};
|
||||
|
||||
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
||||
private_tnccs_reason_strings_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
||||
private_tnccs_reason_strings_msg_t *this)
|
||||
{
|
||||
return this->node;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, destroy, void,
|
||||
private_tnccs_reason_strings_msg_t *this)
|
||||
{
|
||||
free(this->reason.ptr);
|
||||
free(this->language.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(tnccs_reason_strings_msg_t, get_reason, chunk_t,
|
||||
private_tnccs_reason_strings_msg_t *this, chunk_t *language)
|
||||
{
|
||||
*language = this->language;
|
||||
|
||||
return this->reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
|
||||
linked_list_t *errors)
|
||||
{
|
||||
private_tnccs_reason_strings_msg_t *this;
|
||||
char *error_msg, *lang_string, *reason_string;
|
||||
tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||
tnccs_msg_t *msg;
|
||||
xmlNodePtr child;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_reason = _get_reason,
|
||||
},
|
||||
.type = TNCCS_MSG_REASON_STRINGS,
|
||||
.node = node,
|
||||
);
|
||||
|
||||
if (xmlStrcmp(node->name, "TNCCS-ReasonStrings"))
|
||||
{
|
||||
error_msg = "TNCCS-ReasonStrings tag expected";
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
child = node->xmlChildrenNode;
|
||||
while (child)
|
||||
{
|
||||
if (xmlIsBlankNode(child))
|
||||
{
|
||||
child = child->next;
|
||||
continue;
|
||||
}
|
||||
if (xmlStrcmp(child->name, "ReasonString"))
|
||||
{
|
||||
error_msg = "ReasonString tag expected";
|
||||
goto fatal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
lang_string = xmlGetProp(child, "lang");
|
||||
if (!lang_string)
|
||||
{
|
||||
lang_string = strdup("");
|
||||
}
|
||||
this->language = chunk_clone(chunk_from_str(lang_string));
|
||||
xmlFree(lang_string);
|
||||
|
||||
reason_string = xmlNodeGetContent(child);
|
||||
this->reason = chunk_clone(chunk_from_str(reason_string));
|
||||
xmlFree(reason_string);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
|
||||
fatal:
|
||||
msg = tnccs_error_msg_create(error_type, error_msg);
|
||||
errors->insert_last(errors, msg);
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language)
|
||||
{
|
||||
private_tnccs_reason_strings_msg_t *this;
|
||||
xmlNodePtr n, n2, n3;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_reason = _get_reason,
|
||||
},
|
||||
.type = TNCCS_MSG_REASON_STRINGS,
|
||||
.node = xmlNewNode(NULL, "TNCC-TNCS-Message"),
|
||||
.reason = chunk_create_clone(malloc(reason.len + 1), reason),
|
||||
.language = chunk_create_clone(malloc(language.len + 1), language),
|
||||
);
|
||||
|
||||
/* add NULL termination for XML string representation */
|
||||
this->reason.ptr[this->reason.len] = '\0';
|
||||
this->language.ptr[this->language.len] = '\0';
|
||||
|
||||
/* add the message type number in hex */
|
||||
n = xmlNewNode(NULL, "Type");
|
||||
xmlNodeSetContent(n, "00000004");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
n = xmlNewNode(NULL, "XML");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
n2 = xmlNewNode(NULL, enum_to_name(tnccs_msg_type_names, this->type));
|
||||
|
||||
/* could add multiple reasons here, if we had them */
|
||||
|
||||
n3 = xmlNewNode(NULL, "ReasonString");
|
||||
xmlNewProp(n3, "xml:lang", this->language.ptr);
|
||||
xmlNodeSetContent(n3, this->reason.ptr);
|
||||
xmlAddChild(n2, n3);
|
||||
xmlAddChild(n, n2);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_reason_strings_msg tnccs_reason_strings_msg
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_REASON_STRINGS_MSG_H_
|
||||
#define TNCCS_REASON_STRINGS_MSG_H_
|
||||
|
||||
typedef struct tnccs_reason_strings_msg_t tnccs_reason_strings_msg_t;
|
||||
|
||||
#include "tnccs_msg.h"
|
||||
|
||||
/**
|
||||
* Class representing the TNCCS-ReasonStrings message type
|
||||
*/
|
||||
struct tnccs_reason_strings_msg_t {
|
||||
|
||||
/**
|
||||
* TNCCS Message interface
|
||||
*/
|
||||
tnccs_msg_t tnccs_msg_interface;
|
||||
|
||||
/**
|
||||
* Get reason string and language
|
||||
*
|
||||
* @param language reason language
|
||||
* @return reason string
|
||||
*/
|
||||
chunk_t (*get_reason)(tnccs_reason_strings_msg_t *this, chunk_t *language);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a TNCCS-ReasonStrings message from XML-encoded message node
|
||||
*
|
||||
* @param node XML-encoded message node
|
||||
* @param errors linked list of TNCCS error messages
|
||||
*/
|
||||
tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
|
||||
linked_list_t *errors);
|
||||
|
||||
/**
|
||||
* Create a TNCCS-ReasonStrings message from parameters
|
||||
*
|
||||
* @param reason reason string
|
||||
* @param language reason language
|
||||
*/
|
||||
tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language);
|
||||
|
||||
#endif /** TNCCS_REASON_STRINGS_MSG_H_ @}*/
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Mike McCauley ([email protected])
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_recommendation_msg.h"
|
||||
#include "tnccs_error_msg.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_tnccs_recommendation_msg_t private_tnccs_recommendation_msg_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_recommendation_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_tnccs_recommendation_msg_t {
|
||||
/**
|
||||
* Public tnccs_recommendation_msg_t interface.
|
||||
*/
|
||||
tnccs_recommendation_msg_t public;
|
||||
|
||||
/**
|
||||
* TNCCS message type
|
||||
*/
|
||||
tnccs_msg_type_t type;
|
||||
|
||||
/**
|
||||
* XML-encoded message node
|
||||
*/
|
||||
xmlNodePtr node;
|
||||
|
||||
/**
|
||||
* Action Recommendation
|
||||
*/
|
||||
TNC_IMV_Action_Recommendation rec;
|
||||
};
|
||||
|
||||
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
||||
private_tnccs_recommendation_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
||||
private_tnccs_recommendation_msg_t *this)
|
||||
{
|
||||
return this->node;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, destroy, void,
|
||||
private_tnccs_recommendation_msg_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(tnccs_recommendation_msg_t, get_recommendation, TNC_IMV_Action_Recommendation,
|
||||
private_tnccs_recommendation_msg_t *this)
|
||||
{
|
||||
return this->rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node,
|
||||
linked_list_t *errors)
|
||||
{
|
||||
private_tnccs_recommendation_msg_t *this;
|
||||
xmlChar *rec_string;
|
||||
char *error_msg, buf[BUF_LEN];
|
||||
tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
|
||||
tnccs_msg_t *msg;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_recommendation = _get_recommendation,
|
||||
},
|
||||
.type = TNCCS_MSG_RECOMMENDATION,
|
||||
.node = node,
|
||||
);
|
||||
|
||||
rec_string = xmlGetProp(node, "type");
|
||||
if (!rec_string)
|
||||
{
|
||||
error_msg = "type property in TNCCS-Recommendation is missing";
|
||||
goto fatal;
|
||||
}
|
||||
else if (streq(rec_string, "allow"))
|
||||
{
|
||||
this->rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;
|
||||
}
|
||||
else if (streq(rec_string, "isolate"))
|
||||
{
|
||||
this->rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE;
|
||||
}
|
||||
else if (streq(rec_string, "none"))
|
||||
{
|
||||
this->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_msg = buf;
|
||||
snprintf(buf, BUF_LEN, "unsupported type property value '%s' "
|
||||
"in TNCCS-Recommendation", rec_string);
|
||||
xmlFree(rec_string);
|
||||
goto fatal;
|
||||
}
|
||||
xmlFree(rec_string);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
|
||||
fatal:
|
||||
msg = tnccs_error_msg_create(error_type, error_msg);
|
||||
errors->insert_last(errors, msg);
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec)
|
||||
{
|
||||
private_tnccs_recommendation_msg_t *this;
|
||||
xmlNodePtr n, n2;
|
||||
char *rec_string;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_recommendation = _get_recommendation,
|
||||
},
|
||||
.type = TNCCS_MSG_RECOMMENDATION,
|
||||
.node = xmlNewNode(NULL, "TNCC-TNCS-Message"),
|
||||
.rec = rec,
|
||||
);
|
||||
|
||||
/* add the message type number in hex */
|
||||
n = xmlNewNode(NULL, "Type");
|
||||
xmlNodeSetContent(n, "00000001");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
n = xmlNewNode(NULL, "XML");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
switch (rec)
|
||||
{
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
|
||||
rec_string = "allow";
|
||||
break;
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
|
||||
rec_string = "isolate";
|
||||
break;
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
|
||||
default:
|
||||
rec_string = "none";
|
||||
}
|
||||
|
||||
n2 = xmlNewNode(NULL, enum_to_name(tnccs_msg_type_names, this->type));
|
||||
xmlNewProp(n2, BAD_CAST "type", rec_string);
|
||||
xmlNodeSetContent(n2, "");
|
||||
xmlAddChild(n, n2);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_recommendation_msg tnccs_recommendation_msg
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_RECOMMENDATION_MSG_H_
|
||||
#define TNCCS_RECOMMENDATION_MSG_H_
|
||||
|
||||
typedef struct tnccs_recommendation_msg_t tnccs_recommendation_msg_t;
|
||||
|
||||
#include "tnccs_msg.h"
|
||||
|
||||
#include <tncifimv.h>
|
||||
|
||||
/**
|
||||
* Class representing the TNCCS-Recommendation message type
|
||||
*/
|
||||
struct tnccs_recommendation_msg_t {
|
||||
|
||||
/**
|
||||
* TNCCS Message interface
|
||||
*/
|
||||
tnccs_msg_t tnccs_msg_interface;
|
||||
|
||||
/**
|
||||
* Get Action Recommendation
|
||||
*
|
||||
* @return Action Recommendation
|
||||
*/
|
||||
TNC_IMV_Action_Recommendation (*get_recommendation)(tnccs_recommendation_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a TNCCS-Recommendation message from XML-encoded message node
|
||||
*
|
||||
* @param node XML-encoded message node
|
||||
* @param errors linked list of TNCCS error messages
|
||||
*/
|
||||
tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node,
|
||||
linked_list_t *errors);
|
||||
|
||||
/**
|
||||
* Create a TNCCS-Recommendation message from parameters
|
||||
*
|
||||
* @param rec Action Recommendation
|
||||
*/
|
||||
tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec);
|
||||
|
||||
#endif /** TNCCS_RECOMMENDATION_MSG_H_ @}*/
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_tncs_contact_info_msg.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_tnccs_tncs_contact_info_msg_t private_tnccs_tncs_contact_info_msg_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_tncs_contact_info_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_tnccs_tncs_contact_info_msg_t {
|
||||
/**
|
||||
* Public tnccs_tncs_contact_info_msg_t interface.
|
||||
*/
|
||||
tnccs_tncs_contact_info_msg_t public;
|
||||
|
||||
/**
|
||||
* TNCCS message type
|
||||
*/
|
||||
tnccs_msg_type_t type;
|
||||
|
||||
/**
|
||||
* XML-encoded message node
|
||||
*/
|
||||
xmlNodePtr node;
|
||||
};
|
||||
|
||||
METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
|
||||
private_tnccs_tncs_contact_info_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, get_node, xmlNodePtr,
|
||||
private_tnccs_tncs_contact_info_msg_t *this)
|
||||
{
|
||||
return this->node;
|
||||
}
|
||||
|
||||
METHOD(tnccs_msg_t, destroy, void,
|
||||
private_tnccs_tncs_contact_info_msg_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node,
|
||||
linked_list_t *errors)
|
||||
{
|
||||
private_tnccs_tncs_contact_info_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.type = TNCCS_MSG_TNCS_CONTACT_INFO,
|
||||
.node = node,
|
||||
);
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_msg_t *tnccs_tncs_contact_info_msg_create(void)
|
||||
{
|
||||
private_tnccs_tncs_contact_info_msg_t *this;
|
||||
xmlNodePtr n /*, n2 */;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tnccs_msg_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_node = _get_node,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.type = TNCCS_MSG_TNCS_CONTACT_INFO,
|
||||
.node = xmlNewNode(NULL, "TNCC-TNCS-Message"),
|
||||
);
|
||||
|
||||
/* add the message type number in hex */
|
||||
n = xmlNewNode(NULL, "Type");
|
||||
xmlNodeSetContent(n, "00000005");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
n = xmlNewNode(NULL, "XML");
|
||||
xmlAddChild(this->node, n);
|
||||
|
||||
/* TODO
|
||||
n2 = xmlNewNode(NULL, enum_to_name(tnccs_msg_type_names, this->type));
|
||||
xmlNodeSetContent(n2, language);
|
||||
xmlAddChild(n, n2);
|
||||
*/
|
||||
|
||||
return &this->public.tnccs_msg_interface;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_tncs_contact_info_msg tnccs_tncs_contact_info_msg
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_TNCS_CONTACT_INFO_MSG_H_
|
||||
#define TNCCS_TNCS_CONTACT_INFO_MSG_H_
|
||||
|
||||
typedef struct tnccs_tncs_contact_info_msg_t tnccs_tncs_contact_info_msg_t;
|
||||
|
||||
#include "tnccs_msg.h"
|
||||
|
||||
/**
|
||||
* Class representing the TNCCS-TNCSContactInfo message type
|
||||
*/
|
||||
struct tnccs_tncs_contact_info_msg_t {
|
||||
|
||||
/**
|
||||
* TNCCS Message interface
|
||||
*/
|
||||
tnccs_msg_t tnccs_msg_interface;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a TNCCS-TNCSContactInfo message from XML-encoded message node
|
||||
*
|
||||
* @param node XML-encoded message node
|
||||
* @param errors linked list of TNCCS error messages
|
||||
*/
|
||||
tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node,
|
||||
linked_list_t *errors);
|
||||
|
||||
/**
|
||||
* Create a TNCCS-TNCSContactInfo message from parameters
|
||||
*
|
||||
*/
|
||||
tnccs_msg_t *tnccs_tncs_contact_info_msg_create(void);
|
||||
|
||||
#endif /** TNCCS_TNCS_CONTACT_INFO_MSG_H_ @}*/
|
||||
@@ -1,633 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_11.h"
|
||||
#include "batch/tnccs_batch.h"
|
||||
#include "messages/tnccs_msg.h"
|
||||
#include "messages/imc_imv_msg.h"
|
||||
#include "messages/tnccs_error_msg.h"
|
||||
#include "messages/tnccs_preferred_language_msg.h"
|
||||
#include "messages/tnccs_reason_strings_msg.h"
|
||||
#include "messages/tnccs_recommendation_msg.h"
|
||||
|
||||
#include <tncif_names.h>
|
||||
#include <tncif_pa_subtypes.h>
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
#include <tnc/imc/imc_manager.h>
|
||||
#include <tnc/imv/imv_manager.h>
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
#include <tnc/tnccs/tnccs_manager.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <daemon.h>
|
||||
#include <threading/mutex.h>
|
||||
|
||||
typedef struct private_tnccs_11_t private_tnccs_11_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_11_t object.
|
||||
*/
|
||||
struct private_tnccs_11_t {
|
||||
|
||||
/**
|
||||
* Public tnccs_t interface.
|
||||
*/
|
||||
tnccs_t public;
|
||||
|
||||
/**
|
||||
* TNCC if TRUE, TNCS if FALSE
|
||||
*/
|
||||
bool is_server;
|
||||
|
||||
/**
|
||||
* Server identity
|
||||
*/
|
||||
identification_t *server;
|
||||
|
||||
/**
|
||||
* Client identity
|
||||
*/
|
||||
identification_t *peer;
|
||||
|
||||
/**
|
||||
* Underlying TNC IF-T transport protocol
|
||||
*/
|
||||
tnc_ift_type_t transport;
|
||||
|
||||
/**
|
||||
* Type of TNC client authentication
|
||||
*/
|
||||
u_int32_t auth_type;
|
||||
|
||||
/**
|
||||
* Connection ID assigned to this TNCCS connection
|
||||
*/
|
||||
TNC_ConnectionID connection_id;
|
||||
|
||||
/**
|
||||
* Last TNCCS batch ID
|
||||
*/
|
||||
int batch_id;
|
||||
|
||||
/**
|
||||
* TNCCS batch being constructed
|
||||
*/
|
||||
tnccs_batch_t *batch;
|
||||
|
||||
/**
|
||||
* Maximum PA-TNC message size
|
||||
*/
|
||||
size_t max_msg_len;
|
||||
|
||||
/**
|
||||
* Mutex locking the batch in construction
|
||||
*/
|
||||
mutex_t *mutex;
|
||||
|
||||
/**
|
||||
* Flag set while processing
|
||||
*/
|
||||
bool fatal_error;
|
||||
|
||||
/**
|
||||
* Flag set by TNCCS-Recommendation message
|
||||
*/
|
||||
bool delete_state;
|
||||
|
||||
/**
|
||||
* SendMessage() by IMC/IMV only allowed if flag is set
|
||||
*/
|
||||
bool send_msg;
|
||||
|
||||
/**
|
||||
* Flag set by IMC/IMV RequestHandshakeRetry() function
|
||||
*/
|
||||
bool request_handshake_retry;
|
||||
|
||||
/**
|
||||
* Set of IMV recommendations (TNC Server only)
|
||||
*/
|
||||
recommendations_t *recs;
|
||||
|
||||
};
|
||||
|
||||
METHOD(tnccs_t, send_msg, TNC_Result,
|
||||
private_tnccs_11_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
|
||||
TNC_UInt32 msg_flags,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_VendorID msg_vid,
|
||||
TNC_MessageSubtype msg_subtype)
|
||||
{
|
||||
tnccs_msg_t *tnccs_msg;
|
||||
TNC_MessageType msg_type;
|
||||
enum_name_t *pa_subtype_names;
|
||||
|
||||
if (!this->send_msg)
|
||||
{
|
||||
DBG1(DBG_TNC, "%s %u not allowed to call SendMessage()",
|
||||
this->is_server ? "IMV" : "IMC",
|
||||
this->is_server ? imv_id : imc_id);
|
||||
return TNC_RESULT_ILLEGAL_OPERATION;
|
||||
}
|
||||
if (msg_vid > TNC_VENDORID_ANY || msg_subtype > TNC_SUBTYPE_ANY)
|
||||
{
|
||||
return TNC_RESULT_NO_LONG_MESSAGE_TYPES;
|
||||
}
|
||||
msg_type = (msg_vid << 8) | msg_subtype;
|
||||
|
||||
pa_subtype_names = get_pa_subtype_names(msg_vid);
|
||||
if (pa_subtype_names)
|
||||
{
|
||||
DBG2(DBG_TNC, "creating IMC-IMV message type '%N/%N' 0x%06x/0x%02x",
|
||||
pen_names, msg_vid, pa_subtype_names, msg_subtype,
|
||||
msg_vid, msg_subtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_TNC, "creating IMC-IMV message type '%N' 0x%06x/0x%02x",
|
||||
pen_names, msg_vid, msg_vid, msg_subtype);
|
||||
}
|
||||
tnccs_msg = imc_imv_msg_create(msg_type, chunk_create(msg, msg_len));
|
||||
|
||||
/* adding an IMC-IMV Message to TNCCS batch */
|
||||
this->mutex->lock(this->mutex);
|
||||
if (!this->batch)
|
||||
{
|
||||
this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
|
||||
}
|
||||
this->batch->add_msg(this->batch, tnccs_msg);
|
||||
this->mutex->unlock(this->mutex);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a single TNCCS message according to its type
|
||||
*/
|
||||
static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
|
||||
{
|
||||
switch (msg->get_type(msg))
|
||||
{
|
||||
case IMC_IMV_MSG:
|
||||
{
|
||||
imc_imv_msg_t *imc_imv_msg;
|
||||
TNC_MessageType msg_type;
|
||||
chunk_t msg_body;
|
||||
u_int32_t msg_vid, msg_subtype;
|
||||
enum_name_t *pa_subtype_names;
|
||||
|
||||
imc_imv_msg = (imc_imv_msg_t*)msg;
|
||||
msg_type = imc_imv_msg->get_msg_type(imc_imv_msg);
|
||||
msg_body = imc_imv_msg->get_msg_body(imc_imv_msg);
|
||||
msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
|
||||
msg_subtype = msg_type & TNC_SUBTYPE_ANY;
|
||||
|
||||
pa_subtype_names = get_pa_subtype_names(msg_vid);
|
||||
if (pa_subtype_names)
|
||||
{
|
||||
DBG2(DBG_TNC, "handling IMC-IMV message type '%N/%N' 0x%06x/0x%02x",
|
||||
pen_names, msg_vid, pa_subtype_names, msg_subtype,
|
||||
msg_vid, msg_subtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_TNC, "handling IMC-IMV message type '%N' 0x%06x/0x%02x",
|
||||
pen_names, msg_vid, msg_vid, msg_subtype);
|
||||
}
|
||||
|
||||
this->send_msg = TRUE;
|
||||
if (this->is_server)
|
||||
{
|
||||
tnc->imvs->receive_message(tnc->imvs, this->connection_id,
|
||||
FALSE, msg_body.ptr, msg_body.len,
|
||||
msg_vid, msg_subtype, 0, TNC_IMVID_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
tnc->imcs->receive_message(tnc->imcs, this->connection_id,
|
||||
FALSE, msg_body.ptr, msg_body.len,
|
||||
msg_vid, msg_subtype, 0, TNC_IMCID_ANY);
|
||||
}
|
||||
this->send_msg = FALSE;
|
||||
break;
|
||||
}
|
||||
case TNCCS_MSG_RECOMMENDATION:
|
||||
{
|
||||
tnccs_recommendation_msg_t *rec_msg;
|
||||
TNC_IMV_Action_Recommendation rec;
|
||||
TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
|
||||
|
||||
rec_msg = (tnccs_recommendation_msg_t*)msg;
|
||||
rec = rec_msg->get_recommendation(rec_msg);
|
||||
if (this->is_server)
|
||||
{
|
||||
DBG1(DBG_TNC, "ignoring NCCS-Recommendation message from "
|
||||
" TNC client");
|
||||
break;
|
||||
}
|
||||
DBG1(DBG_TNC, "TNC recommendation is '%N'",
|
||||
TNC_IMV_Action_Recommendation_names, rec);
|
||||
switch (rec)
|
||||
{
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
|
||||
break;
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
|
||||
break;
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
|
||||
default:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_NONE;
|
||||
}
|
||||
tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
|
||||
state);
|
||||
this->delete_state = TRUE;
|
||||
break;
|
||||
}
|
||||
case TNCCS_MSG_ERROR:
|
||||
{
|
||||
tnccs_error_msg_t *err_msg;
|
||||
tnccs_error_type_t error_type;
|
||||
char *error_msg;
|
||||
|
||||
err_msg = (tnccs_error_msg_t*)msg;
|
||||
error_msg = err_msg->get_message(err_msg, &error_type);
|
||||
DBG1(DBG_TNC, "received '%N' TNCCS-Error: %s",
|
||||
tnccs_error_type_names, error_type, error_msg);
|
||||
|
||||
/* we assume that all errors are fatal */
|
||||
this->fatal_error = TRUE;
|
||||
break;
|
||||
}
|
||||
case TNCCS_MSG_PREFERRED_LANGUAGE:
|
||||
{
|
||||
tnccs_preferred_language_msg_t *lang_msg;
|
||||
char *lang;
|
||||
|
||||
lang_msg = (tnccs_preferred_language_msg_t*)msg;
|
||||
lang = lang_msg->get_preferred_language(lang_msg);
|
||||
|
||||
DBG2(DBG_TNC, "setting preferred language to '%s'", lang);
|
||||
this->recs->set_preferred_language(this->recs,
|
||||
chunk_create(lang, strlen(lang)));
|
||||
break;
|
||||
}
|
||||
case TNCCS_MSG_REASON_STRINGS:
|
||||
{
|
||||
tnccs_reason_strings_msg_t *reason_msg;
|
||||
chunk_t reason_string, reason_lang;
|
||||
|
||||
reason_msg = (tnccs_reason_strings_msg_t*)msg;
|
||||
reason_string = reason_msg->get_reason(reason_msg, &reason_lang);
|
||||
DBG2(DBG_TNC, "reason string is '%.*s'", (int)reason_string.len,
|
||||
reason_string.ptr);
|
||||
DBG2(DBG_TNC, "language code is '%.*s'", (int)reason_lang.len,
|
||||
reason_lang.ptr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tls_t, process, status_t,
|
||||
private_tnccs_11_t *this, void *buf, size_t buflen)
|
||||
{
|
||||
chunk_t data;
|
||||
tnccs_batch_t *batch;
|
||||
tnccs_msg_t *msg;
|
||||
enumerator_t *enumerator;
|
||||
status_t status;
|
||||
|
||||
if (this->is_server && !this->connection_id)
|
||||
{
|
||||
this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
|
||||
TNCCS_1_1, (tnccs_t*)this, _send_msg,
|
||||
&this->request_handshake_retry,
|
||||
this->max_msg_len, &this->recs);
|
||||
if (!this->connection_id)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_CREATE);
|
||||
tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_HANDSHAKE);
|
||||
}
|
||||
|
||||
data = chunk_create(buf, buflen);
|
||||
DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u",
|
||||
data.len, this->connection_id);
|
||||
DBG3(DBG_TNC, "%.*s", (int)data.len, data.ptr);
|
||||
batch = tnccs_batch_create_from_data(this->is_server, ++this->batch_id, data);
|
||||
status = batch->process(batch);
|
||||
|
||||
if (status == FAILED)
|
||||
{
|
||||
this->fatal_error = TRUE;
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->batch)
|
||||
{
|
||||
DBG1(DBG_TNC, "cancelling TNCCS batch");
|
||||
this->batch->destroy(this->batch);
|
||||
this->batch_id--;
|
||||
}
|
||||
this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
|
||||
|
||||
/* add error messages to outbound batch */
|
||||
enumerator = batch->create_error_enumerator(batch);
|
||||
while (enumerator->enumerate(enumerator, &msg))
|
||||
{
|
||||
this->batch->add_msg(this->batch, msg->get_ref(msg));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
enumerator = batch->create_msg_enumerator(batch);
|
||||
while (enumerator->enumerate(enumerator, &msg))
|
||||
{
|
||||
handle_message(this, msg);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* received any TNCCS-Error messages */
|
||||
if (this->fatal_error)
|
||||
{
|
||||
DBG1(DBG_TNC, "a fatal TNCCS-Error occurred, terminating connection");
|
||||
batch->destroy(batch);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
this->send_msg = TRUE;
|
||||
if (this->is_server)
|
||||
{
|
||||
tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
|
||||
}
|
||||
this->send_msg = FALSE;
|
||||
}
|
||||
batch->destroy(batch);
|
||||
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a recommendation message if a final recommendation is available
|
||||
*/
|
||||
static void check_and_build_recommendation(private_tnccs_11_t *this)
|
||||
{
|
||||
TNC_IMV_Action_Recommendation rec;
|
||||
TNC_IMV_Evaluation_Result eval;
|
||||
TNC_IMVID id;
|
||||
chunk_t reason, language;
|
||||
enumerator_t *enumerator;
|
||||
tnccs_msg_t *msg;
|
||||
|
||||
if (!this->recs->have_recommendation(this->recs, &rec, &eval))
|
||||
{
|
||||
tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
|
||||
}
|
||||
if (this->recs->have_recommendation(this->recs, &rec, &eval))
|
||||
{
|
||||
if (!this->batch)
|
||||
{
|
||||
this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
|
||||
}
|
||||
|
||||
msg = tnccs_recommendation_msg_create(rec);
|
||||
this->batch->add_msg(this->batch, msg);
|
||||
|
||||
/* currently we just send the first Reason String */
|
||||
enumerator = this->recs->create_reason_enumerator(this->recs);
|
||||
if (enumerator->enumerate(enumerator, &id, &reason, &language))
|
||||
{
|
||||
msg = tnccs_reason_strings_msg_create(reason, language);
|
||||
this->batch->add_msg(this->batch, msg);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* we have reache the final state */
|
||||
this->delete_state = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tls_t, build, status_t,
|
||||
private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen)
|
||||
{
|
||||
status_t status;
|
||||
|
||||
/* Initialize the connection */
|
||||
if (!this->is_server && !this->connection_id)
|
||||
{
|
||||
tnccs_msg_t *msg;
|
||||
char *pref_lang;
|
||||
|
||||
this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
|
||||
TNCCS_1_1, (tnccs_t*)this, _send_msg,
|
||||
&this->request_handshake_retry,
|
||||
this->max_msg_len, NULL);
|
||||
if (!this->connection_id)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* Create TNCCS-PreferredLanguage message */
|
||||
pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
|
||||
msg = tnccs_preferred_language_msg_create(pref_lang);
|
||||
this->mutex->lock(this->mutex);
|
||||
this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
|
||||
this->batch->add_msg(this->batch, msg);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_CREATE);
|
||||
tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_HANDSHAKE);
|
||||
this->send_msg = TRUE;
|
||||
tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
|
||||
this->send_msg = FALSE;
|
||||
}
|
||||
|
||||
/* Do not allow any asynchronous IMCs or IMVs to add additional messages */
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
if (this->recs && !this->delete_state &&
|
||||
(!this->batch || this->fatal_error))
|
||||
{
|
||||
check_and_build_recommendation(this);
|
||||
}
|
||||
|
||||
if (this->batch)
|
||||
{
|
||||
chunk_t data;
|
||||
|
||||
this->batch->build(this->batch);
|
||||
data = this->batch->get_encoding(this->batch);
|
||||
DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u",
|
||||
data.len, this->connection_id);
|
||||
DBG3(DBG_TNC, "%.*s", (int)data.len, data.ptr);
|
||||
*msglen = 0;
|
||||
|
||||
if (data.len > *buflen)
|
||||
{
|
||||
DBG1(DBG_TNC, "fragmentation of TNCCS batch not supported yet");
|
||||
}
|
||||
else
|
||||
{
|
||||
*buflen = data.len;
|
||||
}
|
||||
memcpy(buf, data.ptr, *buflen);
|
||||
this->batch->destroy(this->batch);
|
||||
this->batch = NULL;
|
||||
status = ALREADY_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, "no TNCCS Batch to send");
|
||||
status = INVALID_STATE;
|
||||
}
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
METHOD(tls_t, is_server, bool,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
return this->is_server;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_server_id, identification_t*,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
return this->server;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_peer_id, identification_t*,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
return this->peer;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_purpose, tls_purpose_t,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
return TLS_PURPOSE_EAP_TNC;
|
||||
}
|
||||
|
||||
METHOD(tls_t, is_complete, bool,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
TNC_IMV_Action_Recommendation rec;
|
||||
TNC_IMV_Evaluation_Result eval;
|
||||
|
||||
if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
|
||||
{
|
||||
return tnc->imvs->enforce_recommendation(tnc->imvs, rec, eval);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_eap_msk, chunk_t,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
return chunk_empty;
|
||||
}
|
||||
|
||||
METHOD(tls_t, destroy, void,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
|
||||
this->is_server);
|
||||
this->server->destroy(this->server);
|
||||
this->peer->destroy(this->peer);
|
||||
this->mutex->destroy(this->mutex);
|
||||
DESTROY_IF(this->batch);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, get_transport, tnc_ift_type_t,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
return this->transport;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, set_transport, void,
|
||||
private_tnccs_11_t *this, tnc_ift_type_t transport)
|
||||
{
|
||||
this->transport = transport;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, get_auth_type, u_int32_t,
|
||||
private_tnccs_11_t *this)
|
||||
{
|
||||
return this->auth_type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, set_auth_type, void,
|
||||
private_tnccs_11_t *this, u_int32_t auth_type)
|
||||
{
|
||||
this->auth_type = auth_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_t* tnccs_11_create(bool is_server,
|
||||
identification_t *server,
|
||||
identification_t *peer,
|
||||
tnc_ift_type_t transport)
|
||||
{
|
||||
private_tnccs_11_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tls = {
|
||||
.process = _process,
|
||||
.build = _build,
|
||||
.is_server = _is_server,
|
||||
.get_server_id = _get_server_id,
|
||||
.get_peer_id = _get_peer_id,
|
||||
.get_purpose = _get_purpose,
|
||||
.is_complete = _is_complete,
|
||||
.get_eap_msk = _get_eap_msk,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_transport = _get_transport,
|
||||
.set_transport = _set_transport,
|
||||
.get_auth_type = _get_auth_type,
|
||||
.set_auth_type = _set_auth_type,
|
||||
},
|
||||
.is_server = is_server,
|
||||
.server = server->clone(server),
|
||||
.peer = peer->clone(peer),
|
||||
.transport = transport,
|
||||
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||
.max_msg_len = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.tnccs-11.max_message_size", 45000,
|
||||
charon->name),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_11_h tnccs_11
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_11_H_
|
||||
#define TNCCS_11_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
|
||||
/**
|
||||
* Create an instance of the TNC IF-TNCCS 1.1 protocol handler.
|
||||
*
|
||||
* @param is_server TRUE to act as TNC Server, FALSE for TNC Client
|
||||
* @param server Server identity
|
||||
* @param peer Client identity
|
||||
* @param transport Underlying IF-T transport protocol
|
||||
* @return TNC_IF_TNCCS 1.1 protocol stack
|
||||
*/
|
||||
tnccs_t* tnccs_11_create(bool is_server,
|
||||
identification_t *server,
|
||||
identification_t *peer,
|
||||
tnc_ift_type_t transport);
|
||||
|
||||
#endif /** TNCCS_11_H_ @}*/
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_11_plugin.h"
|
||||
#include "tnccs_11.h"
|
||||
|
||||
#include <tnc/tnccs/tnccs_manager.h>
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
tnccs_11_plugin_t *this)
|
||||
{
|
||||
return "tnccs-11";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
tnccs_11_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(tnccs_method_register, tnccs_11_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "tnccs-1.1"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
tnccs_11_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *tnccs_11_plugin_create()
|
||||
{
|
||||
tnccs_11_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
);
|
||||
|
||||
return &this->plugin;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_11 tnccs_11
|
||||
* @ingroup cplugins
|
||||
*
|
||||
* @defgroup tnccs_11_plugin tnccs_11_plugin
|
||||
* @{ @ingroup tnccs_11
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_11_PLUGIN_H_
|
||||
#define TNCCS_11_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct tnccs_11_plugin_t tnccs_11_plugin_t;
|
||||
|
||||
/**
|
||||
* EAP-TNC plugin
|
||||
*/
|
||||
struct tnccs_11_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** TNCCS_11_PLUGIN_H_ @}*/
|
||||
@@ -1,35 +0,0 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libcharon \
|
||||
-I$(top_srcdir)/src/libhydra \
|
||||
-I$(top_srcdir)/src/libtls \
|
||||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libtnccs
|
||||
|
||||
AM_CFLAGS = \
|
||||
-rdynamic
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-tnccs-20.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-tnccs-20.la
|
||||
libstrongswan_tnccs_20_la_LIBADD = \
|
||||
$(top_builddir)/src/libtncif/libtncif.la \
|
||||
$(top_builddir)/src/libtnccs/libtnccs.la
|
||||
endif
|
||||
|
||||
libstrongswan_tnccs_20_la_SOURCES = \
|
||||
tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
|
||||
batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
|
||||
messages/pb_tnc_msg.h messages/pb_tnc_msg.c \
|
||||
messages/pb_experimental_msg.h messages/pb_experimental_msg.c \
|
||||
messages/pb_pa_msg.h messages/pb_pa_msg.c \
|
||||
messages/pb_assessment_result_msg.h messages/pb_assessment_result_msg.c \
|
||||
messages/pb_access_recommendation_msg.h messages/pb_access_recommendation_msg.c \
|
||||
messages/pb_error_msg.h messages/pb_error_msg.c \
|
||||
messages/pb_language_preference_msg.h messages/pb_language_preference_msg.c \
|
||||
messages/pb_reason_string_msg.h messages/pb_reason_string_msg.c \
|
||||
messages/pb_remediation_parameters_msg.h messages/pb_remediation_parameters_msg.c \
|
||||
state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
|
||||
|
||||
libstrongswan_tnccs_20_la_LDFLAGS = -module -avoid-version
|
||||
@@ -1,577 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyanbuu
|
||||
* Copyright (C) 2010-2012 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_tnc_batch.h"
|
||||
#include "messages/pb_error_msg.h"
|
||||
#include "state_machine/pb_tnc_state_machine.h"
|
||||
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
|
||||
#include <collections/linked_list.h>
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <pen/pen.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
ENUM(pb_tnc_batch_type_names, PB_BATCH_CDATA, PB_BATCH_CLOSE,
|
||||
"CDATA",
|
||||
"SDATA",
|
||||
"RESULT",
|
||||
"CRETRY",
|
||||
"SRETRY",
|
||||
"CLOSE"
|
||||
);
|
||||
|
||||
typedef struct private_pb_tnc_batch_t private_pb_tnc_batch_t;
|
||||
|
||||
/**
|
||||
* PB-Batch Header (see section 4.1 of RFC 5793)
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Version |D| Reserved | B-Type|
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Batch Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
#define PB_TNC_BATCH_FLAG_NONE 0x00
|
||||
#define PB_TNC_BATCH_FLAG_D (1<<7)
|
||||
#define PB_TNC_BATCH_HEADER_SIZE 8
|
||||
|
||||
/**
|
||||
* PB-TNC Message (see section 4.2 of RFC 5793)
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Flags | PB-TNC Vendor ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | PB-TNC Message Type |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | PB-TNC Message Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | PB-TNC Message Value (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
#define PB_TNC_FLAG_NONE 0x00
|
||||
#define PB_TNC_FLAG_NOSKIP (1<<7)
|
||||
#define PB_TNC_HEADER_SIZE 12
|
||||
|
||||
#define PB_TNC_RESERVED_MSG_TYPE 0xffffffff
|
||||
|
||||
/**
|
||||
* Private data of a pb_tnc_batch_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_tnc_batch_t {
|
||||
/**
|
||||
* Public pb_pa_msg_t interface.
|
||||
*/
|
||||
pb_tnc_batch_t public;
|
||||
|
||||
/**
|
||||
* TNCC if TRUE, TNCS if FALSE
|
||||
*/
|
||||
bool is_server;
|
||||
|
||||
/**
|
||||
* PB-TNC Batch type
|
||||
*/
|
||||
pb_tnc_batch_type_t type;
|
||||
|
||||
/**
|
||||
* Current PB-TNC Batch size
|
||||
*/
|
||||
size_t batch_len;
|
||||
|
||||
/**
|
||||
* Maximum PB-TNC Batch size
|
||||
*/
|
||||
size_t max_batch_len;
|
||||
|
||||
/**
|
||||
* linked list of PB-TNC messages
|
||||
*/
|
||||
linked_list_t *messages;
|
||||
|
||||
/**
|
||||
* linked list of PB-TNC error messages
|
||||
*/
|
||||
linked_list_t *errors;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
|
||||
/**
|
||||
* Offset into encoding (used for error reporting)
|
||||
*/
|
||||
u_int32_t offset;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_batch_t, get_type, pb_tnc_batch_type_t,
|
||||
private_pb_tnc_batch_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_batch_t, get_encoding, chunk_t,
|
||||
private_pb_tnc_batch_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_batch_t, add_msg, bool,
|
||||
private_pb_tnc_batch_t *this, pb_tnc_msg_t* msg)
|
||||
{
|
||||
chunk_t msg_value;
|
||||
size_t msg_len;
|
||||
|
||||
msg->build(msg);
|
||||
msg_value = msg->get_encoding(msg);
|
||||
msg_len = PB_TNC_HEADER_SIZE + msg_value.len;
|
||||
|
||||
if (this->batch_len + msg_len > this->max_batch_len)
|
||||
{
|
||||
/* message just does not fit into this batch */
|
||||
return FALSE;
|
||||
}
|
||||
this->batch_len += msg_len;
|
||||
|
||||
DBG2(DBG_TNC, "adding %N message", pb_tnc_msg_type_names,
|
||||
msg->get_type(msg));
|
||||
this->messages->insert_last(this->messages, msg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_batch_t, build, void,
|
||||
private_pb_tnc_batch_t *this)
|
||||
{
|
||||
u_int32_t msg_len;
|
||||
chunk_t msg_value;
|
||||
enumerator_t *enumerator;
|
||||
pb_tnc_msg_type_t msg_type;
|
||||
pb_tnc_msg_t *msg;
|
||||
bio_writer_t *writer;
|
||||
|
||||
/* build PB-TNC batch header */
|
||||
writer = bio_writer_create(this->batch_len);
|
||||
writer->write_uint8 (writer, PB_TNC_VERSION);
|
||||
writer->write_uint8 (writer, this->is_server ?
|
||||
PB_TNC_BATCH_FLAG_D : PB_TNC_BATCH_FLAG_NONE);
|
||||
writer->write_uint16(writer, this->type);
|
||||
writer->write_uint32(writer, this->batch_len);
|
||||
|
||||
/* build PB-TNC messages */
|
||||
enumerator = this->messages->create_enumerator(this->messages);
|
||||
while (enumerator->enumerate(enumerator, &msg))
|
||||
{
|
||||
u_int8_t flags = PB_TNC_FLAG_NONE;
|
||||
|
||||
/* build PB-TNC message */
|
||||
msg_value = msg->get_encoding(msg);
|
||||
msg_len = PB_TNC_HEADER_SIZE + msg_value.len;
|
||||
msg_type = msg->get_type(msg);
|
||||
if (pb_tnc_msg_infos[msg_type].has_noskip_flag)
|
||||
{
|
||||
flags |= PB_TNC_FLAG_NOSKIP;
|
||||
}
|
||||
writer->write_uint8 (writer, flags);
|
||||
writer->write_uint24(writer, PEN_IETF);
|
||||
writer->write_uint32(writer, msg_type);
|
||||
writer->write_uint32(writer, msg_len);
|
||||
writer->write_data (writer, msg_value);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
this->encoding = writer->extract_buf(writer);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
static status_t process_batch_header(private_pb_tnc_batch_t *this,
|
||||
pb_tnc_state_machine_t *state_machine)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
pb_tnc_msg_t *msg;
|
||||
pb_error_msg_t *err_msg;
|
||||
u_int8_t version, flags, reserved, type;
|
||||
u_int32_t batch_len;
|
||||
bool directionality;
|
||||
|
||||
if (this->encoding.len < PB_TNC_BATCH_HEADER_SIZE)
|
||||
{
|
||||
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC batch header",
|
||||
this->encoding.len);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, 0);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
reader = bio_reader_create(this->encoding);
|
||||
reader->read_uint8 (reader, &version);
|
||||
reader->read_uint8 (reader, &flags);
|
||||
reader->read_uint8 (reader, &reserved);
|
||||
reader->read_uint8 (reader, &type);
|
||||
reader->read_uint32(reader, &batch_len);
|
||||
reader->destroy(reader);
|
||||
|
||||
/* Version */
|
||||
if (version != PB_TNC_VERSION)
|
||||
{
|
||||
DBG1(DBG_TNC, "unsupported TNCCS batch version 0x%02x", version);
|
||||
msg = pb_error_msg_create(TRUE, PEN_IETF,
|
||||
PB_ERROR_VERSION_NOT_SUPPORTED);
|
||||
err_msg = (pb_error_msg_t*)msg;
|
||||
err_msg->set_bad_version(err_msg, version);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* Directionality */
|
||||
directionality = (flags & PB_TNC_BATCH_FLAG_D) != PB_TNC_BATCH_FLAG_NONE;
|
||||
if (directionality == this->is_server)
|
||||
{
|
||||
DBG1(DBG_TNC, "wrong Directionality: batch is from a PB %s",
|
||||
directionality ? "server" : "client");
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, 1);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
/* Batch Type */
|
||||
this->type = type & 0x0F;
|
||||
if (this->type > PB_BATCH_ROOF)
|
||||
{
|
||||
DBG1(DBG_TNC, "unknown PB-TNC batch type: %d", this->type);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, 3);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
if (!state_machine->receive_batch(state_machine, this->type))
|
||||
{
|
||||
DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N",
|
||||
pb_tnc_batch_type_names, this->type);
|
||||
msg = pb_error_msg_create(TRUE, PEN_IETF,
|
||||
PB_ERROR_UNEXPECTED_BATCH_TYPE);
|
||||
goto fatal;
|
||||
}
|
||||
DBG1(DBG_TNC, "processing PB-TNC %N batch", pb_tnc_batch_type_names,
|
||||
this->type);
|
||||
|
||||
/* Batch Length */
|
||||
if (this->encoding.len != batch_len)
|
||||
{
|
||||
DBG1(DBG_TNC, "%u bytes of data is not equal to batch length of %u bytes",
|
||||
this->encoding.len, batch_len);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, 4);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
this->offset = PB_TNC_BATCH_HEADER_SIZE;
|
||||
|
||||
/* Register an empty CDATA batch with the state machine */
|
||||
if (this->type == PB_BATCH_CDATA)
|
||||
{
|
||||
state_machine->set_empty_cdata(state_machine,
|
||||
this->offset == this->encoding.len);
|
||||
}
|
||||
return SUCCESS;
|
||||
|
||||
fatal:
|
||||
this->errors->insert_last(this->errors, msg);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
pb_tnc_msg_t *pb_tnc_msg, *msg;
|
||||
u_int8_t flags;
|
||||
u_int32_t vendor_id, msg_type, msg_len, offset;
|
||||
chunk_t data, msg_value;
|
||||
bool noskip_flag;
|
||||
status_t status;
|
||||
|
||||
data = chunk_skip(this->encoding, this->offset);
|
||||
|
||||
if (data.len < PB_TNC_HEADER_SIZE)
|
||||
{
|
||||
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message header",
|
||||
data.len);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
reader = bio_reader_create(data);
|
||||
reader->read_uint8 (reader, &flags);
|
||||
reader->read_uint24(reader, &vendor_id);
|
||||
reader->read_uint32(reader, &msg_type);
|
||||
reader->read_uint32(reader, &msg_len);
|
||||
reader->destroy(reader);
|
||||
|
||||
noskip_flag = (flags & PB_TNC_FLAG_NOSKIP) != PB_TNC_FLAG_NONE;
|
||||
|
||||
if (msg_len > data.len)
|
||||
{
|
||||
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message", data.len);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset + 8);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
if (vendor_id == PEN_RESERVED)
|
||||
{
|
||||
DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", PEN_RESERVED);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset + 1);
|
||||
goto fatal;
|
||||
|
||||
}
|
||||
|
||||
if (msg_type == PB_TNC_RESERVED_MSG_TYPE)
|
||||
{
|
||||
DBG1(DBG_TNC, "PB-TNC message Type 0x%08x is reserved",
|
||||
PB_TNC_RESERVED_MSG_TYPE);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset + 4);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
|
||||
if (vendor_id != PEN_IETF || msg_type > PB_MSG_ROOF)
|
||||
{
|
||||
if (msg_len < PB_TNC_HEADER_SIZE)
|
||||
{
|
||||
DBG1(DBG_TNC, "%u bytes too small for PB-TNC message length",
|
||||
msg_len);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset + 8);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
if (noskip_flag)
|
||||
{
|
||||
DBG1(DBG_TNC, "reject PB-TNC message (Vendor ID 0x%06x / "
|
||||
"Type 0x%08x)", vendor_id, msg_type);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset);
|
||||
goto fatal;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, "ignore PB-TNC message (Vendor ID 0x%06x / "
|
||||
"Type 0x%08x)", vendor_id, msg_type);
|
||||
this->offset += msg_len;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msg_type == PB_MSG_EXPERIMENTAL && noskip_flag)
|
||||
{
|
||||
DBG1(DBG_TNC, "reject PB-Experimental message with NOSKIP flag set");
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset);
|
||||
goto fatal;
|
||||
}
|
||||
if (pb_tnc_msg_infos[msg_type].has_noskip_flag != TRUE_OR_FALSE &&
|
||||
pb_tnc_msg_infos[msg_type].has_noskip_flag != noskip_flag)
|
||||
{
|
||||
DBG1(DBG_TNC, "%N message must%s have NOSKIP flag set",
|
||||
pb_tnc_msg_type_names, msg_type,
|
||||
pb_tnc_msg_infos[msg_type].has_noskip_flag ? "" : " not");
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
if (msg_len < pb_tnc_msg_infos[msg_type].min_size ||
|
||||
(pb_tnc_msg_infos[msg_type].exact_size &&
|
||||
msg_len != pb_tnc_msg_infos[msg_type].min_size))
|
||||
{
|
||||
DBG1(DBG_TNC, "%N message length must be %s %u bytes but is %u bytes",
|
||||
pb_tnc_msg_type_names, msg_type,
|
||||
pb_tnc_msg_infos[msg_type].exact_size ? "exactly" : "at least",
|
||||
pb_tnc_msg_infos[msg_type].min_size, msg_len);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset);
|
||||
goto fatal;
|
||||
}
|
||||
}
|
||||
|
||||
if (pb_tnc_msg_infos[msg_type].in_result_batch &&
|
||||
this->type != PB_BATCH_RESULT)
|
||||
{
|
||||
if (this->is_server)
|
||||
{
|
||||
DBG1(DBG_TNC,"reject %N message received from a PB-TNC client",
|
||||
pb_tnc_msg_type_names, msg_type);
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset);
|
||||
goto fatal;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC,"ignore %N message not received within RESULT batch",
|
||||
pb_tnc_msg_type_names, msg_type);
|
||||
this->offset += msg_len;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
DBG2(DBG_TNC, "processing %N message (%u bytes)", pb_tnc_msg_type_names,
|
||||
msg_type, msg_len);
|
||||
data.len = msg_len;
|
||||
msg_value = chunk_skip(data, PB_TNC_HEADER_SIZE);
|
||||
pb_tnc_msg = pb_tnc_msg_create_from_data(msg_type, msg_value);
|
||||
|
||||
status = pb_tnc_msg->process(pb_tnc_msg, &offset);
|
||||
if (status == FAILED || status == VERIFY_ERROR)
|
||||
{
|
||||
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
|
||||
PB_ERROR_INVALID_PARAMETER, this->offset + offset);
|
||||
this->errors->insert_last(this->errors, msg);
|
||||
}
|
||||
if (status == FAILED)
|
||||
{
|
||||
pb_tnc_msg->destroy(pb_tnc_msg);
|
||||
return FAILED;
|
||||
}
|
||||
this->messages->insert_last(this->messages, pb_tnc_msg);
|
||||
this->offset += msg_len;
|
||||
return status;
|
||||
|
||||
fatal:
|
||||
this->errors->insert_last(this->errors, msg);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_batch_t, process, status_t,
|
||||
private_pb_tnc_batch_t *this, pb_tnc_state_machine_t *state_machine)
|
||||
{
|
||||
status_t status;
|
||||
|
||||
status = process_batch_header(this, state_machine);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
while (this->offset < this->encoding.len)
|
||||
{
|
||||
switch (process_tnc_msg(this))
|
||||
{
|
||||
case FAILED:
|
||||
return FAILED;
|
||||
case VERIFY_ERROR:
|
||||
status = VERIFY_ERROR;
|
||||
break;
|
||||
case SUCCESS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_batch_t, create_msg_enumerator, enumerator_t*,
|
||||
private_pb_tnc_batch_t *this)
|
||||
{
|
||||
return this->messages->create_enumerator(this->messages);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_batch_t, create_error_enumerator, enumerator_t*,
|
||||
private_pb_tnc_batch_t *this)
|
||||
{
|
||||
return this->errors->create_enumerator(this->errors);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_batch_t, destroy, void,
|
||||
private_pb_tnc_batch_t *this)
|
||||
{
|
||||
this->messages->destroy_offset(this->messages,
|
||||
offsetof(pb_tnc_msg_t, destroy));
|
||||
this->errors->destroy_offset(this->errors,
|
||||
offsetof(pb_tnc_msg_t, destroy));
|
||||
free(this->encoding.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type,
|
||||
size_t max_batch_len)
|
||||
{
|
||||
private_pb_tnc_batch_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.add_msg = _add_msg,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.create_msg_enumerator = _create_msg_enumerator,
|
||||
.create_error_enumerator = _create_error_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.is_server = is_server,
|
||||
.type = type,
|
||||
.max_batch_len = max_batch_len,
|
||||
.batch_len = PB_TNC_BATCH_HEADER_SIZE,
|
||||
.messages = linked_list_create(),
|
||||
.errors = linked_list_create(),
|
||||
);
|
||||
|
||||
DBG2(DBG_TNC, "creating PB-TNC %N batch", pb_tnc_batch_type_names, type);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data)
|
||||
{
|
||||
private_pb_tnc_batch_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.add_msg = _add_msg,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.create_msg_enumerator = _create_msg_enumerator,
|
||||
.create_error_enumerator = _create_error_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.is_server = is_server,
|
||||
.messages = linked_list_create(),
|
||||
.errors = linked_list_create(),
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2012 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_tnc_batch pb_tnc_batch
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_TNC_BATCH_H_
|
||||
#define PB_TNC_BATCH_H_
|
||||
|
||||
typedef enum pb_tnc_batch_type_t pb_tnc_batch_type_t;
|
||||
typedef struct pb_tnc_batch_t pb_tnc_batch_t;
|
||||
|
||||
#include "messages/pb_tnc_msg.h"
|
||||
#include "state_machine/pb_tnc_state_machine.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* PB-TNC Batch Types as defined in section 4.1 of RFC 5793
|
||||
*/
|
||||
enum pb_tnc_batch_type_t {
|
||||
PB_BATCH_NONE = 0, /* for internal use only */
|
||||
PB_BATCH_CDATA = 1,
|
||||
PB_BATCH_SDATA = 2,
|
||||
PB_BATCH_RESULT = 3,
|
||||
PB_BATCH_CRETRY = 4,
|
||||
PB_BATCH_SRETRY = 5,
|
||||
PB_BATCH_CLOSE = 6,
|
||||
PB_BATCH_ROOF = 6
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for pb_tnc_batch_type_t.
|
||||
*/
|
||||
extern enum_name_t *pb_tnc_batch_type_names;
|
||||
|
||||
/**
|
||||
* Interface for all PB-TNC Batch Types.
|
||||
*/
|
||||
struct pb_tnc_batch_t {
|
||||
|
||||
/**
|
||||
* Get the PB-TNC Message Type
|
||||
*
|
||||
* @return PB-TNC batch type
|
||||
*/
|
||||
pb_tnc_batch_type_t (*get_type)(pb_tnc_batch_t *this);
|
||||
|
||||
/**
|
||||
* Get the encoding of the PB-TNC Batch
|
||||
*
|
||||
* @return encoded PB-TNC batch
|
||||
*/
|
||||
chunk_t (*get_encoding)(pb_tnc_batch_t *this);
|
||||
|
||||
/**
|
||||
* Add a PB-TNC Message
|
||||
*
|
||||
* @param msg PB-TNC message to be addedd
|
||||
* @return TRUE if message fit into batch and was added
|
||||
*/
|
||||
bool (*add_msg)(pb_tnc_batch_t *this, pb_tnc_msg_t* msg);
|
||||
|
||||
/**
|
||||
* Build the PB-TNC Batch
|
||||
*/
|
||||
void (*build)(pb_tnc_batch_t *this);
|
||||
|
||||
/**
|
||||
* Process the PB-TNC Batch
|
||||
*
|
||||
* @param PB-TNC state machine
|
||||
* @return return processing status
|
||||
*/
|
||||
status_t (*process)(pb_tnc_batch_t *this,
|
||||
pb_tnc_state_machine_t *state_machine);
|
||||
|
||||
/**
|
||||
* Enumerates over all PB-TNC Messages
|
||||
*
|
||||
* @return return message enumerator
|
||||
*/
|
||||
enumerator_t* (*create_msg_enumerator)(pb_tnc_batch_t *this);
|
||||
|
||||
/**
|
||||
* Enumerates over all parsing errors
|
||||
*
|
||||
* @return return error enumerator
|
||||
*/
|
||||
enumerator_t* (*create_error_enumerator)(pb_tnc_batch_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a pb_tnc_batch_t object.
|
||||
*/
|
||||
void (*destroy)(pb_tnc_batch_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an empty PB-TNC Batch of a given type
|
||||
*
|
||||
* @param is_server TRUE if server, FALSE if client
|
||||
* @param type PB-TNC batch type
|
||||
* @param max_batch_len maximum size the PB-TNC batch
|
||||
*/
|
||||
pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type,
|
||||
size_t max_batch_len);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-TNC Batch from data
|
||||
*
|
||||
* @param is_server TRUE if server, FALSE if client
|
||||
* @param data encoded PB-TNC batch
|
||||
*/
|
||||
pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data);
|
||||
|
||||
#endif /** PB_TNC_BATCH_H_ @}*/
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_access_recommendation_msg.h"
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
ENUM(pb_access_recommendation_code_names, PB_REC_ACCESS_ALLOWED, PB_REC_QUARANTINED,
|
||||
"Access Allowed",
|
||||
"Access Denied",
|
||||
"Quarantined"
|
||||
);
|
||||
|
||||
typedef struct private_pb_access_recommendation_msg_t private_pb_access_recommendation_msg_t;
|
||||
|
||||
/**
|
||||
* PB-Access-Recommendation message (see section 4.7 of RFC 5793)
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Reserved | Access Recommendation Code |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
#define ACCESS_RECOMMENDATION_RESERVED 0x0000
|
||||
#define ACCESS_RECOMMENDATION_MSG_SIZE 4
|
||||
/**
|
||||
* Private data of a pb_access_recommendation_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_access_recommendation_msg_t {
|
||||
/**
|
||||
* Public pb_access_recommendation_msg_t interface.
|
||||
*/
|
||||
pb_access_recommendation_msg_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC message type
|
||||
*/
|
||||
pb_tnc_msg_type_t type;
|
||||
|
||||
/**
|
||||
* Access recommendation code
|
||||
*/
|
||||
u_int16_t recommendation;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
|
||||
private_pb_access_recommendation_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
|
||||
private_pb_access_recommendation_msg_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, build, void,
|
||||
private_pb_access_recommendation_msg_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
|
||||
if (this->encoding.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
writer = bio_writer_create(ACCESS_RECOMMENDATION_MSG_SIZE);
|
||||
writer->write_uint16(writer, ACCESS_RECOMMENDATION_RESERVED);
|
||||
writer->write_uint16(writer, this->recommendation);
|
||||
this->encoding = writer->get_buf(writer);
|
||||
this->encoding = chunk_clone(this->encoding);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, process, status_t,
|
||||
private_pb_access_recommendation_msg_t *this, u_int32_t *offset)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
u_int16_t reserved;
|
||||
|
||||
reader = bio_reader_create(this->encoding);
|
||||
reader->read_uint16(reader, &reserved);
|
||||
reader->read_uint16(reader, &this->recommendation);
|
||||
reader->destroy(reader);
|
||||
|
||||
if (this->recommendation < PB_REC_ACCESS_ALLOWED ||
|
||||
this->recommendation > PB_REC_QUARANTINED)
|
||||
{
|
||||
DBG1(DBG_TNC, "invalid access recommendation code (%u)",
|
||||
this->recommendation);
|
||||
*offset = 2;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, destroy, void,
|
||||
private_pb_access_recommendation_msg_t *this)
|
||||
{
|
||||
free(this->encoding.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(pb_access_recommendation_msg_t, get_access_recommendation, u_int16_t,
|
||||
private_pb_access_recommendation_msg_t *this)
|
||||
{
|
||||
return this->recommendation;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_access_recommendation_msg_create_from_data(chunk_t data)
|
||||
{
|
||||
private_pb_access_recommendation_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_access_recommendation = _get_access_recommendation,
|
||||
},
|
||||
.type = PB_MSG_ACCESS_RECOMMENDATION,
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_access_recommendation_msg_create(u_int16_t recommendation)
|
||||
{
|
||||
private_pb_access_recommendation_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_access_recommendation = _get_access_recommendation,
|
||||
},
|
||||
.type = PB_MSG_ACCESS_RECOMMENDATION,
|
||||
.recommendation = recommendation,
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_access_recommendation_msg pb_access_recommendation_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_ACCESS_RECOMMENDATION_MSG_H_
|
||||
#define PB_ACCESS_RECOMMENDATION_MSG_H_
|
||||
|
||||
typedef enum pb_access_recommendation_code_t pb_access_recommendation_code_t;
|
||||
typedef struct pb_access_recommendation_msg_t pb_access_recommendation_msg_t;
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
|
||||
/**
|
||||
* PB Access Recommendation Codes as defined in section 4.7 of RFC 5793
|
||||
*/
|
||||
enum pb_access_recommendation_code_t {
|
||||
PB_REC_ACCESS_ALLOWED = 1,
|
||||
PB_REC_ACCESS_DENIED = 2,
|
||||
PB_REC_QUARANTINED = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for pb_access_recommendation_code_t.
|
||||
*/
|
||||
extern enum_name_t *pb_access_recommendation_code_names;
|
||||
|
||||
|
||||
/**
|
||||
* Class representing the PB-Access-Recommendation message type.
|
||||
*/
|
||||
struct pb_access_recommendation_msg_t {
|
||||
|
||||
/**
|
||||
* PB-TNC Message interface
|
||||
*/
|
||||
pb_tnc_msg_t pb_interface;
|
||||
|
||||
/**
|
||||
* Get PB Access Recommendation
|
||||
*
|
||||
* @return PB Access Recommendation
|
||||
*/
|
||||
u_int16_t (*get_access_recommendation)(pb_access_recommendation_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PB-Access-Recommendation message from parameters
|
||||
*
|
||||
* @param recommendation Access Recommendation code
|
||||
*/
|
||||
pb_tnc_msg_t* pb_access_recommendation_msg_create(u_int16_t recommendation);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-Access-Recommendation message from raw data
|
||||
*
|
||||
* @param data PB-Access-Recommendation message data
|
||||
*/
|
||||
pb_tnc_msg_t* pb_access_recommendation_msg_create_from_data(chunk_t data);
|
||||
|
||||
#endif /** PB_PA_MSG_H_ @}*/
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_assessment_result_msg.h"
|
||||
|
||||
#include <tncifimv.h>
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_pb_assessment_result_msg_t private_pb_assessment_result_msg_t;
|
||||
|
||||
/**
|
||||
* PB-Assessment-Result message (see section 4.6 of RFC 5793)
|
||||
*
|
||||
* 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Assessment Result |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
#define ASSESSMENT_RESULT_MSG_SIZE 4
|
||||
|
||||
/**
|
||||
* Private data of a pb_assessment_result_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_assessment_result_msg_t {
|
||||
/**
|
||||
* Public pb_assessment_result_msg_t interface.
|
||||
*/
|
||||
pb_assessment_result_msg_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC message type
|
||||
*/
|
||||
pb_tnc_msg_type_t type;
|
||||
|
||||
/**
|
||||
* Assessment result code
|
||||
*/
|
||||
u_int32_t assessment_result;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
|
||||
private_pb_assessment_result_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
|
||||
private_pb_assessment_result_msg_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, build, void,
|
||||
private_pb_assessment_result_msg_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
|
||||
if (this->encoding.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
writer = bio_writer_create(ASSESSMENT_RESULT_MSG_SIZE);
|
||||
writer->write_uint32(writer, this->assessment_result);
|
||||
this->encoding = writer->get_buf(writer);
|
||||
this->encoding = chunk_clone(this->encoding);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, process, status_t,
|
||||
private_pb_assessment_result_msg_t *this, u_int32_t *offset)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
|
||||
reader = bio_reader_create(this->encoding);
|
||||
reader->read_uint32(reader, &this->assessment_result);
|
||||
reader->destroy(reader);
|
||||
|
||||
if (this->assessment_result < TNC_IMV_EVALUATION_RESULT_COMPLIANT ||
|
||||
this->assessment_result > TNC_IMV_EVALUATION_RESULT_DONT_KNOW)
|
||||
{
|
||||
DBG1(DBG_TNC, "invalid assessment result (%u)",
|
||||
this->assessment_result);
|
||||
*offset = 0;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, destroy, void,
|
||||
private_pb_assessment_result_msg_t *this)
|
||||
{
|
||||
free(this->encoding.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(pb_assessment_result_msg_t, get_assessment_result, u_int32_t,
|
||||
private_pb_assessment_result_msg_t *this)
|
||||
{
|
||||
return this->assessment_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_assessment_result_msg_create_from_data(chunk_t data)
|
||||
{
|
||||
private_pb_assessment_result_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_assessment_result = _get_assessment_result,
|
||||
},
|
||||
.type = PB_MSG_ASSESSMENT_RESULT,
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_assessment_result_msg_create(u_int32_t assessment_result)
|
||||
{
|
||||
private_pb_assessment_result_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_assessment_result = _get_assessment_result,
|
||||
},
|
||||
.type = PB_MSG_ASSESSMENT_RESULT,
|
||||
.assessment_result = assessment_result,
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_assessment_result_msg pb_assessment_result_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_ASSESSMENT_RESULT_MSG_H_
|
||||
#define PB_ASSESSMENT_RESULT_MSG_H_
|
||||
|
||||
typedef struct pb_assessment_result_msg_t pb_assessment_result_msg_t;
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
|
||||
/**
|
||||
* Class representing the PB-Assessment-Result message type.
|
||||
*/
|
||||
struct pb_assessment_result_msg_t {
|
||||
|
||||
/**
|
||||
* PB-TNC Message interface
|
||||
*/
|
||||
pb_tnc_msg_t pb_interface;
|
||||
|
||||
/**
|
||||
* Get PB Assessment result
|
||||
*
|
||||
* @return PB Assessment result
|
||||
*/
|
||||
u_int32_t (*get_assessment_result)(pb_assessment_result_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PB-Assessment-Result message from parameters
|
||||
*
|
||||
* @param assessment_result Assessment result code
|
||||
*/
|
||||
pb_tnc_msg_t* pb_assessment_result_msg_create(u_int32_t assessment_result);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-Assessment-Result message from raw data
|
||||
*
|
||||
* @param data PB-Assessment-Result message data
|
||||
*/
|
||||
pb_tnc_msg_t* pb_assessment_result_msg_create_from_data(chunk_t data);
|
||||
|
||||
#endif /** PB_PA_MSG_H_ @}*/
|
||||
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_error_msg.h"
|
||||
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <pen/pen.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
ENUM(pb_tnc_error_code_names, PB_ERROR_UNEXPECTED_BATCH_TYPE,
|
||||
PB_ERROR_VERSION_NOT_SUPPORTED,
|
||||
"Unexpected Batch Type",
|
||||
"Invalid Parameter",
|
||||
"Local Error",
|
||||
"Unsupported Mandatory Message",
|
||||
"Version Not Supported"
|
||||
);
|
||||
|
||||
typedef struct private_pb_error_msg_t private_pb_error_msg_t;
|
||||
|
||||
/**
|
||||
* PB-Error message (see section 4.9 of RFC 5793)
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Flags | Error Code Vendor ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Error Code | Reserved |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Error Parameters (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
#define ERROR_FLAG_NONE 0x00
|
||||
#define ERROR_FLAG_FATAL (1<<7)
|
||||
#define ERROR_RESERVED 0x0000
|
||||
#define ERROR_HEADER_SIZE 8
|
||||
|
||||
/**
|
||||
* Private data of a pb_error_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_error_msg_t {
|
||||
/**
|
||||
* Public pb_error_msg_t interface.
|
||||
*/
|
||||
pb_error_msg_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC message type
|
||||
*/
|
||||
pb_tnc_msg_type_t type;
|
||||
|
||||
/**
|
||||
* Fatal flag
|
||||
*/
|
||||
bool fatal;
|
||||
|
||||
/**
|
||||
* PB Error Code Vendor ID
|
||||
*/
|
||||
u_int32_t vendor_id;
|
||||
|
||||
/**
|
||||
* PB Error Code
|
||||
*/
|
||||
u_int16_t error_code;
|
||||
|
||||
/**
|
||||
* PB Error Offset
|
||||
*/
|
||||
u_int32_t error_offset;
|
||||
|
||||
/**
|
||||
* Bad PB-TNC version received
|
||||
*/
|
||||
u_int8_t bad_version;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
|
||||
/**
|
||||
* reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, build, void,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
|
||||
if (this->encoding.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* build message header */
|
||||
writer = bio_writer_create(ERROR_HEADER_SIZE);
|
||||
writer->write_uint8 (writer, this->fatal ?
|
||||
ERROR_FLAG_FATAL : ERROR_FLAG_NONE);
|
||||
writer->write_uint24(writer, this->vendor_id);
|
||||
writer->write_uint16(writer, this->error_code);
|
||||
writer->write_uint16(writer, ERROR_RESERVED);
|
||||
|
||||
/* build message body */
|
||||
if (this->error_code == PB_ERROR_VERSION_NOT_SUPPORTED)
|
||||
{
|
||||
/* Bad version */
|
||||
writer->write_uint8(writer, this->bad_version);
|
||||
writer->write_uint8(writer, PB_TNC_VERSION); /* Max version */
|
||||
writer->write_uint8(writer, PB_TNC_VERSION); /* Min version */
|
||||
writer->write_uint8(writer, 0x00); /* Reserved */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error Offset */
|
||||
writer->write_uint32(writer, this->error_offset);
|
||||
}
|
||||
this->encoding = writer->get_buf(writer);
|
||||
this->encoding = chunk_clone(this->encoding);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, process, status_t,
|
||||
private_pb_error_msg_t *this, u_int32_t *offset)
|
||||
{
|
||||
u_int8_t flags, max_version, min_version;
|
||||
u_int16_t reserved;
|
||||
bio_reader_t *reader;
|
||||
|
||||
if (this->encoding.len < ERROR_HEADER_SIZE)
|
||||
{
|
||||
DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes",
|
||||
pb_tnc_msg_type_names, PB_MSG_ERROR, ERROR_HEADER_SIZE);
|
||||
*offset = 0;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* process message header */
|
||||
reader = bio_reader_create(this->encoding);
|
||||
reader->read_uint8 (reader, &flags);
|
||||
reader->read_uint24(reader, &this->vendor_id);
|
||||
reader->read_uint16(reader, &this->error_code);
|
||||
reader->read_uint16(reader, &reserved);
|
||||
this->fatal = (flags & ERROR_FLAG_FATAL) != ERROR_FLAG_NONE;
|
||||
|
||||
if (this->vendor_id == PEN_IETF && reader->remaining(reader) == 4)
|
||||
{
|
||||
if (this->error_code == PB_ERROR_VERSION_NOT_SUPPORTED)
|
||||
{
|
||||
reader->read_uint8(reader, &this->bad_version);
|
||||
reader->read_uint8(reader, &max_version);
|
||||
reader->read_uint8(reader, &min_version);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader->read_uint32(reader, &this->error_offset);
|
||||
}
|
||||
}
|
||||
reader->destroy(reader);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_ref, pb_tnc_msg_t*,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
ref_get(&this->ref);
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, destroy, void,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
free(this->encoding.ptr);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(pb_error_msg_t, get_fatal_flag, bool,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
return this->fatal;
|
||||
}
|
||||
|
||||
METHOD(pb_error_msg_t, get_vendor_id, u_int32_t,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
return this->vendor_id;
|
||||
}
|
||||
|
||||
METHOD(pb_error_msg_t, get_error_code, u_int16_t,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
return this->error_code;
|
||||
}
|
||||
|
||||
METHOD(pb_error_msg_t, get_offset, u_int32_t,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
return this->error_offset;
|
||||
}
|
||||
|
||||
METHOD(pb_error_msg_t, get_bad_version, u_int8_t,
|
||||
private_pb_error_msg_t *this)
|
||||
{
|
||||
return this->bad_version;
|
||||
}
|
||||
|
||||
METHOD(pb_error_msg_t, set_bad_version, void,
|
||||
private_pb_error_msg_t *this, u_int8_t version)
|
||||
{
|
||||
this->bad_version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t* pb_error_msg_create(bool fatal, u_int32_t vendor_id,
|
||||
pb_tnc_error_code_t error_code)
|
||||
{
|
||||
private_pb_error_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_fatal_flag = _get_fatal_flag,
|
||||
.get_vendor_id = _get_vendor_id,
|
||||
.get_error_code = _get_error_code,
|
||||
.get_offset = _get_offset,
|
||||
.get_bad_version = _get_bad_version,
|
||||
.set_bad_version = _set_bad_version,
|
||||
},
|
||||
.type = PB_MSG_ERROR,
|
||||
.ref = 1,
|
||||
.fatal = fatal,
|
||||
.vendor_id = vendor_id,
|
||||
.error_code = error_code,
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t* pb_error_msg_create_with_offset(bool fatal, u_int32_t vendor_id,
|
||||
pb_tnc_error_code_t error_code,
|
||||
u_int32_t error_offset)
|
||||
{
|
||||
private_pb_error_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_fatal_flag = _get_fatal_flag,
|
||||
.get_vendor_id = _get_vendor_id,
|
||||
.get_error_code = _get_error_code,
|
||||
.get_offset = _get_offset,
|
||||
.get_bad_version = _get_bad_version,
|
||||
.set_bad_version = _set_bad_version,
|
||||
},
|
||||
.type = PB_MSG_ERROR,
|
||||
.ref = 1,
|
||||
.fatal = fatal,
|
||||
.vendor_id = vendor_id,
|
||||
.error_code = error_code,
|
||||
.error_offset = error_offset,
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_error_msg_create_from_data(chunk_t data)
|
||||
{
|
||||
private_pb_error_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.get_ref = _get_ref,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_fatal_flag = _get_fatal_flag,
|
||||
.get_vendor_id = _get_vendor_id,
|
||||
.get_error_code = _get_error_code,
|
||||
.get_offset = _get_offset,
|
||||
.get_bad_version = _get_bad_version,
|
||||
.set_bad_version = _set_bad_version,
|
||||
},
|
||||
.type = PB_MSG_ERROR,
|
||||
.ref = 1,
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_error_msg pb_error_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_ERROR_MSG_H_
|
||||
#define PB_ERROR_MSG_H_
|
||||
|
||||
typedef enum pb_tnc_error_code_t pb_tnc_error_code_t;
|
||||
typedef struct pb_error_msg_t pb_error_msg_t;
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
|
||||
/**
|
||||
* PB-TNC Error Codes as defined in section 4.9.1 of RFC 5793
|
||||
*/
|
||||
enum pb_tnc_error_code_t {
|
||||
PB_ERROR_UNEXPECTED_BATCH_TYPE = 0,
|
||||
PB_ERROR_INVALID_PARAMETER = 1,
|
||||
PB_ERROR_LOCAL_ERROR = 2,
|
||||
PB_ERROR_UNSUPPORTED_MANDATORY_MSG = 3,
|
||||
PB_ERROR_VERSION_NOT_SUPPORTED = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for pb_tnc_error_code_t.
|
||||
*/
|
||||
extern enum_name_t *pb_tnc_error_code_names;
|
||||
|
||||
/**
|
||||
* Class representing the PB-Error message type.
|
||||
*/
|
||||
struct pb_error_msg_t {
|
||||
|
||||
/**
|
||||
* PB-TNC Message interface
|
||||
*/
|
||||
pb_tnc_msg_t pb_interface;
|
||||
|
||||
/**
|
||||
* Get the fatal flag
|
||||
*
|
||||
* @return fatal flag
|
||||
*/
|
||||
bool (*get_fatal_flag)(pb_error_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get PB Error code Vendor ID
|
||||
*
|
||||
* @return PB Error Code Vendor ID
|
||||
*/
|
||||
u_int32_t (*get_vendor_id)(pb_error_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get PB Error Code
|
||||
*
|
||||
* @return PB Error Code
|
||||
*/
|
||||
u_int16_t (*get_error_code)(pb_error_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the PB Error Offset
|
||||
*
|
||||
* @return PB Error Offset
|
||||
*/
|
||||
u_int32_t (*get_offset)(pb_error_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the PB Bad Version
|
||||
*
|
||||
* @return PB Bad Version
|
||||
*/
|
||||
u_int8_t (*get_bad_version)(pb_error_msg_t *this);
|
||||
|
||||
/**
|
||||
* Set the PB Bad Version
|
||||
*
|
||||
* @param version PB Bad Version
|
||||
*/
|
||||
void (*set_bad_version)(pb_error_msg_t *this, u_int8_t version);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PB-Error message from parameters
|
||||
*
|
||||
* @param fatal fatal flag
|
||||
* @param vendor_id Error Code Vendor ID
|
||||
* @param error_code Error Code
|
||||
*/
|
||||
pb_tnc_msg_t* pb_error_msg_create(bool fatal, u_int32_t vendor_id,
|
||||
pb_tnc_error_code_t error_code);
|
||||
|
||||
/**
|
||||
* Create a PB-Error message from parameters with offset field
|
||||
*
|
||||
* @param fatal fatal flag
|
||||
* @param vendor_id Error Code Vendor ID
|
||||
* @param error_code Error Code
|
||||
* @param error_offset Error Offset
|
||||
*/
|
||||
pb_tnc_msg_t* pb_error_msg_create_with_offset(bool fatal, u_int32_t vendor_id,
|
||||
pb_tnc_error_code_t error_code,
|
||||
u_int32_t error_offset);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-Error message from raw data
|
||||
*
|
||||
* @param data PB-Error message data
|
||||
*/
|
||||
pb_tnc_msg_t* pb_error_msg_create_from_data(chunk_t data);
|
||||
|
||||
#endif /** PB_PA_MSG_H_ @}*/
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_experimental_msg.h"
|
||||
|
||||
typedef struct private_pb_experimental_msg_t private_pb_experimental_msg_t;
|
||||
|
||||
/**
|
||||
* Private data of a pb_experimental_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_experimental_msg_t {
|
||||
/**
|
||||
* Public pb_experimental_msg_t interface.
|
||||
*/
|
||||
pb_experimental_msg_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC message type
|
||||
*/
|
||||
pb_tnc_msg_type_t type;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
|
||||
private_pb_experimental_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
|
||||
private_pb_experimental_msg_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, build, void,
|
||||
private_pb_experimental_msg_t *this)
|
||||
{
|
||||
/* nothing to do since message contents equal encoding */
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, process, status_t,
|
||||
private_pb_experimental_msg_t *this, u_int32_t *offset)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, destroy, void,
|
||||
private_pb_experimental_msg_t *this)
|
||||
{
|
||||
free(this->encoding.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_experimental_msg_create_from_data(chunk_t data)
|
||||
{
|
||||
private_pb_experimental_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.type = PB_MSG_EXPERIMENTAL,
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_experimental_msg_create(chunk_t body)
|
||||
{
|
||||
return pb_experimental_msg_create_from_data(body);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_experimental_msg pb_experimental_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_EXPERIMENTAL_MSG_H_
|
||||
#define PB_EXPERIMENTAL_MSG_H_
|
||||
|
||||
typedef struct pb_experimental_msg_t pb_experimental_msg_t;
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
|
||||
/**
|
||||
* Class representing the PB-Experimental message type.
|
||||
*/
|
||||
struct pb_experimental_msg_t {
|
||||
|
||||
/**
|
||||
* PB-TNC Message interface
|
||||
*/
|
||||
pb_tnc_msg_t pb_interface;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PB-Experimental message from parameters
|
||||
*
|
||||
* @param body message body
|
||||
*/
|
||||
pb_tnc_msg_t* pb_experimental_msg_create(chunk_t body);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-Experimental message from raw data
|
||||
*
|
||||
* @param data PB-Experimental message data
|
||||
*/
|
||||
pb_tnc_msg_t* pb_experimental_msg_create_from_data(chunk_t data);
|
||||
|
||||
#endif /** PB_EXPERIMENTAL_MSG_H_ @}*/
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_language_preference_msg.h"
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_pb_language_preference_msg_t private_pb_language_preference_msg_t;
|
||||
|
||||
/**
|
||||
* PB-Language-Preference message (see section 4.10 of RFC 5793)
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Language Preference (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
#define PB_LANG_PREFIX "Accept-Language: "
|
||||
#define PB_LANG_PREFIX_LEN strlen(PB_LANG_PREFIX)
|
||||
|
||||
/**
|
||||
* Private data of a pb_language_preference_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_language_preference_msg_t {
|
||||
/**
|
||||
* Public pb_access_recommendation_msg_t interface.
|
||||
*/
|
||||
pb_language_preference_msg_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC message type
|
||||
*/
|
||||
pb_tnc_msg_type_t type;
|
||||
|
||||
/**
|
||||
* Language preference
|
||||
*/
|
||||
chunk_t language_preference;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
|
||||
private_pb_language_preference_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
|
||||
private_pb_language_preference_msg_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, build, void,
|
||||
private_pb_language_preference_msg_t *this)
|
||||
{
|
||||
if (this->encoding.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->encoding = chunk_cat("cc",
|
||||
chunk_create(PB_LANG_PREFIX, PB_LANG_PREFIX_LEN),
|
||||
this->language_preference);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, process, status_t,
|
||||
private_pb_language_preference_msg_t *this, u_int32_t *offset)
|
||||
{
|
||||
chunk_t lang;
|
||||
|
||||
if (this->encoding.len >= PB_LANG_PREFIX_LEN &&
|
||||
memeq(this->encoding.ptr, PB_LANG_PREFIX, PB_LANG_PREFIX_LEN))
|
||||
{
|
||||
lang = chunk_skip(this->encoding, PB_LANG_PREFIX_LEN);
|
||||
this->language_preference = lang.len ? chunk_clone(lang) : chunk_empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, "language preference must be preceded by '%s'",
|
||||
PB_LANG_PREFIX);
|
||||
*offset = 0;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (this->language_preference.len &&
|
||||
this->language_preference.ptr[this->language_preference.len-1] == '\0')
|
||||
{
|
||||
DBG1(DBG_TNC, "language preference must not be null terminated");
|
||||
*offset = PB_LANG_PREFIX_LEN + this->language_preference.len - 1;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, destroy, void,
|
||||
private_pb_language_preference_msg_t *this)
|
||||
{
|
||||
free(this->encoding.ptr);
|
||||
free(this->language_preference.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(pb_language_preference_msg_t, get_language_preference, chunk_t,
|
||||
private_pb_language_preference_msg_t *this)
|
||||
{
|
||||
return this->language_preference;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_language_preference_msg_create_from_data(chunk_t data)
|
||||
{
|
||||
private_pb_language_preference_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_language_preference = _get_language_preference,
|
||||
},
|
||||
.type = PB_MSG_LANGUAGE_PREFERENCE,
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_language_preference_msg_create(chunk_t language_preference)
|
||||
{
|
||||
private_pb_language_preference_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_language_preference = _get_language_preference,
|
||||
},
|
||||
.type = PB_MSG_LANGUAGE_PREFERENCE,
|
||||
.language_preference = chunk_clone(language_preference),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_language_preference_msg pb_language_preference_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_LANGUAGE_PREFERENCE_MSG_H_
|
||||
#define PB_LANGUAGE_PREFERENCE_MSG_H_
|
||||
|
||||
typedef struct pb_language_preference_msg_t pb_language_preference_msg_t;
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
|
||||
/**
|
||||
* Class representing the PB-Language-Preference message type.
|
||||
*/
|
||||
struct pb_language_preference_msg_t {
|
||||
|
||||
/**
|
||||
* PB-TNC Message interface
|
||||
*/
|
||||
pb_tnc_msg_t pb_interface;
|
||||
|
||||
/**
|
||||
* Get PB Language Preference
|
||||
*
|
||||
* @return Language preference
|
||||
*/
|
||||
chunk_t (*get_language_preference)(pb_language_preference_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PB-Language-Preference message from parameters
|
||||
*
|
||||
* @param language_preference Preferred language(s)
|
||||
*/
|
||||
pb_tnc_msg_t* pb_language_preference_msg_create(chunk_t language_preference);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-Language-Preference message from raw data
|
||||
*
|
||||
* @param data PB-Language-Preference message data
|
||||
*/
|
||||
pb_tnc_msg_t* pb_language_preference_msg_create_from_data(chunk_t data);
|
||||
|
||||
#endif /** PB_PA_MSG_H_ @}*/
|
||||
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyanbuu
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
*
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_pa_msg.h"
|
||||
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <pen/pen.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_pb_pa_msg_t private_pb_pa_msg_t;
|
||||
|
||||
/**
|
||||
* PB-PA message
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Flags | PA Message Vendor ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | PA Subtype |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Posture Collector Identifier | Posture Validator Identifier |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | PA Message Body (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
#define PA_FLAG_NONE 0x00
|
||||
#define PA_FLAG_EXCL (1<<7)
|
||||
#define PA_RESERVED_SUBTYPE 0xffffffff
|
||||
|
||||
|
||||
/**
|
||||
* Private data of a pb_pa_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_pa_msg_t {
|
||||
/**
|
||||
* Public pb_pa_msg_t interface.
|
||||
*/
|
||||
pb_pa_msg_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC message type
|
||||
*/
|
||||
pb_tnc_msg_type_t type;
|
||||
|
||||
/**
|
||||
* Exclusive flag
|
||||
*/
|
||||
bool excl;
|
||||
|
||||
/**
|
||||
* Vendor-specific PA Subtype
|
||||
*/
|
||||
pen_type_t subtype;
|
||||
|
||||
/**
|
||||
* Posture Validator Identifier
|
||||
*/
|
||||
u_int16_t collector_id;
|
||||
|
||||
/**
|
||||
* Posture Validator Identifier
|
||||
*/
|
||||
u_int16_t validator_id;
|
||||
|
||||
/**
|
||||
* PA Message Body
|
||||
*/
|
||||
chunk_t msg_body;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, build, void,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
chunk_t msg_header;
|
||||
bio_writer_t *writer;
|
||||
|
||||
if (this->encoding.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* build message header */
|
||||
writer = bio_writer_create(64);
|
||||
writer->write_uint8 (writer, this->excl ? PA_FLAG_EXCL : PA_FLAG_NONE);
|
||||
writer->write_uint24(writer, this->subtype.vendor_id);
|
||||
writer->write_uint32(writer, this->subtype.type);
|
||||
writer->write_uint16(writer, this->collector_id);
|
||||
writer->write_uint16(writer, this->validator_id);
|
||||
msg_header = writer->get_buf(writer);
|
||||
|
||||
/* create encoding by concatenating message header and message body */
|
||||
this->encoding = chunk_cat("cc", msg_header, this->msg_body);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, process, status_t,
|
||||
private_pb_pa_msg_t *this, u_int32_t *offset)
|
||||
{
|
||||
u_int8_t flags;
|
||||
size_t msg_body_len;
|
||||
bio_reader_t *reader;
|
||||
|
||||
/* process message header */
|
||||
reader = bio_reader_create(this->encoding);
|
||||
reader->read_uint8 (reader, &flags);
|
||||
reader->read_uint24(reader, &this->subtype.vendor_id);
|
||||
reader->read_uint32(reader, &this->subtype.type);
|
||||
reader->read_uint16(reader, &this->collector_id);
|
||||
reader->read_uint16(reader, &this->validator_id);
|
||||
this->excl = ((flags & PA_FLAG_EXCL) != PA_FLAG_NONE);
|
||||
|
||||
/* process message body */
|
||||
msg_body_len = reader->remaining(reader);
|
||||
if (msg_body_len)
|
||||
{
|
||||
reader->read_data(reader, msg_body_len, &this->msg_body);
|
||||
this->msg_body = chunk_clone(this->msg_body);
|
||||
}
|
||||
reader->destroy(reader);
|
||||
|
||||
if (this->subtype.vendor_id == PEN_RESERVED)
|
||||
{
|
||||
DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", PEN_RESERVED);
|
||||
*offset = 1;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (this->subtype.type == PA_RESERVED_SUBTYPE)
|
||||
{
|
||||
DBG1(DBG_TNC, "PA Subtype 0x%08x is reserved", PA_RESERVED_SUBTYPE);
|
||||
*offset = 4;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, destroy, void,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
free(this->encoding.ptr);
|
||||
free(this->msg_body.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(pb_pa_msg_t, get_subtype, pen_type_t,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
return this->subtype;
|
||||
}
|
||||
|
||||
METHOD(pb_pa_msg_t, get_collector_id, u_int16_t,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
return this->collector_id;
|
||||
}
|
||||
|
||||
METHOD(pb_pa_msg_t, get_validator_id, u_int16_t,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
return this->validator_id;
|
||||
}
|
||||
|
||||
METHOD(pb_pa_msg_t, get_body, chunk_t,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
return this->msg_body;
|
||||
}
|
||||
|
||||
METHOD(pb_pa_msg_t, get_exclusive_flag, bool,
|
||||
private_pb_pa_msg_t *this)
|
||||
{
|
||||
return this->excl;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data)
|
||||
{
|
||||
private_pb_pa_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_subtype = _get_subtype,
|
||||
.get_collector_id = _get_collector_id,
|
||||
.get_validator_id = _get_validator_id,
|
||||
.get_body = _get_body,
|
||||
.get_exclusive_flag = _get_exclusive_flag,
|
||||
},
|
||||
.type = PB_MSG_PA,
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
|
||||
u_int16_t collector_id, u_int16_t validator_id,
|
||||
bool excl, chunk_t msg_body)
|
||||
{
|
||||
private_pb_pa_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_subtype= _get_subtype,
|
||||
.get_collector_id = _get_collector_id,
|
||||
.get_validator_id = _get_validator_id,
|
||||
.get_body = _get_body,
|
||||
.get_exclusive_flag = _get_exclusive_flag,
|
||||
},
|
||||
.type = PB_MSG_PA,
|
||||
.subtype = { vendor_id, subtype },
|
||||
.collector_id = collector_id,
|
||||
.validator_id = validator_id,
|
||||
.excl = excl,
|
||||
.msg_body = chunk_clone(msg_body),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_pa_msg pb_pa_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_PA_MSG_H_
|
||||
#define PB_PA_MSG_H_
|
||||
|
||||
typedef struct pb_pa_msg_t pb_pa_msg_t;
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
|
||||
#include <pen/pen.h>
|
||||
|
||||
/**
|
||||
* Class representing the PB-PA message type.
|
||||
*/
|
||||
struct pb_pa_msg_t {
|
||||
|
||||
/**
|
||||
* PB-TNC Message interface
|
||||
*/
|
||||
pb_tnc_msg_t pb_interface;
|
||||
|
||||
/**
|
||||
* Get PA Message Vendor ID and Subtype
|
||||
*
|
||||
* @return Vendor-specific PA Subtype
|
||||
*/
|
||||
pen_type_t (*get_subtype)(pb_pa_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get Posture Collector ID
|
||||
*
|
||||
* @return Posture Collector ID
|
||||
*/
|
||||
u_int16_t (*get_collector_id)(pb_pa_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get Posture Validator ID
|
||||
*
|
||||
* @return Posture Validator ID
|
||||
*/
|
||||
u_int16_t (*get_validator_id)(pb_pa_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the PA Message Body
|
||||
*
|
||||
* @return PA Message Body
|
||||
*/
|
||||
chunk_t (*get_body)(pb_pa_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the exclusive flag
|
||||
*
|
||||
* @return exclusive flag
|
||||
*/
|
||||
bool (*get_exclusive_flag)(pb_pa_msg_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PB-PA message from parameters
|
||||
*
|
||||
* @param vendor_id PA Message Vendor ID
|
||||
* @param subtype PA Subtype
|
||||
* @param collector_id Posture Collector ID
|
||||
* @param validator_id Posture Validator ID
|
||||
* @param excl Exclusive Flag
|
||||
* @param msg_body PA Message Body
|
||||
*/
|
||||
pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
|
||||
u_int16_t collector_id, u_int16_t validator_id,
|
||||
bool excl, chunk_t msg_body);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-PA message from raw data
|
||||
*
|
||||
* @param data PB-PA message data
|
||||
*/
|
||||
pb_tnc_msg_t* pb_pa_msg_create_from_data(chunk_t data);
|
||||
|
||||
#endif /** PB_PA_MSG_H_ @}*/
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_reason_string_msg.h"
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_pb_reason_string_msg_t private_pb_reason_string_msg_t;
|
||||
|
||||
/**
|
||||
* PB-Language-Preference message (see section 4.11 of RFC 5793)
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Reason String Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Reason String (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Lang Code Len | Reason String Language Code (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private data of a pb_reason_string_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_reason_string_msg_t {
|
||||
/**
|
||||
* Public pb_reason_string_msg_t interface.
|
||||
*/
|
||||
pb_reason_string_msg_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC message type
|
||||
*/
|
||||
pb_tnc_msg_type_t type;
|
||||
|
||||
/**
|
||||
* Reason string
|
||||
*/
|
||||
chunk_t reason_string;
|
||||
|
||||
/**
|
||||
* Language code
|
||||
*/
|
||||
chunk_t language_code;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
|
||||
private_pb_reason_string_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
|
||||
private_pb_reason_string_msg_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, build, void,
|
||||
private_pb_reason_string_msg_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
|
||||
if (this->encoding.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
writer = bio_writer_create(64);
|
||||
writer->write_data32(writer, this->reason_string);
|
||||
writer->write_data8 (writer, this->language_code);
|
||||
|
||||
this->encoding = writer->get_buf(writer);
|
||||
this->encoding = chunk_clone(this->encoding);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, process, status_t,
|
||||
private_pb_reason_string_msg_t *this, u_int32_t *offset)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
|
||||
reader = bio_reader_create(this->encoding);
|
||||
if (!reader->read_data32(reader, &this->reason_string))
|
||||
{
|
||||
DBG1(DBG_TNC, "could not parse reason string");
|
||||
reader->destroy(reader);
|
||||
*offset = 0;
|
||||
return FAILED;
|
||||
};
|
||||
this->reason_string = chunk_clone(this->reason_string);
|
||||
|
||||
if (this->reason_string.len &&
|
||||
this->reason_string.ptr[this->reason_string.len-1] == '\0')
|
||||
{
|
||||
DBG1(DBG_TNC, "reason string must not be null terminated");
|
||||
reader->destroy(reader);
|
||||
*offset = 3 + this->reason_string.len;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (!reader->read_data8(reader, &this->language_code))
|
||||
{
|
||||
DBG1(DBG_TNC, "could not parse language code");
|
||||
reader->destroy(reader);
|
||||
*offset = 4 + this->reason_string.len;
|
||||
return FAILED;
|
||||
};
|
||||
this->language_code = chunk_clone(this->language_code);
|
||||
reader->destroy(reader);
|
||||
|
||||
if (this->language_code.len &&
|
||||
this->language_code.ptr[this->language_code.len-1] == '\0')
|
||||
{
|
||||
DBG1(DBG_TNC, "language code must not be null terminated");
|
||||
*offset = 4 + this->reason_string.len + this->language_code.len;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, destroy, void,
|
||||
private_pb_reason_string_msg_t *this)
|
||||
{
|
||||
free(this->encoding.ptr);
|
||||
free(this->reason_string.ptr);
|
||||
free(this->language_code.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(pb_reason_string_msg_t, get_reason_string, chunk_t,
|
||||
private_pb_reason_string_msg_t *this)
|
||||
{
|
||||
return this->reason_string;
|
||||
}
|
||||
|
||||
METHOD(pb_reason_string_msg_t, get_language_code, chunk_t,
|
||||
private_pb_reason_string_msg_t *this)
|
||||
{
|
||||
return this->language_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_reason_string_msg_create_from_data(chunk_t data)
|
||||
{
|
||||
private_pb_reason_string_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_reason_string = _get_reason_string,
|
||||
.get_language_code = _get_language_code,
|
||||
},
|
||||
.type = PB_MSG_REASON_STRING,
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_reason_string_msg_create(chunk_t reason_string,
|
||||
chunk_t language_code)
|
||||
{
|
||||
private_pb_reason_string_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_reason_string = _get_reason_string,
|
||||
.get_language_code = _get_language_code,
|
||||
},
|
||||
.type = PB_MSG_REASON_STRING,
|
||||
.reason_string = chunk_clone(reason_string),
|
||||
.language_code = chunk_clone(language_code),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_reason_string_msg pb_reason_string_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_REASON_STRING_MSG_H_
|
||||
#define PB_REASON_STRING_MSG_H_
|
||||
|
||||
typedef struct pb_reason_string_msg_t pb_reason_string_msg_t;
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
|
||||
/**
|
||||
* Class representing the PB-Reason-String message type.
|
||||
*/
|
||||
struct pb_reason_string_msg_t {
|
||||
|
||||
/**
|
||||
* PB-TNC Message interface
|
||||
*/
|
||||
pb_tnc_msg_t pb_interface;
|
||||
|
||||
/**
|
||||
* Get Reason String
|
||||
*
|
||||
* @return Reason string
|
||||
*/
|
||||
chunk_t (*get_reason_string)(pb_reason_string_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get Reason String Language Code
|
||||
*
|
||||
* @return Language code
|
||||
*/
|
||||
chunk_t (*get_language_code)(pb_reason_string_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PB-Reason-String message from parameters
|
||||
*
|
||||
* @param reason_string Reason string
|
||||
* @param language_code Language code
|
||||
*/
|
||||
pb_tnc_msg_t* pb_reason_string_msg_create(chunk_t reason_string,
|
||||
chunk_t language_code);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-Reason-String message from raw data
|
||||
*
|
||||
* @param data PB-Reason-String message data
|
||||
*/
|
||||
pb_tnc_msg_t* pb_reason_string_msg_create_from_data(chunk_t data);
|
||||
|
||||
#endif /** PB_PA_MSG_H_ @}*/
|
||||
@@ -1,311 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_remediation_parameters_msg.h"
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <bio/bio_reader.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
ENUM(pb_tnc_remed_param_type_names, PB_REMEDIATION_URI, PB_REMEDIATION_STRING,
|
||||
"Remediation-URI",
|
||||
"Remediation-String"
|
||||
);
|
||||
|
||||
typedef struct private_pb_remediation_parameters_msg_t private_pb_remediation_parameters_msg_t;
|
||||
|
||||
/**
|
||||
* PB-Remediation-Parameters message (see section 4.8 of RFC 5793)
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Reserved | Remediation Parameters Vendor ID |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Remediation Parameters Type |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Remediation Parameters (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Remediation String Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Remediation String (Variable Length) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Lang Code Len | Remediation String Lang Code (Variable Len) |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private data of a pb_remediation_parameters_msg_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_remediation_parameters_msg_t {
|
||||
/**
|
||||
* Public pb_remediation_parameters_msg_t interface.
|
||||
*/
|
||||
pb_remediation_parameters_msg_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC message type
|
||||
*/
|
||||
pb_tnc_msg_type_t type;
|
||||
|
||||
/**
|
||||
* Remediation Parameters Type
|
||||
*/
|
||||
pen_type_t parameters_type;
|
||||
|
||||
/**
|
||||
* Remediation Parameters
|
||||
*/
|
||||
chunk_t parameters;
|
||||
|
||||
/**
|
||||
* Remediation String
|
||||
*/
|
||||
chunk_t string;
|
||||
|
||||
/**
|
||||
* Remediation Language Code
|
||||
*/
|
||||
chunk_t lang_code;
|
||||
|
||||
/**
|
||||
* Encoded message
|
||||
*/
|
||||
chunk_t encoding;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t,
|
||||
private_pb_remediation_parameters_msg_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
|
||||
private_pb_remediation_parameters_msg_t *this)
|
||||
{
|
||||
return this->encoding;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, build, void,
|
||||
private_pb_remediation_parameters_msg_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
|
||||
if (this->encoding.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
writer = bio_writer_create(64);
|
||||
writer->write_uint32(writer, this->parameters_type.vendor_id);
|
||||
writer->write_uint32(writer, this->parameters_type.type);
|
||||
writer->write_data32(writer, this->parameters);
|
||||
|
||||
this->encoding = writer->get_buf(writer);
|
||||
this->encoding = chunk_clone(this->encoding);
|
||||
writer->destroy(writer);
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, process, status_t,
|
||||
private_pb_remediation_parameters_msg_t *this, u_int32_t *offset)
|
||||
{
|
||||
bio_reader_t *reader;
|
||||
u_int8_t reserved;
|
||||
status_t status = SUCCESS;
|
||||
u_char *pos;
|
||||
|
||||
*offset = 0;
|
||||
|
||||
/* process message */
|
||||
reader = bio_reader_create(this->encoding);
|
||||
reader->read_uint8 (reader, &reserved);
|
||||
reader->read_uint24(reader, &this->parameters_type.vendor_id);
|
||||
reader->read_uint32(reader, &this->parameters_type.type);
|
||||
reader->read_data (reader, reader->remaining(reader), &this->parameters);
|
||||
|
||||
this->parameters = chunk_clone(this->parameters);
|
||||
reader->destroy(reader);
|
||||
|
||||
if (this->parameters_type.vendor_id == PEN_IETF &&
|
||||
this->parameters_type.type == PB_REMEDIATION_STRING)
|
||||
{
|
||||
reader = bio_reader_create(this->parameters);
|
||||
status = FAILED;
|
||||
*offset = 8;
|
||||
|
||||
if (!reader->read_data32(reader, &this->string))
|
||||
{
|
||||
DBG1(DBG_TNC, "insufficient data for remediation string");
|
||||
goto end;
|
||||
};
|
||||
*offset += 4;
|
||||
|
||||
pos = memchr(this->string.ptr, '\0', this->string.len);
|
||||
if (pos)
|
||||
{
|
||||
DBG1(DBG_TNC, "nul termination in remediation string");
|
||||
*offset += (pos - this->string.ptr);
|
||||
goto end;
|
||||
}
|
||||
*offset += this->string.len;
|
||||
|
||||
if (!reader->read_data8(reader, &this->lang_code))
|
||||
{
|
||||
DBG1(DBG_TNC, "insufficient data for remediation string lang code");
|
||||
goto end;
|
||||
};
|
||||
*offset += 1;
|
||||
|
||||
pos = memchr(this->lang_code.ptr, '\0', this->lang_code.len);
|
||||
|
||||
if (pos)
|
||||
{
|
||||
DBG1(DBG_TNC, "nul termination in remediation string lang code");
|
||||
*offset += (pos - this->lang_code.ptr);
|
||||
goto end;
|
||||
}
|
||||
status = SUCCESS;
|
||||
|
||||
end:
|
||||
reader->destroy(reader);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_msg_t, destroy, void,
|
||||
private_pb_remediation_parameters_msg_t *this)
|
||||
{
|
||||
free(this->encoding.ptr);
|
||||
free(this->parameters.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(pb_remediation_parameters_msg_t, get_parameters_type, pen_type_t,
|
||||
private_pb_remediation_parameters_msg_t *this)
|
||||
{
|
||||
return this->parameters_type;
|
||||
}
|
||||
|
||||
METHOD(pb_remediation_parameters_msg_t, get_parameters, chunk_t,
|
||||
private_pb_remediation_parameters_msg_t *this)
|
||||
{
|
||||
return this->parameters;
|
||||
}
|
||||
|
||||
METHOD(pb_remediation_parameters_msg_t, get_string, chunk_t,
|
||||
private_pb_remediation_parameters_msg_t *this, chunk_t *lang_code)
|
||||
{
|
||||
if (lang_code)
|
||||
{
|
||||
*lang_code = this->lang_code;
|
||||
}
|
||||
return this->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t* pb_remediation_parameters_msg_create(pen_type_t parameters_type,
|
||||
chunk_t parameters)
|
||||
{
|
||||
private_pb_remediation_parameters_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_parameters_type = _get_parameters_type,
|
||||
.get_parameters = _get_parameters,
|
||||
.get_uri = _get_parameters,
|
||||
.get_string = _get_string,
|
||||
},
|
||||
.type = PB_MSG_REMEDIATION_PARAMETERS,
|
||||
.parameters_type = parameters_type,
|
||||
.parameters = chunk_clone(parameters),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_uri(chunk_t uri)
|
||||
{
|
||||
pen_type_t type = { PEN_IETF, PB_REMEDIATION_URI };
|
||||
|
||||
return pb_remediation_parameters_msg_create(type, uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_string(chunk_t string,
|
||||
chunk_t lang_code)
|
||||
{
|
||||
pb_tnc_msg_t *msg;
|
||||
bio_writer_t *writer;
|
||||
pen_type_t type = { PEN_IETF, PB_REMEDIATION_STRING };
|
||||
|
||||
/* limit language code to 255 octets */
|
||||
lang_code.len = min(255, lang_code.len);
|
||||
|
||||
writer = bio_writer_create(4 + string.len + 1 + lang_code.len);
|
||||
writer->write_data32(writer, string);
|
||||
writer->write_data8 (writer, lang_code);
|
||||
|
||||
msg = pb_remediation_parameters_msg_create(type, writer->get_buf(writer));
|
||||
writer->destroy(writer);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t *pb_remediation_parameters_msg_create_from_data(chunk_t data)
|
||||
{
|
||||
private_pb_remediation_parameters_msg_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.pb_interface = {
|
||||
.get_type = _get_type,
|
||||
.get_encoding = _get_encoding,
|
||||
.build = _build,
|
||||
.process = _process,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_parameters_type = _get_parameters_type,
|
||||
.get_parameters = _get_parameters,
|
||||
.get_uri = _get_parameters,
|
||||
.get_string = _get_string,
|
||||
},
|
||||
.type = PB_MSG_REMEDIATION_PARAMETERS,
|
||||
.encoding = chunk_clone(data),
|
||||
);
|
||||
|
||||
return &this->public.pb_interface;
|
||||
}
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_remediation_parameters_msg pb_remediation_parameters_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_REMEDIATION_PARAMETERS_MSG_H_
|
||||
#define PB_REMEDIATION_PARAMETERS_MSG_H_
|
||||
|
||||
typedef enum pb_tnc_remed_param_type_t pb_tnc_remed_param_type_t;
|
||||
typedef struct pb_remediation_parameters_msg_t pb_remediation_parameters_msg_t;
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
|
||||
#include <pen/pen.h>
|
||||
|
||||
/**
|
||||
* PB-TNC Remediation Parameter Types as defined in section 4.8.1 of RFC 5793
|
||||
*/
|
||||
enum pb_tnc_remed_param_type_t {
|
||||
PB_REMEDIATION_URI = 1,
|
||||
PB_REMEDIATION_STRING = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for pb_tnc_remed_param_type_t.
|
||||
*/
|
||||
extern enum_name_t *pb_tnc_remed_param_type_names;
|
||||
|
||||
/**
|
||||
* Class representing the PB-Remediation-Parameters message type.
|
||||
*/
|
||||
struct pb_remediation_parameters_msg_t {
|
||||
|
||||
/**
|
||||
* PB-TNC Message interface
|
||||
*/
|
||||
pb_tnc_msg_t pb_interface;
|
||||
|
||||
/**
|
||||
* Get the Remediation Parameters Type (Vendor ID and Type)
|
||||
*
|
||||
* @return Remediation Parameters Type
|
||||
*/
|
||||
pen_type_t (*get_parameters_type)(pb_remediation_parameters_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the Remediation Parameters
|
||||
*
|
||||
* @return Remediation Parameters
|
||||
*/
|
||||
chunk_t (*get_parameters)(pb_remediation_parameters_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the Remediation URI
|
||||
*
|
||||
* @return Remediation URI
|
||||
*/
|
||||
chunk_t (*get_uri)(pb_remediation_parameters_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the Remediation String
|
||||
*
|
||||
* @param lang_code Optional Language Code
|
||||
* @return Remediation String
|
||||
*/
|
||||
chunk_t (*get_string)(pb_remediation_parameters_msg_t *this,
|
||||
chunk_t *lang_code);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a general PB-Remediation-Parameters message
|
||||
*
|
||||
* @param parameters_type Remediation Parameters Type
|
||||
* @param parameters Remediation Parameters
|
||||
*/
|
||||
pb_tnc_msg_t* pb_remediation_parameters_msg_create(pen_type_t parameters_type,
|
||||
chunk_t parameters);
|
||||
|
||||
/**
|
||||
* Create a PB-Remediation-Parameters message of IETF Type Remediation URI
|
||||
*
|
||||
* @param uri Remediation URI
|
||||
*/
|
||||
pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_uri(chunk_t uri);
|
||||
|
||||
/**
|
||||
* Create a PB-Remediation-Parameters message of IETF Type Remediation String
|
||||
*
|
||||
* @param string Remediation String
|
||||
* @param lang_code Remediation String Language Code
|
||||
*/
|
||||
pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_string(chunk_t string,
|
||||
chunk_t lang_code);
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-Remediation-Parameters message from raw data
|
||||
*
|
||||
* @param data PB-Remediation-Parameters message data
|
||||
*/
|
||||
pb_tnc_msg_t* pb_remediation_parameters_msg_create_from_data(chunk_t data);
|
||||
|
||||
#endif /** PB_PA_MSG_H_ @}*/
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_tnc_msg.h"
|
||||
#include "pb_experimental_msg.h"
|
||||
#include "pb_pa_msg.h"
|
||||
#include "pb_error_msg.h"
|
||||
#include "pb_language_preference_msg.h"
|
||||
#include "pb_assessment_result_msg.h"
|
||||
#include "pb_access_recommendation_msg.h"
|
||||
#include "pb_remediation_parameters_msg.h"
|
||||
#include "pb_reason_string_msg.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
ENUM(pb_tnc_msg_type_names, PB_MSG_EXPERIMENTAL, PB_MSG_REASON_STRING,
|
||||
"PB-Experimental",
|
||||
"PB-PA",
|
||||
"PB-Assessment-Result",
|
||||
"PB-Access-Recommendation",
|
||||
"PB-Remediation-Parameters",
|
||||
"PB-Error",
|
||||
"PB-Language-Preference",
|
||||
"PB-Reason-String"
|
||||
);
|
||||
|
||||
pb_tnc_msg_info_t pb_tnc_msg_infos[] = {
|
||||
{ 12, FALSE, FALSE, TRUE_OR_FALSE },
|
||||
{ 24, FALSE, FALSE, TRUE },
|
||||
{ 16, TRUE, TRUE, TRUE },
|
||||
{ 16, TRUE, TRUE, FALSE },
|
||||
{ 20, FALSE, TRUE, FALSE },
|
||||
{ 20, FALSE, FALSE, TRUE },
|
||||
{ 12, FALSE, FALSE, FALSE },
|
||||
{ 17, FALSE, TRUE, FALSE },
|
||||
};
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_msg_t* pb_tnc_msg_create_from_data(pb_tnc_msg_type_t type, chunk_t value)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PB_MSG_PA:
|
||||
return pb_pa_msg_create_from_data(value);
|
||||
case PB_MSG_ERROR:
|
||||
return pb_error_msg_create_from_data(value);
|
||||
case PB_MSG_EXPERIMENTAL:
|
||||
return pb_experimental_msg_create_from_data(value);
|
||||
case PB_MSG_LANGUAGE_PREFERENCE:
|
||||
return pb_language_preference_msg_create_from_data(value);
|
||||
case PB_MSG_ASSESSMENT_RESULT:
|
||||
return pb_assessment_result_msg_create_from_data(value);
|
||||
case PB_MSG_ACCESS_RECOMMENDATION:
|
||||
return pb_access_recommendation_msg_create_from_data(value);
|
||||
case PB_MSG_REMEDIATION_PARAMETERS:
|
||||
return pb_remediation_parameters_msg_create_from_data(value);
|
||||
case PB_MSG_REASON_STRING:
|
||||
return pb_reason_string_msg_create_from_data(value);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_tnc_msg pb_tnc_msg
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_TNC_MSG_H_
|
||||
#define PB_TNC_MSG_H_
|
||||
|
||||
typedef enum pb_tnc_msg_type_t pb_tnc_msg_type_t;
|
||||
typedef struct pb_tnc_msg_info_t pb_tnc_msg_info_t;
|
||||
typedef struct pb_tnc_msg_t pb_tnc_msg_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
#define PB_TNC_VERSION 2
|
||||
|
||||
/**
|
||||
* PB-TNC Message Types as defined in section 4.3 of RFC 5793
|
||||
*/
|
||||
enum pb_tnc_msg_type_t {
|
||||
PB_MSG_EXPERIMENTAL = 0,
|
||||
PB_MSG_PA = 1,
|
||||
PB_MSG_ASSESSMENT_RESULT = 2,
|
||||
PB_MSG_ACCESS_RECOMMENDATION = 3,
|
||||
PB_MSG_REMEDIATION_PARAMETERS = 4,
|
||||
PB_MSG_ERROR = 5,
|
||||
PB_MSG_LANGUAGE_PREFERENCE = 6,
|
||||
PB_MSG_REASON_STRING = 7,
|
||||
PB_MSG_ROOF = 7
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for pb_tnc_msg_type_t.
|
||||
*/
|
||||
extern enum_name_t *pb_tnc_msg_type_names;
|
||||
|
||||
/**
|
||||
* Information entry describing a PB-TNC Message Type
|
||||
*/
|
||||
struct pb_tnc_msg_info_t {
|
||||
u_int32_t min_size;
|
||||
bool exact_size;
|
||||
bool in_result_batch;
|
||||
signed char has_noskip_flag;
|
||||
};
|
||||
|
||||
#define TRUE_OR_FALSE 2
|
||||
|
||||
/**
|
||||
* Information on PB-TNC Message Types
|
||||
*/
|
||||
extern pb_tnc_msg_info_t pb_tnc_msg_infos[];
|
||||
|
||||
/**
|
||||
* Generic interface for all PB-TNC message types.
|
||||
*
|
||||
* To handle all messages in a generic way, this interface
|
||||
* must be implemented by each message type.
|
||||
*/
|
||||
struct pb_tnc_msg_t {
|
||||
|
||||
/**
|
||||
* Get the PB-TNC Message Type
|
||||
*
|
||||
* @return PB-TNC Message Type
|
||||
*/
|
||||
pb_tnc_msg_type_t (*get_type)(pb_tnc_msg_t *this);
|
||||
|
||||
/**
|
||||
* Get the encoding of the PB-TNC Message Value
|
||||
*
|
||||
* @return encoded PB-TNC Message Value
|
||||
*/
|
||||
chunk_t (*get_encoding)(pb_tnc_msg_t *this);
|
||||
|
||||
/**
|
||||
* Build the PB-TNC Message Value
|
||||
*/
|
||||
void (*build)(pb_tnc_msg_t *this);
|
||||
|
||||
/**
|
||||
* Process the PB-TNC Message Value
|
||||
*
|
||||
* @param relative offset where an error occurred
|
||||
* @return return processing status
|
||||
*/
|
||||
status_t (*process)(pb_tnc_msg_t *this, u_int32_t *offset);
|
||||
|
||||
/**
|
||||
* Get a new reference to the message.
|
||||
*
|
||||
* @return this, with an increased refcount
|
||||
*/
|
||||
pb_tnc_msg_t* (*get_ref)(pb_tnc_msg_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a pb_tnc_msg_t object.
|
||||
*/
|
||||
void (*destroy)(pb_tnc_msg_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an unprocessed PB-TNC message
|
||||
*
|
||||
* Useful for the parser which wants a generic constructor for all
|
||||
* pb_tnc_message_t types.
|
||||
*
|
||||
* @param type PB-TNC message type
|
||||
* @param value PB-TNC message value
|
||||
*/
|
||||
pb_tnc_msg_t* pb_tnc_msg_create_from_data(pb_tnc_msg_type_t type, chunk_t value);
|
||||
|
||||
#endif /** PB_TNC_MSG_H_ @}*/
|
||||
@@ -1,316 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pb_tnc_state_machine.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
ENUM(pb_tnc_state_names, PB_STATE_INIT, PB_STATE_END,
|
||||
"Init",
|
||||
"Server Working",
|
||||
"Client Working",
|
||||
"Decided",
|
||||
"End"
|
||||
);
|
||||
|
||||
/**
|
||||
* PB-TNC State Machine (see section 3.2 of RFC 5793)
|
||||
*
|
||||
* Receive CRETRY SRETRY
|
||||
* or SRETRY +----------------+
|
||||
* +--+ | |
|
||||
* v | v |
|
||||
* +---------+ CRETRY +---------+
|
||||
* CDATA | Server |<---------| Decided | CLOSE
|
||||
* +----------->| Working |--------->| |-------+
|
||||
* | +---------+ RESULT +---------+ |
|
||||
* | ^ | | v
|
||||
* | | | +---------------------->=======
|
||||
* ======== | | CLOSE " End "
|
||||
* " Init " CDATA| |SDATA =======
|
||||
* ======== | | ^ ^
|
||||
* | | | v | |
|
||||
* | | SDATA +---------+ CLOSE | |
|
||||
* | +-------->| Client |----------------------+ |
|
||||
* | | Working | |
|
||||
* | +---------+ |
|
||||
* | | ^ |
|
||||
* | +--+ |
|
||||
* | Receive CRETRY |
|
||||
* | CLOSE |
|
||||
* +--------------------------------------------------+
|
||||
*/
|
||||
|
||||
typedef struct private_pb_tnc_state_machine_t private_pb_tnc_state_machine_t;
|
||||
|
||||
/**
|
||||
* Private data of a pb_tnc_state_machine_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pb_tnc_state_machine_t {
|
||||
/**
|
||||
* Public pb_pa_message_t interface.
|
||||
*/
|
||||
pb_tnc_state_machine_t public;
|
||||
|
||||
/**
|
||||
* PB-TNC Server if TRUE, PB-TNC Client if FALSE
|
||||
*/
|
||||
bool is_server;
|
||||
|
||||
/**
|
||||
* Informs whether last received PB-TNC CDATA Batch was empty
|
||||
*/
|
||||
bool empty_cdata;
|
||||
|
||||
/**
|
||||
* Current PB-TNC state
|
||||
*/
|
||||
pb_tnc_state_t state;
|
||||
};
|
||||
|
||||
METHOD(pb_tnc_state_machine_t, get_state, pb_tnc_state_t,
|
||||
private_pb_tnc_state_machine_t *this)
|
||||
{
|
||||
return this->state;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_state_machine_t, receive_batch, bool,
|
||||
private_pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type)
|
||||
{
|
||||
pb_tnc_state_t old_state = this->state;
|
||||
|
||||
switch (this->state)
|
||||
{
|
||||
case PB_STATE_INIT:
|
||||
if (this->is_server && type == PB_BATCH_CDATA)
|
||||
{
|
||||
this->state = PB_STATE_SERVER_WORKING;
|
||||
break;
|
||||
}
|
||||
if (!this->is_server && type == PB_BATCH_SDATA)
|
||||
{
|
||||
this->state = PB_STATE_CLIENT_WORKING;
|
||||
break;
|
||||
}
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
this->state = PB_STATE_END;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
case PB_STATE_SERVER_WORKING:
|
||||
if (!this->is_server && (type == PB_BATCH_SDATA ||
|
||||
type == PB_BATCH_SRETRY))
|
||||
{
|
||||
this->state = PB_STATE_CLIENT_WORKING;
|
||||
break;
|
||||
}
|
||||
if (!this->is_server && type == PB_BATCH_RESULT)
|
||||
{
|
||||
this->state = PB_STATE_DECIDED;
|
||||
break;
|
||||
}
|
||||
if (this->is_server && type == PB_BATCH_CRETRY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
this->state = PB_STATE_END;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
case PB_STATE_CLIENT_WORKING:
|
||||
if (this->is_server && type == PB_BATCH_CDATA)
|
||||
{
|
||||
this->state = PB_STATE_SERVER_WORKING;
|
||||
break;
|
||||
}
|
||||
if (this->is_server && type == PB_BATCH_CRETRY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
this->state = PB_STATE_END;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
case PB_STATE_DECIDED:
|
||||
if ((this->is_server && type == PB_BATCH_CRETRY) ||
|
||||
(!this->is_server && type == PB_BATCH_SRETRY))
|
||||
{
|
||||
this->state = PB_STATE_SERVER_WORKING;
|
||||
break;
|
||||
}
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
this->state = PB_STATE_END;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
case PB_STATE_END:
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (this->state != old_state)
|
||||
{
|
||||
DBG2(DBG_TNC, "PB-TNC state transition from '%N' to '%N'",
|
||||
pb_tnc_state_names, old_state, pb_tnc_state_names, this->state);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_state_machine_t, send_batch, bool,
|
||||
private_pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type)
|
||||
{
|
||||
pb_tnc_state_t old_state = this->state;
|
||||
|
||||
switch (this->state)
|
||||
{
|
||||
case PB_STATE_INIT:
|
||||
if (!this->is_server && type == PB_BATCH_CDATA)
|
||||
{
|
||||
this->state = PB_STATE_SERVER_WORKING;
|
||||
break;
|
||||
}
|
||||
if (this->is_server && type == PB_BATCH_SDATA)
|
||||
{
|
||||
this->state = PB_STATE_CLIENT_WORKING;
|
||||
break;
|
||||
}
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
this->state = PB_STATE_END;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
case PB_STATE_SERVER_WORKING:
|
||||
if (this->is_server && (type == PB_BATCH_SDATA ||
|
||||
type == PB_BATCH_SRETRY))
|
||||
{
|
||||
this->state = PB_STATE_CLIENT_WORKING;
|
||||
break;
|
||||
}
|
||||
if (this->is_server && type == PB_BATCH_RESULT)
|
||||
{
|
||||
this->state = PB_STATE_DECIDED;
|
||||
break;
|
||||
}
|
||||
if (!this->is_server && type == PB_BATCH_CRETRY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
this->state = PB_STATE_END;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
case PB_STATE_CLIENT_WORKING:
|
||||
if (!this->is_server && (type == PB_BATCH_CDATA ||
|
||||
type == PB_BATCH_CRETRY))
|
||||
{
|
||||
this->state = PB_STATE_SERVER_WORKING;
|
||||
break;
|
||||
}
|
||||
if (this->is_server && type == PB_BATCH_SRETRY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
this->state = PB_STATE_END;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
case PB_STATE_DECIDED:
|
||||
if ((this->is_server && type == PB_BATCH_SRETRY) ||
|
||||
(!this->is_server && type == PB_BATCH_CRETRY))
|
||||
{
|
||||
this->state = PB_STATE_SERVER_WORKING;
|
||||
break;
|
||||
}
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
this->state = PB_STATE_END;
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
case PB_STATE_END:
|
||||
if (type == PB_BATCH_CLOSE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (this->state != old_state)
|
||||
{
|
||||
DBG2(DBG_TNC, "PB-TNC state transition from '%N' to '%N'",
|
||||
pb_tnc_state_names, old_state, pb_tnc_state_names, this->state);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_state_machine_t, get_empty_cdata, bool,
|
||||
private_pb_tnc_state_machine_t *this)
|
||||
{
|
||||
return this->empty_cdata;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_state_machine_t, set_empty_cdata, void,
|
||||
private_pb_tnc_state_machine_t *this, bool empty)
|
||||
{
|
||||
if (empty)
|
||||
{
|
||||
DBG2(DBG_TNC, "received empty PB-TNC CDATA batch");
|
||||
}
|
||||
this->empty_cdata = empty;
|
||||
}
|
||||
|
||||
METHOD(pb_tnc_state_machine_t, destroy, void,
|
||||
private_pb_tnc_state_machine_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pb_tnc_state_machine_t* pb_tnc_state_machine_create(bool is_server)
|
||||
{
|
||||
private_pb_tnc_state_machine_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_state = _get_state,
|
||||
.receive_batch = _receive_batch,
|
||||
.send_batch = _send_batch,
|
||||
.get_empty_cdata = _get_empty_cdata,
|
||||
.set_empty_cdata = _set_empty_cdata,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.is_server = is_server,
|
||||
.state = PB_STATE_INIT,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pb_tnc_state_machine pb_tnc_state_machine
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef PB_TNC_STATE_MACHINE_H_
|
||||
#define PB_TNC_STATE_MACHINE_H_
|
||||
|
||||
typedef struct pb_tnc_state_machine_t pb_tnc_state_machine_t;
|
||||
typedef enum pb_tnc_state_t pb_tnc_state_t;
|
||||
|
||||
#include "batch/pb_tnc_batch.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* PB-TNC States (state machine) as defined in section 3.2 of RFC 5793
|
||||
*/
|
||||
enum pb_tnc_state_t {
|
||||
PB_STATE_INIT,
|
||||
PB_STATE_SERVER_WORKING,
|
||||
PB_STATE_CLIENT_WORKING,
|
||||
PB_STATE_DECIDED,
|
||||
PB_STATE_END,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for pb_tnc_state_t.
|
||||
*/
|
||||
extern enum_name_t *pb_tnc_state_names;
|
||||
|
||||
/**
|
||||
* Interface for the PB-TNC state machine.
|
||||
*/
|
||||
struct pb_tnc_state_machine_t {
|
||||
|
||||
/**
|
||||
* Get the current PB-TNC STATE
|
||||
*
|
||||
* @return current state
|
||||
*/
|
||||
pb_tnc_state_t (*get_state)(pb_tnc_state_machine_t *this);
|
||||
|
||||
/**
|
||||
* Compute state transition due to received PB-TNC Batch
|
||||
*
|
||||
* @param type type of received batch
|
||||
* @result TRUE if a valid transition was found, FALSE otherwise
|
||||
*/
|
||||
bool (*receive_batch)(pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type);
|
||||
|
||||
/**
|
||||
* Compute state transition due to sent PB-TNC Batch
|
||||
*
|
||||
* @param type type of sent batch
|
||||
* @result TRUE if a valid transition was found, FALSE otherwise
|
||||
*/
|
||||
bool (*send_batch)(pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type);
|
||||
|
||||
/**
|
||||
* Informs whether the last received PB-TNC CDATA Batch was empty
|
||||
*
|
||||
* @result TRUE if last received PB-TNC CDATA Batch was empty
|
||||
*/
|
||||
bool (*get_empty_cdata)(pb_tnc_state_machine_t *this);
|
||||
|
||||
/**
|
||||
* Store information whether the received PB-TNC CDATA Batch was empty
|
||||
*
|
||||
* @param empty set to TRUE if received PB-TNC CDATA Batch was empty
|
||||
*/
|
||||
void (*set_empty_cdata)(pb_tnc_state_machine_t *this, bool empty);
|
||||
|
||||
/**
|
||||
* Destroys a pb_tnc_state_machine_t object.
|
||||
*/
|
||||
void (*destroy)(pb_tnc_state_machine_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create and initialize a PB-TNC state machine
|
||||
*
|
||||
* @param is_server TRUE if PB-TNC server, FALSE if PB-TNC client
|
||||
*/
|
||||
pb_tnc_state_machine_t* pb_tnc_state_machine_create(bool is_server);
|
||||
|
||||
#endif /** PB_TNC_STATE_MACHINE_H_ @}*/
|
||||
@@ -1,943 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Sansar Choinyanbuu
|
||||
* Copyright (C) 2010-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_20.h"
|
||||
#include "batch/pb_tnc_batch.h"
|
||||
#include "messages/pb_tnc_msg.h"
|
||||
#include "messages/pb_pa_msg.h"
|
||||
#include "messages/pb_error_msg.h"
|
||||
#include "messages/pb_assessment_result_msg.h"
|
||||
#include "messages/pb_access_recommendation_msg.h"
|
||||
#include "messages/pb_remediation_parameters_msg.h"
|
||||
#include "messages/pb_reason_string_msg.h"
|
||||
#include "messages/pb_language_preference_msg.h"
|
||||
#include "state_machine/pb_tnc_state_machine.h"
|
||||
|
||||
#include <tncif_names.h>
|
||||
#include <tncif_pa_subtypes.h>
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
#include <tnc/tnccs/tnccs_manager.h>
|
||||
#include <tnc/imc/imc_manager.h>
|
||||
#include <tnc/imv/imv_manager.h>
|
||||
|
||||
#include <threading/mutex.h>
|
||||
#include <utils/debug.h>
|
||||
#include <collections/linked_list.h>
|
||||
#include <pen/pen.h>
|
||||
|
||||
typedef struct private_tnccs_20_t private_tnccs_20_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_20_t object.
|
||||
*/
|
||||
struct private_tnccs_20_t {
|
||||
|
||||
/**
|
||||
* Public tnccs_t interface.
|
||||
*/
|
||||
tnccs_t public;
|
||||
|
||||
/**
|
||||
* TNCC if TRUE, TNCS if FALSE
|
||||
*/
|
||||
bool is_server;
|
||||
|
||||
/**
|
||||
* Server identity
|
||||
*/
|
||||
identification_t *server;
|
||||
|
||||
/**
|
||||
* Client identity
|
||||
*/
|
||||
identification_t *peer;
|
||||
|
||||
/**
|
||||
* Underlying TNC IF-T transport protocol
|
||||
*/
|
||||
tnc_ift_type_t transport;
|
||||
|
||||
/**
|
||||
* Type of TNC client authentication
|
||||
*/
|
||||
u_int32_t auth_type;
|
||||
|
||||
/**
|
||||
* PB-TNC State Machine
|
||||
*/
|
||||
pb_tnc_state_machine_t *state_machine;
|
||||
|
||||
/**
|
||||
* Connection ID assigned to this TNCCS connection
|
||||
*/
|
||||
TNC_ConnectionID connection_id;
|
||||
|
||||
/**
|
||||
* PB-TNC messages to be sent
|
||||
*/
|
||||
linked_list_t *messages;
|
||||
|
||||
/**
|
||||
* Type of PB-TNC batch being constructed
|
||||
*/
|
||||
pb_tnc_batch_type_t batch_type;
|
||||
|
||||
/**
|
||||
* Maximum PB-TNC batch size
|
||||
*/
|
||||
size_t max_batch_len;
|
||||
|
||||
/**
|
||||
* Maximum PA-TNC message size
|
||||
*/
|
||||
size_t max_msg_len;
|
||||
|
||||
/**
|
||||
* Mutex locking the batch in construction
|
||||
*/
|
||||
mutex_t *mutex;
|
||||
|
||||
/**
|
||||
* Flag set while processing
|
||||
*/
|
||||
bool fatal_error;
|
||||
|
||||
/**
|
||||
* Flag set by IMC/IMV RequestHandshakeRetry() function
|
||||
*/
|
||||
bool request_handshake_retry;
|
||||
|
||||
/**
|
||||
* SendMessage() by IMC/IMV only allowed if flag is set
|
||||
*/
|
||||
bool send_msg;
|
||||
|
||||
/**
|
||||
* Set of IMV recommendations (TNC Server only)
|
||||
*/
|
||||
recommendations_t *recs;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* If the batch type changes then delete all accumulated PB-TNC messages
|
||||
*/
|
||||
void change_batch_type(private_tnccs_20_t *this, pb_tnc_batch_type_t batch_type)
|
||||
{
|
||||
pb_tnc_msg_t *msg;
|
||||
|
||||
if (batch_type != this->batch_type)
|
||||
{
|
||||
if (this->batch_type != PB_BATCH_NONE)
|
||||
{
|
||||
DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
|
||||
pb_tnc_batch_type_names, this->batch_type);
|
||||
|
||||
while (this->messages->remove_last(this->messages,
|
||||
(void**)&msg) == SUCCESS)
|
||||
{
|
||||
msg->destroy(msg);
|
||||
}
|
||||
}
|
||||
this->batch_type = batch_type;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, send_msg, TNC_Result,
|
||||
private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
|
||||
TNC_UInt32 msg_flags,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_VendorID msg_vid,
|
||||
TNC_MessageSubtype msg_subtype)
|
||||
{
|
||||
pb_tnc_msg_t *pb_tnc_msg;
|
||||
pb_tnc_batch_type_t batch_type;
|
||||
enum_name_t *pa_subtype_names;
|
||||
bool excl;
|
||||
|
||||
if (!this->send_msg)
|
||||
{
|
||||
DBG1(DBG_TNC, "%s %u not allowed to call SendMessage()",
|
||||
this->is_server ? "IMV" : "IMC",
|
||||
this->is_server ? imv_id : imc_id);
|
||||
return TNC_RESULT_ILLEGAL_OPERATION;
|
||||
}
|
||||
excl = (msg_flags & TNC_MESSAGE_FLAGS_EXCLUSIVE) != 0;
|
||||
|
||||
pb_tnc_msg = pb_pa_msg_create(msg_vid, msg_subtype, imc_id, imv_id,
|
||||
excl, chunk_create(msg, msg_len));
|
||||
|
||||
pa_subtype_names = get_pa_subtype_names(msg_vid);
|
||||
if (pa_subtype_names)
|
||||
{
|
||||
DBG2(DBG_TNC, "creating PB-PA message type '%N/%N' 0x%06x/0x%08x",
|
||||
pen_names, msg_vid, pa_subtype_names, msg_subtype,
|
||||
msg_vid, msg_subtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_TNC, "creating PB-PA message type '%N' 0x%06x/0x%08x",
|
||||
pen_names, msg_vid, msg_vid, msg_subtype);
|
||||
}
|
||||
|
||||
/* adding PA message to SDATA or CDATA batch only */
|
||||
batch_type = this->is_server ? PB_BATCH_SDATA : PB_BATCH_CDATA;
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->batch_type == PB_BATCH_NONE)
|
||||
{
|
||||
this->batch_type = batch_type;
|
||||
}
|
||||
if (this->batch_type == batch_type)
|
||||
{
|
||||
this->messages->insert_last(this->messages, pb_tnc_msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
pb_tnc_msg->destroy(pb_tnc_msg);
|
||||
}
|
||||
this->mutex->unlock(this->mutex);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a single PB-TNC message according to its type
|
||||
*/
|
||||
static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
|
||||
{
|
||||
switch (msg->get_type(msg))
|
||||
{
|
||||
case PB_MSG_EXPERIMENTAL:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case PB_MSG_PA:
|
||||
{
|
||||
pb_pa_msg_t *pa_msg;
|
||||
pen_type_t msg_subtype;
|
||||
u_int16_t imc_id, imv_id;
|
||||
chunk_t msg_body;
|
||||
bool excl;
|
||||
enum_name_t *pa_subtype_names;
|
||||
|
||||
pa_msg = (pb_pa_msg_t*)msg;
|
||||
msg_subtype = pa_msg->get_subtype(pa_msg);
|
||||
msg_body = pa_msg->get_body(pa_msg);
|
||||
imc_id = pa_msg->get_collector_id(pa_msg);
|
||||
imv_id = pa_msg->get_validator_id(pa_msg);
|
||||
excl = pa_msg->get_exclusive_flag(pa_msg);
|
||||
|
||||
pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id);
|
||||
if (pa_subtype_names)
|
||||
{
|
||||
DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
|
||||
pen_names, msg_subtype.vendor_id, pa_subtype_names,
|
||||
msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
|
||||
pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id,
|
||||
msg_subtype.type);
|
||||
}
|
||||
|
||||
this->send_msg = TRUE;
|
||||
if (this->is_server)
|
||||
{
|
||||
tnc->imvs->receive_message(tnc->imvs, this->connection_id,
|
||||
excl, msg_body.ptr, msg_body.len,
|
||||
msg_subtype.vendor_id,
|
||||
msg_subtype.type, imc_id, imv_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
tnc->imcs->receive_message(tnc->imcs, this->connection_id,
|
||||
excl, msg_body.ptr, msg_body.len,
|
||||
msg_subtype.vendor_id,
|
||||
msg_subtype.type, imv_id, imc_id);
|
||||
}
|
||||
this->send_msg = FALSE;
|
||||
break;
|
||||
}
|
||||
case PB_MSG_ASSESSMENT_RESULT:
|
||||
{
|
||||
pb_assessment_result_msg_t *assess_msg;
|
||||
u_int32_t result;
|
||||
|
||||
assess_msg = (pb_assessment_result_msg_t*)msg;
|
||||
result = assess_msg->get_assessment_result(assess_msg);
|
||||
DBG1(DBG_TNC, "PB-TNC assessment result is '%N'",
|
||||
TNC_IMV_Evaluation_Result_names, result);
|
||||
break;
|
||||
}
|
||||
case PB_MSG_ACCESS_RECOMMENDATION:
|
||||
{
|
||||
pb_access_recommendation_msg_t *rec_msg;
|
||||
pb_access_recommendation_code_t rec;
|
||||
TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
|
||||
|
||||
rec_msg = (pb_access_recommendation_msg_t*)msg;
|
||||
rec = rec_msg->get_access_recommendation(rec_msg);
|
||||
DBG1(DBG_TNC, "PB-TNC access recommendation is '%N'",
|
||||
pb_access_recommendation_code_names, rec);
|
||||
switch (rec)
|
||||
{
|
||||
case PB_REC_ACCESS_ALLOWED:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
|
||||
break;
|
||||
case PB_REC_ACCESS_DENIED:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_NONE;
|
||||
break;
|
||||
case PB_REC_QUARANTINED:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
|
||||
}
|
||||
tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
|
||||
state);
|
||||
break;
|
||||
}
|
||||
case PB_MSG_REMEDIATION_PARAMETERS:
|
||||
{
|
||||
pb_remediation_parameters_msg_t *rem_msg;
|
||||
pen_type_t parameters_type;
|
||||
chunk_t parameters, string, lang_code;
|
||||
|
||||
rem_msg = (pb_remediation_parameters_msg_t*)msg;
|
||||
parameters_type = rem_msg->get_parameters_type(rem_msg);
|
||||
parameters = rem_msg->get_parameters(rem_msg);
|
||||
|
||||
if (parameters_type.vendor_id == PEN_IETF)
|
||||
{
|
||||
switch (parameters_type.type)
|
||||
{
|
||||
case PB_REMEDIATION_URI:
|
||||
DBG1(DBG_TNC, "remediation uri: %.*s",
|
||||
parameters.len, parameters.ptr);
|
||||
break;
|
||||
case PB_REMEDIATION_STRING:
|
||||
string = rem_msg->get_string(rem_msg, &lang_code);
|
||||
DBG1(DBG_TNC, "remediation string: [%.*s]\n%.*s",
|
||||
lang_code.len, lang_code.ptr,
|
||||
string.len, string.ptr);
|
||||
break;
|
||||
default:
|
||||
DBG1(DBG_TNC, "remediation parameters: %B", ¶meters);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, "remediation parameters: %B", ¶meters);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PB_MSG_ERROR:
|
||||
{
|
||||
pb_error_msg_t *err_msg;
|
||||
bool fatal;
|
||||
u_int32_t vendor_id;
|
||||
u_int16_t error_code;
|
||||
|
||||
err_msg = (pb_error_msg_t*)msg;
|
||||
fatal = err_msg->get_fatal_flag(err_msg);
|
||||
vendor_id = err_msg->get_vendor_id(err_msg);
|
||||
error_code = err_msg->get_error_code(err_msg);
|
||||
|
||||
if (fatal)
|
||||
{
|
||||
this->fatal_error = TRUE;
|
||||
}
|
||||
|
||||
if (vendor_id == PEN_IETF)
|
||||
{
|
||||
switch (error_code)
|
||||
{
|
||||
case PB_ERROR_INVALID_PARAMETER:
|
||||
case PB_ERROR_UNSUPPORTED_MANDATORY_MSG:
|
||||
DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
|
||||
"(offset %u bytes)",
|
||||
fatal ? "fatal" : "non-fatal",
|
||||
pb_tnc_error_code_names, error_code,
|
||||
err_msg->get_offset(err_msg));
|
||||
break;
|
||||
case PB_ERROR_VERSION_NOT_SUPPORTED:
|
||||
DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
|
||||
"caused by bad version 0x%02x",
|
||||
fatal ? "fatal" : "non-fatal",
|
||||
pb_tnc_error_code_names, error_code,
|
||||
err_msg->get_bad_version(err_msg));
|
||||
break;
|
||||
case PB_ERROR_UNEXPECTED_BATCH_TYPE:
|
||||
case PB_ERROR_LOCAL_ERROR:
|
||||
default:
|
||||
DBG1(DBG_TNC, "received %s PB-TNC error '%N'",
|
||||
fatal ? "fatal" : "non-fatal",
|
||||
pb_tnc_error_code_names, error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, "received %s PB-TNC error (%u) "
|
||||
"with Vendor ID 0x%06x",
|
||||
fatal ? "fatal" : "non-fatal",
|
||||
error_code, vendor_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PB_MSG_LANGUAGE_PREFERENCE:
|
||||
{
|
||||
pb_language_preference_msg_t *lang_msg;
|
||||
chunk_t lang;
|
||||
|
||||
lang_msg = (pb_language_preference_msg_t*)msg;
|
||||
lang = lang_msg->get_language_preference(lang_msg);
|
||||
|
||||
if (this->recs)
|
||||
{
|
||||
DBG2(DBG_TNC, "setting language preference to '%.*s'",
|
||||
(int)lang.len, lang.ptr);
|
||||
this->recs->set_preferred_language(this->recs, lang);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PB_MSG_REASON_STRING:
|
||||
{
|
||||
pb_reason_string_msg_t *reason_msg;
|
||||
chunk_t reason_string, language_code;
|
||||
|
||||
reason_msg = (pb_reason_string_msg_t*)msg;
|
||||
reason_string = reason_msg->get_reason_string(reason_msg);
|
||||
language_code = reason_msg->get_language_code(reason_msg);
|
||||
DBG1(DBG_TNC, "reason string is '%.*s' [%.*s]",
|
||||
(int)reason_string.len, reason_string.ptr,
|
||||
(int)language_code.len, language_code.ptr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a CRETRY or SRETRY batch
|
||||
*/
|
||||
static void build_retry_batch(private_tnccs_20_t *this)
|
||||
{
|
||||
pb_tnc_batch_type_t batch_retry_type;
|
||||
|
||||
batch_retry_type = this->is_server ? PB_BATCH_SRETRY : PB_BATCH_CRETRY;
|
||||
if (this->batch_type == batch_retry_type)
|
||||
{
|
||||
/* retry batch has already been selected */
|
||||
return;
|
||||
}
|
||||
|
||||
change_batch_type(this, batch_retry_type);
|
||||
|
||||
if (this->is_server)
|
||||
{
|
||||
this->recs->clear_recommendation(this->recs);
|
||||
tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_HANDSHAKE);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tls_t, process, status_t,
|
||||
private_tnccs_20_t *this, void *buf, size_t buflen)
|
||||
{
|
||||
chunk_t data;
|
||||
pb_tnc_batch_t *batch;
|
||||
pb_tnc_msg_t *msg;
|
||||
enumerator_t *enumerator;
|
||||
status_t status;
|
||||
|
||||
if (this->is_server && !this->connection_id)
|
||||
{
|
||||
this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
|
||||
TNCCS_2_0, (tnccs_t*)this, _send_msg,
|
||||
&this->request_handshake_retry,
|
||||
this->max_msg_len, &this->recs);
|
||||
if (!this->connection_id)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_CREATE);
|
||||
tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_HANDSHAKE);
|
||||
}
|
||||
|
||||
data = chunk_create(buf, buflen);
|
||||
DBG1(DBG_TNC, "received TNCCS batch (%u bytes) for Connection ID %u",
|
||||
data.len, this->connection_id);
|
||||
DBG3(DBG_TNC, "%B", &data);
|
||||
batch = pb_tnc_batch_create_from_data(this->is_server, data);
|
||||
status = batch->process(batch, this->state_machine);
|
||||
|
||||
if (status != FAILED)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
pb_tnc_msg_t *msg;
|
||||
pb_tnc_batch_type_t batch_type;
|
||||
bool empty = TRUE;
|
||||
|
||||
batch_type = batch->get_type(batch);
|
||||
|
||||
if (batch_type == PB_BATCH_CRETRY)
|
||||
{
|
||||
/* Send an SRETRY batch in response */
|
||||
this->mutex->lock(this->mutex);
|
||||
build_retry_batch(this);
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
else if (batch_type == PB_BATCH_SRETRY)
|
||||
{
|
||||
/* Restart the measurements */
|
||||
tnc->imcs->notify_connection_change(tnc->imcs,
|
||||
this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
|
||||
this->send_msg = TRUE;
|
||||
tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
|
||||
this->send_msg = FALSE;
|
||||
}
|
||||
|
||||
enumerator = batch->create_msg_enumerator(batch);
|
||||
while (enumerator->enumerate(enumerator, &msg))
|
||||
{
|
||||
handle_message(this, msg);
|
||||
empty = FALSE;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* received an empty CLOSE batch from PB-TNC client */
|
||||
if (this->is_server && batch_type == PB_BATCH_CLOSE && empty)
|
||||
{
|
||||
batch->destroy(batch);
|
||||
if (this->fatal_error)
|
||||
{
|
||||
DBG1(DBG_TNC, "a fatal PB-TNC error occurred, "
|
||||
"terminating connection");
|
||||
return FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
this->send_msg = TRUE;
|
||||
if (this->is_server)
|
||||
{
|
||||
tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
|
||||
}
|
||||
this->send_msg = FALSE;
|
||||
}
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case FAILED:
|
||||
this->fatal_error = TRUE;
|
||||
this->mutex->lock(this->mutex);
|
||||
change_batch_type(this, PB_BATCH_CLOSE);
|
||||
this->mutex->unlock(this->mutex);
|
||||
/* fall through to add error messages to outbound batch */
|
||||
case VERIFY_ERROR:
|
||||
enumerator = batch->create_error_enumerator(batch);
|
||||
while (enumerator->enumerate(enumerator, &msg))
|
||||
{
|
||||
this->mutex->lock(this->mutex);
|
||||
this->messages->insert_last(this->messages, msg->get_ref(msg));
|
||||
this->mutex->unlock(this->mutex);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
break;
|
||||
case SUCCESS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
batch->destroy(batch);
|
||||
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a RESULT batch if a final recommendation is available
|
||||
*/
|
||||
static void check_and_build_recommendation(private_tnccs_20_t *this)
|
||||
{
|
||||
TNC_IMV_Action_Recommendation rec;
|
||||
TNC_IMV_Evaluation_Result eval;
|
||||
TNC_ConnectionState state;
|
||||
TNC_IMVID id;
|
||||
chunk_t reason, language;
|
||||
enumerator_t *enumerator;
|
||||
pb_tnc_msg_t *msg;
|
||||
pb_access_recommendation_code_t pb_rec;
|
||||
|
||||
if (!this->recs->have_recommendation(this->recs, &rec, &eval))
|
||||
{
|
||||
tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
|
||||
}
|
||||
if (this->recs->have_recommendation(this->recs, &rec, &eval))
|
||||
{
|
||||
this->batch_type = PB_BATCH_RESULT;
|
||||
|
||||
msg = pb_assessment_result_msg_create(eval);
|
||||
this->messages->insert_last(this->messages, msg);
|
||||
|
||||
/**
|
||||
* Map IMV Action Recommendation codes to PB Access Recommendation codes
|
||||
* and communicate Access Recommendation to IMVs
|
||||
*/
|
||||
switch (rec)
|
||||
{
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
|
||||
pb_rec = PB_REC_ACCESS_ALLOWED;
|
||||
break;
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
|
||||
pb_rec = PB_REC_QUARANTINED;
|
||||
break;
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
|
||||
case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
|
||||
default:
|
||||
state = TNC_CONNECTION_STATE_ACCESS_NONE;
|
||||
pb_rec = PB_REC_ACCESS_DENIED;
|
||||
}
|
||||
tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
|
||||
state);
|
||||
|
||||
msg = pb_access_recommendation_msg_create(pb_rec);
|
||||
this->messages->insert_last(this->messages, msg);
|
||||
|
||||
enumerator = this->recs->create_reason_enumerator(this->recs);
|
||||
while (enumerator->enumerate(enumerator, &id, &reason, &language))
|
||||
{
|
||||
msg = pb_reason_string_msg_create(reason, language);
|
||||
this->messages->insert_last(this->messages, msg);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tls_t, build, status_t,
|
||||
private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
|
||||
{
|
||||
status_t status;
|
||||
pb_tnc_state_t state;
|
||||
|
||||
/* Initialize the connection */
|
||||
if (!this->is_server && !this->connection_id)
|
||||
{
|
||||
pb_tnc_msg_t *msg;
|
||||
char *pref_lang;
|
||||
|
||||
this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
|
||||
TNCCS_2_0, (tnccs_t*)this, _send_msg,
|
||||
&this->request_handshake_retry,
|
||||
this->max_msg_len, NULL);
|
||||
if (!this->connection_id)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* Create PB-TNC Language Preference message */
|
||||
pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
|
||||
msg = pb_language_preference_msg_create(chunk_create(pref_lang,
|
||||
strlen(pref_lang)));
|
||||
this->mutex->lock(this->mutex);
|
||||
this->batch_type = PB_BATCH_CDATA;
|
||||
this->messages->insert_last(this->messages, msg);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_CREATE);
|
||||
tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
|
||||
TNC_CONNECTION_STATE_HANDSHAKE);
|
||||
this->send_msg = TRUE;
|
||||
tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
|
||||
this->send_msg = FALSE;
|
||||
}
|
||||
|
||||
state = this->state_machine->get_state(this->state_machine);
|
||||
|
||||
if (this->fatal_error && state == PB_STATE_END)
|
||||
{
|
||||
DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* Do not allow any asynchronous IMCs or IMVs to add additional messages */
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
if (this->request_handshake_retry)
|
||||
{
|
||||
if (state != PB_STATE_INIT)
|
||||
{
|
||||
build_retry_batch(this);
|
||||
}
|
||||
|
||||
/* Reset the flag for the next handshake retry request */
|
||||
this->request_handshake_retry = FALSE;
|
||||
}
|
||||
|
||||
if (this->is_server && state == PB_STATE_SERVER_WORKING &&
|
||||
this->recs->have_recommendation(this->recs, NULL, NULL))
|
||||
{
|
||||
check_and_build_recommendation(this);
|
||||
}
|
||||
|
||||
if (this->batch_type == PB_BATCH_NONE)
|
||||
{
|
||||
if (this->is_server)
|
||||
{
|
||||
if (state == PB_STATE_SERVER_WORKING)
|
||||
{
|
||||
if (this->state_machine->get_empty_cdata(this->state_machine))
|
||||
{
|
||||
check_and_build_recommendation(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_TNC, "no recommendation available yet, "
|
||||
"sending empty PB-TNC SDATA batch");
|
||||
this->batch_type = PB_BATCH_SDATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PB_STATE_CLIENT_WORKING:
|
||||
DBG2(DBG_TNC, "no client data to send, "
|
||||
"sending empty PB-TNC CDATA batch");
|
||||
this->batch_type = PB_BATCH_CDATA;
|
||||
break;
|
||||
case PB_STATE_DECIDED:
|
||||
/**
|
||||
* In the DECIDED state and if no CRETRY is under way,
|
||||
* a PB-TNC client replies with an empty CLOSE batch.
|
||||
*/
|
||||
this->batch_type = PB_BATCH_CLOSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->batch_type != PB_BATCH_NONE)
|
||||
{
|
||||
pb_tnc_batch_t *batch;
|
||||
pb_tnc_msg_t *msg;
|
||||
chunk_t data;
|
||||
int msg_count;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
if (this->state_machine->send_batch(this->state_machine, this->batch_type))
|
||||
{
|
||||
batch = pb_tnc_batch_create(this->is_server, this->batch_type,
|
||||
min(this->max_batch_len, *buflen));
|
||||
|
||||
enumerator = this->messages->create_enumerator(this->messages);
|
||||
while (enumerator->enumerate(enumerator, &msg))
|
||||
{
|
||||
if (batch->add_msg(batch, msg))
|
||||
{
|
||||
this->messages->remove_at(this->messages, enumerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
batch->build(batch);
|
||||
data = batch->get_encoding(batch);
|
||||
DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u",
|
||||
pb_tnc_batch_type_names, this->batch_type, data.len,
|
||||
this->connection_id);
|
||||
DBG3(DBG_TNC, "%B", &data);
|
||||
|
||||
*buflen = data.len;
|
||||
*msglen = 0;
|
||||
memcpy(buf, data.ptr, *buflen);
|
||||
batch->destroy(batch);
|
||||
|
||||
msg_count = this->messages->get_count(this->messages);
|
||||
if (msg_count)
|
||||
{
|
||||
DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch",
|
||||
msg_count, (msg_count == 1) ? "" : "s",
|
||||
pb_tnc_batch_type_names, this->batch_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->batch_type = PB_BATCH_NONE;
|
||||
}
|
||||
|
||||
status = ALREADY_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
change_batch_type(this, PB_BATCH_NONE);
|
||||
status = INVALID_STATE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, "no PB-TNC batch to send");
|
||||
status = INVALID_STATE;
|
||||
}
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
METHOD(tls_t, is_server, bool,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
return this->is_server;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_server_id, identification_t*,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
return this->server;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_peer_id, identification_t*,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
return this->peer;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_purpose, tls_purpose_t,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
return TLS_PURPOSE_EAP_TNC;
|
||||
}
|
||||
|
||||
METHOD(tls_t, is_complete, bool,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
TNC_IMV_Action_Recommendation rec;
|
||||
TNC_IMV_Evaluation_Result eval;
|
||||
|
||||
if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
|
||||
{
|
||||
return tnc->imvs->enforce_recommendation(tnc->imvs, rec, eval);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_eap_msk, chunk_t,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
return chunk_empty;
|
||||
}
|
||||
|
||||
METHOD(tls_t, destroy, void,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
|
||||
this->is_server);
|
||||
this->server->destroy(this->server);
|
||||
this->peer->destroy(this->peer);
|
||||
this->state_machine->destroy(this->state_machine);
|
||||
this->mutex->destroy(this->mutex);
|
||||
this->messages->destroy_offset(this->messages,
|
||||
offsetof(pb_tnc_msg_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, get_transport, tnc_ift_type_t,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
return this->transport;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, set_transport, void,
|
||||
private_tnccs_20_t *this, tnc_ift_type_t transport)
|
||||
{
|
||||
this->transport = transport;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, get_auth_type, u_int32_t,
|
||||
private_tnccs_20_t *this)
|
||||
{
|
||||
return this->auth_type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, set_auth_type, void,
|
||||
private_tnccs_20_t *this, u_int32_t auth_type)
|
||||
{
|
||||
this->auth_type = auth_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_t* tnccs_20_create(bool is_server,
|
||||
identification_t *server,
|
||||
identification_t *peer,
|
||||
tnc_ift_type_t transport)
|
||||
{
|
||||
private_tnccs_20_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tls = {
|
||||
.process = _process,
|
||||
.build = _build,
|
||||
.is_server = _is_server,
|
||||
.get_server_id = _get_server_id,
|
||||
.get_peer_id = _get_peer_id,
|
||||
.get_purpose = _get_purpose,
|
||||
.is_complete = _is_complete,
|
||||
.get_eap_msk = _get_eap_msk,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_transport = _get_transport,
|
||||
.set_transport = _set_transport,
|
||||
.get_auth_type = _get_auth_type,
|
||||
.set_auth_type = _set_auth_type,
|
||||
},
|
||||
.is_server = is_server,
|
||||
.server = server->clone(server),
|
||||
.peer = peer->clone(peer),
|
||||
.transport = transport,
|
||||
.state_machine = pb_tnc_state_machine_create(is_server),
|
||||
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||
.messages = linked_list_create(),
|
||||
.max_batch_len = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.tnccs-20.max_batch_size", 65522,
|
||||
"charon"),
|
||||
.max_msg_len = lib->settings->get_int(lib->settings,
|
||||
"%s.plugins.tnccs-20.max_message_size", 65490,
|
||||
"charon"),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_20_h tnccs_20
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_20_H_
|
||||
#define TNCCS_20_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
|
||||
/**
|
||||
* Create an instance of the TNC IF-TNCCS 2.0 protocol handler.
|
||||
*
|
||||
* @param is_server TRUE to act as TNC Server, FALSE for TNC Client
|
||||
* @param server Server identity
|
||||
* @param peer Client identity
|
||||
* @param transport Underlying IF-T transport protocol
|
||||
* @return TNC_IF_TNCCS 2.0 protocol stack
|
||||
*/
|
||||
tnccs_t* tnccs_20_create(bool is_server,
|
||||
identification_t *server,
|
||||
identification_t *peer,
|
||||
tnc_ift_type_t transport);
|
||||
|
||||
#endif /** TNCCS_20_H_ @}*/
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_20_plugin.h"
|
||||
#include "tnccs_20.h"
|
||||
|
||||
#include <tnc/tnccs/tnccs_manager.h>
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
tnccs_20_plugin_t *this)
|
||||
{
|
||||
return "tnccs-20";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
tnccs_20_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(tnccs_method_register, tnccs_20_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "tnccs-2.0"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
tnccs_20_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *tnccs_20_plugin_create()
|
||||
{
|
||||
tnccs_20_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
);
|
||||
|
||||
return &this->plugin;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_20 tnccs_20
|
||||
* @ingroup cplugins
|
||||
*
|
||||
* @defgroup tnccs_20_plugin tnccs_20_plugin
|
||||
* @{ @ingroup tnccs_20
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_20_PLUGIN_H_
|
||||
#define TNCCS_20_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct tnccs_20_plugin_t tnccs_20_plugin_t;
|
||||
|
||||
/**
|
||||
* EAP-TNC plugin
|
||||
*/
|
||||
struct tnccs_20_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** TNCCS_20_PLUGIN_H_ @}*/
|
||||
@@ -1,22 +0,0 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libtls \
|
||||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libtnccs
|
||||
|
||||
AM_CFLAGS = \
|
||||
-rdynamic
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-tnccs-dynamic.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-tnccs-dynamic.la
|
||||
libstrongswan_tnccs_dynamic_la_LIBADD = \
|
||||
$(top_builddir)/src/libtncif/libtncif.la \
|
||||
$(top_builddir)/src/libtnccs/libtnccs.la
|
||||
endif
|
||||
|
||||
libstrongswan_tnccs_dynamic_la_SOURCES = \
|
||||
tnccs_dynamic_plugin.h tnccs_dynamic_plugin.c tnccs_dynamic.h tnccs_dynamic.c
|
||||
|
||||
libstrongswan_tnccs_dynamic_la_LDFLAGS = -module -avoid-version
|
||||
@@ -1,223 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_dynamic.h"
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_tnccs_dynamic_t private_tnccs_dynamic_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnccs_dynamic_t object.
|
||||
*/
|
||||
struct private_tnccs_dynamic_t {
|
||||
|
||||
/**
|
||||
* Public tnccs_t interface.
|
||||
*/
|
||||
tnccs_t public;
|
||||
|
||||
/**
|
||||
* Server identity
|
||||
*/
|
||||
identification_t *server;
|
||||
|
||||
/**
|
||||
* Client identity
|
||||
*/
|
||||
identification_t *peer;
|
||||
|
||||
/**
|
||||
* Detected TNC IF-TNCCS stack
|
||||
*/
|
||||
tls_t *tls;
|
||||
|
||||
/**
|
||||
* Underlying TNC IF-T transport protocol
|
||||
*/
|
||||
tnc_ift_type_t transport;
|
||||
|
||||
/**
|
||||
* Type of TNC client authentication
|
||||
*/
|
||||
u_int32_t auth_type;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine the version of the IF-TNCCS protocol used by analyzing the first
|
||||
* byte of the TNCCS batch received from a TNC Client according to the rules
|
||||
* defined by section 3.5 "Interoperability with older IF-TNCCS versions" of
|
||||
* the TCG TNC IF-TNCCS TLV Bindings Version 2.0 standard.
|
||||
*/
|
||||
tnccs_type_t determine_tnccs_protocol(char version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case ' ':
|
||||
case '<':
|
||||
return TNCCS_1_1;
|
||||
case 0x00:
|
||||
return TNCCS_SOH;
|
||||
case 0x02:
|
||||
return TNCCS_2_0;
|
||||
default:
|
||||
return TNCCS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(tls_t, process, status_t,
|
||||
private_tnccs_dynamic_t *this, void *buf, size_t buflen)
|
||||
{
|
||||
tnccs_type_t type;
|
||||
tnccs_t *tnccs;
|
||||
|
||||
if (!this->tls)
|
||||
{
|
||||
if (buflen == 0)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
type = determine_tnccs_protocol(*(char*)buf);
|
||||
DBG1(DBG_TNC, "%N protocol detected dynamically",
|
||||
tnccs_type_names, type);
|
||||
tnccs = tnc->tnccs->create_instance(tnc->tnccs, type, TRUE,
|
||||
this->server, this->peer, this->transport);
|
||||
if (!tnccs)
|
||||
{
|
||||
DBG1(DBG_TNC, "N% protocol not supported", tnccs_type_names, type);
|
||||
return FAILED;
|
||||
}
|
||||
tnccs->set_auth_type(tnccs, this->auth_type);
|
||||
this->tls = &tnccs->tls;
|
||||
}
|
||||
return this->tls->process(this->tls, buf, buflen);
|
||||
}
|
||||
|
||||
METHOD(tls_t, build, status_t,
|
||||
private_tnccs_dynamic_t *this, void *buf, size_t *buflen, size_t *msglen)
|
||||
{
|
||||
return this->tls->build(this->tls, buf, buflen, msglen);
|
||||
}
|
||||
|
||||
METHOD(tls_t, is_server, bool,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_server_id, identification_t*,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
return this->server;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_peer_id, identification_t*,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
return this->peer;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_purpose, tls_purpose_t,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
return TLS_PURPOSE_EAP_TNC;
|
||||
}
|
||||
|
||||
METHOD(tls_t, is_complete, bool,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
return this->tls ? this->tls->is_complete(this->tls) : FALSE;
|
||||
}
|
||||
|
||||
METHOD(tls_t, get_eap_msk, chunk_t,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
return chunk_empty;
|
||||
}
|
||||
|
||||
METHOD(tls_t, destroy, void,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
DESTROY_IF(this->tls);
|
||||
this->server->destroy(this->server);
|
||||
this->peer->destroy(this->peer);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, get_transport, tnc_ift_type_t,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
return this->transport;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, set_transport, void,
|
||||
private_tnccs_dynamic_t *this, tnc_ift_type_t transport)
|
||||
{
|
||||
this->transport = transport;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, get_auth_type, u_int32_t,
|
||||
private_tnccs_dynamic_t *this)
|
||||
{
|
||||
return this->auth_type;
|
||||
}
|
||||
|
||||
METHOD(tnccs_t, set_auth_type, void,
|
||||
private_tnccs_dynamic_t *this, u_int32_t auth_type)
|
||||
{
|
||||
this->auth_type = auth_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
tnccs_t* tnccs_dynamic_create(bool is_server,
|
||||
identification_t *server,
|
||||
identification_t *peer,
|
||||
tnc_ift_type_t transport)
|
||||
{
|
||||
private_tnccs_dynamic_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.tls = {
|
||||
.process = _process,
|
||||
.build = _build,
|
||||
.is_server = _is_server,
|
||||
.get_server_id = _get_server_id,
|
||||
.get_peer_id = _get_peer_id,
|
||||
.get_purpose = _get_purpose,
|
||||
.is_complete = _is_complete,
|
||||
.get_eap_msk = _get_eap_msk,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_transport = _get_transport,
|
||||
.set_transport = _set_transport,
|
||||
.get_auth_type = _get_auth_type,
|
||||
.set_auth_type = _set_auth_type,
|
||||
},
|
||||
.server = server->clone(server),
|
||||
.peer = peer->clone(peer),
|
||||
.transport = transport,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_dynamic_h tnccs_dynamic
|
||||
* @{ @ingroup tnccs_dynamic
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_DYNAMIC_H_
|
||||
#define TNCCS_DYNAMIC_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
#include <tnc/tnccs/tnccs.h>
|
||||
|
||||
/**
|
||||
* Create an instance of a dynamic TNC IF-TNCCS protocol handler.
|
||||
*
|
||||
* @param is_server TRUE to act as TNC Server, FALSE for TNC Client
|
||||
* @param server Server identity
|
||||
* @param peer Client identity
|
||||
* @param transport Underlying IF-T transport protocol
|
||||
* @return dynamic TNC IF-TNCCS protocol stack
|
||||
*/
|
||||
tnccs_t* tnccs_dynamic_create(bool is_server,
|
||||
identification_t *server,
|
||||
identification_t *peer,
|
||||
tnc_ift_type_t transport);
|
||||
|
||||
#endif /** TNCCS_DYNAMIC_H_ @}*/
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "tnccs_dynamic_plugin.h"
|
||||
#include "tnccs_dynamic.h"
|
||||
|
||||
#include <tnc/tnccs/tnccs_manager.h>
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
tnccs_dynamic_plugin_t *this)
|
||||
{
|
||||
return "tnccs-dynamic";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
tnccs_dynamic_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(tnccs_method_register, tnccs_dynamic_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "tnccs-dynamic"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "tnccs-1.1"),
|
||||
PLUGIN_DEPENDS(CUSTOM, "tnccs-2.0"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
tnccs_dynamic_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *tnccs_dynamic_plugin_create()
|
||||
{
|
||||
tnccs_dynamic_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
);
|
||||
|
||||
return &this->plugin;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup tnccs_dynamic tnccs_dynamic
|
||||
* @ingroup cplugins
|
||||
*
|
||||
* @defgroup tnccs_dynamic_plugin tnccs_dynamic_plugin
|
||||
* @{ @ingroup tnccs_dynamic
|
||||
*/
|
||||
|
||||
#ifndef TNCCS_DYNAMIC_PLUGIN_H_
|
||||
#define TNCCS_DYNAMIC_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct tnccs_dynamic_plugin_t tnccs_dynamic_plugin_t;
|
||||
|
||||
/**
|
||||
* EAP-TNC plugin
|
||||
*/
|
||||
struct tnccs_dynamic_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** TNCCS_DYNAMIC_PLUGIN_H_ @}*/
|
||||
Reference in New Issue
Block a user