static void _oval_test_item_consumer(struct oval_result_item *item, void **args) { struct oval_sysitem *oval_sysitem = oval_result_item_get_sysitem(item); char *item_id = oval_sysitem_get_id(oval_sysitem); struct oval_result_item *mapped_item = oval_string_map_get_value(ITEMMAP, item_id); if (mapped_item == NULL) { oval_string_map_put(ITEMMAP, item_id, item); oval_result_test_add_item(TEST, item); } else { oval_result_item_free(item); } }
static oval_result_t _oval_result_test_evaluate_items(struct oval_test *test, struct oval_syschar *syschar_object, void **args) { struct oval_sysitem_iterator *collected_items_itr; oval_result_t result; int exists_cnt, error_cnt; bool hasstate; oval_check_t test_check; oval_existence_t test_check_existence; struct oval_state_iterator *ste_itr; exists_cnt = error_cnt = 0; collected_items_itr = oval_syschar_get_sysitem(syschar_object); while (oval_sysitem_iterator_has_more(collected_items_itr)) { struct oval_sysitem *item; char *item_id; oval_syschar_status_t item_status; struct oval_result_item *ritem; item = oval_sysitem_iterator_next(collected_items_itr); if (item == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "Iterator returned null."); oval_sysitem_iterator_free(collected_items_itr); return OVAL_RESULT_ERROR; } item_status = oval_sysitem_get_status(item); if (item_status == SYSCHAR_STATUS_EXISTS) exists_cnt++; if (item_status == SYSCHAR_STATUS_ERROR) error_cnt++; item_id = oval_sysitem_get_id(item); ritem = oval_result_item_new(SYSTEM, item_id); oval_result_item_set_result(ritem, OVAL_RESULT_NOT_EVALUATED); _oval_test_item_consumer(ritem, args); } oval_sysitem_iterator_free(collected_items_itr); test_check = oval_test_get_check(test); test_check_existence = oval_test_get_existence(test); ste_itr = oval_test_get_states(test); hasstate = oval_state_iterator_has_more(ste_itr); oval_state_iterator_free(ste_itr); switch (oval_syschar_get_flag(syschar_object)) { case SYSCHAR_FLAG_ERROR: if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_ERROR; } break; case SYSCHAR_FLAG_NOT_COLLECTED: if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_UNKNOWN; } break; case SYSCHAR_FLAG_NOT_APPLICABLE: if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_NOT_APPLICABLE; } break; case SYSCHAR_FLAG_DOES_NOT_EXIST: if (test_check_existence == OVAL_NONE_EXIST || test_check_existence == OVAL_ANY_EXIST) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_FALSE; } break; case SYSCHAR_FLAG_COMPLETE: result = eval_check_existence(test_check_existence, exists_cnt, error_cnt); if (result == OVAL_RESULT_TRUE && hasstate) { result = eval_check_state(test, args); } break; case SYSCHAR_FLAG_INCOMPLETE: if (test_check_existence == OVAL_ANY_EXIST) { result = OVAL_RESULT_TRUE; } else if (test_check_existence == OVAL_AT_LEAST_ONE_EXISTS && exists_cnt > 0) { result = OVAL_RESULT_TRUE; } else if (test_check_existence == OVAL_NONE_EXIST && exists_cnt > 0) { result = OVAL_RESULT_FALSE; } else if (test_check_existence == OVAL_ONLY_ONE_EXISTS && exists_cnt > 1) { result = OVAL_RESULT_FALSE; } else { result = OVAL_RESULT_UNKNOWN; } if (result == OVAL_RESULT_TRUE && hasstate) { result = eval_check_state(test, args); if (result == OVAL_RESULT_TRUE) { if (test_check != OVAL_CHECK_AT_LEAST_ONE) { result = OVAL_RESULT_UNKNOWN; } } else if (result != OVAL_RESULT_FALSE) { result = OVAL_RESULT_UNKNOWN; } } break; default: { const char *object_id = oval_syschar_get_object(syschar_object) ? oval_object_get_id(oval_syschar_get_object(syschar_object)) : "<UNKNOWN>"; oscap_seterr(OSCAP_EFAMILY_OVAL, "Unknown syschar flag: '%d' when evaluating object: '%s' from test: '%s' ", oval_syschar_get_flag(syschar_object), object_id, oval_test_get_id(test)); return OVAL_RESULT_ERROR; } } return result; }
static oval_result_t eval_item(struct oval_syschar_model *syschar_model, struct oval_sysitem *cur_sysitem, struct oval_state *state) { struct oval_state_content_iterator *state_contents_itr; struct oresults ste_ores; oval_operator_t operator; oval_result_t result = OVAL_RESULT_ERROR; ores_clear(&ste_ores); state_contents_itr = oval_state_get_contents(state); while (oval_state_content_iterator_has_more(state_contents_itr)) { struct oval_state_content *content; struct oval_entity *state_entity; char *state_entity_name; oval_operation_t state_entity_operation; oval_check_t entity_check; oval_existence_t check_existence; oval_result_t ste_ent_res; struct oval_sysent_iterator *item_entities_itr; struct oresults ent_ores; struct oval_status_counter counter; bool found_matching_item; if ((content = oval_state_content_iterator_next(state_contents_itr)) == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "OVAL internal error: found NULL state content"); goto fail; } if ((state_entity = oval_state_content_get_entity(content)) == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "OVAL internal error: found NULL entity"); goto fail; } if ((state_entity_name = oval_entity_get_name(state_entity)) == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "OVAL internal error: found NULL entity name"); goto fail; } if (oscap_streq(state_entity_name, "line") && oval_state_get_subtype(state) == (oval_subtype_t) OVAL_INDEPENDENT_TEXT_FILE_CONTENT) { /* Hack: textfilecontent_state/line shall be compared against textfilecontent_item/text. * * textfilecontent_test and textfilecontent54_test share the same syschar * (textfilecontent_item). In OVAL 5.3 and below this syschar did not hold any usable * information ('text' ent). In OVAL 5.4 textfilecontent_test was deprecated. But the * 'text' ent has been added to textfilecontent_item, making it potentially usable. */ oval_schema_version_t over = oval_state_get_platform_schema_version(state); if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.4)) >= 0) { /* The OVAL-5.3 does not have textfilecontent_item/text */ state_entity_name = "text"; } } entity_check = oval_state_content_get_ent_check(content); check_existence = oval_state_content_get_check_existence(content); state_entity_operation = oval_entity_get_operation(state_entity); ores_clear(&ent_ores); found_matching_item = false; oval_status_counter_clear(&counter); item_entities_itr = oval_sysitem_get_sysents(cur_sysitem); while (oval_sysent_iterator_has_more(item_entities_itr)) { struct oval_sysent *item_entity; oval_result_t ent_val_res; char *item_entity_name; oval_syschar_status_t item_status; item_entity = oval_sysent_iterator_next(item_entities_itr); if (item_entity == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "OVAL internal error: found NULL sysent"); oval_sysent_iterator_free(item_entities_itr); goto fail; } item_status = oval_sysent_get_status(item_entity); oval_status_counter_add_status(&counter, item_status); item_entity_name = oval_sysent_get_name(item_entity); if (strcmp(item_entity_name, state_entity_name)) continue; found_matching_item = true; /* copy mask attribute from state to item */ if (oval_entity_get_mask(state_entity)) oval_sysent_set_mask(item_entity,1); ent_val_res = _evaluate_sysent(syschar_model, item_entity, state_entity, state_entity_operation, content); if (((signed) ent_val_res) == -1) { oval_sysent_iterator_free(item_entities_itr); goto fail; } ores_add_res(&ent_ores, ent_val_res); } oval_sysent_iterator_free(item_entities_itr); if (!found_matching_item) dW("Entity name '%s' from state (id: '%s') not found in item (id: '%s').\n", state_entity_name, oval_state_get_id(state), oval_sysitem_get_id(cur_sysitem)); ste_ent_res = ores_get_result_bychk(&ent_ores, entity_check); ores_add_res(&ste_ores, ste_ent_res); oval_result_t cres = oval_status_counter_get_result(&counter, check_existence); ores_add_res(&ste_ores, cres); } oval_state_content_iterator_free(state_contents_itr); operator = oval_state_get_operator(state); result = ores_get_result_byopr(&ste_ores, operator); return result; fail: oval_state_content_iterator_free(state_contents_itr); return OVAL_RESULT_ERROR; }
static oval_result_t _oval_result_test_evaluate_items(struct oval_test *test, struct oval_syschar *syschar_object, void **args) { struct oval_sysitem_iterator *collected_items_itr; oval_result_t result; int exists_cnt, error_cnt; bool hasstate; const char *test_id, *object_id, *flag_text; oval_check_t test_check; oval_existence_t test_check_existence; struct oval_state_iterator *ste_itr; oval_syschar_collection_flag_t flag; struct oval_object *object; exists_cnt = error_cnt = 0; test_id = oval_test_get_id(test); collected_items_itr = oval_syschar_get_sysitem(syschar_object); while (oval_sysitem_iterator_has_more(collected_items_itr)) { struct oval_sysitem *item; char *item_id; oval_syschar_status_t item_status; struct oval_result_item *ritem; item = oval_sysitem_iterator_next(collected_items_itr); if (item == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "Iterator returned null."); oval_sysitem_iterator_free(collected_items_itr); return OVAL_RESULT_ERROR; } item_status = oval_sysitem_get_status(item); if (item_status == SYSCHAR_STATUS_EXISTS) exists_cnt++; if (item_status == SYSCHAR_STATUS_ERROR) error_cnt++; item_id = oval_sysitem_get_id(item); ritem = oval_result_item_new(SYSTEM, item_id); oval_result_item_set_result(ritem, OVAL_RESULT_NOT_EVALUATED); _oval_test_item_consumer(ritem, args); } oval_sysitem_iterator_free(collected_items_itr); test_check = oval_test_get_check(test); test_check_existence = oval_test_get_existence(test); ste_itr = oval_test_get_states(test); hasstate = oval_state_iterator_has_more(ste_itr); oval_state_iterator_free(ste_itr); object = oval_syschar_get_object(syschar_object); object_id = object ? oval_object_get_id(object) : "<UNKNOWN>"; switch (test_check_existence) { case OVAL_ALL_EXIST: dI("Test '%s' requires that every object defined by '%s' exists on the system.", test_id, object_id); break; case OVAL_ANY_EXIST: dI("Test '%s' requires that zero or more objects defined by '%s' exist on the system.", test_id, object_id); break; case OVAL_AT_LEAST_ONE_EXISTS: dI("Test '%s' requires that at least one object defined by '%s' exists on the system.", test_id, object_id); break; case OVAL_NONE_EXIST: dI("Test '%s' requires that none of the objects defined by '%s' exist on the system.", test_id, object_id); break; case OVAL_ONLY_ONE_EXISTS: dI("Test '%s' requires that only one object defined by '%s' exists on the system.", test_id, object_id); break; default: oscap_seterr(OSCAP_EFAMILY_OVAL, "Check_existence parameter of test '%s' is unknown. This may indicate a bug in OpenSCAP.", test_id); } dI("%d objects defined by '%s' exist on the system.", exists_cnt, object_id); if (!hasstate) { dI("Test '%s' does not contain any state to compare object with.", test_id); } flag = oval_syschar_get_flag(syschar_object); flag_text = oval_syschar_collection_flag_get_text(flag); switch (flag) { case SYSCHAR_FLAG_ERROR: dI("An error occured while collecting items matching object '%s'. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_ERROR; } break; case SYSCHAR_FLAG_NOT_COLLECTED: dI("No attempt was made to collect items matching object '%s'. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_UNKNOWN; } break; case SYSCHAR_FLAG_NOT_APPLICABLE: dI("Object '%s' is not applicable to the system. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_NOT_APPLICABLE; } break; case SYSCHAR_FLAG_DOES_NOT_EXIST: dI("No item matching object '%s' was found on the system. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_NONE_EXIST || test_check_existence == OVAL_ANY_EXIST) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_FALSE; } break; case SYSCHAR_FLAG_COMPLETE: dI("All items matching object '%s' were collected. (flag=%s)", object_id, flag_text); result = eval_check_existence(test_check_existence, exists_cnt, error_cnt); if (result == OVAL_RESULT_TRUE && hasstate) { result = eval_check_state(test, args); } break; case SYSCHAR_FLAG_INCOMPLETE: dI("Only some of items matching object '%s' have been collected from the system. It is unknown if other matching items also exist. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_ANY_EXIST) { result = OVAL_RESULT_TRUE; } else if (test_check_existence == OVAL_AT_LEAST_ONE_EXISTS && exists_cnt > 0) { result = OVAL_RESULT_TRUE; } else if (test_check_existence == OVAL_NONE_EXIST && exists_cnt > 0) { result = OVAL_RESULT_FALSE; } else if (test_check_existence == OVAL_ONLY_ONE_EXISTS && exists_cnt > 1) { result = OVAL_RESULT_FALSE; } else { result = OVAL_RESULT_UNKNOWN; } if (result == OVAL_RESULT_TRUE && hasstate) { result = eval_check_state(test, args); if (result == OVAL_RESULT_TRUE) { if (test_check != OVAL_CHECK_AT_LEAST_ONE) { result = OVAL_RESULT_UNKNOWN; } } else if (result != OVAL_RESULT_FALSE) { result = OVAL_RESULT_UNKNOWN; } } break; default: { oscap_seterr(OSCAP_EFAMILY_OVAL, "Item corresponding to object '%s' from test '%s' has an unknown flag. This may indicate a bug in OpenSCAP.", object_id, test_id); return OVAL_RESULT_ERROR; } } return result; }