diff options
Diffstat (limited to 'src/libimcv')
-rw-r--r-- | src/libimcv/ietf/ietf_attr_pa_tnc_error.c | 94 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_remediation_instr.c | 16 | ||||
-rw-r--r-- | src/libimcv/imc/imc_agent.c | 2 | ||||
-rw-r--r-- | src/libimcv/imc/imc_msg.c | 8 | ||||
-rw-r--r-- | src/libimcv/imc/imc_msg.h | 7 | ||||
-rw-r--r-- | src/libimcv/imv/imv_agent.c | 111 | ||||
-rw-r--r-- | src/libimcv/imv/imv_msg.c | 7 | ||||
-rw-r--r-- | src/libimcv/imv/imv_msg.h | 7 | ||||
-rw-r--r-- | src/libimcv/os_info/os_info.c | 2 | ||||
-rw-r--r-- | src/libimcv/pa_tnc/pa_tnc_msg.c | 12 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_os/imv_os.c | 22 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_os/imv_os_state.c | 19 | ||||
-rw-r--r-- | src/libimcv/plugins/imv_os/imv_os_state.h | 15 |
13 files changed, 242 insertions, 80 deletions
diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c index f92022fe0..cc3ec28c5 100644 --- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c @@ -325,22 +325,12 @@ METHOD(ietf_attr_pa_tnc_error_t, get_offset, u_int32_t, } /** - * Described in header. + * Generic constructor */ -pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_type_t error_code, - chunk_t msg_info) +static private_ietf_attr_pa_tnc_error_t* create_generic() { private_ietf_attr_pa_tnc_error_t *this; - if (error_code.vendor_id == PEN_IETF) - { - msg_info.len = PA_ERROR_MSG_INFO_SIZE; - } - else if (msg_info.len > PA_ERROR_MSG_INFO_MAX_SIZE) - { - msg_info.len = PA_ERROR_MSG_INFO_MAX_SIZE; - } - INIT(this, .public = { .pa_tnc_attribute = { @@ -360,11 +350,33 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_type_t error_code, .get_offset = _get_offset, }, .type = { PEN_IETF, IETF_ATTR_PA_TNC_ERROR }, - .error_code = error_code, - .msg_info = chunk_clone(msg_info), .ref = 1, ); + return this; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_type_t error_code, + chunk_t msg_info) +{ + private_ietf_attr_pa_tnc_error_t *this; + + if (error_code.vendor_id == PEN_IETF) + { + msg_info.len = PA_ERROR_MSG_INFO_SIZE; + } + else if (msg_info.len > PA_ERROR_MSG_INFO_MAX_SIZE) + { + msg_info.len = PA_ERROR_MSG_INFO_MAX_SIZE; + } + + this = create_generic(); + this->error_code = error_code; + this->msg_info = chunk_clone(msg_info); + return &this->public.pa_tnc_attribute; } @@ -380,30 +392,10 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code, /* the first 8 bytes of the erroneous PA-TNC message are sent back */ msg_info.len = PA_ERROR_MSG_INFO_SIZE; - INIT(this, - .public = { - .pa_tnc_attribute = { - .get_type = _get_type, - .get_value = _get_value, - .get_noskip_flag = _get_noskip_flag, - .set_noskip_flag = _set_noskip_flag, - .build = _build, - .process = _process, - .get_ref = _get_ref, - .destroy = _destroy, - }, - .get_error_code = _get_error_code, - .get_msg_info = _get_msg_info, - .get_attr_info = _get_attr_info, - .set_attr_info = _set_attr_info, - .get_offset = _get_offset, - }, - .type = { PEN_IETF, IETF_ATTR_PA_TNC_ERROR }, - .error_code = error_code, - .msg_info = chunk_clone(msg_info), - .error_offset = error_offset, - .ref = 1, - ); + this = create_generic(); + this->error_code = error_code; + this->msg_info = chunk_clone(msg_info); + this->error_offset = error_offset; return &this->public.pa_tnc_attribute; } @@ -415,30 +407,8 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_from_data(chunk_t data) { private_ietf_attr_pa_tnc_error_t *this; - INIT(this, - .public = { - .pa_tnc_attribute = { - .get_type = _get_type, - .get_value = _get_value, - .get_noskip_flag = _get_noskip_flag, - .set_noskip_flag = _set_noskip_flag, - .build = _build, - .process = _process, - .get_ref = _get_ref, - .destroy = _destroy, - }, - .get_error_code = _get_error_code, - .get_msg_info = _get_msg_info, - .get_attr_info = _get_attr_info, - .set_attr_info = _set_attr_info, - .get_offset = _get_offset, - }, - .type = { PEN_IETF, IETF_ATTR_PA_TNC_ERROR }, - .value = chunk_clone(data), - .ref = 1, - ); + this = create_generic(); + this->value = chunk_clone(data); return &this->public.pa_tnc_attribute; } - - diff --git a/src/libimcv/ietf/ietf_attr_remediation_instr.c b/src/libimcv/ietf/ietf_attr_remediation_instr.c index f3b4e83dd..d28631ec7 100644 --- a/src/libimcv/ietf/ietf_attr_remediation_instr.c +++ b/src/libimcv/ietf/ietf_attr_remediation_instr.c @@ -194,14 +194,16 @@ METHOD(pa_tnc_attr_t, process, status_t, DBG1(DBG_TNC, "insufficient data for IETF remediation string"); goto end; } + *offset += 4; + pos = memchr(this->string.ptr, '\0', this->string.len); if (pos) { DBG1(DBG_TNC, "nul termination in IETF remediation string"); - *offset += 1 + (pos - this->string.ptr); + *offset += (pos - this->string.ptr); goto end; } - *offset += 4 + this->string.len; + *offset += this->string.len; if (!reader->read_data8(reader, &this->lang_code)) { @@ -246,12 +248,6 @@ METHOD(ietf_attr_remediation_instr_t, get_parameters, chunk_t, return this->parameters; } -METHOD(ietf_attr_remediation_instr_t, get_uri, chunk_t, - private_ietf_attr_remediation_instr_t *this) -{ - return this->parameters; -} - METHOD(ietf_attr_remediation_instr_t, get_string, chunk_t, private_ietf_attr_remediation_instr_t *this, chunk_t *lang_code) { @@ -284,7 +280,7 @@ pa_tnc_attr_t *ietf_attr_remediation_instr_create(pen_type_t parameters_type, }, .get_parameters_type = _get_parameters_type, .get_parameters = _get_parameters, - .get_uri = _get_uri, + .get_uri = _get_parameters, .get_string = _get_string, }, .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS }, @@ -350,7 +346,7 @@ pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_data(chunk_t data) }, .get_parameters_type = _get_parameters_type, .get_parameters = _get_parameters, - .get_uri = _get_uri, + .get_uri = _get_parameters, .get_string = _get_string, }, .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS }, diff --git a/src/libimcv/imc/imc_agent.c b/src/libimcv/imc/imc_agent.c index 161623477..f309abe74 100644 --- a/src/libimcv/imc/imc_agent.c +++ b/src/libimcv/imc/imc_agent.c @@ -190,8 +190,6 @@ METHOD(imc_agent_t, bind_functions, TNC_Result, { this->reserve_additional_id = NULL; } - DBG2(DBG_IMC, "IMC %u \"%s\" provided with bind function", - this->id, this->name); if (this->report_message_types_long) { diff --git a/src/libimcv/imc/imc_msg.c b/src/libimcv/imc/imc_msg.c index 050e63f32..1fc3d3be5 100644 --- a/src/libimcv/imc/imc_msg.c +++ b/src/libimcv/imc/imc_msg.c @@ -91,6 +91,12 @@ METHOD(imc_msg_t, get_dst_id, TNC_UInt32, return this->dst_id; } +METHOD(imc_msg_t, get_msg_type, pen_type_t, + private_imc_msg_t *this) +{ + return this->msg_type; +} + METHOD(imc_msg_t, send_, TNC_Result, private_imc_msg_t *this, bool excl) { @@ -380,6 +386,7 @@ imc_msg_t *imc_msg_create(imc_agent_t *agent, imc_state_t *state, .public = { .get_src_id = _get_src_id, .get_dst_id = _get_dst_id, + .get_msg_type = _get_msg_type, .send = _send_, .receive = _receive, .add_attribute = _add_attribute, @@ -454,4 +461,3 @@ imc_msg_t *imc_msg_create_from_long_data(imc_agent_t *agent, imc_state_t *state, return &this->public; } - diff --git a/src/libimcv/imc/imc_msg.h b/src/libimcv/imc/imc_msg.h index 6dd712e84..9a4623ae9 100644 --- a/src/libimcv/imc/imc_msg.h +++ b/src/libimcv/imc/imc_msg.h @@ -48,6 +48,13 @@ struct imc_msg_t { TNC_UInt32 (*get_dst_id)(imc_msg_t *this); /** + * Get the PA-TNC message type. + * + * @return message type + */ + pen_type_t (*get_msg_type)(imc_msg_t *this); + + /** * Sends one or multiple PA-TNC messages * * @param excl set the excl message flag if supported diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c index 6a33e396c..78e584dfb 100644 --- a/src/libimcv/imv/imv_agent.c +++ b/src/libimcv/imv/imv_agent.c @@ -18,8 +18,11 @@ #include "ietf/ietf_attr_assess_result.h" #include <tncif_names.h> +#include <tncif_identity.h> #include <utils/debug.h> +#include <collections/linked_list.h> +#include <bio/bio_reader.h> #include <threading/rwlock.h> typedef struct private_imv_agent_t private_imv_agent_t; @@ -210,8 +213,6 @@ METHOD(imv_agent_t, bind_functions, TNC_Result, { this->reserve_additional_id = NULL; } - DBG2(DBG_IMV, "IMV %u \"%s\" provided with bind function", - this->id, this->name); if (this->report_message_types_long) { @@ -352,12 +353,59 @@ static u_int32_t get_uint_attribute(private_imv_agent_t *this, TNC_ConnectionID return 0; } +/** + * Read a TNC identity attribute + */ +static linked_list_t* get_identity_attribute(private_imv_agent_t *this, + TNC_ConnectionID id, + TNC_AttributeID attribute_id) +{ + TNC_UInt32 len; + char buf[2048]; + u_int32_t count; + tncif_identity_t *tnc_id; + bio_reader_t *reader; + linked_list_t *list; + + list = linked_list_create(); + + if (!this->get_attribute || + this->get_attribute(this->id, id, attribute_id, sizeof(buf), buf, &len) + != TNC_RESULT_SUCCESS || len > sizeof(buf)) + { + return list; + } + + reader = bio_reader_create(chunk_create(buf, len)); + if (!reader->read_uint32(reader, &count)) + { + goto end; + } + while (count--) + { + tnc_id = tncif_identity_create_empty(); + if (!tnc_id->process(tnc_id, reader)) + { + tnc_id->destroy(tnc_id); + goto end; + } + list->insert_last(list, tnc_id); + } + +end: + reader->destroy(reader); + return list; + } + METHOD(imv_agent_t, create_state, TNC_Result, private_imv_agent_t *this, imv_state_t *state) { TNC_ConnectionID conn_id; char *tnccs_p = NULL, *tnccs_v = NULL, *t_p = NULL, *t_v = NULL; bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE; + linked_list_t *ar_identities; + enumerator_t *enumerator; + tncif_identity_t *tnc_id; u_int32_t max_msg_len; conn_id = state->get_connection_id(state); @@ -378,6 +426,7 @@ METHOD(imv_agent_t, create_state, TNC_Result, t_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_PROTOCOL); t_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_VERSION); max_msg_len = get_uint_attribute(this, conn_id, TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE); + ar_identities = get_identity_attribute(this, conn_id, TNC_ATTRIBUTEID_AR_IDENTITIES); state->set_flags(state, has_long, has_excl); state->set_max_msg_len(state, max_msg_len); @@ -389,6 +438,64 @@ METHOD(imv_agent_t, create_state, TNC_Result, DBG2(DBG_IMV, " over %s %s with maximum PA-TNC message size of %u bytes", t_p ? t_p:"?", t_v ? t_v :"?", max_msg_len); + enumerator = ar_identities->create_enumerator(ar_identities); + while (enumerator->enumerate(enumerator, &tnc_id)) + { + pen_type_t id_type, subject_type, auth_type; + int tcg_id_type, tcg_subject_type, tcg_auth_type; + chunk_t id_value; + id_type_t ike_type; + identification_t *id; + + id_type = tnc_id->get_identity_type(tnc_id); + id_value = tnc_id->get_identity_value(tnc_id); + subject_type = tnc_id->get_subject_type(tnc_id); + auth_type = tnc_id->get_auth_type(tnc_id); + + tcg_id_type = (id_type.vendor_id == PEN_TCG) ? + id_type.type : TNC_ID_UNKNOWN; + tcg_subject_type = (subject_type.vendor_id == PEN_TCG) ? + subject_type.type : TNC_SUBJECT_UNKNOWN; + tcg_auth_type = (auth_type.vendor_id == PEN_TCG) ? + auth_type.type : TNC_AUTH_UNKNOWN; + + switch (tcg_id_type) + { + case TNC_ID_IPV4_ADDR: + ike_type = ID_IPV4_ADDR; + break; + case TNC_ID_IPV6_ADDR: + ike_type = ID_IPV6_ADDR; + break; + case TNC_ID_FQDN: + case TNC_ID_USER_NAME: + ike_type = ID_FQDN; + break; + case TNC_ID_RFC822_ADDR: + ike_type = ID_RFC822_ADDR; + break; + case TNC_ID_DER_ASN1_DN: + ike_type = ID_DER_ASN1_DN; + break; + case TNC_ID_DER_ASN1_GN: + ike_type = ID_IPV4_ADDR; + break; + case TNC_ID_UNKNOWN: + default: + ike_type = ID_KEY_ID; + break; + } + + id = identification_create_from_encoding(ike_type, id_value); + DBG2(DBG_IMV, "%N identity '%Y' authenticated by %N", + TNC_Subject_names, tcg_subject_type, id, + TNC_Authentication_names, tcg_auth_type); + id->destroy(id); + } + enumerator->destroy(enumerator); + + ar_identities->destroy_offset(ar_identities, + offsetof(tncif_identity_t, destroy)); free(tnccs_p); free(tnccs_v); free(t_p); diff --git a/src/libimcv/imv/imv_msg.c b/src/libimcv/imv/imv_msg.c index 4ed19dd13..496d0ee1c 100644 --- a/src/libimcv/imv/imv_msg.c +++ b/src/libimcv/imv/imv_msg.c @@ -102,6 +102,12 @@ METHOD(imv_msg_t, set_msg_type, void, } } +METHOD(imv_msg_t, get_msg_type, pen_type_t, + private_imv_msg_t *this) +{ + return this->msg_type; +} + METHOD(imv_msg_t, add_attribute, void, private_imv_msg_t *this, pa_tnc_attr_t *attr) { @@ -352,6 +358,7 @@ imv_msg_t *imv_msg_create(imv_agent_t *agent, imv_state_t *state, .get_src_id = _get_src_id, .get_dst_id = _get_dst_id, .set_msg_type = _set_msg_type, + .get_msg_type = _get_msg_type, .send = _send_, .send_assessment = _send_assessment, .receive = _receive, diff --git a/src/libimcv/imv/imv_msg.h b/src/libimcv/imv/imv_msg.h index b639712e8..2a2810170 100644 --- a/src/libimcv/imv/imv_msg.h +++ b/src/libimcv/imv/imv_msg.h @@ -55,6 +55,13 @@ struct imv_msg_t { void (*set_msg_type)(imv_msg_t *this, pen_type_t msg_type); /** + * Get the type of a PA-TNC message. + * + * @return message type + */ + pen_type_t (*get_msg_type)(imv_msg_t *this); + + /** * Sends one or multiple PA-TNC messages * * @param excl set the excl message flag if supported diff --git a/src/libimcv/os_info/os_info.c b/src/libimcv/os_info/os_info.c index 13374c876..2c49cb01d 100644 --- a/src/libimcv/os_info/os_info.c +++ b/src/libimcv/os_info/os_info.c @@ -156,7 +156,7 @@ METHOD(os_info_t, get_uptime, time_t, { const char proc_uptime[] = "/proc/uptime"; FILE *file; - time_t uptime; + u_int uptime; file = fopen(proc_uptime, "r"); if (!file) diff --git a/src/libimcv/pa_tnc/pa_tnc_msg.c b/src/libimcv/pa_tnc/pa_tnc_msg.c index 63445f3a1..d3aceee06 100644 --- a/src/libimcv/pa_tnc/pa_tnc_msg.c +++ b/src/libimcv/pa_tnc/pa_tnc_msg.c @@ -284,6 +284,18 @@ METHOD(pa_tnc_msg_t, process, status_t, } DBG3(DBG_TNC, "%B", &value); + if (vendor_id == PEN_RESERVED) + { + error = ietf_attr_pa_tnc_error_create_with_offset(error_code, + this->encoding, offset + 1); + goto err; + } + if (type == IETF_ATTR_RESERVED) + { + error = ietf_attr_pa_tnc_error_create_with_offset(error_code, + this->encoding, offset + 4); + goto err; + } attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes, vendor_id, type, value); if (!attr) diff --git a/src/libimcv/plugins/imv_os/imv_os.c b/src/libimcv/plugins/imv_os/imv_os.c index 65538df07..ecc6cfc4f 100644 --- a/src/libimcv/plugins/imv_os/imv_os.c +++ b/src/libimcv/plugins/imv_os/imv_os.c @@ -360,7 +360,9 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg) out_msg->add_attribute(out_msg, attr); } - if (fatal_error) + if (fatal_error || + (os_state->get_attribute_request(os_state) && + os_state->get_info(os_state, NULL, NULL, NULL) == NULL)) { state->set_recommendation(state, TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, @@ -371,7 +373,8 @@ static TNC_Result receive_message(imv_state_t *state, imv_msg_t *in_msg) /* If all Installed Packages attributes were received, go to assessment */ if (!assessment && !os_state->get_package_request(os_state) && - !os_state->get_angel_count(os_state)) + !os_state->get_angel_count(os_state) && + os_state->get_info(os_state, NULL, NULL, NULL)) { int device_id, count, count_update, count_blacklist, count_ok; u_int os_settings; @@ -518,6 +521,8 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, { imv_state_t *state; imv_os_state_t *os_state; + TNC_IMV_Action_Recommendation rec; + TNC_IMV_Evaluation_Result eval; TNC_Result result = TNC_RESULT_SUCCESS; if (!imv_os) @@ -531,6 +536,18 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, } os_state = (imv_os_state_t*)state; + state->get_recommendation(state, &rec, &eval); + + /* + * Don't send an attribute request if an evaluation is available + * or if an attribute request has already been sent + */ + if (eval != TNC_IMV_EVALUATION_RESULT_DONT_KNOW || + os_state->get_attribute_request(os_state)) + { + return TNC_RESULT_SUCCESS; + } + if (os_state->get_info(os_state, NULL, NULL, NULL) == NULL) { imv_msg_t *out_msg; @@ -548,6 +565,7 @@ TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id, attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_FORWARDING_ENABLED); attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED); out_msg->add_attribute(out_msg, attr); + os_state->set_attribute_request(os_state, TRUE); /* send PA-TNC message with excl flag not set */ result = out_msg->send(out_msg, FALSE); diff --git a/src/libimcv/plugins/imv_os/imv_os_state.c b/src/libimcv/plugins/imv_os/imv_os_state.c index ca6e050f7..00e0424fb 100644 --- a/src/libimcv/plugins/imv_os/imv_os_state.c +++ b/src/libimcv/plugins/imv_os/imv_os_state.c @@ -137,6 +137,11 @@ struct private_imv_os_state_t { int count_ok; /** + * Attribute request sent - mandatory response expected + */ + bool attribute_request; + + /** * OS Installed Package request sent - mandatory response expected */ bool package_request; @@ -506,6 +511,18 @@ METHOD(imv_os_state_t, get_count, void, } } +METHOD(imv_os_state_t, set_attribute_request, void, + private_imv_os_state_t *this, bool set) +{ + this->attribute_request = set; +} + +METHOD(imv_os_state_t, get_attribute_request, bool, + private_imv_os_state_t *this) +{ + return this->attribute_request; +} + METHOD(imv_os_state_t, set_package_request, void, private_imv_os_state_t *this, bool set) { @@ -597,6 +614,8 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id) .get_info = _get_info, .set_count = _set_count, .get_count = _get_count, + .set_attribute_request = _set_attribute_request, + .get_attribute_request = _get_attribute_request, .set_package_request = _set_package_request, .get_package_request = _get_package_request, .set_device_id = _set_device_id, diff --git a/src/libimcv/plugins/imv_os/imv_os_state.h b/src/libimcv/plugins/imv_os/imv_os_state.h index 05abdbb6c..d3e319171 100644 --- a/src/libimcv/plugins/imv_os/imv_os_state.h +++ b/src/libimcv/plugins/imv_os/imv_os_state.h @@ -87,6 +87,21 @@ struct imv_os_state_t { */ void (*get_count)(imv_os_state_t *this, int *count, int *count_update, int *count_blacklist, int *count_ok); + + /** + * Set/reset attribute request status + * + * @param set TRUE to set, FALSE to clear + */ + void (*set_attribute_request)(imv_os_state_t *this, bool set); + + /** + * Get attribute request status + * + * @return TRUE if set, FALSE if unset + */ + bool (*get_attribute_request)(imv_os_state_t *this); + /** * Set/reset OS Installed Packages request status * |