#include <dlfcn.h>
#include <debug.h>
-#include <library.h>
+#include <daemon.h>
typedef struct private_tnc_imc_t private_tnc_imc_t;
{
DBG2(DBG_TNC,"TNCC_SendMessage %u %u '%s' %u %0x", imc_id, connection_id,
message, message_len, message_type);
-
- /*
- -----TNCCS 2.0-----
- tnc_tncc_connection* conn;
-
- conn = libtnc_array_index(&connections, connectionID);
-
- TNC_MessageSubtype message_type = messageType & TNC_SUBTYPE_ANY;
- TNC_VendorID message_vendor_id = (messageType >> 8) & TNC_VENDORID_ANY;
-
- chunk_t pa_message = tnc_create_pa_message(FALSE, message_vendor_id,
- message_type, 0, 0, message, messageLength);
-
- if(conn->current_batch.len)
- {
- chunk_t batch = conn->current_batch;
- htoun32(batch.ptr + 4,batch.len + pa_message.len);
- conn->current_batch = chunk_cat("cc", batch, pa_message);
-
- }
- else
- {
- chunk_t header = tnc_create_batch_header(TNCCS_BATCH_TYPE_CDATA, false);
-
- htoun32(header.ptr + 4,header.len + pa_message.len);
- conn->current_batch = chunk_cat("cc", header, pa_message);
-
- }
- -----TNCCS 1.1-----
- libtnc_mutex_lock();
- conn = libtnc_array_index(&connections, connectionID);
- libtnc_mutex_unlock();
- return libtnc_tncc_add_imc_imv_message(conn, message, messageLength, messageType);
- */
-
- return TNC_RESULT_SUCCESS;
+ return charon->tnccs->send_message(charon->tnccs, connection_id, message,
+ message_len, message_type);
}
/**
* Connection ID assigned to this TNCCS connection
*/
TNC_ConnectionID connection_id;
+
+ /**
+ * Batch being constructed
+ */
+ chunk_t batch;
};
+METHOD(tnccs_t, send_message, void,
+ private_tnccs_20_t* this, TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type)
+{
+ chunk_t msg = { message, message_len },
+ batch = this->batch;
+
+ DBG1(DBG_TNC, "TNCCS 2.0 send message");
+ this->batch = chunk_cat("mc", batch, msg);
+}
+
METHOD(tls_t, process, status_t,
private_tnccs_20_t *this, void *buf, size_t buflen)
{
if (this->is_server && !this->connection_id)
{
this->connection_id = charon->tnccs->create_connection(charon->tnccs,
- (tnccs_t*)this);
+ (tnccs_t*)this, _send_message);
charon->imvs->notify_connection_change(charon->imvs,
this->connection_id, TNC_CONNECTION_STATE_CREATE);
}
METHOD(tls_t, build, status_t,
private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
{
- char *msg;
+ char *msg = this->is_server ? "|tncs->tncc 2.0|" : "|tncc->tncs 2.0|";
+ size_t len;
+
+ this->batch = chunk_clone(chunk_create(msg, strlen(msg)));
if (!this->is_server && !this->connection_id)
{
this->connection_id = charon->tnccs->create_connection(charon->tnccs,
- (tnccs_t*)this);
+ (tnccs_t*)this, _send_message);
charon->imcs->notify_connection_change(charon->imcs,
this->connection_id, TNC_CONNECTION_STATE_CREATE);
charon->imcs->notify_connection_change(charon->imcs,
charon->imcs->begin_handshake(charon->imcs, this->connection_id);
}
- msg = this->is_server ? "tncs-tncc 2.0" : "tncc-tncs 2.0";
+ len = this->batch.len;
+ *msglen = len;
+ *buflen = len;
+ memcpy(buf, this->batch.ptr, len);
+
DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u",
- strlen(msg), this->connection_id);
- DBG3(DBG_TNC, "%s", msg);
- *msglen = strlen(msg);
- memcpy(buf, msg, *msglen);
- *buflen = *msglen;
+ len, this->connection_id);
+ DBG3(DBG_TNC, "%.*s", len, buf);
+ chunk_free(&this->batch);
return ALREADY_DONE;
}
private_tnccs_20_t *this)
{
charon->tnccs->remove_connection(charon->tnccs, this->connection_id);
+ free(this->batch.ptr);
free(this);
}
#ifndef TNCCS_H_
#define TNCCS_H_
-typedef enum tnccs_type_t tnccs_type_t;
-
#include <library.h>
+#include <tnc/tncif.h>
+
+typedef enum tnccs_type_t tnccs_type_t;
+
/**
* Type of TNC Client/Server protocol
*/
*/
typedef tnccs_t* (*tnccs_constructor_t)(bool is_server);
+/**
+ * Callback function adding a message to a TNCCS batch
+ *
+ * @param message message to be added
+ * @param message_len message length
+ * @param message_type message type
+ */
+typedef void (*tnccs_send_message_t)(tnccs_t* tncss,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type);
+
#endif /** TNC_H_ @}*/
* TNCCS instance
*/
tnccs_t *tnccs;
+
+ /** TNCCS send message function
+ *
+ */
+ tnccs_send_message_t send_message;
};
/**
}
METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID,
- private_tnccs_manager_t *this, tnccs_t *tnccs)
+ private_tnccs_manager_t *this, tnccs_t *tnccs,
+ tnccs_send_message_t send_message)
{
tnccs_connection_entry_t *entry = malloc_thing(tnccs_connection_entry_t);
entry->id = ++this->connection_id;
entry->tnccs = tnccs;
+ entry->send_message = send_message;
this->lock->write_lock(this->lock);
this->connections->insert_last(this->connections, entry);
this->lock->unlock(this->lock);
}
+METHOD(tnccs_manager_t, send_message, TNC_Result,
+ private_tnccs_manager_t *this, TNC_ConnectionID id,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type)
+{
+ enumerator_t *enumerator;
+ tnccs_connection_entry_t *entry;
+ tnccs_send_message_t send_message;
+ tnccs_t *tnccs = NULL;
+
+ this->lock->write_lock(this->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->lock->unlock(this->lock);
+
+ if (tnccs)
+ {
+ send_message(tnccs, message, message_len, message_type);
+ return TNC_RESULT_SUCCESS;
+ }
+ return TNC_RESULT_FATAL;
+}
+
METHOD(tnccs_manager_t, destroy, void,
private_tnccs_manager_t *this)
{
.create_instance = _create_instance,
.create_connection = _create_connection,
.remove_connection = _remove_connection,
+ .send_message = _send_message,
.destroy = _destroy,
},
.protocols = linked_list_create(),
* Create a TNCCS connection and assign a unique connection ID
*
* @param tnccs TNCCS connection instance
+ * @param send_message callback function adding a message to a TNCCS batch
* @result assigned connection ID
*/
- TNC_ConnectionID (*create_connection)(tnccs_manager_t *this, tnccs_t *tnccs);
+ TNC_ConnectionID (*create_connection)(tnccs_manager_t *this, tnccs_t *tnccs,
+ tnccs_send_message_t send_message);
/**
* Remove a TNCCS connection using its connection ID.
void (*remove_connection)(tnccs_manager_t *this, TNC_ConnectionID id);
/**
+ * Add an IMC/IMV message to the batch of a given connection ID.
+ *
+ * @param id target connection ID
+ * @param message message to be added
+ * @param message_len message length
+ * @param message_type message type
+ * @result return code
+ */
+ TNC_Result (*send_message)(tnccs_manager_t *this, TNC_ConnectionID id,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type);
+
+ /**
* Destroy a tnccs_manager instance.
*/
void (*destroy)(tnccs_manager_t *this);