Пример #1
0
static int collect_item(struct route_info *rt, probe_ctx *ctx)
{
	SEXP_t *item, *rt_dst;
        oval_datatype_t addr_type;

	rt_dst = SEXP_string_new(rt->ip_dst, strlen(rt->ip_dst));

	if (probe_entobj_cmp(rt->ip_dst_ent, rt_dst) != OVAL_RESULT_TRUE) {
		SEXP_free(rt_dst);
		return 0;
	}

        addr_type = rt->ip_version == 4 ? OVAL_DATATYPE_IPV4ADDR : OVAL_DATATYPE_IPV6ADDR;
	
	/* create the item */
	item = probe_item_create(OVAL_UNIX_ROUTINGTABLE, NULL,
				"destination",    addr_type, rt->ip_dst,
				"gateway",        addr_type, rt->ip_gw,
				"flags",          OVAL_DATATYPE_STRING_M, rt->rt_flags,
				"interface_name", OVAL_DATATYPE_STRING,   rt->if_name,
				NULL);

        SEXP_free(rt_dst);
	return probe_item_collect(ctx, item) == 2 ? 1 : 0;
}
Пример #2
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);
}
Пример #3
0
int probe_main (probe_ctx *ctx, void *arg)
{
        SEXP_t *object;
        struct runlevel_req request_st;
        struct runlevel_rep *reply_st = NULL;

        object = probe_ctx_getobject(ctx);

	request_st.service_name_ent = probe_obj_getent(object, "service_name", 1);
	if (request_st.service_name_ent == NULL) {
		dI("%s: element not found", "service_name");

		return PROBE_ENOELM;
	}

	request_st.runlevel_ent = probe_obj_getent(object, "runlevel", 1);
	if (request_st.runlevel_ent == NULL) {
		SEXP_free(request_st.service_name_ent);
		dI("%s: element not found", "runlevel");

		return PROBE_ENOELM;
	}

	if (get_runlevel(&request_st, &reply_st) == -1) {
		SEXP_t *msg;

		msg = probe_msg_creat(OVAL_MESSAGE_LEVEL_ERROR, "get_runlevel failed.");
		probe_cobj_add_msg(probe_ctx_getresult(ctx), msg);
		SEXP_free(msg);
		probe_cobj_set_flag(probe_ctx_getresult(ctx), SYSCHAR_FLAG_ERROR);
	} else {
		struct runlevel_rep *next_rep;
		SEXP_t *item;

		while (reply_st != NULL) {
			dI("get_runlevel: [0]=\"%s\", [1]=\"%s\", [2]=\"%d\", [3]=\"%d\"",
			   reply_st->service_name, reply_st->runlevel, reply_st->start, reply_st->kill);

                        item = probe_item_create(OVAL_UNIX_RUNLEVEL, NULL,
                                                 "service_name", OVAL_DATATYPE_STRING,  reply_st->service_name,
                                                 "runlevel",     OVAL_DATATYPE_STRING,  reply_st->runlevel,
                                                 "start",        OVAL_DATATYPE_BOOLEAN, reply_st->start,
                                                 "kill",         OVAL_DATATYPE_BOOLEAN, reply_st->kill,
                                                 NULL);

                        probe_item_collect(ctx, item);

			next_rep = reply_st->next;
			oscap_free(reply_st->service_name);
			oscap_free(reply_st->runlevel);
			oscap_free(reply_st);
			reply_st = next_rep;
		}
        }

        SEXP_free(request_st.runlevel_ent);
        SEXP_free(request_st.service_name_ent);

	return 0;
}
Пример #4
0
static void rpmverify_additem(probe_ctx *ctx, struct rpmverify_res *res)
{
        SEXP_t *item;

#define VF_RESULT(f) (res->oflags & (f) ? "not performed" : (res->vflags & RPMVERIFY_FAILURES ? "not performed" : (res->vflags & (f) ? "fail" : "pass")))
#define FF_RESULT(f) (res->fflags & (f) ? true : false)

        item = probe_item_create(OVAL_LINUX_RPMVERIFY, NULL,
                                 "name",                OVAL_DATATYPE_STRING, res->name,
                                 "filepath",            OVAL_DATATYPE_STRING, res->file,
                                 "size_differs",        OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_FILESIZE),
                                 "mode_differs",        OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_MODE),
                                 "md5_differs",         OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_MD5),
                                 "device_differs",      OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_RDEV),
                                 "link_mismatch",       OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_LINKTO),
                                 "ownership_differs",   OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_USER),
                                 "group_differs",       OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_GROUP),
                                 "mtime_differs",       OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_MTIME),
#ifndef HAVE_LIBRPM44
                                 "capabilities_differ", OVAL_DATATYPE_STRING, VF_RESULT(RPMVERIFY_CAPS),
