static void test_class_ref(void) { { ClassRef ref = ClassRefParse("class"); assert_true(ref.ns == NULL); assert_string_equal("class", ref.name); char *expr = ClassRefToString(ref.ns, ref.name); assert_string_equal("class", expr); free(expr); ClassRefDestroy(ref); } { ClassRef ref = ClassRefParse("default:class"); assert_string_equal("default", ref.ns); assert_string_equal("class", ref.name); char *expr = ClassRefToString(ref.ns, ref.name); assert_string_equal("class", expr); free(expr); ClassRefDestroy(ref); } { ClassRef ref = ClassRefParse("ns:class"); assert_string_equal("ns", ref.ns); assert_string_equal("class", ref.name); char *expr = ClassRefToString(ref.ns, ref.name); assert_string_equal("ns:class", expr); free(expr); ClassRefDestroy(ref); } }
static JsonElement *DefaultTemplateData(const EvalContext *ctx) { JsonElement *hash = JsonObjectCreate(10); { ClassTableIterator *it = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Class *cls = NULL; while ((cls = ClassTableIteratorNext(it))) { char *key = ClassRefToString(cls->ns, cls->name); JsonObjectAppendBool(hash, key, true); free(key); } ClassTableIteratorDestroy(it); } { ClassTableIterator *it = EvalContextClassTableIteratorNewLocal(ctx); Class *cls = NULL; while ((cls = ClassTableIteratorNext(it))) { char *key = ClassRefToString(cls->ns, cls->name); JsonObjectAppendBool(hash, key, true); free(key); } ClassTableIteratorDestroy(it); } { VariableTableIterator *it = EvalContextVariableTableIteratorNew(ctx, NULL, NULL, NULL); Variable *var = NULL; while ((var = VariableTableIteratorNext(it))) { // TODO: need to get a CallRef, this is bad char *scope_key = ClassRefToString(var->ref->ns, var->ref->scope); JsonElement *scope_obj = JsonObjectGetAsObject(hash, scope_key); if (!scope_obj) { scope_obj = JsonObjectCreate(50); JsonObjectAppendObject(hash, scope_key, scope_obj); } free(scope_key); char *lval_key = VarRefToString(var->ref, false); JsonObjectAppendElement(scope_obj, lval_key, RvalToJson(var->rval)); free(lval_key); } VariableTableIteratorDestroy(it); } return hash; }
static void ShowContextsFormatted(EvalContext *ctx) { ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Class *cls = NULL; Seq *seq = SeqNew(1000, free); while ((cls = ClassTableIteratorNext(iter))) { char *class_name = ClassRefToString(cls->ns, cls->name); StringSet *tagset = EvalContextClassTags(ctx, cls->ns, cls->name); Buffer *tagbuf = StringSetToBuffer(tagset, ','); char *line; xasprintf(&line, "%-60s %-40s", class_name, BufferData(tagbuf)); SeqAppend(seq, line); BufferDestroy(tagbuf); free(class_name); } SeqSort(seq, (SeqItemComparator)strcmp, NULL); printf("%-60s %-40s\n", "Class name", "Meta tags"); for (size_t i = 0; i < SeqLength(seq); i++) { const char *context = SeqAt(seq, i); printf("%s\n", context); } SeqDestroy(seq); ClassTableIteratorDestroy(iter); }
Class *ClassTableMatch(const ClassTable *table, const char *regex) { ClassTableIterator *it = ClassTableIteratorNew(table, NULL, true, true); Class *cls = NULL; pcre *pattern = CompileRegex(regex); if (pattern == NULL) { // TODO: perhaps pcre has can give more info on this error? Log(LOG_LEVEL_ERR, "Unable to pcre compile regex '%s'", regex); return false; } while ((cls = ClassTableIteratorNext(it))) { bool matched; if (cls->ns) { char *class_expr = ClassRefToString(cls->ns, cls->name); matched = StringMatchFullWithPrecompiledRegex(pattern, class_expr); free(class_expr); } else { matched = StringMatchFullWithPrecompiledRegex(pattern, cls->name); } if (matched) { break; } } pcre_free(pattern); ClassTableIteratorDestroy(it); return cls; }
int MatchClasses(EvalContext *ctx, ServerConnectionState *conn) { char recvbuffer[CF_BUFSIZE]; Item *classlist = NULL, *ip; int count = 0; while (true && (count < 10)) /* arbitrary check to avoid infinite loop, DoS attack */ { count++; if (ReceiveTransaction(&conn->conn_info, recvbuffer, NULL) == -1) { Log(LOG_LEVEL_VERBOSE, "Unable to read data from network. (ReceiveTransaction: %s)", GetErrorStr()); return false; } Log(LOG_LEVEL_DEBUG, "Got class buffer '%s'", recvbuffer); if (strncmp(recvbuffer, CFD_TERMINATOR, strlen(CFD_TERMINATOR)) == 0) { if (count == 1) { Log(LOG_LEVEL_DEBUG, "No classes were sent, assuming no restrictions..."); return true; } break; } classlist = SplitStringAsItemList(recvbuffer, ' '); for (ip = classlist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "Checking whether class %s can be identified as me...", ip->name); if (IsDefinedClass(ctx, ip->name, NULL)) { Log(LOG_LEVEL_DEBUG, "Class '%s' matched, accepting...", ip->name); DeleteItemList(classlist); return true; } { ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Class *cls = NULL; while ((cls = ClassTableIteratorNext(iter))) { char *expr = ClassRefToString(cls->ns, cls->name); bool match = StringMatchFull(ip->name, expr); free(expr); if (match) { Log(LOG_LEVEL_DEBUG, "Class matched regular expression '%s', accepting...", ip->name); DeleteItemList(classlist); return true; } } ClassTableIteratorDestroy(iter); } if (strncmp(ip->name, CFD_TERMINATOR, strlen(CFD_TERMINATOR)) == 0) { Log(LOG_LEVEL_VERBOSE, "No classes matched, rejecting...."); ReplyNothing(conn); DeleteItemList(classlist); return false; } } } ReplyNothing(conn); Log(LOG_LEVEL_VERBOSE, "No classes matched, rejecting...."); DeleteItemList(classlist); return false; }