diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2010-12-12 00:42:31 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2010-12-12 00:42:31 +0100 |
commit | 54eb669dd5bc99b350383f5defb7c638ae6676bb (patch) | |
tree | 600370cf76bfdd6fffb3e4a4879190ed0648e65e /src | |
parent | 3a4695dc5ea7f5afdd821e676b0ca039ce171866 (diff) | |
download | strongswan-54eb669dd5bc99b350383f5defb7c638ae6676bb.tar.bz2 strongswan-54eb669dd5bc99b350383f5defb7c638ae6676bb.tar.xz |
implemented PB-TNC message parsing checks
Diffstat (limited to 'src')
25 files changed, 1195 insertions, 605 deletions
diff --git a/src/libcharon/plugins/tnccs_20/Makefile.am b/src/libcharon/plugins/tnccs_20/Makefile.am index 4b335a0ac..d72fd3e34 100644 --- a/src/libcharon/plugins/tnccs_20/Makefile.am +++ b/src/libcharon/plugins/tnccs_20/Makefile.am @@ -13,15 +13,16 @@ endif libstrongswan_tnccs_20_la_SOURCES = \ tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \ - tnccs_20_types.h tnccs_20_types.c \ batch/pb_tnc_batch.h batch/pb_tnc_batch.c \ - messages/pb_tnc_message.h messages/pb_tnc_message.c \ - messages/pb_pa_message.h messages/pb_pa_message.c \ - messages/pb_assessment_result_message.h messages/pb_assessment_result_message.c \ - messages/pb_access_recommendation_message.h messages/pb_access_recommendation_message.c \ - messages/pb_error_message.h messages/pb_error_message.c \ - messages/pb_language_preference_message.h messages/pb_language_preference_message.c \ - messages/pb_reason_string_message.h messages/pb_reason_string_message.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 diff --git a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c index 1f89369f7..1e0a6bf97 100644 --- a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c +++ b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c @@ -14,9 +14,8 @@ * for more details. */ -#include "tnccs_20_types.h" #include "pb_tnc_batch.h" -#include "messages/pb_error_message.h" +#include "messages/pb_error_msg.h" #include "state_machine/pb_tnc_state_machine.h" #include <debug.h> @@ -80,7 +79,7 @@ typedef struct private_pb_tnc_batch_t private_pb_tnc_batch_t; */ struct private_pb_tnc_batch_t { /** - * Public pb_pa_message_t interface. + * Public pb_pa_msg_t interface. */ pb_tnc_batch_t public; @@ -112,7 +111,7 @@ struct private_pb_tnc_batch_t { /** * Offset into encoding (used for error reporting) */ - size_t offset; + u_int32_t offset; }; METHOD(pb_tnc_batch_t, get_type, pb_tnc_batch_type_t, @@ -127,8 +126,8 @@ METHOD(pb_tnc_batch_t, get_encoding, chunk_t, return this->encoding; } -METHOD(pb_tnc_batch_t, add_message, void, - private_pb_tnc_batch_t *this, pb_tnc_message_t* msg) +METHOD(pb_tnc_batch_t, add_msg, void, + private_pb_tnc_batch_t *this, pb_tnc_msg_t* msg) { DBG2(DBG_TNC, "adding %N Message", pb_tnc_msg_type_names, msg->get_type(msg)); @@ -139,11 +138,10 @@ METHOD(pb_tnc_batch_t, build, void, private_pb_tnc_batch_t *this) { u_int32_t batch_len, msg_len; - u_int8_t flags = PB_TNC_FLAG_NONE; chunk_t msg_value; enumerator_t *enumerator; pb_tnc_msg_type_t msg_type; - pb_tnc_message_t *msg; + pb_tnc_msg_t *msg; tls_writer_t *writer; /* compute total PB-TNC batch size by summing over all messages */ @@ -169,24 +167,16 @@ METHOD(pb_tnc_batch_t, build, void, 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); - switch (msg_type) + if (pb_tnc_msg_infos[msg_type].has_noskip_flag) { - case PB_MSG_PA: - case PB_MSG_ASSESSMENT_RESULT: - case PB_MSG_ERROR: - flags |= PB_TNC_FLAG_NOSKIP; - break; - case PB_MSG_EXPERIMENTAL: - case PB_MSG_ACCESS_RECOMMENDATION: - case PB_MSG_REMEDIATION_PARAMETERS: - case PB_MSG_LANGUAGE_PREFERENCE: - case PB_MSG_REASON_STRING: - break; - } + flags |= PB_TNC_FLAG_NOSKIP; + } writer->write_uint8 (writer, flags); writer->write_uint24(writer, IETF_VENDOR_ID); writer->write_uint32(writer, msg_type); @@ -203,8 +193,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, pb_tnc_state_machine_t *state_machine) { tls_reader_t *reader; - pb_tnc_message_t *msg; - pb_error_message_t *err_msg; + 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; @@ -213,10 +203,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, { DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC batch header", this->encoding.len); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, 0); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, 0); goto fatal; } @@ -232,9 +220,9 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, if (version != PB_TNC_VERSION) { DBG1(DBG_TNC, "unsupported TNCCS Batch Version 0x%01x", version); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_VERSION_NOT_SUPPORTED); - err_msg = (pb_error_message_t*)msg; + msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID, + PB_ERROR_VERSION_NOT_SUPPORTED); + err_msg = (pb_error_msg_t*)msg; err_msg->set_bad_version(err_msg, version); goto fatal; } @@ -245,10 +233,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, { DBG1(DBG_TNC, "wrong Directionality: Batch is from a PB %s", directionality ? "Server" : "Client"); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, 1); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, 1); goto fatal; } @@ -257,10 +243,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, if (this->type > PB_BATCH_ROOF) { DBG1(DBG_TNC, "unknown PB-TNC Batch Type: %d", this->type); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, 3); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, 3); goto fatal; } @@ -268,8 +252,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, { DBG1(DBG_TNC, "unexpected PB-TNC Batch Type: %N", pb_tnc_batch_type_names, this->type); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_UNEXPECTED_BATCH_TYPE); + msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID, + PB_ERROR_UNEXPECTED_BATCH_TYPE); goto fatal; } @@ -278,10 +262,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, { DBG1(DBG_TNC, "%u bytes of data is not equal to batch length of %u bytes", this->encoding.len, batch_len); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, 4); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, 4); goto fatal; } @@ -293,14 +275,14 @@ fatal: return FAILED; } -static status_t process_tnc_message(private_pb_tnc_batch_t *this) +static status_t process_tnc_msg(private_pb_tnc_batch_t *this) { tls_reader_t *reader; - pb_tnc_message_t *pb_tnc_msg, *msg; - pb_error_message_t *err_msg; + pb_tnc_msg_t *pb_tnc_msg, *msg; u_int8_t flags; - u_int32_t vendor_id, msg_type, msg_len; + 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); @@ -309,10 +291,8 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this) { DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message header", data.len); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, this->offset); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, this->offset); goto fatal; } @@ -323,33 +303,21 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this) reader->read_uint32(reader, &msg_len); reader->destroy(reader); - if (msg_len < PB_TNC_HEADER_SIZE) - { - DBG1(DBG_TNC, "%u bytes too small for PB-TNC message length", msg_len); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, this->offset + 8); - goto fatal; - } - + 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_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, this->offset + 8); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, this->offset + 8); goto fatal; } if (vendor_id == RESERVED_VENDOR_ID) { DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, this->offset + 1); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, this->offset + 1); goto fatal; } @@ -358,23 +326,29 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this) { DBG1(DBG_TNC, "PB-TNC Message Type 0x%08x is reserved", PB_TNC_RESERVED_MSG_TYPE); - msg = pb_error_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, this->offset + 4); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, this->offset + 4); goto fatal; } + if (vendor_id != IETF_VENDOR_ID || msg_type > PB_MSG_ROOF) { - if (flags & PB_TNC_FLAG_NOSKIP) + 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, IETF_VENDOR_ID, + 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_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_UNSUPPORTED_MANDATORY_MESSAGE); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, this->offset); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset); goto fatal; } else @@ -385,20 +359,42 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this) return SUCCESS; } } + else + { + 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, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, this->offset); + goto fatal; + } - if ((msg_type == PB_MSG_ASSESSMENT_RESULT || - msg_type == PB_MSG_ACCESS_RECOMMENDATION || - msg_type == PB_MSG_REMEDIATION_PARAMETERS) && - this->type != PB_BATCH_RESULT) + 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, IETF_VENDOR_ID, + 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_message_create(TRUE, IETF_VENDOR_ID, - PB_ERROR_INVALID_PARAMETER); - err_msg = (pb_error_message_t*)msg; - err_msg->set_offset(err_msg, this->offset); + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, this->offset); goto fatal; } else @@ -415,9 +411,15 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this) data.len = msg_len; DBG3(DBG_TNC, "%B", &data); msg_value = chunk_skip(data, PB_TNC_HEADER_SIZE); - pb_tnc_msg = pb_tnc_message_create(msg_type, msg_value); + pb_tnc_msg = pb_tnc_msg_create_from_data(msg_type, msg_value); - status = pb_tnc_msg->process(pb_tnc_msg); + status = pb_tnc_msg->process(pb_tnc_msg, &offset); + if (status == FAILED || status == VERIFY_ERROR) + { + msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID, + PB_ERROR_INVALID_PARAMETER, this->offset); + this->errors->insert_last(this->errors, msg); + } if (status == FAILED) { pb_tnc_msg->destroy(pb_tnc_msg); @@ -425,7 +427,7 @@ static status_t process_tnc_message(private_pb_tnc_batch_t *this) } this->messages->insert_last(this->messages, pb_tnc_msg); this->offset += msg_len; - return SUCCESS; + return status; fatal: this->errors->insert_last(this->errors, msg); @@ -446,7 +448,7 @@ METHOD(pb_tnc_batch_t, process, status_t, this->type); while (this->offset < this->encoding.len) { - switch (process_tnc_message(this)) + switch (process_tnc_msg(this)) { case FAILED: return FAILED; @@ -477,9 +479,9 @@ METHOD(pb_tnc_batch_t, destroy, void, private_pb_tnc_batch_t *this) { this->messages->destroy_offset(this->messages, - offsetof(pb_tnc_message_t, destroy)); + offsetof(pb_tnc_msg_t, destroy)); this->errors->destroy_offset(this->errors, - offsetof(pb_tnc_message_t, destroy)); + offsetof(pb_tnc_msg_t, destroy)); free(this->encoding.ptr); free(this); } @@ -495,7 +497,7 @@ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type) .public = { .get_type = _get_type, .get_encoding = _get_encoding, - .add_message = _add_message, + .add_msg = _add_msg, .build = _build, .process = _process, .create_msg_enumerator = _create_msg_enumerator, @@ -524,7 +526,7 @@ pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data) .public = { .get_type = _get_type, .get_encoding = _get_encoding, - .add_message = _add_message, + .add_msg = _add_msg, .build = _build, .process = _process, .create_msg_enumerator = _create_msg_enumerator, diff --git a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.h b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.h index a437799d3..559b382be 100644 --- a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.h +++ b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.h @@ -24,7 +24,7 @@ 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_message.h" +#include "messages/pb_tnc_msg.h" #include "state_machine/pb_tnc_state_machine.h" #include <library.h> @@ -71,7 +71,7 @@ struct pb_tnc_batch_t { * * @param msg PB-TNC message to be addedd */ - void (*add_message)(pb_tnc_batch_t *this, pb_tnc_message_t* msg); + void (*add_msg)(pb_tnc_batch_t *this, pb_tnc_msg_t* msg); /** * Build the PB-TNC Batch diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_message.c b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c index cb744b706..2cb7b925c 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_message.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c @@ -13,13 +13,19 @@ * for more details. */ -#include "pb_access_recommendation_message.h" +#include "pb_access_recommendation_msg.h" #include <tls_writer.h> #include <tls_reader.h> #include <debug.h> -typedef struct private_pb_access_recommendation_message_t private_pb_access_recommendation_message_t; +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) @@ -32,17 +38,16 @@ typedef struct private_pb_access_recommendation_message_t private_pb_access_reco */ #define ACCESS_RECOMMENDATION_RESERVED 0x0000 -#define ACCESS_RECOMMENDATION_MESSAGE_SIZE 4 - +#define ACCESS_RECOMMENDATION_MSG_SIZE 4 /** - * Private data of a private_pb_access_recommendation_message_t object. + * Private data of a private_pb_access_recommendation_msg_t object. * */ -struct private_pb_access_recommendation_message_t { +struct private_pb_access_recommendation_msg_t { /** - * Public pb_access_recommendation_message_t interface. + * Public pb_access_recommendation_msg_t interface. */ - pb_access_recommendation_message_t public; + pb_access_recommendation_msg_t public; /** * PB-TNC message type @@ -60,25 +65,25 @@ struct private_pb_access_recommendation_message_t { chunk_t encoding; }; -METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t, - private_pb_access_recommendation_message_t *this) +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_message_t, get_encoding, chunk_t, - private_pb_access_recommendation_message_t *this) +METHOD(pb_tnc_msg_t, get_encoding, chunk_t, + private_pb_access_recommendation_msg_t *this) { return this->encoding; } -METHOD(pb_tnc_message_t, build, void, - private_pb_access_recommendation_message_t *this) +METHOD(pb_tnc_msg_t, build, void, + private_pb_access_recommendation_msg_t *this) { tls_writer_t *writer; /* build message */ - writer = tls_writer_create(ACCESS_RECOMMENDATION_MESSAGE_SIZE); + writer = tls_writer_create(ACCESS_RECOMMENDATION_MSG_SIZE); writer->write_uint16(writer, ACCESS_RECOMMENDATION_RESERVED); writer->write_uint16(writer, this->recommendation); free(this->encoding.ptr); @@ -87,38 +92,39 @@ METHOD(pb_tnc_message_t, build, void, writer->destroy(writer); } -METHOD(pb_tnc_message_t, process, status_t, - private_pb_access_recommendation_message_t *this) +METHOD(pb_tnc_msg_t, process, status_t, + private_pb_access_recommendation_msg_t *this, u_int32_t *offset) { tls_reader_t *reader; u_int16_t reserved; - if (this->encoding.len < ACCESS_RECOMMENDATION_MESSAGE_SIZE) - { - DBG1(DBG_TNC,"%N message is shorter than message size of %u bytes", - pb_tnc_msg_type_names, PB_MSG_ACCESS_RECOMMENDATION, - ACCESS_RECOMMENDATION_MESSAGE_SIZE); - return FAILED; - } - /* process message */ reader = tls_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_message_t, destroy, void, - private_pb_access_recommendation_message_t *this) +METHOD(pb_tnc_msg_t, destroy, void, + private_pb_access_recommendation_msg_t *this) { free(this->encoding.ptr); free(this); } -METHOD(pb_access_recommendation_message_t, get_access_recommendation, u_int16_t, - private_pb_access_recommendation_message_t *this) +METHOD(pb_access_recommendation_msg_t, get_access_recommendation, u_int16_t, + private_pb_access_recommendation_msg_t *this) { return this->recommendation; } @@ -126,9 +132,9 @@ METHOD(pb_access_recommendation_message_t, get_access_recommendation, u_int16_t, /** * See header */ -pb_tnc_message_t *pb_access_recommendation_message_create_from_data(chunk_t data) +pb_tnc_msg_t *pb_access_recommendation_msg_create_from_data(chunk_t data) { - private_pb_access_recommendation_message_t *this; + private_pb_access_recommendation_msg_t *this; INIT(this, .public = { @@ -151,9 +157,9 @@ pb_tnc_message_t *pb_access_recommendation_message_create_from_data(chunk_t data /** * See header */ -pb_tnc_message_t *pb_access_recommendation_message_create(u_int16_t recommendation) +pb_tnc_msg_t *pb_access_recommendation_msg_create(u_int16_t recommendation) { - private_pb_access_recommendation_message_t *this; + private_pb_access_recommendation_msg_t *this; INIT(this, .public = { diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_message.h b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.h index 0b3c849e9..3053f7261 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_message.h +++ b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.h @@ -14,33 +14,49 @@ */ /** - * @defgroup pb_access_recommendation_message pb_access_recommendation_message + * @defgroup pb_access_recommendation_msg pb_access_recommendation_msg * @{ @ingroup tnccs_20 */ -#ifndef PB_ACCESS_RECOMMENDATION_MESSAGE_H_ -#define PB_ACCESS_RECOMMENDATION_MESSAGE_H_ +#ifndef PB_ACCESS_RECOMMENDATION_MSG_H_ +#define PB_ACCESS_RECOMMENDATION_MSG_H_ -#include "pb_tnc_message.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; -typedef struct pb_access_recommendation_message_t pb_access_recommendation_message_t; /** * Classs representing the PB-Access-Recommendation message type. */ -struct pb_access_recommendation_message_t { +struct pb_access_recommendation_msg_t { /** * PB-TNC Message interface */ - pb_tnc_message_t pb_interface; + pb_tnc_msg_t pb_interface; /** * Get PB Access Recommendation * * @return PB Access Recommendation */ - u_int16_t (*get_access_recommendation)(pb_access_recommendation_message_t *this); + u_int16_t (*get_access_recommendation)(pb_access_recommendation_msg_t *this); }; /** @@ -48,13 +64,13 @@ struct pb_access_recommendation_message_t { * * @param access_recommendation Access Recommendation code */ -pb_tnc_message_t* pb_access_recommendation_message_create(u_int16_t recommendation); +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_message_t* pb_access_recommendation_message_create_from_data(chunk_t data); +pb_tnc_msg_t* pb_access_recommendation_msg_create_from_data(chunk_t data); -#endif /** PB_PA_MESSAGE_H_ @}*/ +#endif /** PB_PA_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_message.c b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c index 752a1623c..c91e54176 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_message.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c @@ -13,13 +13,14 @@ * for more details. */ -#include "pb_assessment_result_message.h" +#include "pb_assessment_result_msg.h" #include <tls_writer.h> #include <tls_reader.h> +#include <tnc/tncifimv.h> #include <debug.h> -typedef struct private_pb_assessment_result_message_t private_pb_assessment_result_message_t; +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) @@ -31,17 +32,17 @@ typedef struct private_pb_assessment_result_message_t private_pb_assessment_resu * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define ASSESSMENT_RESULT_MESSAGE_SIZE 4 +#define ASSESSMENT_RESULT_MSG_SIZE 4 /** - * Private data of a pb_assessment_result_message_t object. + * Private data of a pb_assessment_result_msg_t object. * */ -struct private_pb_assessment_result_message_t { +struct private_pb_assessment_result_msg_t { /** - * Public pb_assessment_result_message_t interface. + * Public pb_assessment_result_msg_t interface. */ - pb_assessment_result_message_t public; + pb_assessment_result_msg_t public; /** * PB-TNC message type @@ -59,25 +60,25 @@ struct private_pb_assessment_result_message_t { chunk_t encoding; }; -METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t, - private_pb_assessment_result_message_t *this) +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_message_t, get_encoding, chunk_t, - private_pb_assessment_result_message_t *this) +METHOD(pb_tnc_msg_t, get_encoding, chunk_t, + private_pb_assessment_result_msg_t *this) { return this->encoding; } -METHOD(pb_tnc_message_t, build, void, - private_pb_assessment_result_message_t *this) +METHOD(pb_tnc_msg_t, build, void, + private_pb_assessment_result_msg_t *this) { tls_writer_t *writer; /* build message */ - writer = tls_writer_create(ASSESSMENT_RESULT_MESSAGE_SIZE); + writer = tls_writer_create(ASSESSMENT_RESULT_MSG_SIZE); writer->write_uint32(writer, this->assessment_result); free(this->encoding.ptr); this->encoding = writer->get_buf(writer); @@ -85,36 +86,37 @@ METHOD(pb_tnc_message_t, build, void, writer->destroy(writer); } -METHOD(pb_tnc_message_t, process, status_t, - private_pb_assessment_result_message_t *this) +METHOD(pb_tnc_msg_t, process, status_t, + private_pb_assessment_result_msg_t *this, u_int32_t *offset) { tls_reader_t *reader; - if (this->encoding.len < ASSESSMENT_RESULT_MESSAGE_SIZE) - { - DBG1(DBG_TNC,"%N message is shorter than message size of %u bytes", - pb_tnc_msg_type_names, PB_MSG_ASSESSMENT_RESULT, - ASSESSMENT_RESULT_MESSAGE_SIZE); - return FAILED; - } - /* process message */ reader = tls_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_message_t, destroy, void, - private_pb_assessment_result_message_t *this) +METHOD(pb_tnc_msg_t, destroy, void, + private_pb_assessment_result_msg_t *this) { free(this->encoding.ptr); free(this); } -METHOD(pb_assessment_result_message_t, get_assessment_result, u_int32_t, - private_pb_assessment_result_message_t *this) +METHOD(pb_assessment_result_msg_t, get_assessment_result, u_int32_t, + private_pb_assessment_result_msg_t *this) { return this->assessment_result; } @@ -122,9 +124,9 @@ METHOD(pb_assessment_result_message_t, get_assessment_result, u_int32_t, /** * See header */ -pb_tnc_message_t *pb_assessment_result_message_create_from_data(chunk_t data) +pb_tnc_msg_t *pb_assessment_result_msg_create_from_data(chunk_t data) { - private_pb_assessment_result_message_t *this; + private_pb_assessment_result_msg_t *this; INIT(this, .public = { @@ -147,9 +149,9 @@ pb_tnc_message_t *pb_assessment_result_message_create_from_data(chunk_t data) /** * See header */ -pb_tnc_message_t *pb_assessment_result_message_create(u_int32_t assessment_result) +pb_tnc_msg_t *pb_assessment_result_msg_create(u_int32_t assessment_result) { - private_pb_assessment_result_message_t *this; + private_pb_assessment_result_msg_t *this; INIT(this, .public = { diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_message.h b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.h index cec7a292e..74d101521 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_message.h +++ b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.h @@ -14,33 +14,33 @@ */ /** - * @defgroup pb_assessment_result_message pb_assessment_result_message + * @defgroup pb_assessment_result_msg pb_assessment_result_msg * @{ @ingroup tnccs_20 */ -#ifndef PB_ASSESSMENT_RESULT_MESSAGE_H_ -#define PB_ASSESSMENT_RESULT_MESSAGE_H_ +#ifndef PB_ASSESSMENT_RESULT_MSG_H_ +#define PB_ASSESSMENT_RESULT_MSG_H_ -#include "pb_tnc_message.h" +typedef struct pb_assessment_result_msg_t pb_assessment_result_msg_t; -typedef struct pb_assessment_result_message_t pb_assessment_result_message_t; +#include "pb_tnc_msg.h" /** * Classs representing the PB-Assessment-Result message type. */ -struct pb_assessment_result_message_t { +struct pb_assessment_result_msg_t { /** * PB-TNC Message interface */ - pb_tnc_message_t pb_interface; + pb_tnc_msg_t pb_interface; /** * Get PB Assessment result * * @return PB Assessment result */ - u_int32_t (*get_assessment_result)(pb_assessment_result_message_t *this); + u_int32_t (*get_assessment_result)(pb_assessment_result_msg_t *this); }; /** @@ -48,13 +48,13 @@ struct pb_assessment_result_message_t { * * @param assessment_result Assessment result code */ -pb_tnc_message_t* pb_assessment_result_message_create(u_int32_t assessment_result); +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_message_t* pb_assessment_result_message_create_from_data(chunk_t data); +pb_tnc_msg_t* pb_assessment_result_msg_create_from_data(chunk_t data); -#endif /** PB_PA_MESSAGE_H_ @}*/ +#endif /** PB_PA_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_error_message.c b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c index 43355d8b9..e1755c512 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_error_message.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c @@ -13,8 +13,7 @@ * for more details. */ -#include "pb_error_message.h" -#include "../tnccs_20_types.h" +#include "pb_error_msg.h" #include <debug.h> #include <tls_writer.h> @@ -30,7 +29,7 @@ ENUM(pb_tnc_error_code_names, PB_ERROR_UNEXPECTED_BATCH_TYPE, "Version Not Supported" ); -typedef struct private_pb_error_message_t private_pb_error_message_t; +typedef struct private_pb_error_msg_t private_pb_error_msg_t; /** * PB-Error message (see section 4.9 of RFC 5793) @@ -52,14 +51,14 @@ typedef struct private_pb_error_message_t private_pb_error_message_t; #define ERROR_HEADER_SIZE 8 /** - * Private data of a pb_error_message_t object. + * Private data of a pb_error_msg_t object. * */ -struct private_pb_error_message_t { +struct private_pb_error_msg_t { /** - * Public pb_error_message_t interface. + * Public pb_error_msg_t interface. */ - pb_error_message_t public; + pb_error_msg_t public; /** * PB-TNC message type @@ -102,20 +101,20 @@ struct private_pb_error_message_t { refcount_t ref; }; -METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t, - private_pb_error_message_t *this) +METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t, + private_pb_error_msg_t *this) { return this->type; } -METHOD(pb_tnc_message_t, get_encoding, chunk_t, - private_pb_error_message_t *this) +METHOD(pb_tnc_msg_t, get_encoding, chunk_t, + private_pb_error_msg_t *this) { return this->encoding; } -METHOD(pb_tnc_message_t, build, void, - private_pb_error_message_t *this) +METHOD(pb_tnc_msg_t, build, void, + private_pb_error_msg_t *this) { tls_writer_t *writer; @@ -148,8 +147,8 @@ METHOD(pb_tnc_message_t, build, void, writer->destroy(writer); } -METHOD(pb_tnc_message_t, process, status_t, - private_pb_error_message_t *this) +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; @@ -188,15 +187,15 @@ METHOD(pb_tnc_message_t, process, status_t, return SUCCESS; } -METHOD(pb_tnc_message_t, get_ref, pb_tnc_message_t*, - private_pb_error_message_t *this) +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_message_t, destroy, void, - private_pb_error_message_t *this) +METHOD(pb_tnc_msg_t, destroy, void, + private_pb_error_msg_t *this) { if (ref_put(&this->ref)) { @@ -205,55 +204,85 @@ METHOD(pb_tnc_message_t, destroy, void, } } -METHOD(pb_error_message_t, get_fatal_flag, bool, - private_pb_error_message_t *this) +METHOD(pb_error_msg_t, get_fatal_flag, bool, + private_pb_error_msg_t *this) { return this->fatal; } -METHOD(pb_error_message_t, get_vendor_id, u_int32_t, - private_pb_error_message_t *this) +METHOD(pb_error_msg_t, get_vendor_id, u_int32_t, + private_pb_error_msg_t *this) { return this->vendor_id; } -METHOD(pb_error_message_t, get_error_code, u_int16_t, - private_pb_error_message_t *this) +METHOD(pb_error_msg_t, get_error_code, u_int16_t, + private_pb_error_msg_t *this) { return this->error_code; } -METHOD(pb_error_message_t, get_offset, u_int32_t, - private_pb_error_message_t *this) +METHOD(pb_error_msg_t, get_offset, u_int32_t, + private_pb_error_msg_t *this) { return this->error_offset; } -METHOD(pb_error_message_t, set_offset, void, - private_pb_error_message_t *this, u_int32_t offset) +METHOD(pb_error_msg_t, get_bad_version, u_int8_t, + private_pb_error_msg_t *this) { - this->error_offset = offset; + return this->bad_version; } -METHOD(pb_error_message_t, get_bad_version, u_int8_t, - private_pb_error_message_t *this) +METHOD(pb_error_msg_t, set_bad_version, void, + private_pb_error_msg_t *this, u_int8_t version) { - return this->bad_version; + this->bad_version = version; } -METHOD(pb_error_message_t, set_bad_version, void, - private_pb_error_message_t *this, u_int8_t 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) { - this->bad_version = version; + 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_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id, - pb_tnc_error_code_t error_code) +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_message_t *this; + private_pb_error_msg_t *this; INIT(this, .public = { @@ -269,7 +298,6 @@ pb_tnc_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id, .get_vendor_id = _get_vendor_id, .get_error_code = _get_error_code, .get_offset = _get_offset, - .set_offset = _set_offset, .get_bad_version = _get_bad_version, .set_bad_version = _set_bad_version, }, @@ -278,6 +306,7 @@ pb_tnc_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id, .fatal = fatal, .vendor_id = vendor_id, .error_code = error_code, + .error_offset = error_offset, ); return &this->public.pb_interface; @@ -286,9 +315,9 @@ pb_tnc_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id, /** * See header */ -pb_tnc_message_t *pb_error_message_create_from_data(chunk_t data) +pb_tnc_msg_t *pb_error_msg_create_from_data(chunk_t data) { - private_pb_error_message_t *this; + private_pb_error_msg_t *this; INIT(this, .public = { @@ -304,7 +333,6 @@ pb_tnc_message_t *pb_error_message_create_from_data(chunk_t data) .get_vendor_id = _get_vendor_id, .get_error_code = _get_error_code, .get_offset = _get_offset, - .set_offset = _set_offset, .get_bad_version = _get_bad_version, .set_bad_version = _set_bad_version, }, diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_error_message.h b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.h index 1286eab2e..66714123a 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_error_message.h +++ b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.h @@ -14,27 +14,27 @@ */ /** - * @defgroup pb_error_message pb_error_message + * @defgroup pb_error_msg pb_error_msg * @{ @ingroup tnccs_20 */ -#ifndef PB_ERROR_MESSAGE_H_ -#define PB_ERROR_MESSAGE_H_ - -#include "pb_tnc_message.h" +#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_message_t pb_error_message_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_MESSAGE = 3, - PB_ERROR_VERSION_NOT_SUPPORTED = 4 + 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 }; /** @@ -45,61 +45,54 @@ extern enum_name_t *pb_tnc_error_code_names; /** * Classs representing the PB-Error message type. */ -struct pb_error_message_t { +struct pb_error_msg_t { /** * PB-TNC Message interface */ - pb_tnc_message_t pb_interface; + pb_tnc_msg_t pb_interface; /** * Get the fatal flag * * @return fatal flag */ - bool (*get_fatal_flag)(pb_error_message_t *this); + 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_message_t *this); + 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_message_t *this); + 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_message_t *this); - - /** - * Set the PB Error Offset - * - * @param offset PB Error Offset - */ - void (*set_offset)(pb_error_message_t *this, u_int32_t 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_message_t *this); + 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_message_t *this, u_int8_t version); + void (*set_bad_version)(pb_error_msg_t *this, u_int8_t version); }; /** @@ -109,13 +102,26 @@ struct pb_error_message_t { * @param vendor_id Error Code Vendor ID * @param error_code Error Code */ -pb_tnc_message_t* pb_error_message_create(bool fatal, u_int32_t vendor_id, - pb_tnc_error_code_t 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_message_t* pb_error_message_create_from_data(chunk_t data); +pb_tnc_msg_t* pb_error_msg_create_from_data(chunk_t data); -#endif /** PB_PA_MESSAGE_H_ @}*/ +#endif /** PB_PA_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.c new file mode 100644 index 000000000..c78db1cb2 --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.c @@ -0,0 +1,102 @@ +/* + * 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 private_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, size_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); +} diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.h new file mode 100644 index 000000000..fbe93e287 --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/messages/pb_experimental_msg.h @@ -0,0 +1,53 @@ +/* + * 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" + +/** + * Classs 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_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_message.c b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c index 15ea05099..1116dacc4 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_message.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c @@ -13,13 +13,13 @@ * for more details. */ -#include "pb_language_preference_message.h" +#include "pb_language_preference_msg.h" #include <tls_writer.h> #include <tls_reader.h> #include <debug.h> -typedef struct private_pb_language_preference_message_t private_pb_language_preference_message_t; +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) @@ -35,14 +35,14 @@ typedef struct private_pb_language_preference_message_t private_pb_language_pref #define PB_LANG_PREFIX_LEN strlen(PB_LANG_PREFIX) /** - * Private data of a private_pb_language_preference_message_t object. + * Private data of a private_pb_language_preference_msg_t object. * */ -struct private_pb_language_preference_message_t { +struct private_pb_language_preference_msg_t { /** - * Public pb_access_recommendation_message_t interface. + * Public pb_access_recommendation_msg_t interface. */ - pb_language_preference_message_t public; + pb_language_preference_msg_t public; /** * PB-TNC message type @@ -60,28 +60,28 @@ struct private_pb_language_preference_message_t { chunk_t encoding; }; -METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t, - private_pb_language_preference_message_t *this) +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_message_t, get_encoding, chunk_t, - private_pb_language_preference_message_t *this) +METHOD(pb_tnc_msg_t, get_encoding, chunk_t, + private_pb_language_preference_msg_t *this) { return this->encoding; } -METHOD(pb_tnc_message_t, build, void, - private_pb_language_preference_message_t *this) +METHOD(pb_tnc_msg_t, build, void, + private_pb_language_preference_msg_t *this) { this->encoding = chunk_cat("cc", chunk_create(PB_LANG_PREFIX, PB_LANG_PREFIX_LEN), this->language_preference); } -METHOD(pb_tnc_message_t, process, status_t, - private_pb_language_preference_message_t *this) +METHOD(pb_tnc_msg_t, process, status_t, + private_pb_language_preference_msg_t *this, u_int32_t *offset) { chunk_t lang; @@ -90,25 +90,36 @@ METHOD(pb_tnc_message_t, process, status_t, { lang = chunk_skip(this->encoding, PB_LANG_PREFIX_LEN); this->language_preference = lang.len ? chunk_clone(lang) : chunk_empty; - return SUCCESS; } else { - /* TODO generate non-fatal PB-TNC error msg */ - return VERIFY_ERROR; + 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_message_t, destroy, void, - private_pb_language_preference_message_t *this) +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_message_t, get_language_preference, chunk_t, - private_pb_language_preference_message_t *this) +METHOD(pb_language_preference_msg_t, get_language_preference, chunk_t, + private_pb_language_preference_msg_t *this) { return this->language_preference; } @@ -116,9 +127,9 @@ METHOD(pb_language_preference_message_t, get_language_preference, chunk_t, /** * See header */ -pb_tnc_message_t *pb_language_preference_message_create_from_data(chunk_t data) +pb_tnc_msg_t *pb_language_preference_msg_create_from_data(chunk_t data) { - private_pb_language_preference_message_t *this; + private_pb_language_preference_msg_t *this; INIT(this, .public = { @@ -141,9 +152,9 @@ pb_tnc_message_t *pb_language_preference_message_create_from_data(chunk_t data) /** * See header */ -pb_tnc_message_t *pb_language_preference_message_create(chunk_t language_preference) +pb_tnc_msg_t *pb_language_preference_msg_create(chunk_t language_preference) { - private_pb_language_preference_message_t *this; + private_pb_language_preference_msg_t *this; INIT(this, .public = { diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_message.h b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.h index 25d8a578c..c7cf2d8a3 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_message.h +++ b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.h @@ -14,33 +14,33 @@ */ /** - * @defgroup pb_language_preference_message pb_language_preference_message + * @defgroup pb_language_preference_msg pb_language_preference_msg * @{ @ingroup tnccs_20 */ -#ifndef PB_LANGUAGE_PREFERENCE_MESSAGE_H_ -#define PB_LANGUAGE_PREFERENCE_MESSAGE_H_ +#ifndef PB_LANGUAGE_PREFERENCE_MSG_H_ +#define PB_LANGUAGE_PREFERENCE_MSG_H_ -#include "pb_tnc_message.h" +typedef struct pb_language_preference_msg_t pb_language_preference_msg_t; -typedef struct pb_language_preference_message_t pb_language_preference_message_t; +#include "pb_tnc_msg.h" /** * Classs representing the PB-Language-Preference message type. */ -struct pb_language_preference_message_t { +struct pb_language_preference_msg_t { /** * PB-TNC Message interface */ - pb_tnc_message_t pb_interface; + pb_tnc_msg_t pb_interface; /** * Get PB Language Preference * * @return Language preference */ - chunk_t (*get_language_preference)(pb_language_preference_message_t *this); + chunk_t (*get_language_preference)(pb_language_preference_msg_t *this); }; /** @@ -48,13 +48,13 @@ struct pb_language_preference_message_t { * * @param language_preference Preferred language(s) */ -pb_tnc_message_t* pb_language_preference_message_create(chunk_t language_preference); +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_message_t* pb_language_preference_message_create_from_data(chunk_t data); +pb_tnc_msg_t* pb_language_preference_msg_create_from_data(chunk_t data); -#endif /** PB_PA_MESSAGE_H_ @}*/ +#endif /** PB_PA_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_pa_message.c b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c index 0e52c295c..8315bfb76 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_pa_message.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c @@ -15,13 +15,26 @@ * for more details. */ -#include "pb_pa_message.h" +#include "pb_pa_msg.h" #include <tls_writer.h> #include <tls_reader.h> +#include <tnc/tnccs/tnccs.h> #include <debug.h> -typedef struct private_pb_pa_message_t private_pb_pa_message_t; +ENUM(pa_tnc_subtype_names, PA_SUBTYPE_TESTING, PA_SUBTYPE_NEA_CLIENT, + "Testing", + "Operating System", + "Anti-Virus", + "Anti-Spyware", + "Anti-Malware", + "Firewall", + "IDPS", + "VPN", + "NEA Client" +); + +typedef struct private_pb_pa_msg_t private_pb_pa_msg_t; /** * PB-PA message @@ -39,20 +52,20 @@ typedef struct private_pb_pa_message_t private_pb_pa_message_t; * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define PA_FLAG_NONE 0x00 -#define PA_FLAG_EXCL (1<<7) +#define PA_FLAG_NONE 0x00 +#define PA_FLAG_EXCL (1<<7) +#define PA_RESERVED_SUBTYPE 0xffffffff -#define PB_PA_HEADER_SIZE 12 /** - * Private data of a pb_pa_message_t object. + * Private data of a pb_pa_msg_t object. * */ -struct private_pb_pa_message_t { +struct private_pb_pa_msg_t { /** - * Public pb_pa_message_t interface. + * Public pb_pa_msg_t interface. */ - pb_pa_message_t public; + pb_pa_msg_t public; /** * PB-TNC message type @@ -95,26 +108,26 @@ struct private_pb_pa_message_t { chunk_t encoding; }; -METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t, - private_pb_pa_message_t *this) +METHOD(pb_tnc_msg_t, get_type, pb_tnc_msg_type_t, + private_pb_pa_msg_t *this) { return this->type; } -METHOD(pb_tnc_message_t, get_encoding, chunk_t, - private_pb_pa_message_t *this) +METHOD(pb_tnc_msg_t, get_encoding, chunk_t, + private_pb_pa_msg_t *this) { return this->encoding; } -METHOD(pb_tnc_message_t, build, void, - private_pb_pa_message_t *this) +METHOD(pb_tnc_msg_t, build, void, + private_pb_pa_msg_t *this) { chunk_t msg_header; tls_writer_t *writer; /* build message header */ - writer = tls_writer_create(PB_PA_HEADER_SIZE); + writer = tls_writer_create(64); writer->write_uint8 (writer, this->excl ? PA_FLAG_EXCL : PA_FLAG_NONE); writer->write_uint24(writer, this->vendor_id); writer->write_uint32(writer, this->subtype); @@ -128,20 +141,13 @@ METHOD(pb_tnc_message_t, build, void, writer->destroy(writer); } -METHOD(pb_tnc_message_t, process, status_t, - private_pb_pa_message_t *this) +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; tls_reader_t *reader; - if (this->encoding.len < PB_PA_HEADER_SIZE) - { - DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes", - pb_tnc_msg_type_names, PB_MSG_PA, PB_PA_HEADER_SIZE); - return FAILED; - } - /* process message header */ reader = tls_reader_create(this->encoding); reader->read_uint8 (reader, &flags); @@ -159,50 +165,64 @@ METHOD(pb_tnc_message_t, process, status_t, this->msg_body = chunk_clone(this->msg_body); } reader->destroy(reader); + + if (this->vendor_id == RESERVED_VENDOR_ID) + { + DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID); + *offset = 1; + return FAILED; + } + + if (this->subtype == PA_RESERVED_SUBTYPE) + { + DBG1(DBG_TNC, "PA Subtype 0x%08x is reserved", PA_RESERVED_SUBTYPE); + *offset = 4; + } + return SUCCESS; } -METHOD(pb_tnc_message_t, destroy, void, - private_pb_pa_message_t *this) +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_message_t, get_vendor_id, u_int32_t, - private_pb_pa_message_t *this, u_int32_t *subtype) +METHOD(pb_pa_msg_t, get_vendor_id, u_int32_t, + private_pb_pa_msg_t *this, u_int32_t *subtype) { *subtype = this->subtype; return this->vendor_id; } -METHOD(pb_pa_message_t, get_collector_id, u_int16_t, - private_pb_pa_message_t *this) +METHOD(pb_pa_msg_t, get_collector_id, u_int16_t, + private_pb_pa_msg_t *this) { return this->collector_id; } -METHOD(pb_pa_message_t, get_validator_id, u_int16_t, - private_pb_pa_message_t *this) +METHOD(pb_pa_msg_t, get_validator_id, u_int16_t, + private_pb_pa_msg_t *this) { return this->validator_id; } -METHOD(pb_pa_message_t, get_body, chunk_t, - private_pb_pa_message_t *this) +METHOD(pb_pa_msg_t, get_body, chunk_t, + private_pb_pa_msg_t *this) { return this->msg_body; } -METHOD(pb_pa_message_t, get_exclusive_flag, bool, - private_pb_pa_message_t *this) +METHOD(pb_pa_msg_t, get_exclusive_flag, bool, + private_pb_pa_msg_t *this) { return this->excl; } -METHOD(pb_pa_message_t, set_exclusive_flag, void, - private_pb_pa_message_t *this, bool excl) +METHOD(pb_pa_msg_t, set_exclusive_flag, void, + private_pb_pa_msg_t *this, bool excl) { this->excl = excl; } @@ -210,9 +230,9 @@ METHOD(pb_pa_message_t, set_exclusive_flag, void, /** * See header */ -pb_tnc_message_t *pb_pa_message_create_from_data(chunk_t data) +pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data) { - private_pb_pa_message_t *this; + private_pb_pa_msg_t *this; INIT(this, .public = { @@ -239,12 +259,11 @@ pb_tnc_message_t *pb_pa_message_create_from_data(chunk_t data) /** * See header */ -pb_tnc_message_t *pb_pa_message_create(u_int32_t vendor_id, u_int32_t subtype, - u_int16_t collector_id, - u_int16_t validator_id, - chunk_t msg_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, + chunk_t msg_body) { - private_pb_pa_message_t *this; + private_pb_pa_msg_t *this; INIT(this, .public = { diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_pa_message.h b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h index c4c4bccc2..872b22e20 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_pa_message.h +++ b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h @@ -14,26 +14,47 @@ */ /** - * @defgroup pb_pa_message pb_pa_message + * @defgroup pb_pa_msg pb_pa_msg * @{ @ingroup tnccs_20 */ -#ifndef PB_PA_MESSAGE_H_ -#define PB_PA_MESSAGE_H_ +#ifndef PB_PA_MSG_H_ +#define PB_PA_MSG_H_ -#include "pb_tnc_message.h" +typedef enum pa_tnc_subtype_t pa_tnc_subtype_t; +typedef struct pb_pa_msg_t pb_pa_msg_t; -typedef struct pb_pa_message_t pb_pa_message_t; +#include "pb_tnc_msg.h" + +/** + * PA-TNC Subtypes as defined in section 3.5 of RFC 5792 + */ + enum pa_tnc_subtype_t { + PA_SUBTYPE_TESTING = 0, + PA_SUBTYPE_OPERATING_SYSTEM = 1, + PA_SUBTYPE_ANTI_VIRUS = 2, + PA_SUBTYPE_ANTI_SPYWARE = 3, + PA_SUBTYPE_ANTI_MALWARE = 4, + PA_SUBTYPE_FIREWALL = 5, + PA_SUBTYPE_IDPS = 6, + PA_SUBTYPE_VPN = 7, + PA_SUBTYPE_NEA_CLIENT = 8 +}; + +/** + * enum name for pa_tnc_subtype_t. + */ +extern enum_name_t *pa_tnc_subtype_names; /** * Classs representing the PB-PA message type. */ -struct pb_pa_message_t { +struct pb_pa_msg_t { /** * PB-TNC Message interface */ - pb_tnc_message_t pb_interface; + pb_tnc_msg_t pb_interface; /** * Get PA Message Vendor ID and Subtype @@ -41,42 +62,42 @@ struct pb_pa_message_t { * @param subtype PA Subtype * @return PA Message Vendor ID */ - u_int32_t (*get_vendor_id)(pb_pa_message_t *this, u_int32_t *subtype); + u_int32_t (*get_vendor_id)(pb_pa_msg_t *this, u_int32_t *subtype); /** * Get Posture Collector ID * * @return Posture Collector ID */ - u_int16_t (*get_collector_id)(pb_pa_message_t *this); + 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_message_t *this); + 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_message_t *this); + chunk_t (*get_body)(pb_pa_msg_t *this); /** * Get the exclusive flag * * @return exclusive flag */ - bool (*get_exclusive_flag)(pb_pa_message_t *this); + bool (*get_exclusive_flag)(pb_pa_msg_t *this); /** * Set the exclusive flag * * @param excl vexclusive flag */ - void (*set_exclusive_flag)(pb_pa_message_t *this, bool excl); + void (*set_exclusive_flag)(pb_pa_msg_t *this, bool excl); }; /** @@ -88,16 +109,15 @@ struct pb_pa_message_t { * @param validator_id Posture Validator ID * @param msg_body PA Message Body */ -pb_tnc_message_t *pb_pa_message_create(u_int32_t vendor_id, u_int32_t subtype, - u_int16_t collector_id, - u_int16_t validator_id, - chunk_t msg_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, + chunk_t msg_body); /** * Create an unprocessed PB-PA message from raw data * * @param data PB-PA message data */ -pb_tnc_message_t* pb_pa_message_create_from_data(chunk_t data); +pb_tnc_msg_t* pb_pa_msg_create_from_data(chunk_t data); -#endif /** PB_PA_MESSAGE_H_ @}*/ +#endif /** PB_PA_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_message.c b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c index 1cfbb60bd..6e05c5033 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_message.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c @@ -13,13 +13,13 @@ * for more details. */ -#include "pb_reason_string_message.h" +#include "pb_reason_string_msg.h" #include <tls_writer.h> #include <tls_reader.h> #include <debug.h> -typedef struct private_pb_reason_string_message_t private_pb_reason_string_message_t; +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) @@ -35,17 +35,15 @@ typedef struct private_pb_reason_string_message_t private_pb_reason_string_messa * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define REASON_STRING_HEADER_SIZE 5 - /** - * Private data of a private_pb_reason_string_message_t object. + * Private data of a private_pb_reason_string_msg_t object. * */ -struct private_pb_reason_string_message_t { +struct private_pb_reason_string_msg_t { /** - * Public pb_reason_string_message_t interface. + * Public pb_reason_string_msg_t interface. */ - pb_reason_string_message_t public; + pb_reason_string_msg_t public; /** * PB-TNC message type @@ -68,30 +66,27 @@ struct private_pb_reason_string_message_t { chunk_t encoding; }; -METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t, - private_pb_reason_string_message_t *this) +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_message_t, get_encoding, chunk_t, - private_pb_reason_string_message_t *this) +METHOD(pb_tnc_msg_t, get_encoding, chunk_t, + private_pb_reason_string_msg_t *this) { return this->encoding; } -METHOD(pb_tnc_message_t, build, void, - private_pb_reason_string_message_t *this) +METHOD(pb_tnc_msg_t, build, void, + private_pb_reason_string_msg_t *this) { tls_writer_t *writer; /* build message */ - writer = tls_writer_create(REASON_STRING_HEADER_SIZE); - writer->write_uint32(writer, this->reason_string.len); - writer->write_data(writer, this->reason_string); - - writer->write_uint8(writer, this->language_code.len); - writer->write_data(writer, this->language_code); + writer = tls_writer_create(64); + writer->write_data32(writer, this->reason_string); + writer->write_data8 (writer, this->language_code); free(this->encoding.ptr); this->encoding = writer->get_buf(writer); @@ -99,41 +94,54 @@ METHOD(pb_tnc_message_t, build, void, writer->destroy(writer); } -METHOD(pb_tnc_message_t, process, status_t, - private_pb_reason_string_message_t *this) +METHOD(pb_tnc_msg_t, process, status_t, + private_pb_reason_string_msg_t *this, u_int32_t *offset) { tls_reader_t *reader; - if (this->encoding.len < REASON_STRING_HEADER_SIZE) - { - DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes", - pb_tnc_msg_type_names, PB_MSG_REASON_STRING, - REASON_STRING_HEADER_SIZE); - return FAILED; - } - /* process message */ reader = tls_reader_create(this->encoding); if (!reader->read_data32(reader, &this->reason_string)) { - DBG1(DBG_TNC, "Could not parse 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"); + 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_message_t, destroy, void, - private_pb_reason_string_message_t *this) +METHOD(pb_tnc_msg_t, destroy, void, + private_pb_reason_string_msg_t *this) { free(this->encoding.ptr); free(this->reason_string.ptr); @@ -141,14 +149,14 @@ METHOD(pb_tnc_message_t, destroy, void, free(this); } -METHOD(pb_reason_string_message_t, get_reason_string, chunk_t, - private_pb_reason_string_message_t *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_message_t, get_language_code, chunk_t, - private_pb_reason_string_message_t *this) +METHOD(pb_reason_string_msg_t, get_language_code, chunk_t, + private_pb_reason_string_msg_t *this) { return this->language_code; } @@ -156,9 +164,9 @@ METHOD(pb_reason_string_message_t, get_language_code, chunk_t, /** * See header */ -pb_tnc_message_t *pb_reason_string_message_create_from_data(chunk_t data) +pb_tnc_msg_t *pb_reason_string_msg_create_from_data(chunk_t data) { - private_pb_reason_string_message_t *this; + private_pb_reason_string_msg_t *this; INIT(this, .public = { @@ -182,10 +190,10 @@ pb_tnc_message_t *pb_reason_string_message_create_from_data(chunk_t data) /** * See header */ -pb_tnc_message_t *pb_reason_string_message_create(chunk_t reason_string, - chunk_t language_code) +pb_tnc_msg_t *pb_reason_string_msg_create(chunk_t reason_string, + chunk_t language_code) { - private_pb_reason_string_message_t *this; + private_pb_reason_string_msg_t *this; INIT(this, .public = { diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_message.h b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.h index 2245e33bc..791c72b7f 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_message.h +++ b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.h @@ -14,40 +14,40 @@ */ /** - * @defgroup pb_reason_string_message pb_reason_string_message + * @defgroup pb_reason_string_msg pb_reason_string_msg * @{ @ingroup tnccs_20 */ -#ifndef PB_REASON_STRING_MESSAGE_H_ -#define PB_REASON_STRING_MESSAGE_H_ +#ifndef PB_REASON_STRING_MSG_H_ +#define PB_REASON_STRING_MSG_H_ -#include "pb_tnc_message.h" +typedef struct pb_reason_string_msg_t pb_reason_string_msg_t; -typedef struct pb_reason_string_message_t pb_reason_string_message_t; +#include "pb_tnc_msg.h" /** * Classs representing the PB-Reason-String message type. */ -struct pb_reason_string_message_t { +struct pb_reason_string_msg_t { /** * PB-TNC Message interface */ - pb_tnc_message_t pb_interface; + pb_tnc_msg_t pb_interface; /** * Get Reason String * * @return Reason string */ - chunk_t (*get_reason_string)(pb_reason_string_message_t *this); + 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_message_t *this); + chunk_t (*get_language_code)(pb_reason_string_msg_t *this); }; /** @@ -56,14 +56,14 @@ struct pb_reason_string_message_t { * @param reason_string Reason string * @param language_code Language code */ -pb_tnc_message_t* pb_reason_string_message_create(chunk_t reason_string, - chunk_t 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_message_t* pb_reason_string_message_create_from_data(chunk_t data); +pb_tnc_msg_t* pb_reason_string_msg_create_from_data(chunk_t data); -#endif /** PB_PA_MESSAGE_H_ @}*/ +#endif /** PB_PA_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c new file mode 100644 index 000000000..96a675045 --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c @@ -0,0 +1,259 @@ +/* + * 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 <tls_writer.h> +#include <tls_reader.h> +#include <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 private_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 Vendor ID + */ + u_int32_t vendor_id; + + /** + * Remediation Parameters Type + */ + u_int32_t parameters_type; + + /** + * Remediation Parameters string + */ + chunk_t remediation_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_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) +{ + tls_writer_t *writer; + + /* build message */ + writer = tls_writer_create(64); + writer->write_uint32(writer, this->vendor_id); + writer->write_uint32(writer, this->parameters_type); + writer->write_data32(writer, this->remediation_string); + writer->write_data8 (writer, this->language_code); + + free(this->encoding.ptr); + 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, size_t *offset) +{ + tls_reader_t *reader; + + /* process message */ + reader = tls_reader_create(this->encoding); + reader->read_uint32(reader, &this->vendor_id); + reader->read_uint32(reader, &this->parameters_type); + + if (!reader->read_data32(reader, &this->remediation_string)) + { + DBG1(DBG_TNC, "could not parse remediation string"); + reader->destroy(reader); + *offset = 8; + return FAILED; + }; + this->remediation_string = chunk_clone(this->remediation_string); + + if (this->remediation_string.len && + this->remediation_string.ptr[this->remediation_string.len-1] == '\0') + { + DBG1(DBG_TNC, "remediation string must not be null terminated"); + reader->destroy(reader); + *offset = 11 + this->remediation_string.len; + return FAILED; + } + + if (!reader->read_data8(reader, &this->language_code)) + { + DBG1(DBG_TNC, "could not parse language code"); + reader->destroy(reader); + *offset = 12 + this->remediation_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 = 12 + this->remediation_string.len + this->language_code.len; + return FAILED; + } + + return SUCCESS; +} + +METHOD(pb_tnc_msg_t, destroy, void, + private_pb_remediation_parameters_msg_t *this) +{ + free(this->encoding.ptr); + free(this->remediation_string.ptr); + free(this->language_code.ptr); + free(this); +} + +METHOD(pb_remediation_parameters_msg_t, get_vendor_id, u_int32_t, + private_pb_remediation_parameters_msg_t *this, u_int32_t *type) +{ + *type = this->parameters_type; + return this->vendor_id; +} + +METHOD(pb_remediation_parameters_msg_t, get_remediation_string, chunk_t, + private_pb_remediation_parameters_msg_t *this) +{ + return this->remediation_string; +} + +METHOD(pb_remediation_parameters_msg_t, get_language_code, chunk_t, + private_pb_remediation_parameters_msg_t *this) +{ + return this->language_code; +} + +/** + * 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_vendor_id = _get_vendor_id, + .get_remediation_string = _get_remediation_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_remediation_parameters_msg_create(u_int32_t vendor_id, + u_int32_t type, + chunk_t remediation_string, + chunk_t language_code) +{ + 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_vendor_id = _get_vendor_id, + .get_remediation_string = _get_remediation_string, + .get_language_code = _get_language_code, + }, + .type = PB_MSG_REASON_STRING, + .vendor_id = vendor_id, + .parameters_type = type, + .remediation_string = chunk_clone(remediation_string), + .language_code = chunk_clone(language_code), + ); + + return &this->public.pb_interface; +} diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.h new file mode 100644 index 000000000..eb9562516 --- /dev/null +++ b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.h @@ -0,0 +1,96 @@ +/* + * 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_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" + +/** + * 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; + +/** + * Classs representing the PB-Remediation-Parameters message type. + */ +struct pb_remediation_parameters_msg_t { + + /** + * PB-TNC Message interface + */ + pb_tnc_msg_t pb_interface; + + /** + * Get Remediation Parameters Vendor ID and Type + * + * @param type Remediation Parameters Type + * @return Remediation Parameters Vendor ID + */ + u_int32_t (*get_vendor_id)(pb_remediation_parameters_msg_t *this, + u_int32_t *type); + + /** + * Get Remediation String + * + * @return Remediation String + */ + chunk_t (*get_remediation_string)(pb_remediation_parameters_msg_t *this); + + /** + * Get Reason String Language Code + * + * @return Language Code + */ + chunk_t (*get_language_code)(pb_remediation_parameters_msg_t *this); +}; + +/** + * Create a PB-Remediation-Parameters message from parameters + * + * @param vendor_id Remediation Parameters Vendor ID + * @param type Remediation Parameters Type + * @param remediation_string Remediation String + * @param language_code Language Code + */ +pb_tnc_msg_t* pb_remediation_parameters_msg_create(u_int32_t vendor_id, + u_int32_t type, + chunk_t remediation_string, + chunk_t language_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_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_tnc_message.c b/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.c index 989193342..3565c2d84 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_tnc_message.c +++ b/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.c @@ -13,13 +13,15 @@ * for more details. */ -#include "pb_tnc_message.h" -#include "pb_pa_message.h" -#include "pb_error_message.h" -#include "pb_language_preference_message.h" -#include "pb_assessment_result_message.h" -#include "pb_access_recommendation_message.h" -#include "pb_reason_string_message.h" +#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> @@ -34,29 +36,40 @@ ENUM(pb_tnc_msg_type_names, PB_MSG_EXPERIMENTAL, PB_MSG_REASON_STRING, "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_message_t* pb_tnc_message_create(pb_tnc_msg_type_t type, chunk_t value) +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_message_create_from_data(value); + return pb_pa_msg_create_from_data(value); case PB_MSG_ERROR: - return pb_error_message_create_from_data(value); + return pb_error_msg_create_from_data(value); case PB_MSG_EXPERIMENTAL: - return NULL; + return pb_experimental_msg_create_from_data(value); case PB_MSG_LANGUAGE_PREFERENCE: - return pb_language_preference_message_create_from_data(value); + return pb_language_preference_msg_create_from_data(value); case PB_MSG_ASSESSMENT_RESULT: - return pb_assessment_result_message_create_from_data(value); + return pb_assessment_result_msg_create_from_data(value); case PB_MSG_ACCESS_RECOMMENDATION: - return pb_access_recommendation_message_create_from_data(value); + return pb_access_recommendation_msg_create_from_data(value); case PB_MSG_REMEDIATION_PARAMETERS: - return NULL; + return pb_remediation_parameters_msg_create_from_data(value); case PB_MSG_REASON_STRING: - return pb_reason_string_message_create_from_data(value); + return pb_reason_string_msg_create_from_data(value); } return NULL; } diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_tnc_message.h b/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.h index 729f22ef1..7b7566dab 100644 --- a/src/libcharon/plugins/tnccs_20/messages/pb_tnc_message.h +++ b/src/libcharon/plugins/tnccs_20/messages/pb_tnc_msg.h @@ -14,17 +14,20 @@ */ /** - * @defgroup pb_tnc_message pb_tnc_message + * @defgroup pb_tnc_msg pb_tnc_msg * @{ @ingroup tnccs_20 */ -#ifndef PB_TNC_MESSAGE_H_ -#define PB_TNC_MESSAGE_H_ +#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> -#include <tnccs_20_types.h> -typedef enum pb_tnc_msg_type_t pb_tnc_msg_type_t; +#define PB_TNC_VERSION 2 /** * PB-TNC Message Types as defined in section 4.3 of RFC 5793 @@ -46,7 +49,22 @@ enum pb_tnc_msg_type_t { */ extern enum_name_t *pb_tnc_msg_type_names; -typedef struct pb_tnc_message_t pb_tnc_message_t; +/** + * 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; + bool 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. @@ -54,45 +72,46 @@ typedef struct pb_tnc_message_t pb_tnc_message_t; * To handle all messages in a generic way, this interface * must be implemented by each message type. */ -struct pb_tnc_message_t { +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_message_t *this); + 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_message_t *this); + chunk_t (*get_encoding)(pb_tnc_msg_t *this); /** * Build the PB-TNC Message Value */ - void (*build)(pb_tnc_message_t *this); + 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_message_t *this); + 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_message_t* (*get_ref)(pb_tnc_message_t *this); + pb_tnc_msg_t* (*get_ref)(pb_tnc_msg_t *this); /** - * Destroys a pb_tnc_message_t object. + * Destroys a pb_tnc_msg_t object. */ - void (*destroy)(pb_tnc_message_t *this); + void (*destroy)(pb_tnc_msg_t *this); }; /** @@ -104,6 +123,6 @@ struct pb_tnc_message_t { * @param type PB-TNC message type * @param value PB-TNC message value */ -pb_tnc_message_t* pb_tnc_message_create(pb_tnc_msg_type_t type, chunk_t value); +pb_tnc_msg_t* pb_tnc_msg_create_from_data(pb_tnc_msg_type_t type, chunk_t value); -#endif /** PB_TNC_MESSAGE_H_ @}*/ +#endif /** PB_TNC_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c b/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c index 4cca60f5e..a46dc0ab9 100644 --- a/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c +++ b/src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c @@ -14,13 +14,8 @@ */ #include "pb_tnc_state_machine.h" -#include "messages/pb_error_message.h" #include <debug.h> -#include <utils/linked_list.h> -#include <tls_writer.h> -#include <tls_reader.h> -#include <tnc/tnccs/tnccs.h> ENUM(pb_tnc_state_names, PB_STATE_INIT, PB_STATE_END, "Init", diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20.c b/src/libcharon/plugins/tnccs_20/tnccs_20.c index 134641d46..235163261 100644 --- a/src/libcharon/plugins/tnccs_20/tnccs_20.c +++ b/src/libcharon/plugins/tnccs_20/tnccs_20.c @@ -15,15 +15,15 @@ */ #include "tnccs_20.h" -#include "tnccs_20_types.h" #include "batch/pb_tnc_batch.h" -#include "messages/pb_tnc_message.h" -#include "messages/pb_pa_message.h" -#include "messages/pb_error_message.h" -#include "messages/pb_assessment_result_message.h" -#include "messages/pb_access_recommendation_message.h" -#include "messages/pb_reason_string_message.h" -#include "messages/pb_language_preference_message.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 <debug.h> @@ -71,6 +71,11 @@ struct private_tnccs_20_t { mutex_t *mutex; /** + * Flag set while processingn + */ + bool fatal_error; + + /** * Flag set by IMC/IMV RequestHandshakeRetry() function */ bool request_handshake_retry; @@ -81,7 +86,7 @@ struct private_tnccs_20_t { recommendations_t *recs; }; -METHOD(tnccs_t, send_message, void, +METHOD(tnccs_t, send_msg, void, private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id, TNC_BufferReference msg, TNC_UInt32 msg_len, @@ -89,13 +94,13 @@ METHOD(tnccs_t, send_message, void, { TNC_MessageSubtype msg_sub_type; TNC_VendorID msg_vendor_id; - pb_tnc_message_t *pb_tnc_msg; + pb_tnc_msg_t *pb_tnc_msg; pb_tnc_batch_type_t batch_type; msg_sub_type = msg_type & TNC_SUBTYPE_ANY; msg_vendor_id = (msg_type >> 8) & TNC_VENDORID_ANY; - pb_tnc_msg = pb_pa_message_create(msg_vendor_id, msg_sub_type, imc_id, imv_id, + pb_tnc_msg = pb_pa_msg_create(msg_vendor_id, msg_sub_type, imc_id, imv_id, chunk_create(msg, msg_len)); /* adding PA message to SDATA or CDATA batch only */ @@ -107,7 +112,7 @@ METHOD(tnccs_t, send_message, void, } if (this->batch->get_type(this->batch) == batch_type) { - this->batch->add_message(this->batch, pb_tnc_msg); + this->batch->add_msg(this->batch, pb_tnc_msg); } else { @@ -119,21 +124,21 @@ METHOD(tnccs_t, send_message, void, /** * Handle a single PB-TNC message according to its type */ -static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg) +static void handle_msg(private_tnccs_20_t *this, pb_tnc_msg_t *msg) { switch (msg->get_type(msg)) { case PB_MSG_EXPERIMENTAL: - /* for experiments */ + /* nothing to do */ break; case PB_MSG_PA: { - pb_pa_message_t *pa_msg; + pb_pa_msg_t *pa_msg; TNC_MessageType msg_type; u_int32_t vendor_id, subtype; chunk_t msg_body; - pa_msg = (pb_pa_message_t*)msg; + pa_msg = (pb_pa_msg_t*)msg; vendor_id = pa_msg->get_vendor_id(pa_msg, &subtype); msg_type = (vendor_id << 8) | (subtype & 0xff); msg_body = pa_msg->get_body(pa_msg); @@ -154,10 +159,10 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg) } case PB_MSG_ASSESSMENT_RESULT: { - pb_assessment_result_message_t *assess_msg; + pb_assessment_result_msg_t *assess_msg; u_int32_t result; - assess_msg = (pb_assessment_result_message_t*)msg; + assess_msg = (pb_assessment_result_msg_t*)msg; result = assess_msg->get_assessment_result(assess_msg); DBG1(DBG_TNC, "assessment result is '%N'", evaluation_result_names, result); @@ -165,13 +170,13 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg) } case PB_MSG_ACCESS_RECOMMENDATION: { - pb_access_recommendation_message_t *rec_msg; - u_int16_t rec; + pb_access_recommendation_msg_t *rec_msg; + pb_access_recommendation_code_t rec; - rec_msg = (pb_access_recommendation_message_t*)msg; + rec_msg = (pb_access_recommendation_msg_t*)msg; rec = rec_msg->get_access_recommendation(rec_msg); DBG1(DBG_TNC, "access recommendation is '%N'", - action_recommendation_names, rec); + pb_access_recommendation_code_names, rec); break; } case PB_MSG_REMEDIATION_PARAMETERS: @@ -181,22 +186,27 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg) } case PB_MSG_ERROR: { - pb_error_message_t *err_msg; + pb_error_msg_t *err_msg; bool fatal; u_int32_t vendor_id; u_int16_t error_code; - err_msg = (pb_error_message_t*)msg; + 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 == IETF_VENDOR_ID) { switch (error_code) { case PB_ERROR_INVALID_PARAMETER: - case PB_ERROR_UNSUPPORTED_MANDATORY_MESSAGE: + case PB_ERROR_UNSUPPORTED_MANDATORY_MSG: DBG1(DBG_TNC, "received %s PB-TNC Error '%N' " "(offset %u bytes)", fatal ? "fatal" : "non-fatal", @@ -230,10 +240,10 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg) } case PB_MSG_LANGUAGE_PREFERENCE: { - pb_language_preference_message_t *lang_msg; + pb_language_preference_msg_t *lang_msg; chunk_t lang; - lang_msg = (pb_language_preference_message_t*)msg; + lang_msg = (pb_language_preference_msg_t*)msg; lang = lang_msg->get_language_preference(lang_msg); DBG2(DBG_TNC, "setting language preference to '%.*s'", @@ -243,10 +253,10 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_message_t *msg) } case PB_MSG_REASON_STRING: { - pb_reason_string_message_t *reason_msg; + pb_reason_string_msg_t *reason_msg; chunk_t reason_string, language_code; - reason_msg = (pb_reason_string_message_t*)msg; + 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); DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len, @@ -280,14 +290,14 @@ METHOD(tls_t, process, status_t, { chunk_t data; pb_tnc_batch_t *batch; - pb_tnc_message_t *msg; + pb_tnc_msg_t *msg; enumerator_t *enumerator; status_t status; if (this->is_server && !this->connection_id) { this->connection_id = charon->tnccs->create_connection(charon->tnccs, - (tnccs_t*)this, _send_message, + (tnccs_t*)this, _send_msg, &this->request_handshake_retry, &this->recs); if (!this->connection_id) { @@ -307,7 +317,7 @@ METHOD(tls_t, process, status_t, if (status != FAILED) { enumerator_t *enumerator; - pb_tnc_message_t *msg; + pb_tnc_msg_t *msg; pb_tnc_batch_type_t batch_type; bool empty = TRUE; @@ -331,7 +341,7 @@ METHOD(tls_t, process, status_t, enumerator = batch->create_msg_enumerator(batch); while (enumerator->enumerate(enumerator, &msg)) { - handle_message(this, msg); + handle_msg(this, msg); empty = FALSE; } enumerator->destroy(enumerator); @@ -340,7 +350,16 @@ METHOD(tls_t, process, status_t, if (this->is_server && batch_type == PB_BATCH_CLOSE && empty) { batch->destroy(batch); - return SUCCESS; + if (this->fatal_error) + { + DBG1(DBG_TNC, "a fatal PB-TNC Error occurred, " + "terminating connection"); + return FAILED; + } + else + { + return SUCCESS; + } } if (this->is_server) @@ -356,6 +375,7 @@ METHOD(tls_t, process, status_t, switch (status) { case FAILED: + this->fatal_error = TRUE; this->mutex->lock(this->mutex); if (this->batch) { @@ -371,7 +391,7 @@ METHOD(tls_t, process, status_t, while (enumerator->enumerate(enumerator, &msg)) { this->mutex->lock(this->mutex); - this->batch->add_message(this->batch, msg->get_ref(msg)); + this->batch->add_msg(this->batch, msg->get_ref(msg)); this->mutex->unlock(this->mutex); } enumerator->destroy(enumerator); @@ -395,7 +415,7 @@ static void check_and_build_recommendation(private_tnccs_20_t *this) TNC_IMVID id; chunk_t reason, language; enumerator_t *enumerator; - pb_tnc_message_t *msg; + pb_tnc_msg_t *msg; if (!this->recs->have_recommendation(this->recs, &rec, &eval)) { @@ -405,17 +425,21 @@ static void check_and_build_recommendation(private_tnccs_20_t *this) { this->batch = pb_tnc_batch_create(this->is_server, PB_BATCH_RESULT); - msg = pb_assessment_result_message_create(eval); - this->batch->add_message(this->batch, msg); + msg = pb_assessment_result_msg_create(eval); + this->batch->add_msg(this->batch, msg); - msg = pb_access_recommendation_message_create(rec); - this->batch->add_message(this->batch, msg); + /** + * IMV Action Recommendation and PB Access Recommendation codes + * are shifted by one. + */ + msg = pb_access_recommendation_msg_create(rec + 1); + this->batch->add_msg(this->batch, msg); enumerator = this->recs->create_reason_enumerator(this->recs); while (enumerator->enumerate(enumerator, &id, &reason, &language)) { - msg = pb_reason_string_message_create(reason, language); - this->batch->add_message(this->batch, msg); + msg = pb_reason_string_msg_create(reason, language); + this->batch->add_msg(this->batch, msg); } enumerator->destroy(enumerator); } @@ -429,11 +453,11 @@ METHOD(tls_t, build, status_t, /* Initialize the connection */ if (!this->is_server && !this->connection_id) { - pb_tnc_message_t *msg; + pb_tnc_msg_t *msg; char *pref_lang; this->connection_id = charon->tnccs->create_connection(charon->tnccs, - (tnccs_t*)this, _send_message, + (tnccs_t*)this, _send_msg, &this->request_handshake_retry, NULL); if (!this->connection_id) { @@ -442,11 +466,11 @@ METHOD(tls_t, build, status_t, /* Create PB-TNC Language Preference Message */ pref_lang = charon->imcs->get_preferred_language(charon->imcs); - msg = pb_language_preference_message_create(chunk_create(pref_lang, + msg = pb_language_preference_msg_create(chunk_create(pref_lang, strlen(pref_lang))); this->mutex->lock(this->mutex); this->batch = pb_tnc_batch_create(this->is_server, PB_BATCH_CDATA); - this->batch->add_message(this->batch, msg); + this->batch->add_msg(this->batch, msg); this->mutex->unlock(this->mutex); charon->imcs->notify_connection_change(charon->imcs, @@ -456,6 +480,13 @@ METHOD(tls_t, build, status_t, charon->imcs->begin_handshake(charon->imcs, this->connection_id); } + if (this->is_server && this->fatal_error && + this->state_machine->get_state(this->state_machine) == 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); diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20_types.c b/src/libcharon/plugins/tnccs_20/tnccs_20_types.c deleted file mode 100644 index d555a5052..000000000 --- a/src/libcharon/plugins/tnccs_20/tnccs_20_types.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010 Sansar Choinynambuu - * 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_types.h" - -ENUM(pb_tnc_remed_param_type_names, PB_REMEDIATION_URI, PB_REMEDIATION_STRING, - "Remediation-URI", - "Remediation-String" -); - -ENUM(pa_tnc_subtype_names, PA_SUBTYPE_TESTING, PA_SUBTYPE_NEA_CLIENT, - "Testing", - "Operating System", - "Anti-Virus", - "Anti-Spyware", - "Anti-Malware", - "Firewall", - "IDPS", - "VPN", - "NEA Client" -); diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20_types.h b/src/libcharon/plugins/tnccs_20/tnccs_20_types.h deleted file mode 100644 index 78bd9a2f4..000000000 --- a/src/libcharon/plugins/tnccs_20/tnccs_20_types.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2010 Sansar Choinynambuu - * 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_types_h tnccs_20 - * @{ @ingroup tnccs_20 - */ - -#ifndef TNCCS_20_TYPES_H_ -#define TNCCS_20_TYPES_H_ - -#define PB_TNC_VERSION 2 - -#include <library.h> - -typedef enum pb_tnc_remed_param_type_t pb_tnc_remed_param_type_t; -typedef enum pa_tnc_subtype_t pa_tnc_subtype_t; - -/** - * 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; - -/** - * PA-TNC Subtypes as defined in section 3.5 of RFC 5792 - */ - enum pa_tnc_subtype_t { - PA_SUBTYPE_TESTING = 0, - PA_SUBTYPE_OPERATING_SYSTEM = 1, - PA_SUBTYPE_ANTI_VIRUS = 2, - PA_SUBTYPE_ANTI_SPYWARE = 3, - PA_SUBTYPE_ANTI_MALWARE = 4, - PA_SUBTYPE_FIREWALL = 5, - PA_SUBTYPE_IDPS = 6, - PA_SUBTYPE_VPN = 7, - PA_SUBTYPE_NEA_CLIENT = 8 -}; - -/** - * enum name for pa_tnc_subtype_t. - */ -extern enum_name_t *pa_tnc_subtype_names; - -#endif /** TNCCS_20_TYPES_H_ @}*/ |