TALLOC_CTX *tmp_ctx = talloc_new(NULL);
TR_FILTER *filt = NULL;
TR_FLINE *fline = NULL;
+ TR_FSPEC *fspec = NULL;
json_t *jfaction = NULL;
json_t *jfline = NULL;
json_t *jfspecs = NULL;
goto cleanup;
}
- if (TR_MAX_FILTER_SPECS < json_array_size(jfspecs)) {
- tr_debug("tr_cfg_parse_one_filter: Filter has too many specs, maximimum of %d.", TR_MAX_FILTER_SPECS);
- *rc = TR_CFG_NOPARSE;
- goto cleanup;
- }
-
fline = tr_fline_new(tmp_ctx);
if (fline == NULL) {
tr_debug("tr_cfg_parse_one_filter: Out of memory allocating filter line %d.", i + 1);
}
/* allocate the filter spec */
- if (NULL == (fline->specs[j] = tr_fspec_new(fline))) {
+ if (NULL == (fspec = tr_fspec_new(fline))) {
tr_debug("tr_cfg_parse_one_filter: Out of memory.");
*rc = TR_CFG_NOMEM;
goto cleanup;
}
/* fill in the field */
- if (NULL == (fline->specs[j]->field = tr_new_name(json_string_value(jfield)))) {
+ if (NULL == (fspec->field = tr_new_name(json_string_value(jfield)))) {
tr_debug("tr_cfg_parse_one_filter: Out of memory.");
*rc = TR_CFG_NOMEM;
goto cleanup;
*rc = TR_CFG_NOMEM;
goto cleanup;
}
- tr_fspec_add_match(fline->specs[j], name);
+ tr_fspec_add_match(fspec, name);
} else {
/* jmatch is an array (we checked earlier) */
json_array_foreach(jmatch, k, this_jmatch) {
*rc = TR_CFG_NOMEM;
goto cleanup;
}
- tr_fspec_add_match(fline->specs[j], name);
+ tr_fspec_add_match(fspec, name);
}
}
- if (!tr_filter_validate_spec_field(ftype, fline->specs[j])){
+ if (!tr_filter_validate_spec_field(ftype, fspec)){
tr_debug("tr_cfg_parse_one_filter: Invalid filter field \"%.*s\" for %s filter, spec %d, filter %d.",
- fline->specs[j]->field->len,
- fline->specs[j]->field->buf,
+ fspec->field->len,
+ fspec->field->buf,
tr_filter_type_to_string(filt->type),
i, j);
*rc = TR_CFG_ERROR;
goto cleanup;
}
+
+ if(tr_fline_add_spec(fline, fspec) == NULL) {
+ tr_debug("tr_cfg_parse_one_filter: Unable to add spec %d to line %d of %s filter.",
+ j, i, tr_filter_type_to_string(filt->type));
+ }
}
if (NULL == tr_filter_add_line(filt, fline)) {
tr_debug("tr_cfg_parse_one_filter: Error adding line %d for %s filter",
- i+1, tr_filter_type_to_string(filt->type));
+ i, tr_filter_type_to_string(filt->type));
*rc = TR_CFG_NOMEM;
goto cleanup;
}
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
TR_FILTER *filt=NULL;
TR_FLINE *fline = NULL;
+ TR_FSPEC *fspec = NULL;
TR_FILTER_SET *filt_set=NULL;
TR_CONSTRAINT *cons=NULL;
TR_NAME *name=NULL;
}
fline->action=TR_FILTER_ACTION_ACCEPT;
- fline->specs[0]=tr_fspec_new(fline);
- fline->specs[0]->field=n_rp_realm_1;
+
+ fspec=tr_fspec_new(tmp_ctx);
+ fspec->field=n_rp_realm_1;
n_rp_realm_1=NULL; /* we don't own this name any more */
name=tr_dup_name(realm);
*rc=TR_CFG_NOMEM;
goto cleanup;
}
- tr_fspec_add_match(fline->specs[0], name);
+ tr_fspec_add_match(fspec, name);
name=NULL; /* we no longer own the name */
+ if (tr_fline_add_spec(fline, fspec) == NULL) {
+ tr_debug("tr_cfg_default_filters: could not add first spec to filter line");
+ *rc = TR_CFG_NOMEM;
+ goto cleanup;
+ }
+
/* now do the wildcard name */
- fline->specs[1]=tr_fspec_new(fline);
- fline->specs[1]->field=n_rp_realm_2;
+ fspec=tr_fspec_new(tmp_ctx);
+ fspec->field=n_rp_realm_2;
n_rp_realm_2=NULL; /* we don't own this name any more */
if (NULL==(name=tr_name_cat(n_prefix, realm))) {
goto cleanup;
}
- tr_fspec_add_match(fline->specs[1], name);
+ tr_fspec_add_match(fspec, name);
name=NULL; /* we no longer own the name */
+ if (tr_fline_add_spec(fline, fspec) == NULL) {
+ tr_debug("tr_cfg_default_filters: could not add second spec to filter line");
+ *rc = TR_CFG_NOMEM;
+ goto cleanup;
+ }
+
/* domain constraint */
if (NULL==(cons=tr_constraint_new(fline))) {
tr_debug("tr_cfg_default_filters: could not allocate domain constraint.");
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
TR_FILTER_ITER *filt_iter = tr_filter_iter_new(tmp_ctx);
TR_FLINE *this_fline = NULL;
- unsigned int jj=0;
+ TR_FLINE_ITER *fline_iter = tr_fline_iter_new(tmp_ctx);
+ TR_FSPEC *this_fspec = NULL;
int retval=TR_FILTER_NO_MATCH;
/* Default action is reject */
*out_action = TR_FILTER_ACTION_REJECT;
/* Validate filter */
- if ((filt_iter == NULL) || (filt==NULL) || (filt->type==TR_FILTER_TYPE_UNKNOWN)) {
+ if ((filt_iter == NULL) || (fline_iter == NULL) || (filt==NULL) || (filt->type==TR_FILTER_TYPE_UNKNOWN)) {
talloc_free(tmp_ctx);
return TR_FILTER_NO_MATCH;
}
/* Assume we are going to succeed. If any specs fail to match, we'll set
* this to TR_FILTER_NO_MATCH. */
retval=TR_FILTER_MATCH;
- for (jj=0; jj<TR_MAX_FILTER_SPECS; jj++) {
- /* skip empty specs (these shouldn't really happen either) */
- if (this_fline->specs[jj]==NULL)
- continue;
-
- if (!tr_fspec_matches(this_fline->specs[jj], filt->type, target)) {
+ this_fspec = tr_fline_iter_first(fline_iter, this_fline);
+ while(this_fspec) {
+ if (!tr_fspec_matches(this_fspec, filt->type, target)) {
retval=TR_FILTER_NO_MATCH; /* set this in case this is the last filter line */
break; /* give up on this filter line */
}
+ this_fspec = tr_fline_iter_next(fline_iter);
}
if (retval==TR_FILTER_MATCH)
break;
+
+ this_fline = tr_filter_iter_next(filt_iter);
}
if (retval==TR_FILTER_MATCH) {
talloc_free(fline);
}
+TR_FSPEC *tr_fline_add_spec(TR_FLINE *fline, TR_FSPEC *spec)
+{
+ guint old_len = fline->specs->len;
+ g_ptr_array_add(fline->specs, spec);
+
+ if (old_len == fline->specs->len)
+ return NULL; /* failed to add */
+
+ talloc_steal(fline, spec);
+ return spec;
+}
+
+static int tr_fline_destructor(void *object)
+{
+ TR_FLINE *fline = talloc_get_type_abort(object, TR_FLINE);
+ if (fline->specs)
+ g_ptr_array_unref(fline->specs);
+ return 0;
+}
+
TR_FLINE *tr_fline_new(TALLOC_CTX *mem_ctx)
{
TR_FLINE *fl = talloc(mem_ctx, TR_FLINE);
- int ii = 0;
if (fl != NULL) {
fl->action = TR_FILTER_ACTION_UNKNOWN;
fl->realm_cons = NULL;
fl->domain_cons = NULL;
- for (ii = 0; ii < TR_MAX_FILTER_SPECS; ii++)
- fl->specs[ii] = NULL;
+ fl->specs = g_ptr_array_new();
+ if (fl->specs == NULL) {
+ talloc_free(fl);
+ return NULL;
+ }
+ talloc_set_destructor((void *)fl, tr_fline_destructor);
}
return fl;
}
talloc_free(iter);
}
+TR_FLINE *tr_filter_iter_first(TR_FILTER_ITER *iter, TR_FILTER *filter)
+{
+ if (!iter || !filter)
+ return NULL;
+
+ iter->filter = filter;
+ iter->ii = 0;
+ return tr_filter_iter_next(iter);
+}
+
TR_FLINE *tr_filter_iter_next(TR_FILTER_ITER *iter)
{
if (!iter)
return NULL;
}
-TR_FLINE *tr_filter_iter_first(TR_FILTER_ITER *iter, TR_FILTER *filter)
+TR_FLINE_ITER *tr_fline_iter_new(TALLOC_CTX *mem_ctx)
{
- if (!iter || !filter)
+ TR_FLINE_ITER *iter = talloc(mem_ctx, TR_FLINE_ITER);
+ if (iter) {
+ iter->fline = NULL;
+ }
+ return iter;
+}
+
+void tr_fline_iter_free(TR_FLINE_ITER *iter)
+{
+ talloc_free(iter);
+}
+
+TR_FSPEC * tr_fline_iter_first(TR_FLINE_ITER *iter, TR_FLINE *fline)
+{
+ if (!iter || !fline)
return NULL;
- iter->filter = filter;
+ iter->fline = fline;
iter->ii = 0;
- return tr_filter_iter_next(iter);
+ return tr_fline_iter_next(iter);
+}
+
+TR_FSPEC * tr_fline_iter_next(TR_FLINE_ITER *iter)
+{
+ if (!iter)
+ return NULL;
+
+ if (iter->ii < iter->fline->specs->len)
+ return g_ptr_array_index(iter->fline->specs, iter->ii++);
+ return NULL;
}
TR_FSPEC_ITER *tr_fspec_iter_new(TALLOC_CTX *mem_ctx)
int tr_filter_validate(TR_FILTER *filt)
{
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
- size_t jj=0;
TR_FILTER_ITER *filt_iter = tr_filter_iter_new(tmp_ctx);
TR_FLINE *this_fline = NULL;
+ TR_FLINE_ITER *fline_iter = tr_fline_iter_new(tmp_ctx);
+ TR_FSPEC *this_fspec = NULL;
- if (!filt) {
+ if ((!filt) || (!filt_iter) || (!fline_iter)) {
talloc_free(tmp_ctx);
return 0;
}
return 0;
}
- for (jj=0; jj<TR_MAX_FILTER_SPECS; jj++) {
- if (this_fline->specs[jj]==NULL)
- continue; /* an empty filter spec is valid */
-
- if (!tr_filter_validate_spec_field(filt->type, this_fline->specs[jj])) {
+ this_fspec = tr_fline_iter_first(fline_iter, this_fline);
+ while(this_fspec) {
+ if (!tr_filter_validate_spec_field(filt->type, this_fspec)) {
talloc_free(tmp_ctx);
return 0;
}
/* check that at least one match is defined*/
- if (this_fline->specs[jj]->match->len == 0) {
+ if (this_fspec->match->len == 0) {
talloc_free(tmp_ctx);
return 0;
}
+ this_fspec = tr_fline_iter_next(fline_iter);
}
this_fline = tr_filter_iter_next(filt_iter);
}
return retval;
}
+static json_t *tr_fspecs_to_json_array(TR_FLINE *fline)
+{
+ json_t *jarray = json_array();
+ json_t *retval = NULL;
+ TR_FLINE_ITER *iter = tr_fline_iter_new(NULL);
+ TR_FSPEC *this_fspec = NULL;
+
+ if ((jarray == NULL) || (iter == NULL))
+ goto cleanup;
+
+ this_fspec = tr_fline_iter_first(iter, fline);
+ while(this_fspec) {
+ ARRAY_APPEND_OR_FAIL(jarray, tr_fspec_to_json(this_fspec));
+ this_fspec = tr_fline_iter_next(iter);
+ }
+ /* success */
+ retval = jarray;
+ json_incref(retval);
+
+cleanup:
+ if (jarray)
+ json_decref(jarray);
+ if (iter)
+ tr_fline_iter_free(iter);
+
+ return retval;
+}
+
static json_t *tr_fline_to_json(TR_FLINE *fline)
{
json_t *fline_json = NULL;
OBJECT_SET_OR_FAIL(fline_json, "action",
json_string( (fline->action == TR_FILTER_ACTION_ACCEPT) ? "accept" : "reject"));
OBJECT_SET_OR_FAIL(fline_json, "specs",
- items_to_json_array((void **)fline->specs,
- (ITEM_ENCODER_FUNC *) tr_fspec_to_json,
- TR_MAX_FILTER_SPECS));
+ tr_fspecs_to_json_array(fline));
if (fline->realm_cons) {
OBJECT_SET_OR_FAIL(fline_json, "realm_constraints",
items_to_json_array((void **) fline->realm_cons->matches,
#include <trust_router/tid.h>
#include <trust_router/trp.h>
-#define TR_MAX_FILTER_SPECS 8
-
/* Filter actions */
typedef enum tr_filter_action {
TR_FILTER_ACTION_REJECT = 0,
typedef struct tr_fline {
TR_FILTER_ACTION action;
- TR_FSPEC *specs[TR_MAX_FILTER_SPECS];
+ GPtrArray *specs;
TR_CONSTRAINT *realm_cons;
TR_CONSTRAINT *domain_cons;
} TR_FLINE;
+typedef struct tr_fline_iter {
+ TR_FLINE *fline;
+ guint ii;
+} TR_FLINE_ITER;
+
typedef struct tr_filter {
TR_FILTER_TYPE type;
GPtrArray *lines;
TR_FLINE *tr_filter_add_line(TR_FILTER *filt, TR_FLINE *line);
TR_FLINE *tr_fline_new(TALLOC_CTX *mem_ctx);
-
void tr_fline_free(TR_FLINE *fline);
+TR_FSPEC *tr_fline_add_spec(TR_FLINE *fline, TR_FSPEC *spec);
TR_FSPEC *tr_fspec_new(TALLOC_CTX *mem_ctx);
-
void tr_fspec_free(TR_FSPEC *fspec);
-
TR_NAME *tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match);
int tr_fspec_matches(TR_FSPEC *fspec, TR_FILTER_TYPE ftype, TR_FILTER_TARGET *target);
TR_FLINE *tr_filter_iter_first(TR_FILTER_ITER *iter, TR_FILTER *filter);
TR_FLINE *tr_filter_iter_next(TR_FILTER_ITER *iter);
+TR_FLINE_ITER *tr_fline_iter_new(TALLOC_CTX *mem_ctx);
+void tr_fline_iter_free(TR_FLINE_ITER *iter);
+TR_FSPEC * tr_fline_iter_first(TR_FLINE_ITER *iter, TR_FLINE *fline);
+TR_FSPEC * tr_fline_iter_next(TR_FLINE_ITER *iter);
+
TR_FSPEC_ITER *tr_fspec_iter_new(TALLOC_CTX *mem_ctx);
void tr_fspec_iter_free(TR_FSPEC_ITER *iter);
TR_NAME *tr_fspec_iter_first(TR_FSPEC_ITER *iter, TR_FSPEC *fspec);