#endif
                                 "configuration_file",  OVAL_DATATYPE_BOOLEAN, FF_RESULT(RPMFILE_CONFIG),
                                 "documentation_file",  OVAL_DATATYPE_BOOLEAN, FF_RESULT(RPMFILE_DOC),
                                 "ghost_file",          OVAL_DATATYPE_BOOLEAN, FF_RESULT(RPMFILE_GHOST),
                                 "license_file",        OVAL_DATATYPE_BOOLEAN, FF_RESULT(RPMFILE_LICENSE),
                                 "readme_file",         OVAL_DATATYPE_BOOLEAN, FF_RESULT(RPMFILE_README),
                                 NULL);

        probe_item_collect(ctx, item);
}
Пример #5
0
static int unit_callback(const char *unit, void *cbarg)
{
	struct unit_callback_vars *vars = (struct unit_callback_vars *)cbarg;
	SEXP_t *se_unit = SEXP_string_new(unit, strlen(unit));

	if (probe_entobj_cmp(vars->unit_entity, se_unit) != OVAL_RESULT_TRUE) {
		/* Do nothing, continue with the next unit */
		SEXP_free(se_unit);
		return 0;
	}

	vars->se_unit = se_unit;
	vars->se_property = NULL;
	vars->item = NULL;

	char *unit_path = get_path_by_unit(vars->dbus_conn, unit);

	if (unit_path == NULL) {
		return 1;
	}

	get_all_properties_by_unit_path(vars->dbus_conn, unit_path,
					property_callback, vars);

	if (vars->item != NULL) {
		probe_item_collect(vars->ctx, vars->item);
		vars->item = NULL;
		SEXP_free(vars->se_property);
		vars->se_property = NULL;
	}

	SEXP_free(se_unit);
	return 0;
}
Пример #6
0
int probe_main(probe_ctx *ctx, void *arg)
{
        SEXP_t *item_sexp;

	item_sexp = probe_item_creat ("process_item", NULL, NULL);
        probe_item_setstatus (item_sexp, SYSCHAR_STATUS_NOT_COLLECTED);
        probe_item_collect(ctx, item_sexp);

	return 0;
}
Пример #7
0
static void report_finding(struct result_info *res, llist *l, probe_ctx *ctx)
{
        SEXP_t *item;
        SEXP_t se_lport_mem, se_rport_mem, se_lfull_mem, se_ffull_mem, *se_uid_mem = NULL;
	lnode *n = NULL;

	if (l) {
		n = list_get_cur(l);
	}

	if (n) {
                item = probe_item_create(OVAL_LINUX_INET_LISTENING_SERVER, NULL,
                                 "protocol",             OVAL_DATATYPE_STRING,  res->proto,
                                 "local_address",        OVAL_DATATYPE_STRING,  res->laddr,
				 "local_port",           OVAL_DATATYPE_SEXP, SEXP_number_newu_64_r(&se_lport_mem, res->lport),
                                 "local_full_address",   OVAL_DATATYPE_SEXP,    SEXP_string_newf_r(&se_lfull_mem,
                                                                                                   "%s:%u", res->laddr, res->lport),
                                 "program_name",         OVAL_DATATYPE_STRING,  n->cmd,
                                 "foreign_address",      OVAL_DATATYPE_STRING,  res->raddr,
				 "foreign_port",         OVAL_DATATYPE_SEXP, SEXP_number_newu_64_r(&se_rport_mem, res->rport),
                                 "foreign_full_address", OVAL_DATATYPE_SEXP,    SEXP_string_newf_r(&se_ffull_mem,
                                                                                                   "%s:%u", res->raddr, res->rport),
                                 "pid",                  OVAL_DATATYPE_INTEGER, (int64_t)n->pid,
				 "user_id",              OVAL_DATATYPE_SEXP, se_uid_mem = SEXP_number_newu_64(n->uid),
                                 NULL);
	} else {
                item = probe_item_create(OVAL_LINUX_INET_LISTENING_SERVER, NULL,
                                 "protocol",             OVAL_DATATYPE_STRING,  res->proto,
                                 "local_address",        OVAL_DATATYPE_STRING,  res->laddr,
				 "local_port",           OVAL_DATATYPE_SEXP, SEXP_number_newu_64_r(&se_lport_mem, res->lport),
                                 "local_full_address",   OVAL_DATATYPE_SEXP,    SEXP_string_newf_r(&se_lfull_mem,
                                                                                                   "%s:%u", res->laddr, res->lport),
                                 "foreign_address",      OVAL_DATATYPE_STRING,  res->raddr,
				 "foreign_port",         OVAL_DATATYPE_SEXP, SEXP_number_newu_64_r(&se_rport_mem, res->rport),
                                 "foreign_full_address", OVAL_DATATYPE_SEXP,    SEXP_string_newf_r(&se_ffull_mem,
                                                                                                   "%s:%u", res->raddr, res->rport),
                                 NULL);
	}

        probe_item_collect(ctx, item);

        SEXP_free_r(&se_lport_mem);
        SEXP_free_r(&se_rport_mem);
        SEXP_free_r(&se_lfull_mem);
        SEXP_free_r(&se_ffull_mem);
        SEXP_free(se_uid_mem);
}
Пример #8
0
static int property_callback(const char *property, const char *value, void *cbarg)
{
	struct unit_callback_vars *vars = (struct unit_callback_vars *)cbarg;

	if (vars->se_property != NULL) {
		//
		// Compare the previously matched entity to the current one
		// If they are the same, continue to fill the current item
		// with property values. If not, collect the item and create
		// a new one for the current property.
		//
		if (SEXP_strcmp(vars->se_property, property) == 0) {
			SEXP_t *se_value = SEXP_string_new(value, strlen(value));
			probe_item_ent_add(vars->item, "value", NULL, se_value);
			SEXP_free(se_value);
			return 0;
		} else {
			probe_item_collect(vars->ctx, vars->item);
			vars->item = NULL;
			SEXP_free(vars->se_property);
			vars->se_property = NULL;
		}
	}

	SEXP_t *se_property = SEXP_string_new(property, strlen(property));

	if (probe_entobj_cmp(vars->property_entity, se_property) != OVAL_RESULT_TRUE) {
		SEXP_free(se_property);
		return 0;
	}

	vars->se_property = se_property;
	vars->item = probe_item_create(OVAL_LINUX_SYSTEMDUNITPROPERTY, NULL,
				       "unit", OVAL_DATATYPE_SEXP, vars->se_unit,
				       "property", OVAL_DATATYPE_SEXP, vars->se_property,
				       "value", OVAL_DATATYPE_STRING, value,
				       NULL);
	return 0;
}
Пример #9
0
static int get_selinuxboolean(SEXP_t *ut_ent, probe_ctx *ctx)
{
	int err = 1, active, pending, len, i;
	SEXP_t *boolean, *item;
	char **booleans;

	if ( ! is_selinux_enabled()) {
		probe_cobj_set_flag(probe_ctx_getresult(ctx), SYSCHAR_FLAG_NOT_APPLICABLE);
		return 0;
	}

	if (security_get_boolean_names(&booleans, &len) == -1) {
		probe_cobj_set_flag(probe_ctx_getresult(ctx), SYSCHAR_FLAG_ERROR);
		return err;
	}

	for (i = 0; i < len; i++) {
		boolean = SEXP_string_new(booleans[i], strlen(booleans[i]));
		if (probe_entobj_cmp(ut_ent, boolean) == OVAL_RESULT_TRUE) {
			active = security_get_boolean_active(booleans[i]);
			pending = security_get_boolean_pending(booleans[i]);
			item = probe_item_create(
				OVAL_LINUX_SELINUXBOOLEAN, NULL,
				"name", OVAL_DATATYPE_SEXP, boolean,
				"current_status",  OVAL_DATATYPE_BOOLEAN, active,
				"pending_status", OVAL_DATATYPE_BOOLEAN, pending,
			      NULL);
			probe_item_collect(ctx, item);
		}
		SEXP_free(boolean);
	}

	for (i = 0; i < len; i++)
		free(booleans[i]);
        free(booleans);

	return 0;
}
Пример #10
0
static void report_finding(struct result_info *res, probe_ctx *ctx, oval_schema_version_t over)
{
        SEXP_t *item;

        item = probe_item_create(OVAL_UNIX_PASSWORD, NULL,
                                 "username",    OVAL_DATATYPE_STRING, res->username,
                                 "password",    OVAL_DATATYPE_STRING, res->password,
                                 "user_id",     OVAL_DATATYPE_INTEGER, (int64_t)res->user_id,
                                 "group_id",    OVAL_DATATYPE_INTEGER, (int64_t)res->group_id,
                                 "gcos",        OVAL_DATATYPE_STRING, res->gcos,
                                 "home_dir",    OVAL_DATATYPE_STRING, res->home_dir,
                                 "login_shell", OVAL_DATATYPE_STRING, res->login_shell,
                                 NULL);

        if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.10)) >= 0) {
	        SEXP_t last_login;
	        SEXP_number_newi_64_r(&last_login, res->last_login);
	        probe_item_ent_add(item, "last_login", NULL, &last_login);
	        SEXP_free_r(&last_login);
        }

        probe_item_collect(ctx, item);
}
Пример #11
0
static void report_finding(struct result_info *res, llist *l, probe_ctx *ctx, oval_schema_version_t over)
{
        SEXP_t *item, *user_id;
	lnode *n = list_get_cur(l);

	if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.10)) < 0)
		user_id = SEXP_string_newf("%d", n->uid);
	else
		user_id = SEXP_number_newi_64((int64_t)n->uid);

	item = probe_item_create(OVAL_LINUX_IFLISTENERS, NULL,
                                 "interface_name",       OVAL_DATATYPE_STRING,  res->interface_name,
                                 "protocol",             OVAL_DATATYPE_STRING,  res->protocol,
                                 "hw_address",           OVAL_DATATYPE_STRING,  res->hw_address,
                                 "program_name",         OVAL_DATATYPE_STRING,  n->cmd,
                                 "pid",                  OVAL_DATATYPE_INTEGER, (int64_t)n->pid,
				 "user_id",              OVAL_DATATYPE_SEXP, user_id,
                                 NULL);

        probe_item_collect(ctx, item);
	SEXP_free(user_id);

}
Пример #12
0
static void report_finding(struct result_info *res, probe_ctx *ctx)
{
        SEXP_t *item;

        item = probe_item_create(OVAL_UNIX_PROCESS58, NULL,
                                 "command_line", OVAL_DATATYPE_STRING, res->command_line,
                                 "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_INTEGER, (int64_t) res->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,
                                 "exec_shield",  OVAL_DATATYPE_BOOLEAN, (bool)res->exec_shield,
                                 "loginuid",     OVAL_DATATYPE_INTEGER, (int64_t)res->loginuid,
				 "posix_capability", OVAL_DATATYPE_STRING_M, res->posix_capability,
				 "selinux_domain_label", OVAL_DATATYPE_STRING, res->selinux_domain_label,
                                 "session_id", OVAL_DATATYPE_INTEGER, (int64_t)res->session_id,
                                 NULL);

        probe_item_collect(ctx, item);
}
Пример #13
0
static int collect_item(probe_ctx *ctx, oval_schema_version_t over, struct mntent *mnt_ent)
#endif
{
        SEXP_t *item;
        char   *uuid = "", *tok, *save = NULL, **mnt_opts = NULL;
        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_ocnt = 0;

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

        do {
            add_mnt_opt(&mnt_opts, ++mnt_ocnt, tok);
        } while ((tok = strtok_r(NULL, ",", &save)) != NULL);

        /*
         * Check for "remount", "bind" and "move" mount options
         * These options can't be found in /proc/mounts,
         * we must use flags got by statvfs().
         */
        if (stvfs.f_flag & MS_REMOUNT) {
            add_mnt_opt(&mnt_opts, ++mnt_ocnt, "remount");
        }
        if (stvfs.f_flag & MS_BIND) {
            add_mnt_opt(&mnt_opts, ++mnt_ocnt, "bind");
        }
        if (stvfs.f_flag & MS_MOVE) {
            add_mnt_opt(&mnt_opts, ++mnt_ocnt, "move");
        }

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

	/*
	 * "Correct" the type (this won't be (hopefully) needed in a later version
	 * of OVAL)
	 */
        if (oval_schema_version_cmp(over, OVAL_SCHEMA_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);
        free(mnt_opts);

        return (0);
}
static int file_cb (const char *p, const char *f, void *ptr)
{
        char path_buffer[PATH_MAX];
        SEXP_t *item, xattr_name;
        struct cbargs *args = (struct cbargs *) ptr;
        const char *st_path;

        ssize_t xattr_count = -1;
        char   *xattr_buf = NULL;
        size_t  xattr_buflen = 0, i;

	if (f == NULL) {
		st_path = p;
	} else {
		snprintf (path_buffer, sizeof path_buffer, "%s/%s", p, f);
		st_path = path_buffer;
	}

        SEXP_init(&xattr_name);

	do {
		/* estimate the size of the buffer */
		xattr_count = llistxattr(st_path, NULL, 0);

		if (xattr_count == 0)
				return (0);

		if (xattr_count < 0) {
				dI("FAIL: llistxattr(%s, %p, %zu): errno=%u, %s.", errno, strerror(errno));
				return 0;
		}

		/* allocate space for xattr names */
		xattr_buflen = xattr_count;
		xattr_buf    = oscap_realloc(xattr_buf, sizeof(char) * xattr_buflen);

		/* fill the buffer */
		xattr_count = llistxattr(st_path, xattr_buf, xattr_buflen);

		/* check & retry if needed */
	} while (errno == ERANGE);

        if (xattr_count < 0) {
                dI("FAIL: llistxattr(%s, %p, %zu): errno=%u, %s.", errno, strerror(errno));
                oscap_free(xattr_buf);
        }

        /* update lastpath if needed */
        if (!SEXP_emptyp(&gr_lastpath)) {
                if (SEXP_strcmp(&gr_lastpath, p) != 0) {
                        SEXP_free_r(&gr_lastpath);
                        SEXP_string_new_r(&gr_lastpath, p, strlen(p));
                }
        } else
                SEXP_string_new_r(&gr_lastpath, p, strlen(p));

        i = 0;
        /* collect */
        do {
                SEXP_string_new_r(&xattr_name, xattr_buf + i, strlen(xattr_buf +i));

                if (probe_entobj_cmp(args->attr_ent, &xattr_name) == OVAL_RESULT_TRUE) {
                        ssize_t xattr_vallen = -1;
                        char   *xattr_val = NULL;

                        xattr_vallen = lgetxattr(st_path, xattr_buf + i, NULL, 0);
                retry_value:
                        if (xattr_vallen >= 0) {
				// Check possible buffer overflow
				if (sizeof(char) * (xattr_vallen + 1) <= sizeof(char) * xattr_vallen) {
					dE("Attribute is too long.");
					abort();
				}

				// Allocate buffer, '+1' is for trailing '\0'
 				xattr_val    = oscap_realloc(xattr_val, sizeof(char) * (xattr_vallen + 1));

				// we don't want to override space for '\0' by call of 'lgetxattr'
				// we pass only 'xattr_vallen' instead of 'xattr_vallen + 1'
                                xattr_vallen = lgetxattr(st_path, xattr_buf + i, xattr_val, xattr_vallen);

                                if (xattr_vallen < 0 || errno == ERANGE)
                                        goto retry_value;

				xattr_val[xattr_vallen] = '\0';

                                item = probe_item_create(OVAL_UNIX_FILEEXTENDEDATTRIBUTE, NULL,
                                                         "filepath", OVAL_DATATYPE_STRING, f == NULL ? NULL : st_path,
                                                         "path",     OVAL_DATATYPE_SEXP,  &gr_lastpath,
                                                         "filename", OVAL_DATATYPE_STRING, f == NULL ? "" : f,
                                                         "attribute_name", OVAL_DATATYPE_SEXP,   &xattr_name,
                                                         "value",          OVAL_DATATYPE_STRING, xattr_val,
                                                         NULL);

                                oscap_free(xattr_val);
                        } else {
                                dI("FAIL: lgetxattr(%s, %s, NULL, 0): errno=%u, %s.", errno, strerror(errno));

                                item = probe_item_create(OVAL_UNIX_FILEEXTENDEDATTRIBUTE, NULL, NULL);
                                probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);

                                if (xattr_val != NULL)
                                        oscap_free(xattr_val);
                        }

                        probe_item_collect(args->ctx, item); /* XXX: handle ENOMEM */
                }

                SEXP_free_r(&xattr_name);

                /* skip to next name */
                while (i < xattr_buflen && xattr_buf[i] != '\0')
                        ++i;
		++i;
        } while (xattr_buf + i < xattr_buf + xattr_buflen - 1);

        oscap_free(xattr_buf);

        return (0);
}
Пример #15
0
static int process_file(const char *prefix, const char *path, const char *filename, void *arg, oval_schema_version_t over)
{
	struct pfdata *pfd = (struct pfdata *) arg;
	int ret = 0, path_len, filename_len;
	char *whole_path = NULL, *whole_path_with_prefix = NULL;
	FILE *fp = NULL;
	struct stat st;

// todo: move to probe_main()?
	int erroffset = -1;
	pcre *re = NULL;
	const char *error;

	re = pcre_compile(pfd->pattern, PCRE_UTF8, &error, &erroffset, NULL);
	if (re == NULL) {
		return -1;
	}

	if (filename == NULL)
		goto cleanup;

	path_len = strlen(path);
	filename_len = strlen(filename);
	whole_path = malloc(path_len + filename_len + 2);
	memcpy(whole_path, path, path_len);
	if (whole_path[path_len - 1] != FILE_SEPARATOR) {
		whole_path[path_len] = FILE_SEPARATOR;
		++path_len;
	}
	memcpy(whole_path + path_len, filename, filename_len + 1);

	/*
	 * If stat() fails, don't report an error and just skip the file.
	 * This is an expected situation, because the fts_*() functions
	 * are called with the 'FTS_PHYSICAL' option. Normally, stumbling
	 * upon a symlink without a target would cause fts_read() to return
	 * the 'FTS_SLNONE' flag, but the 'FTS_PHYSICAL' option causes it
	 * to return 'FTS_SL' and the presence of a valid target has to
	 * be determined with stat().
	 */
	whole_path_with_prefix = oscap_path_join(prefix, whole_path);
	if (stat(whole_path_with_prefix, &st) == -1)
		goto cleanup;
	if (!S_ISREG(st.st_mode))
		goto cleanup;

	fp = fopen(whole_path_with_prefix, "rb");
	if (fp == NULL) {
		ret = -2;
		goto cleanup;
	}

	int cur_inst = 0;
	char line[4096];

	while (fgets(line, sizeof(line), fp) != NULL) {
		char **substrs;
		int substr_cnt;

		substr_cnt = get_substrings(line, re, 1, &substrs);
		if (substr_cnt > 0) {
			int k;
			SEXP_t *item;

			++cur_inst;
			item = create_item(path, filename, pfd->pattern,
					cur_inst, substrs, substr_cnt, over);

                        probe_item_collect(pfd->ctx, item);

			for (k = 0; k < substr_cnt; ++k)
				free(substrs[k]);
			free(substrs);
		}
	}

 cleanup:
	if (fp != NULL)
		fclose(fp);
	if (whole_path != NULL)
		free(whole_path);
	if (re != NULL)
		pcre_free(re);
	free(whole_path_with_prefix);

	return ret;
}
Пример #16
0
static int read_environment(SEXP_t *pid_ent, SEXP_t *name_ent, probe_ctx *ctx)
{
	int err = 1, pid, fd;
	bool empty;
	size_t env_name_size;
	SEXP_t *env_name, *env_value, *item, *pid_sexp;
	DIR *d;
	struct dirent *d_entry;
	char *buffer, env_file[256], *null_char;
	ssize_t buffer_used;
	size_t buffer_size;

	d = opendir("/proc");
	if (d == NULL) {
		dE("Can't read /proc: errno=%d, %s.\n", errno, strerror (errno));
		return PROBE_EACCESS;
	}

	if ((buffer = oscap_realloc(NULL, BUFFER_SIZE)) == NULL) {
		dE("Can't allocate memory");
		closedir(d);
		return PROBE_EFAULT;
	}
	buffer_size = BUFFER_SIZE;

	while ((d_entry = readdir(d))) {
		if (strspn(d_entry->d_name, "0123456789") != strlen(d_entry->d_name))
			continue;

		pid = atoi(d_entry->d_name);
		pid_sexp = SEXP_number_newi_32(pid);

		if (probe_entobj_cmp(pid_ent, pid_sexp) != OVAL_RESULT_TRUE) {
			SEXP_free(pid_sexp);
			continue;
		}
		SEXP_free(pid_sexp);

		sprintf(env_file, "/proc/%d/environ", pid);

		if ((fd = open(env_file, O_RDONLY)) == -1) {
			dE("Can't open \"%s\": errno=%d, %s.\n", env_file, errno, strerror (errno));
			item = probe_item_create(
					OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL,
					"pid", OVAL_DATATYPE_INTEGER, (int64_t)pid,
					NULL
			);

			probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);
			probe_item_add_msg(item, OVAL_MESSAGE_LEVEL_ERROR,
					   "Can't open \"%s\": errno=%d, %s.", env_file, errno, strerror (errno));
			probe_item_collect(ctx, item);
			continue;
		}

		empty = true;

		if ((buffer_used = read(fd, buffer, buffer_size - 1)) > 0) {
			empty = false;
		}

		while (! empty) {
			while (! (null_char = memchr(buffer, 0, buffer_used))) {
				ssize_t s;
				if ((size_t)buffer_used >= buffer_size) {
					buffer_size += BUFFER_SIZE;
					buffer = oscap_realloc(buffer, buffer_size);
					if (buffer == NULL) {
						dE("Can't allocate memory");
						exit(ENOMEM);
					}

				}
				s = read(fd, buffer + buffer_used, buffer_size - buffer_used);
				if (s <= 0) {
					empty = true;
					buffer[buffer_used++] = 0;
				}
				else {
					buffer_used += s;
				}
			}

			do {
				char *eq_char = strchr(buffer, '=');
				if (eq_char == NULL) {
					/* strange but possible:
					 * $ strings /proc/1218/environ
 					/dev/input/event0 /dev/input/event1 /dev/input/event4 /dev/input/event3
					*/
					buffer_used -= null_char + 1 - buffer;
					memmove(buffer, null_char + 1, buffer_used);
					continue;
				}

				env_name_size =  eq_char - buffer;
				env_name = SEXP_string_new(buffer, env_name_size);
				env_value = SEXP_string_newf("%s", buffer + env_name_size + 1);
				if (probe_entobj_cmp(name_ent, env_name) == OVAL_RESULT_TRUE) {
					item = probe_item_create(
						OVAL_INDEPENDENT_ENVIRONMENT_VARIABLE58, NULL,
						"pid", OVAL_DATATYPE_INTEGER, (int64_t)pid,
						"name",  OVAL_DATATYPE_SEXP, env_name,
						"value", OVAL_DATATYPE_SEXP, env_value,
					      NULL);
					probe_item_collect(ctx, item);
					err = 0;
				}
				SEXP_free(env_name);
				SEXP_free(env_value);

				buffer_used -= null_char + 1 - buffer;
				memmove(buffer, null_char + 1, buffer_used);
			} while ((null_char = memchr(buffer, 0, buffer_used)));
		}

		close(fd);
	}
	closedir(d);
	oscap_free(buffer);
	if (err) {
		SEXP_t *msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR,
				"Can't find process with requested PID.");
		probe_cobj_add_msg(probe_ctx_getresult(ctx), msg);
		SEXP_free(msg);
		err = 0;
	}

	return err;
}
Пример #17
0
int probe_main(probe_ctx *ctx, void *mutex)
{
        LDAP        *ldp;
        LDAPMessage *ldpres, *entry;

        SEXP_t *se_ldap_behaviors = NULL, *se_relative_dn = NULL;
        SEXP_t *se_suffix = NULL, *se_attribute = NULL;
        SEXP_t *sa_scope, *sv_op;
        SEXP_t *item;
        SEXP_t *probe_in;

        char *relative_dn = NULL;
        char *suffix = NULL, *xattribute = NULL;
        char *uri_list, *uri, *uri_save, *attr;

        int   scope;
        char  base[2048];
        char *attrs[3];

        bool a_pattern_match = false, rdn_pattern_match = false;

        /* runtime */
#if defined(PROBE_LDAP_MUTEX)
        assume_r(mutex != NULL, PROBE_EINIT);
#endif
        probe_in = probe_ctx_getobject(ctx);
        se_ldap_behaviors = probe_obj_getent(probe_in, "behaviors", 1);

        if (se_ldap_behaviors != NULL) {
                sa_scope = probe_ent_getattrval(se_ldap_behaviors, "scope");
                SEXP_free(se_ldap_behaviors);

                if (sa_scope == NULL) {
                        dE("Atrribute `scope' is missing!");
                        return (PROBE_ENOATTR);
                }

                if (!SEXP_stringp(sa_scope)) {
                        dE("Invalid value type of the `scope' attribute.");
                        SEXP_free(sa_scope);
                        return (PROBE_EINVAL);
                }

                if (SEXP_strcmp(sa_scope, "ONE") == 0)
                        scope = LDAP_SCOPE_ONELEVEL;
                else if (SEXP_strcmp(sa_scope, "BASE") == 0)
                        scope = LDAP_SCOPE_BASE;
                else if (SEXP_strcmp(sa_scope, "SUBTREE") == 0)
                        scope = LDAP_SCOPE_SUBTREE;
                else {
                        dE("Invalid value of the `scope' attribute.");
                        SEXP_free(sa_scope);
                        return (PROBE_EINVAL);
                }

                SEXP_free(sa_scope);
        } else
                scope = LDAP_SCOPE_BASE;

#define get_string(dst, se_dst, obj, ent_name)                          \
	do {								\
		SEXP_t *__sval;						\
									\
		__sval = probe_obj_getentval (obj, ent_name, 1);	\
									\
		if (__sval != NULL) {					\
                        (dst) = SEXP_string_cstr (__sval);              \
									\
                        if ((dst) == NULL) {                            \
                                SEXP_free(__sval);                      \
                                return (PROBE_EINVAL);                  \
                        }                                               \
                                                                        \
                        (se_dst) = __sval;                              \
		} else {						\
			return (PROBE_ENOATTR);				\
		}							\
	} while (0)

        get_string(suffix,      se_suffix,      probe_in, "suffix");
        get_string(relative_dn, se_relative_dn, probe_in, "relative_dn");
        get_string(xattribute,  se_attribute,   probe_in, "attribute");

        if ((sv_op = probe_ent_getattrval(se_relative_dn, "operation")) != NULL) {
                if (SEXP_number_geti_32(sv_op) == OVAL_OPERATION_PATTERN_MATCH)
                        rdn_pattern_match = true;
                SEXP_free(sv_op);
        }

        if ((sv_op = probe_ent_getattrval(se_attribute, "operation")) != NULL) {
                if (SEXP_number_geti_32(sv_op) == OVAL_OPERATION_PATTERN_MATCH)
                        a_pattern_match = true;
                SEXP_free(sv_op);
        }

        /*
         * Construct the attribute array for ldap_search_*
         *
         * nil   -> "1.1"
         * .*    -> "*"
         * "foo" -> "foo"
         */
        attrs[0] = "objectClass";

        if (xattribute == NULL)
                attrs[1] = strdup("1.1"); /* no attibutes */
        else if (a_pattern_match)
                attrs[1] = strdup("*");   /* collect all, we'll filter them afterwards */
        else
                attrs[1] = xattribute;     /* no pattern match, use the string directly */

        attrs[2] = NULL;

        /*
         * Construct `base'
         */
        assume_r(((relative_dn ? strlen(relative_dn) : 0) +
                  (     suffix ? strlen(suffix)      : 0) + 2) < (sizeof base/sizeof(char)),
                 PROBE_ERANGE);

        if (relative_dn != NULL) {
                strcpy(base, relative_dn);
                strcat(base, ",");
                strcat(base, suffix);
        } else
                strcpy(base, suffix);

        /*
         * Get URIs
         */
        if (ldap_get_option(NULL, LDAP_OPT_URI, &uri_list) != LDAP_OPT_SUCCESS) {
                item = probe_item_creat("ldap57_item", NULL, NULL);

                probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);
                probe_item_collect(ctx, item);

                dE("ldap_get_option failed");
                goto fail0;
        }

        /*
         * Query each URI
         */
        for (;;) {
                char *entry_dn = NULL;

                if ((uri = strtok_r(uri_list, " ,", &uri_save)) == NULL)
                        break;

                ldp = NULL;

                if (ldap_initialize(&ldp, uri) != LDAP_SUCCESS)
                        continue;

                if (ldap_search_ext_s(ldp, base, scope, NULL, attrs, 0,
                                      NULL /* serverctrls */,
                                      NULL /* clientctrls */,
                                      NULL /* timeout */,
                                      0, &ldpres) != LDAP_SUCCESS)
                {
                        item = probe_item_creat("ldap57_item", NULL, NULL);

                        probe_item_setstatus(item, SYSCHAR_STATUS_ERROR);
                        probe_item_collect(ctx, item);

                        dE("ldap_search_ext_s failed");
                        goto fail0;
                }

                entry    = ldap_first_entry(ldp, ldpres);
                entry_dn = ldap_get_dn(ldp, entry);

                while (entry != NULL) {
                        BerElement *berelm = NULL;

                        attr = ldap_first_attribute(ldp, entry, &berelm);

                        /* XXX: pattern match filter */

                        while (attr != NULL) {
                                SEXP_t   *se_value = NULL;
                                ber_tag_t bertag   = LBER_DEFAULT;
                                ber_len_t berlen   = 0;
                                Sockbuf  *berbuf   = NULL;
                                SEXP_t    se_tmp_mem;

                                berbuf = ber_sockbuf_alloc();

                                /*
                                 * Prepare the value (record) entity. Collect only
                                 * primitive (i.e. simple) types.
                                 */
                                se_value = probe_ent_creat1("value", NULL, NULL);
                                probe_ent_setdatatype(se_value, OVAL_DATATYPE_RECORD);

                                /*
                                 * XXX: does ber_get_next() return LBER_ERROR after the last value?
                                 */
                                while ((bertag = ber_get_next(berbuf, &berlen, berelm)) != LBER_ERROR) {
                                        SEXP_t *field = NULL;
                                        oval_datatype_t field_type = OVAL_DATATYPE_UNKNOWN;

                                        switch(bertag & LBER_ENCODING_MASK) {
                                        case LBER_PRIMITIVE:
                                                dI("Found primitive value, bertag = %u", bertag);
						break;
                                        case LBER_CONSTRUCTED:
                                                dW("Don't know how to handle LBER_CONSTRUCTED values");
						/* FALLTHROUGH */
                                        default:
                                                dW("Skipping attribute value, bertag = %u", bertag);
                                                continue;
                                        }

                                        assume_d(bertag & LBER_PRIMITIVE, NULL);

                                        switch(bertag & LBER_BIG_TAG_MASK) {
                                        case LBER_BOOLEAN:
                                        {       /* LDAPTYPE_BOOLEAN */
                                                ber_int_t val = -1;

                                                if (ber_get_boolean(berelm, &val) == LBER_ERROR) {
                                                        dW("ber_get_boolean: LBER_ERROR");
                                                        /* XXX: set error status on field */
                                                        continue;
                                                }

                                                assume_d(val != -1, NULL);
                                                field = probe_ent_creat1("field", NULL, SEXP_number_newb_r(&se_tmp_mem, (bool)val));
                                                field_type = OVAL_DATATYPE_BOOLEAN;
                                                SEXP_free_r(&se_tmp_mem);
                                        }       break;
                                        case LBER_INTEGER:
                                        {       /* LDAPTYPE_INTEGER */
                                                ber_int_t val = -1;

                                                if (ber_get_int(berelm, &val) == LBER_ERROR) {
                                                        dW("ber_get_int: LBER_ERROR");
                                                        /* XXX: set error status on field */
                                                        continue;
                                                }

                                                field = probe_ent_creat1("field", NULL, SEXP_number_newi_r(&se_tmp_mem, (int)val));
                                                field_type = OVAL_DATATYPE_INTEGER;
                                                SEXP_free_r(&se_tmp_mem);
                                        }       break;
                                        case LBER_BITSTRING:
                                                /* LDAPTYPE_BIT_STRING */
                                                dW("LBER_BITSTRING: not implemented");
                                                continue;
                                        case LBER_OCTETSTRING:
                                        {       /*
                                                 * LDAPTYPE_PRINTABLE_STRING
                                                 * LDAPTYPE_NUMERIC_STRING
                                                 * LDAPTYPE_DN_STRING
                                                 * LDAPTYPE_BINARY (?)
                                                 */
                                                char *val = NULL;

                                                if (ber_get_stringa(berelm, &val) == LBER_ERROR) {
                                                        dW("ber_get_stringa: LBER_ERROR");
                                                        /* XXX: set error status on field */
                                                        continue;
                                                }

                                                assume_d(val != NULL, NULL);
                                                field = probe_ent_creat1("field", NULL, SEXP_string_new_r(&se_tmp_mem, val, strlen(val)));
                                                field_type = OVAL_DATATYPE_STRING;
                                                SEXP_free_r(&se_tmp_mem);
                                                ber_memfree(val);
                                        }       break;
                                        case LBER_NULL:
                                                /* XXX: no equivalent LDAPTYPE_? or empty */
                                                dI("LBER_NULL: skipped");
                                                continue;
                                        case LBER_ENUMERATED:
                                                /* XXX: no equivalent LDAPTYPE_? */
                                                dW("Don't know how to handle LBER_ENUMERATED type");
                                                continue;
                                        default:
                                                dW("Unknown attribute value type, bertag = %u", bertag);
                                                continue;
                                        }

                                        if (field != NULL) {
                                                assume_d(field_type != OVAL_DATATYPE_UNKNOWN, NULL);

                                                probe_ent_setdatatype(field, field_type);
                                                probe_ent_attr_add(field, "name", SEXP_string_new_r(&se_tmp_mem, attr, strlen(attr)));
                                                SEXP_list_add(se_value, field);
                                                SEXP_free_r(&se_tmp_mem);
                                                SEXP_free(field);
                                        }
                                }

                                ber_sockbuf_free(berbuf);

                                /*
                                 * Create the item
                                 */
                                item = probe_item_create(OVAL_INDEPENDENT_LDAP57, NULL,
                                                         "suffix",       OVAL_DATATYPE_STRING, suffix,
                                                         "relative_dn",  OVAL_DATATYPE_STRING, relative_dn, /* XXX: pattern match */
                                                         "attribute",    OVAL_DATATYPE_STRING, attr,
                                                         "object_class", OVAL_DATATYPE_STRING, "",
                                                         "ldaptype",     OVAL_DATATYPE_STRING, "",
                                                         NULL);

                                SEXP_list_add(item, se_value);
                                SEXP_free(se_value);

                                probe_item_collect(ctx, item);

                                attr = ldap_next_attribute(ldp, entry, berelm);
                        }

                        ber_free(berelm, 0);
                        ldap_memfree(entry_dn);

                        entry    = ldap_next_entry(ldp, entry);
                        entry_dn = ldap_get_dn(ldp, entry);
                }

                /*
                 * Close the LDAP connection and free resources
                 */
                ldap_unbind_ext_s(ldp, NULL, NULL);
        }

        ldap_memfree(uri_list);

