static SEXP_t *oval_probe_cmd_obj_eval(SEXP_t *sexp, void *arg) { char *id_str; struct oval_definition_model *defs; struct oval_object *obj; struct oval_syschar *res; oval_pext_t *pext = (oval_pext_t *) arg; SEXP_t *ret, *ret_code; int r; if (sexp == NULL || arg == NULL) { return NULL; } if (!SEXP_stringp(sexp)) { dE("Invalid argument: type=%s.", SEXP_strtype(sexp)); return (NULL); } id_str = SEXP_string_cstr(sexp); defs = oval_syschar_model_get_definition_model(*(pext->model)); obj = oval_definition_model_get_object(defs, id_str); ret = SEXP_list_new (sexp, NULL); dI("Get_object: %s.", id_str); if (obj == NULL) { dE("Can't find obj: id=%s.", id_str); free(id_str); SEXP_free(ret); return (NULL); } oscap_clearerr(); r = oval_probe_query_object(pext->sess_ptr, obj, OVAL_PDFLAG_NOREPLY|OVAL_PDFLAG_SLAVE, &res); if (r < 0) ret_code = SEXP_number_newu((unsigned int) SYSCHAR_FLAG_COMPLETE); else ret_code = SEXP_number_newu((unsigned int) oval_syschar_get_flag(res)); SEXP_list_add(ret, ret_code); SEXP_free(ret_code); if (oscap_err()) { dE("Failed: id: %s, err: %d, %s.", id_str, oscap_err_family(), oscap_err_desc()); oscap_clearerr(); free(id_str); SEXP_free(ret); return (NULL); } free(id_str); return (ret); }
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 _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; }
int oval_probe_query_object(oval_probe_session_t *psess, struct oval_object *object, int flags, struct oval_syschar **out_syschar) { char *oid; struct oval_syschar *sysc; oval_subtype_t type; oval_ph_t *ph; struct oval_string_map *vm; struct oval_syschar_model *model; int ret; oid = oval_object_get_id(object); model = psess->sys_model; dI("Querying object id: \"%s\", flags: %u.\n", oid, flags); sysc = oval_syschar_model_get_syschar(model, oid); if (sysc != NULL) { int variable_instance_hint = oval_syschar_get_variable_instance_hint(sysc); if (oval_syschar_get_variable_instance_hint(sysc) != oval_syschar_get_variable_instance(sysc)) { dI("Creating another syschar for variable_instance=%d)\n", variable_instance_hint); sysc = oval_syschar_new(model, object); oval_syschar_set_variable_instance(sysc, variable_instance_hint); oval_syschar_set_variable_instance_hint(sysc, variable_instance_hint); } else { oval_syschar_collection_flag_t sc_flg; sc_flg = oval_syschar_get_flag(sysc); dI("Syschar already exists, flag: %u, '%s'.\n", sc_flg, oval_syschar_collection_flag_get_text(sc_flg)); if (sc_flg != SYSCHAR_FLAG_UNKNOWN || (flags & OVAL_PDFLAG_NOREPLY)) { if (out_syschar) *out_syschar = sysc; return 0; } } } else sysc = oval_syschar_new(model, object); if (out_syschar) *out_syschar = sysc; type = oval_object_get_subtype(object); ph = oval_probe_handler_get(psess->ph, type); if (ph == NULL) { char *msg = "OVAL object not supported."; dW("%s\n", msg); oval_syschar_add_new_message(sysc, msg, OVAL_MESSAGE_LEVEL_WARNING); oval_syschar_set_flag(sysc, SYSCHAR_FLAG_NOT_COLLECTED); return 1; } if ((ret = ph->func(type, ph->uptr, PROBE_HANDLER_ACT_EVAL, sysc, flags)) != 0) { return ret; } if (!(flags & OVAL_PDFLAG_NOREPLY)) { vm = oval_string_map_new(); oval_obj_collect_var_refs(object, vm); _syschar_add_bindings(sysc, vm); oval_string_map_free(vm, NULL); } return 0; }
int app_collect_oval(const struct oscap_action *action) { struct oval_definition_model *def_model = NULL; struct oval_variable_model *var_model = NULL; struct oval_syschar_model *sys_model = NULL; struct oval_sysinfo *sysinfo = NULL; struct oval_probe_session *pb_sess = NULL; struct oval_generator *generator = NULL; int ret = OSCAP_ERROR; /* Turn on verbosity */ if (!oscap_set_verbose(action->verbosity_level, action->f_verbose_log, false)) { goto cleanup; } /* validate inputs */ if (action->validate) { if (!valid_inputs(action)) { goto cleanup; } } /* import definitions */ struct oscap_source *source = oscap_source_new_from_file(action->f_oval); def_model = oval_definition_model_import_source(source); oscap_source_free(source); if (def_model == NULL) { fprintf(stderr, "Failed to import the OVAL Definitions from '%s'.\n", action->f_oval); goto cleanup; } /* bind external variables */ if(action->f_variables) { struct oscap_source *var_source = oscap_source_new_from_file(action->f_variables); var_model = oval_variable_model_import_source(var_source); oscap_source_free(var_source); if (var_model == NULL) { fprintf(stderr, "Failed to import the OVAL Variables from '%s'.\n", action->f_variables); goto cleanup; } if (oval_definition_model_bind_variable_model(def_model, var_model)) { fprintf(stderr, "Failed to bind Variables to Definitions\n"); goto cleanup; } } /* create empty syschar model */ sys_model = oval_syschar_model_new(def_model); /* set product name */ generator = oval_syschar_model_get_generator(sys_model); oval_generator_set_product_name(generator, OSCAP_PRODUCTNAME); /* create probe session */ pb_sess = oval_probe_session_new(sys_model); /* query sysinfo */ ret = oval_probe_query_sysinfo(pb_sess, &sysinfo); if (ret != 0) { fprintf(stderr, "Failed to query sysinfo\n"); goto cleanup; } oval_syschar_model_set_sysinfo(sys_model, sysinfo); /* query objects */ struct oval_object *object; struct oval_syschar *syschar; oval_syschar_collection_flag_t sc_flg; if (action->id) { object = oval_definition_model_get_object(def_model, action->id); if (!object) { fprintf(stderr, "Object ID(%s) does not exist in '%s'.\n", action->id, action->f_oval); goto cleanup; } printf("Collected: \"%s\" : ", oval_object_get_id(object)); oval_probe_query_object(pb_sess, object, 0, &syschar); sc_flg = oval_syschar_get_flag(syschar); printf("%s\n", oval_syschar_collection_flag_get_text(sc_flg)); } else { struct oval_object_iterator *objects = oval_definition_model_get_objects(def_model); while (oval_object_iterator_has_more(objects)) { object = oval_object_iterator_next(objects); printf("Collected: \"%s\" : ", oval_object_get_id(object)); oval_probe_query_object(pb_sess, object, 0, &syschar); sc_flg = oval_syschar_get_flag(syschar); printf("%s\n", oval_syschar_collection_flag_get_text(sc_flg)); } oval_object_iterator_free(objects); } const char* full_validation = getenv("OSCAP_FULL_VALIDATION"); /* output */ if (action->f_syschar != NULL) { /* export OVAL System Characteristics */ oval_syschar_model_export(sys_model, action->f_syschar); /* validate OVAL System Characteristics */ if (action->validate && full_validation) { struct oscap_source *syschar_source = oscap_source_new_from_file(action->f_syschar); if (oscap_source_validate(syschar_source, reporter, (void *)action)) { oscap_source_free(syschar_source); goto cleanup; } fprintf(stdout, "OVAL System Characteristics are exported correctly.\n"); oscap_source_free(syschar_source); } } ret = OSCAP_OK; cleanup: if(oscap_err()) fprintf(stderr, "%s %s\n", OSCAP_ERR_MSG, oscap_err_desc()); if (sysinfo) oval_sysinfo_free(sysinfo); if (pb_sess) oval_probe_session_destroy(pb_sess); if (sys_model) oval_syschar_model_free(sys_model); if (def_model) oval_definition_model_free(def_model); return ret; }