static int eval_data(const char *type, const char *local_address, unsigned int local_port) { SEXP_t *r0; r0 = SEXP_string_newf("%s", type); if (probe_entobj_cmp(req.protocol_ent, r0) != OVAL_RESULT_TRUE) { SEXP_free(r0); return 0; } SEXP_free(r0); r0 = SEXP_string_newf("%s", local_address); if (probe_entobj_cmp(req.local_address_ent, r0) != OVAL_RESULT_TRUE) { SEXP_free(r0); return 0; } SEXP_free(r0); r0 = SEXP_number_newu_32(local_port); if (probe_entobj_cmp(req.local_port_ent, r0) != OVAL_RESULT_TRUE) { SEXP_free(r0); return 0; } SEXP_free(r0); return 1; }
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 SEXP_t *oval_record_field_STATE_to_sexp(struct oval_record_field *rf) { struct oval_entity *rf_ent; struct oval_variable *var; oval_check_t ochk; oval_datatype_t dt; SEXP_t *rf_sexp, *r0; rf_ent = oval_entity_new(NULL); oval_entity_set_name(rf_ent, oval_record_field_get_name(rf)); oval_entity_set_operation(rf_ent, oval_record_field_get_operation(rf)); dt = oval_record_field_get_datatype(rf); oval_entity_set_datatype(rf_ent, dt); var = oval_record_field_get_variable(rf); if (var != NULL) { oval_entity_set_varref_type(rf_ent, OVAL_ENTITY_VARREF_ATTRIBUTE); oval_entity_set_variable(rf_ent, var); } else { struct oval_value *val; val = oval_value_new(dt, oval_record_field_get_value(rf)); oval_entity_set_value(rf_ent, val); } rf_sexp = oval_entity_to_sexp(rf_ent); ochk = oval_record_field_get_var_check(rf); if (ochk != OVAL_CHECK_UNKNOWN) { probe_ent_attr_add(rf_sexp, "var_check", r0 = SEXP_number_newu_32(ochk)); SEXP_free(r0); } ochk = oval_record_field_get_ent_check(rf); if (ochk != OVAL_CHECK_UNKNOWN) { probe_ent_attr_add(rf_sexp, "entity_check", r0 = SEXP_number_newu_32(ochk)); SEXP_free(r0); } oval_entity_free(rf_ent); return rf_sexp; }
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 SEXP_t *oval_set_to_sexp(struct oval_setobject *set) { SEXP_t *elm, *elm_name; SEXP_t *r0, *r1, *r2; elm_name = SEXP_list_new(r0 = SEXP_string_new("set", 3), /* operation */ r1 = SEXP_string_new(":operation", 10), r2 = SEXP_number_newu_32(oval_setobject_get_operation(set)), NULL); SEXP_free(r0); SEXP_free(r1); SEXP_free(r2); elm = SEXP_list_new(elm_name, NULL); SEXP_free(elm_name); switch (oval_setobject_get_type(set)) { case OVAL_SET_AGGREGATE:{ struct oval_setobject_iterator *sit; struct oval_setobject *subset; sit = oval_setobject_get_subsets(set); while (oval_setobject_iterator_has_more(sit)) { subset = oval_setobject_iterator_next(sit); SEXP_list_add(elm, r0 = oval_set_to_sexp(subset)); SEXP_free(r0); } oval_setobject_iterator_free(sit); } break; case OVAL_SET_COLLECTIVE:{ struct oval_object_iterator *oit; struct oval_filter_iterator *fit; struct oval_object *obj; SEXP_t *subelm; oit = oval_setobject_get_objects(set); while (oval_object_iterator_has_more(oit)) { obj = oval_object_iterator_next(oit); subelm = SEXP_list_new(r0 = SEXP_string_new("obj_ref", 7), r1 = SEXP_string_newf("%s", oval_object_get_id(obj)), NULL); SEXP_free(r0); SEXP_free(r1); SEXP_list_add(elm, subelm); SEXP_free(subelm); } oval_object_iterator_free(oit); fit = oval_setobject_get_filters(set); while (oval_filter_iterator_has_more(fit)) { struct oval_filter *fil; fil = oval_filter_iterator_next(fit); subelm = oval_filter_to_sexp(fil); SEXP_list_add(elm, subelm); SEXP_free(subelm); } oval_filter_iterator_free(fit); } break; default: abort(); } return (elm); }
int main (void) { SEXP_t *s_exp; int8_t i8 = -1; uint8_t u8 = 1; int16_t i16 = -32000; uint16_t u16 = 65000; int32_t i32 = -100000; uint32_t u32 = 100000; int64_t i64 = -1 * (1 << 30); uint64_t u64 = (uint64_t)1 << 48; double f = 123.456; s_exp = SEXP_number_newi_8 (i8); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newu_8 (u8); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newi_16 (i16); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newu_16 (u16); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newi_32 (i32); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newu_32 (u32); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newi_64 (i64); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newu_64 (u64); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); s_exp = SEXP_number_newf (f); SEXP_fprintfa (stdout, s_exp); putc('\n', stdout); SEXP_free (s_exp); return (0); }
static int read_process(SEXP_t *cmd_ent, SEXP_t *pid_ent, probe_ctx *ctx) { int err = 1, max_cap_id; DIR *d; struct dirent *ent; oval_version_t oval_version; d = opendir("/proc"); if (d == NULL) return err; // Get the time tick hertz ticks = (unsigned long)sysconf(_SC_CLK_TCK); get_boot_time(); oval_version = probe_obj_get_schema_version(probe_ctx_getobject(ctx)); if (oval_version_cmp(oval_version, OVAL_VERSION(5.11)) < 0) { max_cap_id = OVAL_5_8_MAX_CAP_ID; } else { max_cap_id = OVAL_5_11_MAX_CAP_ID; } struct oscap_buffer *cmdline_buffer = oscap_buffer_new(); char cmd_buffer[1 + 15 + 11 + 1]; // Format:" [ cmd:15 ] <defunc>" cmd_buffer[0] = '['; // Scan the directories while (( ent = readdir(d) )) { int fd, len; char buf[256]; char *tmp, state, tty_dev[128]; int pid, ppid, pgrp, session, tty_nr, tpgid; unsigned flags, sched_policy; unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime; long cutime, cstime, priority, cnice, nthreads, itrealvalue; unsigned long long start; SEXP_t *cmd_sexp = NULL, *pid_sexp = NULL; // Skip non-process58 dir entries if(*ent->d_name<'0' || *ent->d_name>'9') continue; errno = 0; pid = strtol(ent->d_name, NULL, 10); if (errno || pid == 2) // skip err & kthreads continue; // Parse up the stat file for the proc snprintf(buf, 32, "/proc/%d/stat", pid); fd = open(buf, O_RDONLY, 0); if (fd < 0) continue; len = read(fd, buf, sizeof buf - 1); close(fd); if (len < 40) continue; buf[len] = 0; tmp = strrchr(buf, ')'); if (tmp) *tmp = 0; else continue; memset(cmd_buffer + 1, 0, sizeof(cmd_buffer)-1); // clear cmd after starting '[' sscanf(buf, "%d (%15c", &ppid, cmd_buffer + 1); sscanf(tmp+2, "%c %d %d %d %d %d " "%u %lu %lu %lu %lu " "%lu %lu %lu %ld %ld " "%ld %ld %ld %llu", &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, &minflt, &cminflt, &majflt, &cmajflt, &uutime, &ustime, &cutime, &cstime, &priority, &cnice, &nthreads, &itrealvalue, &start ); // Skip kthreads if (ppid == 2) continue; const char* cmd; if (state == 'Z') { // zombie cmd = make_defunc_str(cmd_buffer); } else { snprintf(buf, 32, "/proc/%d/cmdline", pid); if (get_process_cmdline(buf, cmdline_buffer)) { cmd = oscap_buffer_get_raw(cmdline_buffer); // use full cmdline } else { cmd = cmd_buffer + 1; } } err = 0; // If we get this far, no permission problems dI("Have command: %s\n", cmd); cmd_sexp = SEXP_string_newf("%s", cmd); pid_sexp = SEXP_number_newu_32(pid); if ((cmd_sexp == NULL || probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) && (pid_sexp == NULL || probe_entobj_cmp(pid_ent, pid_sexp) == OVAL_RESULT_TRUE) ) { struct result_info r; unsigned long t = uutime/ticks + ustime/ticks; char tbuf[32], sbuf[32], *selinux_domain_label, **posix_capabilities; int tday,tyear; time_t s_time; struct tm *proc, *now; const char *fmt; // Now get scheduler policy sched_policy = sched_getscheduler(pid); switch (sched_policy) { case SCHED_OTHER: r.scheduling_class = "TS"; break; case SCHED_BATCH: r.scheduling_class = "B"; break; #ifdef SCHED_IDLE case SCHED_IDLE: r.scheduling_class = "#5"; break; #endif case SCHED_FIFO: r.scheduling_class = "FF"; break; case SCHED_RR: r.scheduling_class = "RR"; break; default: r.scheduling_class = "?"; break; } // Calculate the start time s_time = time(NULL); now = localtime(&s_time); tyear = now->tm_year; tday = now->tm_yday; s_time = boot + (start / ticks); proc = localtime(&s_time); // Select format based on how long we've been running // // FROM THE SPEC: // "This is the time of day the process started formatted in HH:MM:SS if // the same day the process started or formatted as MMM_DD (Ex.: Feb_5) // if process started the previous day or further in the past." // if (tday != proc->tm_yday || tyear != proc->tm_year) fmt = "%b_%d"; else fmt = "%H:%M:%S"; strftime(sbuf, sizeof(sbuf), fmt, proc); r.command_line = cmd; r.exec_time = convert_time(t, tbuf, sizeof(tbuf)); r.pid = pid; r.ppid = ppid; r.priority = priority; r.start_time = sbuf; dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV); r.tty = tty_dev; r.exec_shield = (get_exec_shield_status(pid) > 0); selinux_domain_label = get_selinux_label(pid); r.selinux_domain_label = selinux_domain_label; posix_capabilities = get_posix_capability(pid, max_cap_id); r.posix_capability = posix_capabilities; r.session_id = session; get_uids(pid, &r); report_finding(&r, ctx); if (selinux_domain_label != NULL) free(selinux_domain_label); if (posix_capabilities != NULL) { char **posix_capabilities_p = posix_capabilities; while (*posix_capabilities_p) free(*posix_capabilities_p++); free(posix_capabilities); } } SEXP_free(cmd_sexp); SEXP_free(pid_sexp); } closedir(d); oscap_buffer_free(cmdline_buffer); return err; }