示例#1
0
static void report_finding(struct result_info *res, probe_ctx *ctx)
{
        SEXP_t *item;
	SEXP_t *se_ruid;

	if (oval_version_cmp(over, OVAL_VERSION(5.8)) < 0) {
		se_ruid = NULL;
	} else {
		se_ruid = SEXP_number_newu_64(res->ruid);
	}

        item = probe_item_create(OVAL_UNIX_PROCESS, NULL,
                                 "command",   OVAL_DATATYPE_STRING, res->command,
                                 "exec_time", OVAL_DATATYPE_STRING, res->exec_time,
                                 "pid",       OVAL_DATATYPE_INTEGER, (int64_t)res->pid,
                                 "ppid",      OVAL_DATATYPE_INTEGER, (int64_t)res->ppid,
                                 "priority",  OVAL_DATATYPE_INTEGER, (int64_t)res->priority,
				 "ruid",      OVAL_DATATYPE_SEXP, se_ruid,
                                 "scheduling_class", OVAL_DATATYPE_STRING, res->scheduling_class,
                                 "start_time", OVAL_DATATYPE_STRING, res->start_time,
                                 "tty",          OVAL_DATATYPE_STRING, res->tty,
                                 "user_id",    OVAL_DATATYPE_INTEGER, (int64_t)res->user_id,
                                 NULL);

        probe_item_collect(ctx, item);
}
示例#2
0
int probe_main(probe_ctx *ctx, void *probe_arg)
{
	SEXP_t *unit_entity, *probe_in, *property_entity;
	oval_version_t oval_version;

	probe_in = probe_ctx_getobject(ctx);
	oval_version = probe_obj_get_schema_version(probe_in);

	if (oval_version_cmp(oval_version, OVAL_VERSION(5.11)) < 0) {
		// OVAL 5.10 and less
		return PROBE_EOPNOTSUPP;
	}

	unit_entity = probe_obj_getent(probe_in, "unit", 1);
	property_entity = probe_obj_getent(probe_in, "property", 1);

	DBusError dbus_error;
	DBusConnection *dbus_conn;

	dbus_error_init(&dbus_error);
	dbus_conn = connect_dbus();

	if (dbus_conn == NULL) {
		dbus_error_free(&dbus_error);
		SEXP_free(property_entity);
		SEXP_free(unit_entity);
		return PROBE_ESYSTEM;
	}

	struct unit_callback_vars vars;

	vars.dbus_conn = dbus_conn;
	vars.ctx = ctx;
	vars.unit_entity = unit_entity;
	vars.property_entity = property_entity;

	get_all_systemd_units(dbus_conn, unit_callback, &vars);

	SEXP_free(unit_entity);
	SEXP_free(property_entity);
	dbus_error_free(&dbus_error);
	disconnect_dbus(dbus_conn);

	return 0;
}
示例#3
0
static int collect_item(probe_ctx *ctx, oval_version_t over, struct mntent *mnt_ent)
#endif
{
        SEXP_t *item;
        char   *uuid = "", *tok, *save = NULL, **mnt_opts;
        uint8_t mnt_ocnt;
        struct statvfs stvfs;

        /*
         * Get FS stats
         */
        if (statvfs(mnt_ent->mnt_dir, &stvfs) != 0)
                return (-1);

        /*
         * Get UUID
         */
#if defined(HAVE_BLKID_GET_TAG_VALUE)
        uuid = blkid_get_tag_value(blkcache, "UUID", mnt_ent->mnt_fsname);
        if (uuid == NULL) {
	        uuid = "";
        }
#endif
        /*
         * Create a NULL-terminated array from the mount options
         */
        mnt_opts = oscap_alloc(sizeof(char *) * 2);
        mnt_ocnt = 0;

        tok = strtok_r(mnt_ent->mnt_opts, ",", &save);

        do {
                mnt_opts[++mnt_ocnt - 1] = tok;
                mnt_opts = oscap_realloc(mnt_opts,
                                         sizeof(char *) * (mnt_ocnt + 1));
                mnt_opts[mnt_ocnt] = NULL;
        } while ((tok = strtok_r(NULL, ",", &save)) != NULL);

        dI("mnt_ocnt = %d, mnt_opts[mnt_ocnt]=%p\n", mnt_ocnt, mnt_opts[mnt_ocnt]);

	/*
	 * "Correct" the type (this won't be (hopefully) needed in a later version
	 * of OVAL)
	 */
        if (oval_version_cmp(over, OVAL_VERSION(5.10)) < 0)
	        mnt_ent->mnt_type = (char *)correct_fstype(mnt_ent->mnt_type);

        /*
         * Create the item
         */
        item = probe_item_create(OVAL_LINUX_PARTITION, NULL,
                                 "mount_point",   OVAL_DATATYPE_STRING,   mnt_ent->mnt_dir,
                                 "device",        OVAL_DATATYPE_STRING,   mnt_ent->mnt_fsname,
                                 "uuid",          OVAL_DATATYPE_STRING,   uuid,
                                 "fs_type",       OVAL_DATATYPE_STRING,   mnt_ent->mnt_type,
                                 "mount_options", OVAL_DATATYPE_STRING_M, mnt_opts,
                                 "total_space",   OVAL_DATATYPE_INTEGER, (int64_t)stvfs.f_blocks,
                                 "space_used",    OVAL_DATATYPE_INTEGER, (int64_t)(stvfs.f_blocks - stvfs.f_bfree),
                                 "space_left",    OVAL_DATATYPE_INTEGER, (int64_t)stvfs.f_bfree,
                                 NULL);

#if defined(HAVE_BLKID_GET_TAG_VALUE)
        /*
         * If the partition doesn't have an UUID assigned, set the uuid entity status to
         * "does not exist" which means that the value was collected but does not exist
         * on the system.
         */
        if (strcmp(uuid, "") == 0) {
	        probe_itement_setstatus(item, "uuid", 1, SYSCHAR_STATUS_DOES_NOT_EXIST);
        }
#else
	/* Compiled without blkid library, we don't collect UUID */
	probe_itement_setstatus(item, "uuid", 1, SYSCHAR_STATUS_NOT_COLLECTED);
#endif /* HAVE_BLKID_GET_TAG_VALUE */

        probe_item_collect(ctx, item);
        oscap_free(mnt_opts);

        return (0);
}
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_result_t ste_ent_res;
		struct oval_sysent_iterator *item_entities_itr;
		struct oresults ent_ores;
		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_version_t over = oval_state_get_schema_version(state);
			if (oval_version_cmp(over, OVAL_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);
		state_entity_operation = oval_entity_get_operation(state_entity);

		ores_clear(&ent_ores);
		found_matching_item = false;

		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;

			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_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_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;
}
示例#5
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;
}