static int get_all_trustee_names(struct oscap_list *trustees_list) { get_all_well_known_sids(trustees_list); get_all_local_users(trustees_list); struct oscap_list *local_groups_list = oscap_list_new(); get_all_local_groups(local_groups_list); /* Find members of each local group */ struct oscap_iterator *local_groups_it = oscap_iterator_new(local_groups_list); while (oscap_iterator_has_more(local_groups_it)) { WCHAR *group = oscap_iterator_next(local_groups_it); oscap_list_add(trustees_list, wcsdup(group)); expand_group(group, trustees_list, get_local_group_members); } oscap_iterator_free(local_groups_it); oscap_list_free(local_groups_list, free); struct oscap_list *global_groups_list = oscap_list_new(); get_all_global_groups(global_groups_list); /* Find members of each global group */ struct oscap_iterator *global_groups_it = oscap_iterator_new(global_groups_list); while (oscap_iterator_has_more(global_groups_it)) { WCHAR *group = oscap_iterator_next(global_groups_it); oscap_list_add(trustees_list, wcsdup(group)); expand_group(group, trustees_list, get_global_group_members); } oscap_iterator_free(global_groups_it); oscap_list_free(global_groups_list, free); return 0; }
struct xccdf_item *xccdf_group_new_internal(struct xccdf_item *parent) { struct xccdf_item *group = xccdf_item_new(XCCDF_GROUP, parent); group->sub.group.content = oscap_list_new(); group->sub.group.requires = oscap_list_new(); group->sub.group.conflicts = oscap_list_new(); group->sub.group.values = oscap_list_new(); return group; }
struct xccdf_check *xccdf_check_new(void) { struct xccdf_check *check = calloc(1, sizeof(struct xccdf_check)); check->content_refs = oscap_list_new(); check->imports = oscap_list_new(); check->exports = oscap_list_new(); check->children = oscap_list_new(); return check; }
struct xccdf_benchmark *xccdf_benchmark_new(void) { struct xccdf_item *bench = xccdf_item_new(XCCDF_BENCHMARK, NULL); bench->sub.benchmark.schema_version = NULL; // lists bench->sub.benchmark.rear_matter = oscap_list_new(); bench->sub.benchmark.front_matter = oscap_list_new(); bench->sub.benchmark.notices = oscap_list_new(); bench->sub.benchmark.models = oscap_list_new(); bench->sub.benchmark.content = oscap_list_new(); bench->sub.benchmark.values = oscap_list_new(); bench->sub.benchmark.plain_texts = oscap_list_new(); bench->sub.benchmark.cpe_list = NULL; bench->sub.benchmark.cpe_lang_model = NULL; bench->sub.benchmark.profiles = oscap_list_new(); bench->sub.benchmark.results = oscap_list_new(); // hash tables bench->sub.benchmark.items_dict = oscap_htable_new(); bench->sub.benchmark.profiles_dict = oscap_htable_new(); bench->sub.benchmark.results_dict = oscap_htable_new(); bench->sub.benchmark.clusters_dict = oscap_htable_new(); // add the implied default scoring model struct xccdf_model *default_model = xccdf_model_new(); xccdf_model_set_system(default_model, "urn:xccdf:scoring:default"); assume_ex(xccdf_benchmark_add_model(XBENCHMARK(bench), default_model), XBENCHMARK(bench)); return XBENCHMARK(bench); }
static struct oscap_tsort_context *oscap_tsort_context_new(oscap_tsort_edge_func edge_func, oscap_cmp_func cmp_func, void *userdata) { struct oscap_tsort_context *ctx = oscap_calloc(1, sizeof(struct oscap_tsort_context)); ctx->visited = oscap_list_new(); ctx->cur_stack = oscap_list_new(); ctx->result = oscap_list_new(); ctx->edge_func = edge_func; ctx->cmp_func = cmp_func; ctx->userdata = userdata; return ctx; }
static struct oscap_list *xccdf_benchmark_resolve_dependencies(void *itemptr, void *userdata) { struct xccdf_item *item = XITEM(itemptr); struct oscap_list *ret = oscap_list_new(); struct xccdf_value_iterator *val_it = NULL; const char *extends = xccdf_item_get_extends(item); if (extends) oscap_list_add(ret, xccdf_benchmark_get_member(xccdf_item_get_benchmark(item), xccdf_item_get_type(item), extends)); switch (xccdf_item_get_type(item)) { case XCCDF_BENCHMARK: { OSCAP_FOR(xccdf_profile, profile, xccdf_benchmark_get_profiles(xccdf_item_to_benchmark(item))) oscap_list_add(ret, profile); val_it = xccdf_benchmark_get_values(xccdf_item_to_benchmark(item)); break; } case XCCDF_GROUP: val_it = xccdf_group_get_values(xccdf_item_to_group(item)); default: break; /* no-op */ } OSCAP_FOR(xccdf_item, child, xccdf_item_get_content(item)) oscap_list_add(ret, child); OSCAP_FOR(xccdf_value, val, val_it) oscap_list_add(ret, val); return ret; }
static bool xccdf_item_parse_deps(xmlTextReaderPtr reader, struct xccdf_item *item) { struct oscap_list *conflicts = NULL; struct oscap_list *requires = NULL; xccdf_deps_get(item, &conflicts, &requires); switch (xccdf_element_get(reader)) { case XCCDFE_REQUIRES:{ struct oscap_list *reqs = oscap_list_new(); char *ids = xccdf_attribute_copy(reader, XCCDFA_IDREF), *idsstr = ids, *id; while ((id = strsep(&ids, " ")) != NULL) { if (strcmp(id, "") == 0) continue; oscap_list_add(reqs, oscap_strdup(id)); } if (reqs->itemcount == 0) { oscap_list_free(reqs, NULL); return false; } oscap_list_add(requires, reqs); free(idsstr); break; } case XCCDFE_CONFLICTS: oscap_list_add(conflicts, xccdf_attribute_copy(reader, XCCDFA_IDREF)); break; default: assert(false); } return true; }
struct rds_asset_index *rds_asset_index_new(void) { struct rds_asset_index *ret = oscap_calloc(1, sizeof(struct rds_asset_index)); ret->id = NULL; ret->reports = oscap_list_new(); return ret; }
/** * Enforce given content with given name to be the only check-content of the check. * This may turn to be usefull,when processing check within rule-result -- * such check may (and in some cases must) refer only to the executed content. */ bool xccdf_check_inject_content_ref(struct xccdf_check *check, const struct xccdf_check_content_ref *content, const char *name) { struct xccdf_check_content_ref *content_clone = xccdf_check_content_ref_clone(content); if (name != NULL) xccdf_check_content_ref_set_name(content_clone, name); oscap_list_free(check->content_refs, (oscap_destruct_func) xccdf_check_content_ref_free); check->content_refs = oscap_list_new(); return oscap_list_add(check->content_refs, content_clone); }
struct xccdf_tailoring *xccdf_tailoring_new(void) { struct xccdf_tailoring *tailoring = oscap_calloc(1, sizeof(struct xccdf_tailoring)); tailoring->id = NULL; tailoring->benchmark_ref = NULL; tailoring->benchmark_ref_version = NULL; tailoring->statuses = oscap_list_new(); tailoring->dc_statuses = oscap_list_new(); tailoring->version = NULL; tailoring->version_update = NULL; tailoring->version_time = NULL; tailoring->metadata = oscap_list_new(); tailoring->profiles = oscap_list_new(); return tailoring; }
struct cpe_lang_model *cpe_lang_model_new() { struct cpe_lang_model *ret; ret = oscap_alloc(sizeof(struct cpe_lang_model)); if (ret == NULL) return NULL; ret->platforms = oscap_list_new(); ret->item = oscap_htable_new(); ret->origin_file = NULL; return ret; }
static void expand_group(WCHAR *group, struct oscap_list *output_list, int (*get_group_members)(WCHAR *group_name, struct oscap_list *list)) { struct oscap_list *members_list = oscap_list_new(); get_group_members(group, members_list); struct oscap_iterator *members_it = oscap_iterator_new(members_list); while (oscap_iterator_has_more(members_it)) { WCHAR *member = oscap_iterator_next(members_it); /* TODO: implement this using a HashSet instead of linked list */ if (!oscap_list_contains(output_list, member, _members_cmp_func)) { oscap_list_add(output_list, wcsdup(member)); } } oscap_iterator_free(members_it); oscap_list_free(members_list, free); }
struct cpe_platform *cpe_platform_new() { struct cpe_platform *ret; ret = oscap_alloc(sizeof(struct cpe_platform)); if (ret == NULL) return NULL; ret->titles = oscap_list_new(); ret->expr = cpe_testexpr_new(); ret->id = NULL; ret->remark = NULL; return ret; }
struct xccdf_item *xccdf_rule_new_internal(struct xccdf_item *parent) { struct xccdf_item *rule = xccdf_item_new(XCCDF_RULE, parent); rule->sub.rule.role = 0; rule->sub.rule.severity = 0; rule->sub.rule.idents = oscap_list_new(); rule->sub.rule.checks = oscap_list_new(); rule->sub.rule.requires = oscap_list_new(); rule->sub.rule.conflicts = oscap_list_new(); rule->sub.rule.profile_notes = oscap_list_new(); rule->sub.rule.fixes = oscap_list_new(); rule->sub.rule.fixtexts = oscap_list_new(); return rule; }
bool xccdf_benchmark_resolve(struct xccdf_benchmark *benchmark) { struct oscap_list *resolve_order = NULL, *root_nodes = oscap_list_new(); oscap_list_add(root_nodes, benchmark); bool ret = false; if (oscap_tsort(root_nodes, &resolve_order, xccdf_benchmark_resolve_dependencies, NULL, NULL)) { OSCAP_FOR(xccdf_item, item, oscap_iterator_new(resolve_order)) xccdf_resolve_item(item, NULL); ret = true; } oscap_list_free(root_nodes, NULL); oscap_list_free(resolve_order, NULL); xccdf_resolve_cleanup(XITEM(benchmark)); return ret; }
int accesstoken_probe_main(probe_ctx *ctx, void *arg) { SEXP_t *probe_in = probe_ctx_getobject(ctx); SEXP_t *behaviors_ent = probe_obj_getent(probe_in, "behaviors", 1); SEXP_t *security_principle_ent = probe_obj_getent(probe_in, "security_principle", 1); SEXP_t *security_principle_val = probe_ent_getval(security_principle_ent); bool include_group = accesstoken_behaviors_get_include_group(behaviors_ent); bool resolve_group = accesstoken_behaviors_get_resolve_group(behaviors_ent); oval_operation_t operation = probe_ent_getoperation(security_principle_ent, OVAL_OPERATION_EQUALS); if (operation == OVAL_OPERATION_EQUALS) { char *security_principle_str = SEXP_string_cstr(security_principle_val); WCHAR *security_principle_wstr = oscap_windows_str_to_wstr(security_principle_str); collect_access_rights(ctx, security_principle_wstr, include_group, resolve_group); free(security_principle_str); free(security_principle_wstr); } else { struct oscap_list *trustees_list = oscap_list_new(); get_all_trustee_names(trustees_list); struct oscap_iterator *it = oscap_iterator_new(trustees_list); while (oscap_iterator_has_more(it)) { WCHAR *trustee_wstr = oscap_iterator_next(it); char *trustee_str = oscap_windows_wstr_to_str(trustee_wstr); SEXP_t *tmp = SEXP_string_new(trustee_str, strlen(trustee_str)); if (probe_entobj_cmp(security_principle_ent, tmp) == OVAL_RESULT_TRUE) { collect_access_rights(ctx, trustee_wstr, include_group, resolve_group); } free(trustee_str); SEXP_free(tmp); } oscap_iterator_free(it); oscap_list_free(trustees_list, free); } SEXP_free(behaviors_ent); SEXP_free(security_principle_ent); SEXP_free(security_principle_val); return 0; }
static struct cpe_ext_deprecation *cpe_ext_deprecation_new() { struct cpe_ext_deprecation *deprecation = oscap_calloc(1, sizeof(struct cpe_ext_deprecation)); deprecation->deprecatedbys = oscap_list_new(); return deprecation; }
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; }
struct cpe_testexpr *cpe_testexpr_parse(xmlTextReaderPtr reader) { xmlChar *temp = NULL; size_t elem_cnt = 0; struct cpe_testexpr *ret = NULL; __attribute__nonnull__(reader); // allocation ret = cpe_testexpr_new(); if (ret == NULL) return NULL; // it's fact-ref only, fill the structure and return it if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_FACT_REF_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { ret->oper = CPE_LANG_OPER_MATCH; temp = xmlTextReaderGetAttribute(reader, ATTR_NAME_STR); ret->meta.cpe = cpe_name_new((char *)temp); xmlFree(temp); return ret; // it's check-fact-ref only, fill the structure and return it } else if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_CHECK_FACT_REF_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { ret->oper = CPE_LANG_OPER_CHECK; ret->meta.check.system = (char*)xmlTextReaderGetAttribute(reader, ATTR_SYSTEM_STR); ret->meta.check.href = (char*)xmlTextReaderGetAttribute(reader, ATTR_HREF_STR); ret->meta.check.id = (char*)xmlTextReaderGetAttribute(reader, ATTR_ID_REF_STR); return ret; } else if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_LOGICAL_TEST_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { // it's logical-test, fill the structure and go to next node temp = xmlTextReaderGetAttribute(reader, ATTR_OPERATOR_STR); if (xmlStrcasecmp(temp, VAL_AND_STR) == 0) ret->oper = CPE_LANG_OPER_AND; else if (xmlStrcasecmp(temp, VAL_OR_STR) == 0) ret->oper = CPE_LANG_OPER_OR; else { // unknown operator problem xmlFree(temp); oscap_free(ret); return NULL; } xmlFree(temp); ret->meta.expr = oscap_list_new(); // initialise a list of subexpressions temp = xmlTextReaderGetAttribute(reader, ATTR_NEGATE_STR); if (temp && xmlStrcasecmp(temp, VAL_TRUE_STR) == 0) ret->oper |= CPE_LANG_OPER_NOT; xmlFree(temp); } else if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) oscap_seterr(OSCAP_EFAMILY_OSCAP, "Unknown XML element in test expression"); // go to next node // skip to next node xmlTextReaderNextNode(reader); int depth = xmlTextReaderDepth(reader); //printf("[%d] logical-test\n", depth); // while it's not 'logical-test' or it's not ended element .. //while (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_FACT_REF_STR) || // !xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_LOGICAL_TEST_STR)) { while (xmlTextReaderDepth(reader) >= depth) { //printf("[%d:%d] logical-test::%s\n", depth, xmlTextReaderDepth(reader), xmlTextReaderConstLocalName(reader)); if (xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT) { xmlTextReaderNextNode(reader); continue; } elem_cnt++; // We assume that the expression is a logical one (meaning that it // can have subexpressions). // TODO: Enforce that assumption and don't rely on just validation. // .. and the next node is logical-test element, we need recursive call if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_LOGICAL_TEST_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { // ret->meta.expr[elem_cnt - 1] = *(cpe_testexpr_parse(reader)); oscap_list_add(ret->meta.expr, cpe_testexpr_parse(reader)); if (xmlTextReaderDepth(reader) < depth) { return ret; } else if (xmlTextReaderDepth(reader) == depth) continue; } else if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_FACT_REF_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { // fill the structure struct cpe_testexpr *subexpr = cpe_testexpr_new(); subexpr->oper = CPE_LANG_OPER_MATCH; temp = xmlTextReaderGetAttribute(reader, ATTR_NAME_STR); subexpr->meta.cpe = cpe_name_new((char *)temp); //printf("FACT-REF: %s\n", temp); xmlFree(temp); oscap_list_add(ret->meta.expr, subexpr); } else if (!xmlStrcmp(xmlTextReaderConstLocalName(reader), TAG_CHECK_FACT_REF_STR) && xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { struct cpe_testexpr *subexpr = cpe_testexpr_new(); subexpr->oper = CPE_LANG_OPER_CHECK; subexpr->meta.check.system = (char*)xmlTextReaderGetAttribute(reader, ATTR_SYSTEM_STR); subexpr->meta.check.href = (char*)xmlTextReaderGetAttribute(reader, ATTR_HREF_STR); subexpr->meta.check.id = (char*)xmlTextReaderGetAttribute(reader, ATTR_ID_REF_STR); oscap_list_add(ret->meta.expr, subexpr); } else if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { oscap_seterr(OSCAP_EFAMILY_OSCAP, "Unknown XML element in test expression"); } xmlTextReaderNextNode(reader); } //ret->meta.expr[elem_cnt].oper = CPE_LANG_OPER_HALT; return ret; }
static struct cpe23_item *cpe23_item_new() { struct cpe23_item *item = oscap_calloc(1, sizeof(struct cpe23_item)); item->deprecations = oscap_list_new(); return item; }