static void test_object_iterator(void **state) { JsonElement *obj = JsonObjectCreate(10); JsonObjectAppendString(obj, "first", "one"); JsonObjectAppendString(obj, "second", "two"); JsonObjectAppendInteger(obj, "third", 3); JsonObjectAppendBool(obj, "fourth", true); JsonObjectAppendBool(obj, "fifth", false); { JsonIterator it = JsonIteratorInit(obj); assert_string_equal("first", JsonIteratorNextKey(&it)); assert_string_equal("second", JsonIteratorNextKey(&it)); assert_string_equal("third", JsonIteratorNextKey(&it)); assert_string_equal("fourth", JsonIteratorNextKey(&it)); assert_string_equal("fifth", JsonIteratorNextKey(&it)); assert_false(JsonIteratorNextKey(&it)); } { JsonIterator it = JsonIteratorInit(obj); assert_string_equal("one", JsonPrimitiveGetAsString(JsonIteratorNextValue(&it))); assert_string_equal("two", JsonPrimitiveGetAsString(JsonIteratorNextValue(&it))); assert_int_equal(3, JsonPrimitiveGetAsInteger(JsonIteratorNextValue(&it))); assert_true(JsonPrimitiveGetAsBool(JsonIteratorNextValue(&it))); assert_false(JsonPrimitiveGetAsBool(JsonIteratorNextValue(&it))); assert_false(JsonIteratorNextValue(&it)); } JsonElementDestroy(obj); }
Rlist *RlistFromContainer(const JsonElement *container) { Rlist *list = NULL; switch (JsonGetElementType(container)) { case JSON_ELEMENT_TYPE_PRIMITIVE: RlistAppendContainerPrimitive(&list, container); break; case JSON_ELEMENT_TYPE_CONTAINER: { JsonIterator iter = JsonIteratorInit(container); const JsonElement *child; while (NULL != (child = JsonIteratorNextValue(&iter))) { if (JsonGetElementType(child) == JSON_ELEMENT_TYPE_PRIMITIVE) { RlistAppendContainerPrimitive(&list, child); } } } break; } return list; }
static void test_array_iterator(void **state) { JsonElement *arr = JsonArrayCreate(10); JsonArrayAppendString(arr, "first"); JsonArrayAppendString(arr, "second"); { JsonIterator it = JsonIteratorInit(arr); assert_string_equal("first", JsonPrimitiveGetAsString(JsonIteratorNextValue(&it))); assert_string_equal("second", JsonPrimitiveGetAsString(JsonIteratorNextValue(&it))); assert_false(JsonIteratorNextValue(&it)); } JsonElementDestroy(arr); }
static void test_iterator_current(void **state) { const char *data = ARRAY_SIMPLE; JsonElement *arr = JsonParse(&data); JsonElement *json = JsonObjectCreate(1); JsonObjectAppendArray(json, "array", arr); JsonIterator it = JsonIteratorInit(json); while (JsonIteratorNextValue(&it) != NULL) { assert_int_equal((int)JsonIteratorCurrentElementType(&it), (int)JSON_ELEMENT_TYPE_CONTAINER); assert_int_equal((int)JsonIteratorCurrentContrainerType(&it), (int)JSON_CONTAINER_TYPE_ARRAY); assert_string_equal(JsonIteratorCurrentKey(&it), "array"); } JsonElementDestroy(json); }
static JsonElement *BundleTypesToJson(void) { JsonElement *bundle_types = JsonObjectCreate(50); Seq *common_promise_types = SeqNew(50, free); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { for (int promise_type_index = 0; CF_ALL_PROMISE_TYPES[module_index][promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &CF_ALL_PROMISE_TYPES[module_index][promise_type_index]; // skip global constraints if (strcmp("*", promise_type_syntax->promise_type) == 0) { continue; } // collect common promise types to be appended at the end if (strcmp("*", promise_type_syntax->bundle_type) == 0) { SeqAppend(common_promise_types, xstrdup(promise_type_syntax->promise_type)); continue; } if (promise_type_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonElement *bundle_type = JsonObjectGet(bundle_types, promise_type_syntax->bundle_type); if (!bundle_type) { bundle_type = JsonBundleTypeNew(); JsonObjectAppendObject(bundle_types, promise_type_syntax->bundle_type, bundle_type); } assert(bundle_type); JsonElement *promise_types = JsonObjectGet(bundle_type, "promiseTypes"); assert(promise_types); JsonArrayAppendString(promise_types, promise_type_syntax->promise_type); } } // Append the common bundle, which has only common promise types, but is not declared in syntax { JsonElement *bundle_type = JsonBundleTypeNew(); JsonObjectAppendObject(bundle_types, "common", bundle_type); } JsonIterator it = JsonIteratorInit(bundle_types); const char *bundle_type = NULL; while ((bundle_type = JsonIteratorNextKey(&it))) { JsonElement *promise_types = JsonObjectGetAsArray(JsonObjectGetAsObject(bundle_types, bundle_type), "promiseTypes"); for (int i = 0; i < SeqLength(common_promise_types); i++) { const char *common_promise_type = SeqAt(common_promise_types, i); JsonArrayAppendString(promise_types, common_promise_type); } } SeqDestroy(common_promise_types); return bundle_types; }
static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file, StringSet *parsed_files_and_checksums, StringSet *failed_files) { unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 }; char hashbuffer[CF_HOSTKEY_STRING_SIZE] = { 0 }; char hashprintbuffer[CF_BUFSIZE] = { 0 }; HashFile(policy_file, digest, CF_DEFAULT_DIGEST); snprintf(hashprintbuffer, CF_BUFSIZE - 1, "{checksum}%s", HashPrintSafe(hashbuffer, sizeof(hashbuffer), digest, CF_DEFAULT_DIGEST, true)); Log(LOG_LEVEL_DEBUG, "Hashed policy file %s to %s", policy_file, hashprintbuffer); if (StringSetContains(parsed_files_and_checksums, policy_file)) { Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate policy file %s", policy_file); return NULL; } else if (StringSetContains(parsed_files_and_checksums, hashprintbuffer)) { Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate (detected by hash) policy file %s", policy_file); return NULL; } else { Log(LOG_LEVEL_DEBUG, "Loading policy file %s", policy_file); } Policy *policy = Cf3ParseFile(config, policy_file); // we keep the checksum and the policy file name to help debugging StringSetAdd(parsed_files_and_checksums, xstrdup(policy_file)); StringSetAdd(parsed_files_and_checksums, xstrdup(hashprintbuffer)); if (policy) { Seq *errors = SeqNew(10, free); if (!PolicyCheckPartial(policy, errors)) { Writer *writer = FileWriter(stderr); for (size_t i = 0; i < errors->length; i++) { PolicyErrorWrite(writer, errors->data[i]); } WriterClose(writer); SeqDestroy(errors); StringSetAdd(failed_files, xstrdup(policy_file)); PolicyDestroy(policy); return NULL; } SeqDestroy(errors); } else { StringSetAdd(failed_files, xstrdup(policy_file)); return NULL; } PolicyResolve(ctx, policy, config); DataType def_inputs_type = CF_DATA_TYPE_NONE; VarRef *inputs_ref = VarRefParse("def.augment_inputs"); const void *def_inputs = EvalContextVariableGet(ctx, inputs_ref, &def_inputs_type); VarRefDestroy(inputs_ref); if (RVAL_TYPE_CONTAINER == DataTypeToRvalType(def_inputs_type) && NULL != def_inputs) { const JsonElement *el; JsonIterator iter = JsonIteratorInit((JsonElement*) def_inputs); while ((el = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { char *input = JsonPrimitiveToString(el); Log(LOG_LEVEL_VERBOSE, "Loading augments from def.augment_inputs: %s", input); Rlist* inputs_rlist = NULL; RlistAppendScalar(&inputs_rlist, input); Policy *aux_policy = LoadPolicyInputFiles(ctx, config, inputs_rlist, parsed_files_and_checksums, failed_files); if (aux_policy) { policy = PolicyMerge(policy, aux_policy); } RlistDestroy(inputs_rlist); free(input); } } Body *body_common_control = PolicyGetBody(policy, NULL, "common", "control"); Body *body_file_control = PolicyGetBody(policy, NULL, "file", "control"); if (body_common_control) { Seq *potential_inputs = BodyGetConstraint(body_common_control, "inputs"); Constraint *cp = EffectiveConstraint(ctx, potential_inputs); SeqDestroy(potential_inputs); if (cp) { Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files); if (aux_policy) { policy = PolicyMerge(policy, aux_policy); } } } if (body_file_control) { Seq *potential_inputs = BodyGetConstraint(body_file_control, "inputs"); Constraint *cp = EffectiveConstraint(ctx, potential_inputs); SeqDestroy(potential_inputs); if (cp) { Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files); if (aux_policy) { policy = PolicyMerge(policy, aux_policy); } } } return policy; }