fail0:
        SEXP_free(se_suffix);
        SEXP_free(se_relative_dn);
        SEXP_free(se_attribute);

        free(suffix);
        free(relative_dn);
        free(attrs[1]); /* attribute */

        return (0);
}
Пример #18
0
static int filehash58_cb (const char *p, const char *f, const char *h, probe_ctx *ctx)
{
	SEXP_t *itm;

	char   pbuf[PATH_MAX+1];
	size_t plen, flen;

	int fd;

	if (f == NULL)
		return (0);

	/*
	 * Prepare path
	 */
	plen = strlen (p);
	flen = strlen (f);

	if (plen + flen + 1 > PATH_MAX)
		return (-1);

	memcpy (pbuf, p, sizeof (char) * plen);

	if (p[plen - 1] != FILE_SEPARATOR) {
		pbuf[plen] = FILE_SEPARATOR;
		++plen;
	}

	memcpy (pbuf + plen, f, sizeof (char) * flen);
	pbuf[plen+flen] = '\0';

	/*
	 * Open the file
	 */
	fd = open (pbuf, O_RDONLY);

	if (fd < 0) {
		strerror_r (errno, pbuf, PATH_MAX);
		pbuf[PATH_MAX] = '\0';

		itm = probe_item_create (OVAL_INDEPENDENT_FILE_HASH58, NULL,
					"filepath", OVAL_DATATYPE_STRING, pbuf,
					"path",     OVAL_DATATYPE_STRING, p,
					"filename", OVAL_DATATYPE_STRING, f,
					"hash_type",OVAL_DATATYPE_STRING, h,
					NULL);
		probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR,
			"Can't open \"%s\": errno=%d, %s.", pbuf, errno, strerror (errno));
		probe_item_setstatus(itm, SYSCHAR_STATUS_ERROR);
	} else {
		uint8_t hash_dst[1025];
		size_t  hash_dstlen = sizeof hash_dst;
		char    hash_str[2051];

		crapi_alg_t hash_type;

		hash_type = oscap_string_to_enum(CRAPI_ALG_MAP, h);
		hash_dstlen = oscap_string_to_enum(CRAPI_ALG_MAP_SIZE, h);

		/*
		 * Compute hash value
		 */
		if (crapi_mdigest_fd (fd, 1, hash_type, hash_dst, &hash_dstlen) != 0) {
			close (fd);
			return (-1);
		}

		close (fd);

		hash_str[0] = '\0';
		mem2hex (hash_dst, hash_dstlen, hash_str, sizeof hash_str);

		/*
		 * Create and add the item
		 */
		itm = probe_item_create(OVAL_INDEPENDENT_FILE_HASH58, NULL,
					"filepath", OVAL_DATATYPE_STRING, pbuf,
					"path",     OVAL_DATATYPE_STRING, p,
					"filename", OVAL_DATATYPE_STRING, f,
					"hash_type",OVAL_DATATYPE_STRING, h,
					"hash",     OVAL_DATATYPE_STRING, hash_str,
					NULL);

		if (hash_dstlen == 0) {
			probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR,
					   "Unable to compute %s hash value of \"%s\".", h, pbuf);
			probe_item_setstatus(itm, SYSCHAR_STATUS_ERROR);
		}
	}

	probe_item_collect(ctx, itm);

	return (0);
}
Пример #19
0
static int filehash_cb (const char *p, const char *f, probe_ctx *ctx, oval_schema_version_t over)
{
        SEXP_t *itm;
        char   pbuf[PATH_MAX+1];
        size_t plen, flen;
	bool include_filepath;
        int fd;

        if (f == NULL)
                return (0);

        /*
         * Prepare path
         */
        plen = strlen (p);
        flen = strlen (f);

        if (plen + flen + 1 > PATH_MAX)
                return (-1);

        memcpy (pbuf, p, sizeof (char) * plen);

        if (p[plen - 1] != FILE_SEPARATOR) {
                pbuf[plen] = FILE_SEPARATOR;
                ++plen;
        }

        memcpy (pbuf + plen, f, sizeof (char) * flen);
        pbuf[plen+flen] = '\0';
	include_filepath = oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.6)) >= 0;

        /*
         * Open the file
         */
        fd = open (pbuf, O_RDONLY);

        if (fd < 0) {
                strerror_r (errno, pbuf, PATH_MAX);
                pbuf[PATH_MAX] = '\0';

		itm = probe_item_create(OVAL_INDEPENDENT_FILE_HASH, NULL,
				"filepath", OVAL_DATATYPE_STRING, include_filepath ? pbuf : NULL,
				"path",     OVAL_DATATYPE_STRING, p,
				"filename", OVAL_DATATYPE_STRING, f,
				NULL
				);
		probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR,
				"Can't open \"%s\": errno=%d, %s.", pbuf, errno, strerror (errno));
		probe_item_setstatus(itm, SYSCHAR_STATUS_ERROR);

       } else {
                uint8_t md5_dst[16];
                size_t  md5_dstlen = sizeof md5_dst;
                char    md5_str[(sizeof md5_dst * 2) + 1];

                uint8_t sha1_dst[20];
                size_t  sha1_dstlen = sizeof sha1_dst;
                char    sha1_str[(sizeof sha1_dst * 2) + 1];

                /*
                 * Compute hash values
                 */
                if (crapi_mdigest_fd (fd, 2,
                                      CRAPI_DIGEST_MD5,  md5_dst,  &md5_dstlen,
                                      CRAPI_DIGEST_SHA1, sha1_dst, &sha1_dstlen) != 0)
                {
                        close (fd);
                        return (-1);
                }

                close (fd);

		md5_str[0] = '\0';
		sha1_str[0] = '\0';
                mem2hex (md5_dst,  md5_dstlen,  md5_str,  sizeof md5_str);
                mem2hex (sha1_dst, sha1_dstlen, sha1_str, sizeof sha1_str);

                /*
                 * Create and add the item
                 */
                itm = probe_item_create(OVAL_INDEPENDENT_FILE_HASH, NULL,
                                        "filepath", OVAL_DATATYPE_STRING, include_filepath ? pbuf : NULL,
                                        "path",     OVAL_DATATYPE_STRING, p,
                                        "filename", OVAL_DATATYPE_STRING, f,
                                        "md5",      OVAL_DATATYPE_STRING, md5_str,
                                        "sha1",     OVAL_DATATYPE_STRING, sha1_str,
                                        NULL);

		if (md5_dstlen == 0 || sha1_dstlen == 0)
			probe_item_setstatus(itm, SYSCHAR_STATUS_ERROR);
		if (md5_dstlen == 0)
			probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR,
					   "Unable to compute md5 hash value of \"%s\".", pbuf);
		if (sha1_dstlen == 0)
			probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR,
					   "Unable to compute sha1 hash value of \"%s\".", pbuf);
        }

        probe_item_collect(ctx, itm);

        return (0);
}
Пример #20
0
static int process_file(const char *path, const char *file, void *arg)
{
	struct pfdata *pfd = (struct pfdata *) arg;
	int ret = 0, path_len, file_len, cur_inst = 0, fd = -1, substr_cnt,
		buf_size = 0, buf_used = 0, ofs = 0, buf_inc = 4096;
	char *whole_path = NULL, *buf = NULL;
	SEXP_t *next_inst = NULL;
	struct stat st;

	if (file == NULL)
		goto cleanup;

	path_len   = strlen(path);
	file_len   = strlen(file);
	whole_path = oscap_alloc(path_len + file_len + 2);

	memcpy(whole_path, path, path_len);

	if (whole_path[path_len - 1] != FILE_SEPARATOR) {
		whole_path[path_len] = FILE_SEPARATOR;
		++path_len;
	}

	memcpy(whole_path + path_len, file, file_len + 1);

	/*
	 * If stat() fails, don't report an error and just skip the file.
	 * This is an expected situation, because the fts_*() functions
	 * are called with the 'FTS_PHYSICAL' option. Normally, stumbling
	 * upon a symlink without a target would cause fts_read() to return
	 * the 'FTS_SLNONE' flag, but the 'FTS_PHYSICAL' option causes it
	 * to return 'FTS_SL' and the presence of a valid target has to
	 * be determined with stat().
	 */
	if (stat(whole_path, &st) == -1)
		goto cleanup;
	if (!S_ISREG(st.st_mode))
		goto cleanup;

	fd = open(whole_path, O_RDONLY);
	if (fd == -1) {
		SEXP_t *msg;

		msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "open(): '%s' %s.", whole_path, strerror(errno));
		probe_cobj_add_msg(probe_ctx_getresult(pfd->ctx), msg);
		SEXP_free(msg);
		probe_cobj_set_flag(probe_ctx_getresult(pfd->ctx), SYSCHAR_FLAG_ERROR);
		ret = -1;
		goto cleanup;
	}

	do {
		buf_size += buf_inc;
		buf = oscap_realloc(buf, buf_size);
		ret = read(fd, buf + buf_used, buf_inc);
		if (ret == -1) {
			SEXP_t *msg;

			msg = probe_msg_creatf(OVAL_MESSAGE_LEVEL_ERROR, "read(): '%s' %s.", whole_path, strerror(errno));
			probe_cobj_add_msg(probe_ctx_getresult(pfd->ctx), msg);
			SEXP_free(msg);
			probe_cobj_set_flag(probe_ctx_getresult(pfd->ctx), SYSCHAR_FLAG_ERROR);
			ret = -2;
			goto cleanup;
		}
		buf_used += ret;
	} while (ret == buf_inc);

	if (buf_used == buf_size)
		buf = realloc(buf, ++buf_size);
	buf[buf_used++] = '\0';

	do {
		char **substrs;
		int want_instance;

		next_inst = SEXP_number_newi_32(cur_inst + 1);

		if (probe_entobj_cmp(pfd->instance_ent, next_inst) == OVAL_RESULT_TRUE)
			want_instance = 1;
		else
			want_instance = 0;

		SEXP_free(next_inst);
		substr_cnt = get_substrings(buf, &ofs, pfd->compiled_regex, want_instance, &substrs);

		if (substr_cnt > 0) {
			++cur_inst;

			if (want_instance) {
				int k;
				SEXP_t *item;

				item = create_item(path, file, pfd->pattern,
						   cur_inst, substrs, substr_cnt);

                                probe_item_collect(pfd->ctx, item);

				for (k = 0; k < substr_cnt; ++k)
					oscap_free(substrs[k]);
				oscap_free(substrs);
			}
		}
	} while (substr_cnt > 0 && ofs < buf_used);

 cleanup:
	if (fd != -1)
		close(fd);
	oscap_free(buf);
	if (whole_path != NULL)
		oscap_free(whole_path);

	return ret;
}
Пример #21
0
static int collect_access_rights(probe_ctx *ctx, WCHAR *security_principle, bool include_group, bool resolve_group)
{
	char *security_principle_str = oscap_windows_wstr_to_str(security_principle);

	LSA_OBJECT_ATTRIBUTES object_attributes;
	ZeroMemory(&object_attributes, sizeof(LSA_OBJECT_ATTRIBUTES));
	LSA_HANDLE lsa_policy_handle;

	NTSTATUS status = LsaOpenPolicy(NULL, &object_attributes, POLICY_LOOKUP_NAMES, &lsa_policy_handle);
	if (status != STATUS_SUCCESS) {
		DWORD err = LsaNtStatusToWinError(status);
		char *error_message = oscap_windows_error_message(err);
		dD("LsaOpenPolicy failed for principle '%s': %s", security_principle_str, error_message);
		free(error_message);
		free(security_principle_str);
		return 1;
	}

	/* Convert the value of the security_principle element to a SID. */
	DWORD sid_len = 0;
	DWORD domain_name_len = 0;
	SID_NAME_USE sid_type;
	LookupAccountNameW(NULL, security_principle, NULL, &sid_len, NULL, &domain_name_len, &sid_type);
	SID *sid = malloc(sid_len);
	WCHAR *domain_name = malloc(domain_name_len * sizeof(WCHAR));
	if (!LookupAccountNameW(NULL, security_principle, sid, &sid_len, domain_name, &domain_name_len, &sid_type)) {
		DWORD err = GetLastError();
		char *error_message = oscap_windows_error_message(err);
		dD("LookupAccountNameW failed for '%s': %s", security_principle_str, error_message);
		free(error_message);
		free(security_principle_str);
		free(sid);
		free(domain_name);
		return 1;
	}

	/* Is it a group? */
	if (sid_type == SidTypeGroup || sid_type == SidTypeWellKnownGroup || sid_type == SidTypeAlias) {
		if (resolve_group) {
			struct oscap_list *group_members_list = oscap_list_new();
			get_local_group_members(security_principle, group_members_list);
			get_global_group_members(security_principle, group_members_list);
			struct oscap_iterator *group_members_it = oscap_iterator_new(group_members_list);
			while (oscap_iterator_has_more(group_members_it)) {
				WCHAR *group_member = oscap_iterator_next(group_members_it);
				collect_access_rights(ctx, group_member, include_group, resolve_group);
			}
			oscap_iterator_free(group_members_it);
			oscap_list_free(group_members_list, free);
		}
		if (!include_group) {
			free(sid);
			free(domain_name);
			free(security_principle_str);
			return 0;
		}
	}

	/* Users and groups can inherit their privileges from their parents */
	struct oscap_list *every_rights_sources = oscap_list_new();
	oscap_list_add(every_rights_sources, wcsdup(security_principle));
	get_user_local_groups(security_principle, every_rights_sources);
	get_user_global_groups(security_principle, every_rights_sources);

	/* Iterate over the items */
	bool privileges_enabled[OVAL_PRIVILEGES_COUNT] = { false };
	struct oscap_iterator *it = oscap_iterator_new(every_rights_sources);
	while (oscap_iterator_has_more(it)) {
		WCHAR *account_name = oscap_iterator_next(it);

		DWORD account_sid_len = 0;
		DWORD account_domain_name_len = 0;
		SID_NAME_USE account_sid_type;
		LookupAccountNameW(NULL, account_name, NULL, &account_sid_len, NULL, &account_domain_name_len, &account_sid_type);
		SID *account_sid = malloc(account_sid_len);
		WCHAR *account_domain_name = malloc(account_domain_name_len * sizeof(WCHAR));
		if (!LookupAccountNameW(NULL, account_name, account_sid, &account_sid_len, account_domain_name, &account_domain_name_len, &account_sid_type)) {
			free(account_sid);
			free(account_domain_name);
			DWORD err = GetLastError();
			char *error_message = oscap_windows_error_message(err);
			dD("LookupAccountNameW failed for '%s': %s", security_principle_str, error_message);
			free(error_message);
			free(security_principle_str);
			return 1;
		}

		LSA_UNICODE_STRING *granted_rights = NULL;
		ULONG granted_rights_count = 0;
		status = LsaEnumerateAccountRights(lsa_policy_handle, account_sid, &granted_rights, &granted_rights_count);
		if (status != STATUS_SUCCESS) {
			free(account_sid);
			free(account_domain_name);
			DWORD err = LsaNtStatusToWinError(status);
			char *error_message = oscap_windows_error_message(err);
			dD("LsaEnumerateAccountRights failed for '%s': %s", security_principle_str, error_message);
			free(error_message);
			/* We should not exit here, because when LsaEnumerateAccountRights
			* failed it can mean that the entity simply doesn't have any specific
			* privileges, it only inhertis privileges form its parent group(s).
			*/
			continue;
		}

		for (int i = 0; i < OVAL_PRIVILEGES_COUNT; i++) {
			if (!privileges_enabled[i]) {
				for (ULONG j = 0; j < granted_rights_count; j++) {
					if (wcscmp(granted_rights[j].Buffer, privileges_texts[i]) == 0) {
						privileges_enabled[i] = true;
						break;
					}
				}
			}
		}
		LsaFreeMemory(granted_rights);
		free(account_sid);
		free(account_domain_name);

	}
	oscap_iterator_free(it);
	oscap_list_free(every_rights_sources, free);

	/* Collect the OVAL item */
	SEXP_t *item = probe_item_create(OVAL_WINDOWS_ACCESS_TOKEN, NULL,
		"security_principle", OVAL_DATATYPE_STRING, strdup(security_principle_str), NULL);
	for (int i = 0; i < OVAL_PRIVILEGES_COUNT; i++) {
		char *privilege_name = oscap_windows_wstr_to_str(privileges_texts[i]);
		/* Convert the element name to lowercase */
		for (char *p = privilege_name; *p; p++) {
			*p = tolower(*p);
		}
		SEXP_t *privilege_value = SEXP_number_newb(privileges_enabled[i]);
		probe_item_ent_add(item, privilege_name, NULL, privilege_value);
		free(privilege_name);
		SEXP_free(privilege_value);
	}
	probe_item_collect(ctx, item);
	free(security_principle_str);

	return 0;
}