コード例 #1
0
ファイル: ldap57.c プロジェクト: AxelNennker/openscap
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);
}
コード例 #2
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);
}
コード例 #3
0
ファイル: oval_sexp.c プロジェクト: AxelNennker/openscap
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);
}