static struct oval_variable *oval_probe_variable_objgetvar(struct oval_object *obj) { struct oval_entity *ent; struct oval_object_content *con; struct oval_object_content_iterator *cit; struct oval_variable *var; char *ent_name; var = NULL; cit = oval_object_get_object_contents(obj); while (oval_object_content_iterator_has_more(cit)) { con = oval_object_content_iterator_next(cit); if (oval_object_content_get_type(con) != OVAL_OBJECTCONTENT_ENTITY) continue; ent = oval_object_content_get_entity(con); ent_name = oval_entity_get_name(ent); if (strcmp(ent_name, "var_ref") != 0) continue; var = oval_entity_get_variable(ent); break; } oval_object_content_iterator_free(cit); return(var); }
struct oval_entity *oval_entity_clone(struct oval_definition_model *new_model, struct oval_entity *old_entity) { struct oval_entity *new_entity = oval_entity_new(new_model); oval_datatype_t datatype = oval_entity_get_datatype(old_entity); oval_entity_set_datatype(new_entity, datatype); int mask = oval_entity_get_mask(old_entity); oval_entity_set_mask(new_entity, mask); bool xsi_nil = oval_entity_get_xsi_nil(old_entity); oval_entity_set_xsi_nil(new_entity, xsi_nil); char *name = oval_entity_get_name(old_entity); oval_entity_set_name(new_entity, name); oval_operation_t operation = oval_entity_get_operation(old_entity); oval_entity_set_operation(new_entity, operation); oval_entity_type_t type = oval_entity_get_type(old_entity); oval_entity_set_type(new_entity, type); struct oval_value *value = oval_entity_get_value(old_entity); if (value) { oval_entity_set_value(new_entity, oval_value_clone(value)); } struct oval_variable *old_variable = oval_entity_get_variable(old_entity); if (old_variable) { oval_entity_set_variable(new_entity, oval_variable_clone(new_model, old_variable)); } oval_entity_varref_type_t reftype = oval_entity_get_varref_type(old_entity); oval_entity_set_varref_type(new_entity, reftype); return new_entity; }
static inline oval_result_t _evaluate_sysent_with_variable(struct oval_syschar_model *syschar_model, struct oval_entity *state_entity, struct oval_sysent *item_entity, oval_operation_t state_entity_operation, struct oval_state_content *content) { oval_syschar_collection_flag_t flag; oval_result_t ent_val_res; struct oval_variable *state_entity_var; if ((state_entity_var = oval_entity_get_variable(state_entity)) == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "OVAL internal error: found NULL variable"); return -1; } if (0 != oval_syschar_model_compute_variable(syschar_model, state_entity_var)) { return -1; } flag = oval_variable_get_collection_flag(state_entity_var); switch (flag) { case SYSCHAR_FLAG_COMPLETE: case SYSCHAR_FLAG_INCOMPLETE:{ struct oresults var_ores; struct oval_value_iterator *val_itr; ores_clear(&var_ores); val_itr = oval_variable_get_values(state_entity_var); while (oval_value_iterator_has_more(val_itr)) { struct oval_value *var_val; char *state_entity_val_text = NULL; oval_result_t var_val_res; var_val = oval_value_iterator_next(val_itr); state_entity_val_text = oval_value_get_text(var_val); if (state_entity_val_text == NULL) { dE("Found NULL variable value text.\n"); ores_add_res(&var_ores, OVAL_RESULT_ERROR); break; } oval_datatype_t state_entity_val_datatype = oval_value_get_datatype(var_val); var_val_res = oval_ent_cmp_str(state_entity_val_text, state_entity_val_datatype, item_entity, state_entity_operation); ores_add_res(&var_ores, var_val_res); } oval_value_iterator_free(val_itr); oval_check_t var_check = oval_state_content_get_var_check(content); ent_val_res = ores_get_result_bychk(&var_ores, var_check); } break; case SYSCHAR_FLAG_ERROR: case SYSCHAR_FLAG_DOES_NOT_EXIST: case SYSCHAR_FLAG_NOT_COLLECTED: case SYSCHAR_FLAG_NOT_APPLICABLE: ent_val_res = OVAL_RESULT_ERROR; break; default: ent_val_res = -1; } return ent_val_res; }
static SEXP_t *oval_entity_to_sexp(struct oval_entity *ent) { SEXP_t *elm, *elm_name; SEXP_t *r0, *r1, *r2; oval_datatype_t datatype; oval_entity_varref_type_t vr_type; elm_name = SEXP_list_new(r0 = SEXP_string_newf("%s", oval_entity_get_name(ent)), /* operation */ r1 = SEXP_string_new(":operation", 10), r2 = SEXP_number_newu_32(oval_entity_get_operation(ent)), NULL); SEXP_vfree(r0, r1, r2, NULL); if (oval_entity_get_mask(ent)) { SEXP_list_add(elm_name, r0 = SEXP_string_new("mask", 4)); SEXP_free(r0); } elm = SEXP_list_new(NULL); datatype = oval_entity_get_datatype(ent); probe_ent_setdatatype(elm, datatype); vr_type = oval_entity_get_varref_type(ent); if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE || vr_type == OVAL_ENTITY_VARREF_ELEMENT) { /* var_ref */ struct oval_variable *var; var = oval_entity_get_variable(ent); SEXP_list_add(elm_name, r0 = SEXP_string_new(":var_ref", 8)); SEXP_list_add(elm_name, r1 = SEXP_string_newf("%s", oval_variable_get_id(var))); SEXP_list_add(elm, elm_name); SEXP_vfree(r0, r1, elm_name, NULL); } else { /* value */ struct oval_value *val; SEXP_list_add(elm, elm_name); SEXP_free(elm_name); val = oval_entity_get_value(ent); if (datatype != OVAL_DATATYPE_RECORD && val != NULL) { SEXP_t *val_sexp; val_sexp = oval_value_to_sexp(val, datatype); if (val_sexp != NULL) { SEXP_list_add(elm, val_sexp); SEXP_free(val_sexp); } } } return (elm); }
static int oval_probe_query_var_ref(oval_probe_session_t *sess, struct oval_state *state) { struct oval_state_content_iterator *contents = oval_state_get_contents(state); while (oval_state_content_iterator_has_more(contents)) { struct oval_state_content *content = oval_state_content_iterator_next(contents); struct oval_entity * entity = oval_state_content_get_entity(content); if (oval_entity_get_varref_type(entity) == OVAL_ENTITY_VARREF_ATTRIBUTE) { oval_syschar_collection_flag_t flag; struct oval_variable *var = oval_entity_get_variable(entity); const char *state_id = oval_state_get_id(state); oval_variable_type_t var_type = oval_variable_get_type(var); const char *var_type_text = oval_variable_type_get_text(var_type); const char *var_id = oval_variable_get_id(var); dI("State '%s' references %s '%s'.", state_id, var_type_text, var_id); int ret = oval_probe_query_variable(sess, var); if (ret == -1) { oval_state_content_iterator_free(contents); return ret; } flag = oval_variable_get_collection_flag(var); switch (flag) { case SYSCHAR_FLAG_COMPLETE: case SYSCHAR_FLAG_INCOMPLETE: break; default: oval_state_content_iterator_free(contents); return 0; } } } oval_state_content_iterator_free(contents); return 1; }
/** * @returns 0 on success; -1 on error; 1 on warning */ static int oval_probe_query_criteria(oval_probe_session_t *sess, struct oval_criteria_node *cnode) { int ret; switch (oval_criteria_node_get_type(cnode)) { /* Criterion node is the final node that has a reference to a test */ case OVAL_NODETYPE_CRITERION:{ /* There should be a test .. */ struct oval_test *test; struct oval_object *object; struct oval_state_iterator *ste_itr; test = oval_criteria_node_get_test(cnode); if (test == NULL) return 0; object = oval_test_get_object(test); if (object == NULL) return 0; /* probe object */ ret = oval_probe_query_object(sess, object, 0, NULL); if (ret == -1) return ret; /* probe objects referenced like this: test->state->variable->object */ ste_itr = oval_test_get_states(test); while (oval_state_iterator_has_more(ste_itr)) { struct oval_state *state = oval_state_iterator_next(ste_itr); struct oval_state_content_iterator *contents = oval_state_get_contents(state); while (oval_state_content_iterator_has_more(contents)) { struct oval_state_content *content = oval_state_content_iterator_next(contents); struct oval_entity * entity = oval_state_content_get_entity(content); if (oval_entity_get_varref_type(entity) == OVAL_ENTITY_VARREF_ATTRIBUTE) { oval_syschar_collection_flag_t flag; struct oval_variable *var = oval_entity_get_variable(entity); ret = oval_probe_query_variable(sess, var); if (ret == -1) { oval_state_content_iterator_free(contents); oval_state_iterator_free(ste_itr); return ret; } flag = oval_variable_get_collection_flag(var); switch (flag) { case SYSCHAR_FLAG_COMPLETE: case SYSCHAR_FLAG_INCOMPLETE: break; default: oval_state_content_iterator_free(contents); oval_state_iterator_free(ste_itr); return 0; } } } oval_state_content_iterator_free(contents); } oval_state_iterator_free(ste_itr); return 0; } break; /* Criteria node is type of set that contains more criterias. Criteria node * child can be also type of criteria, criterion or extended definition */ case OVAL_NODETYPE_CRITERIA:{ /* group of criterion nodes, get subnodes, continue recursive */ struct oval_criteria_node_iterator *cnode_it = oval_criteria_node_get_subnodes(cnode); if (cnode_it == NULL) return 0; /* we have subnotes */ struct oval_criteria_node *node; while (oval_criteria_node_iterator_has_more(cnode_it)) { node = oval_criteria_node_iterator_next(cnode_it); ret = oval_probe_query_criteria(sess, node); if (ret != 0) { oval_criteria_node_iterator_free(cnode_it); return ret; } } oval_criteria_node_iterator_free(cnode_it); return 0; } break; /* Extended definition contains reference to definition, we need criteria of this * definition to be evaluated completely */ case OVAL_NODETYPE_EXTENDDEF:{ struct oval_definition *oval_def = oval_criteria_node_get_definition(cnode); struct oval_criteria_node *node = oval_definition_get_criteria(oval_def); if (node == NULL) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not find extended definition: %s.", oval_definition_get_id(oval_def)); return -1; } return oval_probe_query_criteria(sess, node); } break; case OVAL_NODETYPE_UNKNOWN: break; } /* we shouldn't get here */ return -1; }
int oval_state_to_sexp(void *sess, struct oval_state *state, SEXP_t **out_sexp) { SEXP_t *ste, *ste_name, *ste_ent; SEXP_t *r0, *r1, *r2, *r3, *r4; char buffer[128]; size_t buflen; const char *subtype_name; struct oval_state_content_iterator *contents; subtype_name = oval_subtype_to_str(oval_state_get_subtype(state)); if (subtype_name == NULL) { dI("FAIL: unknown subtype: %d", oval_state_get_subtype(state)); return (-1); } buflen = snprintf(buffer, sizeof buffer, "%s_state", subtype_name); _A(buflen < sizeof buffer); ste_name = SEXP_list_new(r0 = SEXP_string_new(buffer, buflen), r1 = SEXP_string_new(":id", 3), r2 = SEXP_string_newf("%s", oval_state_get_id(state)), r3 = SEXP_string_new(":operator", 9), r4 = SEXP_number_newu(oval_state_get_operator(state)), NULL); ste = SEXP_list_new(ste_name, NULL); SEXP_vfree(r0, r1, r2, r3, r4, ste_name, NULL); contents = oval_state_get_contents(state); while (oval_state_content_iterator_has_more(contents)) { oval_check_t ochk; oval_existence_t oext; oval_entity_varref_type_t vr_type; struct oval_entity *ent; struct oval_state_content *content = oval_state_content_iterator_next(contents); struct oval_record_field_iterator *rf_itr; ent = oval_state_content_get_entity(content); ste_ent = oval_entity_to_sexp(ent); if (ste_ent == NULL) { goto fail; } rf_itr = oval_state_content_get_record_fields(content); while (oval_record_field_iterator_has_more(rf_itr)) { struct oval_record_field *rf; SEXP_t *rf_sexp; rf = oval_record_field_iterator_next(rf_itr); rf_sexp = oval_record_field_STATE_to_sexp(rf); SEXP_list_add(ste_ent, rf_sexp); SEXP_free(rf_sexp); } oval_record_field_iterator_free(rf_itr); ochk = oval_state_content_get_var_check(content); if (ochk != OVAL_CHECK_UNKNOWN) { probe_ent_attr_add(ste_ent, "var_check", r0 = SEXP_number_newu_32(ochk)); SEXP_free(r0); } ochk = oval_state_content_get_ent_check(content); if (ochk != OVAL_CHECK_UNKNOWN) { probe_ent_attr_add(ste_ent, "entity_check", r0 = SEXP_number_newu_32(ochk)); SEXP_free(r0); } oext = oval_state_content_get_check_existence(content); if (oext != OVAL_EXISTENCE_UNKNOWN) { probe_ent_attr_add(ste_ent, "check_existence", r0 = SEXP_number_newu_32(oext)); SEXP_free(r0); } vr_type = oval_entity_get_varref_type(ent); if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE || vr_type == OVAL_ENTITY_VARREF_ELEMENT) { SEXP_t *val_lst; struct oval_variable *var; oval_datatype_t dt; var = oval_entity_get_variable(ent); dt = oval_entity_get_datatype(ent); if (oval_varref_elm_to_sexp(sess, var, dt, &val_lst, NULL) != 0) goto fail; SEXP_list_add(ste_ent, val_lst); SEXP_free(val_lst); } SEXP_list_add(ste, ste_ent); SEXP_free(ste_ent); } oval_state_content_iterator_free(contents); *out_sexp = ste; return (0); fail: oval_state_content_iterator_free(contents); SEXP_vfree(ste, ste_ent, NULL); return (-1); }
int oval_object_to_sexp(void *sess, const char *typestr, struct oval_syschar *syschar, SEXP_t **out_sexp) { unsigned int ent_cnt, varref_cnt; int ret; SEXP_t *obj_sexp, *elm, *varrefs, *ent_lst, *lst, *stmp; SEXP_t *r0, *r1, *r2, *obj_attr, sm0, sm1; struct oval_object *object; struct oval_object_content_iterator *cit; struct oval_behavior_iterator *bit; struct oval_object_content *content; struct oval_entity *entity; char obj_name[128]; const char *obj_id; object = oval_syschar_get_object(syschar); /* * Object name & attributes (id) */ ret = snprintf(obj_name, sizeof obj_name, "%s_object", typestr); if (ret<0 || (unsigned int) ret > sizeof obj_name) { dE("obj_name length too short"); return -1; } // even though it returns const char* it has to be freed :-( char *obj_over = (char*)oval_schema_version_to_cstr(oval_object_get_platform_schema_version(object)); obj_id = oval_object_get_id(object); obj_attr = probe_attr_creat("id", SEXP_string_new_r(&sm0, obj_id, strlen(obj_id)), "oval_version", SEXP_string_new_r(&sm1, obj_over, strlen(obj_over)), NULL); free(obj_over); obj_sexp = probe_obj_new(obj_name, obj_attr); SEXP_free_r(&sm0); SEXP_free_r(&sm1); SEXP_free(obj_attr); /* * Object content */ ent_lst = SEXP_list_new(NULL); varrefs = NULL; ent_cnt = varref_cnt = 0; cit = oval_object_get_object_contents(object); while (oval_object_content_iterator_has_more(cit)) { oval_check_t ochk; oval_entity_varref_type_t vr_type; content = oval_object_content_iterator_next(cit); elm = NULL; lst = ent_lst; switch (oval_object_content_get_type(content)) { case OVAL_OBJECTCONTENT_ENTITY: entity = oval_object_content_get_entity(content); elm = oval_entity_to_sexp(entity); if (elm == NULL) break; ochk = oval_object_content_get_varCheck(content); if (ochk != OVAL_CHECK_UNKNOWN) { probe_ent_attr_add(elm, "var_check", r0 = SEXP_number_newu_32(ochk)); SEXP_free(r0); } ret = 0; vr_type = oval_entity_get_varref_type(entity); if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE) { const char *var_id = oval_variable_get_id(oval_entity_get_variable(entity)); const char *field_name = oval_object_content_get_field_name(content); dI("Object '%s' references variable '%s' in '%s' field.", obj_id, var_id, field_name); ret = oval_varref_attr_to_sexp(sess, entity, syschar, &stmp); if (ret == 0) { if (varrefs == NULL) varrefs = SEXP_list_new(NULL); SEXP_list_add(varrefs, stmp); SEXP_free(stmp); // todo: don't add duplicates ++varref_cnt; lst = obj_sexp; ++ent_cnt; } } else if (vr_type == OVAL_ENTITY_VARREF_ELEMENT) { SEXP_t *val_lst; struct oval_variable *var; oval_datatype_t dt; var = oval_entity_get_variable(entity); dt = oval_entity_get_datatype(entity); ret = oval_varref_elm_to_sexp(sess, var, dt, &val_lst, syschar); if (ret == 0) { SEXP_list_add(elm, val_lst); SEXP_free(val_lst); } } if (ret != 0) { SEXP_t s_flag; SEXP_number_newi_32_r(&s_flag, SYSCHAR_FLAG_DOES_NOT_EXIST); probe_item_attr_add(obj_sexp, "skip_eval", &s_flag); SEXP_free_r(&s_flag); SEXP_free(elm); SEXP_free(ent_lst); if (varrefs != NULL) SEXP_free(varrefs); oval_object_content_iterator_free(cit); *out_sexp = obj_sexp; return (0); } break; case OVAL_OBJECTCONTENT_SET: elm = oval_set_to_sexp(oval_object_content_get_setobject(content)); break; case OVAL_OBJECTCONTENT_FILTER: { struct oval_filter *filter = oval_object_content_get_filter(content); struct oval_state *ste = oval_filter_get_state(filter); const char *ste_id = oval_state_get_id(ste); oval_filter_action_t action = oval_filter_get_filter_action(filter); const char *action_text = oval_filter_action_get_text(action); dI("Object '%s' has a filter that %ss items conforming to state '%s'.", obj_id, action_text, ste_id); elm = oval_filter_to_sexp(filter); } break; case OVAL_OBJECTCONTENT_UNKNOWN: break; } if (elm == NULL) { SEXP_free(obj_sexp); SEXP_free(ent_lst); if (varrefs != NULL) SEXP_free(varrefs); oval_object_content_iterator_free(cit); return -1; } SEXP_list_add(lst, elm); SEXP_free(elm); } if (varrefs != NULL) { // todo: SEXP_list_push() stmp = SEXP_list_new(r0 = SEXP_string_new("varrefs", 7), r1 = SEXP_number_newu(varref_cnt), r2 = SEXP_number_newu(ent_cnt), NULL); SEXP_vfree(r0, r1, r2, NULL); r0 = SEXP_list_join(stmp, varrefs); SEXP_list_add(obj_sexp, r0); SEXP_vfree(stmp, varrefs, r0, NULL); } stmp = SEXP_list_join(obj_sexp, ent_lst); SEXP_free(obj_sexp); SEXP_free(ent_lst); obj_sexp = stmp; oval_object_content_iterator_free(cit); /* * Object behaviors */ bit = oval_object_get_behaviors(object); if (oval_behavior_iterator_has_more(bit)) { elm = oval_behaviors_to_sexp(bit); SEXP_list_add(obj_sexp, elm); SEXP_free(elm); } oval_behavior_iterator_free(bit); *out_sexp = obj_sexp; return (0); }
static int oval_varref_attr_to_sexp(void *sess, struct oval_entity *entity, struct oval_syschar *syschar, SEXP_t **out_sexp) { unsigned int val_cnt = 0; SEXP_t *val_lst, *val_sexp, *varref, *id_sexp, *val_cnt_sexp; oval_datatype_t dt; struct oval_variable *var; struct oval_value_iterator *vit; struct oval_value *val; oval_syschar_collection_flag_t flag; char msg[100]; int ret = 0; var = oval_entity_get_variable(entity); if (oval_probe_query_variable(sess, var) != 0) { dE("Can't convert variable reference to SEXP."); return -1; } flag = oval_variable_get_collection_flag(var); switch (flag) { case SYSCHAR_FLAG_COMPLETE: case SYSCHAR_FLAG_INCOMPLETE: vit = oval_variable_get_values(var); if (oval_value_iterator_has_more(vit)) break; oval_value_iterator_free(vit); /* fall through */ case SYSCHAR_FLAG_DOES_NOT_EXIST: snprintf(msg, sizeof(msg), "Referenced variable has no values (%s).", oval_variable_get_id(var)); dI("%s", msg); ret = 1; break; default: snprintf(msg, sizeof(msg), "There was a problem processing referenced variable (%s).", oval_variable_get_id(var)); dW("%s", msg); ret = 1; } if (ret) { oval_syschar_add_new_message(syschar, msg, OVAL_MESSAGE_LEVEL_WARNING); oval_syschar_set_flag(syschar, SYSCHAR_FLAG_DOES_NOT_EXIST); return ret; } val_lst = SEXP_list_new(NULL); while (oval_value_iterator_has_more(vit)) { val = oval_value_iterator_next(vit); dt = oval_entity_get_datatype(entity); val_sexp = oval_value_to_sexp(val, dt); if (val_sexp == NULL) { oval_syschar_add_new_message(syschar, "Failed to convert variable value.", OVAL_MESSAGE_LEVEL_ERROR); oval_syschar_set_flag(syschar, SYSCHAR_FLAG_ERROR); SEXP_free(val_lst); oval_value_iterator_free(vit); return -1; } SEXP_list_add(val_lst, val_sexp); SEXP_free(val_sexp); ++val_cnt; } oval_value_iterator_free(vit); id_sexp = SEXP_string_newf("%s", oval_variable_get_id(var)); val_cnt_sexp = SEXP_number_newu(val_cnt); varref = SEXP_list_new(id_sexp, val_cnt_sexp, val_lst, NULL); SEXP_free(id_sexp); SEXP_free(val_cnt_sexp); SEXP_free(val_lst); *out_sexp = varref; return 0; }