From: Margaret Wasserman Date: Wed, 18 Dec 2013 12:25:52 +0000 (-0500) Subject: Configuration for full filter structures. X-Git-Tag: 1.0.1-2~7 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=commitdiff_plain;h=c9e656a2c5536236c9491496326e8c996992688f Configuration for full filter structures. --- diff --git a/common/tr_config.c b/common/tr_config.c index 7b1e58b..8e49c95 100644 --- a/common/tr_config.c +++ b/common/tr_config.c @@ -39,6 +39,7 @@ #include #include +#include void tr_print_config (FILE *stream, TR_CFG *cfg) { fprintf(stream, "tr_print_config: Not yet implemented.\n"); @@ -90,92 +91,176 @@ static TR_CFG_RC tr_cfg_parse_internal (TR_INSTANCE *tr, json_t *jcfg) { return TR_CFG_SUCCESS; } -static TR_RP_CLIENT *tr_cfg_parse_one_rp_client (TR_INSTANCE *tr, json_t *jrp, TR_CFG_RC *rc) +static TR_FILTER *tr_cfg_parse_one_filter (TR_INSTANCE *tr, json_t *jfilt, TR_CFG_RC *rc) { - TR_RP_CLIENT *rp = NULL; - json_t *jgns = NULL; - json_t *jfilt = NULL; - json_t *jfls = NULL; + TR_FILTER *filt = NULL; json_t *jftype = NULL; - json_t *jfact = NULL; + json_t *jfls = NULL; + json_t *jfaction = NULL; json_t *jfspecs = NULL; json_t *jffield = NULL; - json_t *jfrealm = NULL; - int i = 0; - - if ((!jrp) || (!rc)) { - fprintf(stderr, "tr_cfg_parse_one_rp_realm: Bad parameters.\n"); - if (rc) - *rc = TR_CFG_BAD_PARAMS; - return NULL; - } + json_t *jfmatch = NULL; + int i = 0, j = 0; - if (NULL == (rp = malloc(sizeof(TR_RP_CLIENT)))) { - fprintf(stderr, "tr_config_parse_one_rp_realm: Out of memory.\n"); - *rc = TR_CFG_NOMEM; + if ((NULL == (jftype = json_object_get(jfilt, "type"))) || + (!json_is_string(jftype))) { + fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing filter type.\n"); + *rc = TR_CFG_NOPARSE; return NULL; } - - memset(rp, 0, sizeof(TR_RP_CLIENT)); - if ((NULL == (jfilt = json_object_get(jrp, "filter"))) || - (NULL == (jfls = json_object_get(jfilt, "filter_lines"))) || - (!json_is_array(jfls)) || - (NULL == (jgns = json_object_get(jrp, "gss_names"))) || - (!json_is_array(jgns))) { - fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing RP client configuration.\n"); - free(rp); + if ((NULL == (jfls = json_object_get(jfilt, "filter_lines"))) || + (!json_is_array(jfls))) { + fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing filter type.\n"); *rc = TR_CFG_NOPARSE; return NULL; } - if (0 == json_array_size(jfls)) { - fprintf(stderr, "tr_cfg_parse_one_rp_client: RP Client has no filter lines.\n"); + if (TR_MAX_FILTER_LINES < json_array_size(jfls)) { + fprintf(stderr, "tr_cfg_parse_one_filter: Filter has too many filter_lines, maximimum of %d.\n", TR_MAX_FILTER_LINES); *rc = TR_CFG_NOPARSE; return NULL; } - if ((NULL == (jftype = json_object_get(jfilt, "type"))) || - (!json_is_string(jftype)) || - (strcmp(json_string_value(jftype), "rp_permitted"))) { - fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing RP client filter type.\n"); - *rc = TR_CFG_NOPARSE; + /* TBD -- optionally parse realm and domain constraints */ + + if (NULL == (filt = malloc(sizeof(TR_FILTER)))) { + fprintf(stderr, "tr_config_parse_one_filter: Out of memory.\n"); + *rc = TR_CFG_NOMEM; return NULL; } + memset(filt, 0, sizeof(TR_FILTER)); - /* Right now, we only accept one type of filter, and we only care - * about one per rp_client. */ - if ((NULL == (jfact = json_object_get(json_array_get(jfls, 0), "action"))) || - (!json_is_string(jfact)) || - (strcmp(json_string_value(jfact), "accept"))) { - fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing RP client filter action.\n"); + if (!strcmp(json_string_value(jftype), "rp_permitted")) { + filt->type = TR_FILTER_TYPE_RP_PERMITTED; + } + else { + fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing filter type, unknown type '%s'.\n", json_string_value(jftype)); *rc = TR_CFG_NOPARSE; + tr_filter_free(filt); return NULL; - } + } + + /* For each filter line... */ + for (i = 0; i < json_array_size(jfls); i++) { - if ((NULL == (jfspecs = json_object_get(json_array_get(jfls, 0), "filter_specs"))) || - (!json_is_array(jfspecs)) || - (0 == json_array_size(jfspecs))) { - fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing RP client filter specs.\n"); + if ((NULL == (jfaction = json_object_get(json_array_get(jfls, i), "action"))) || + (!json_is_string(jfaction))) { + fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing filter action.\n"); *rc = TR_CFG_NOPARSE; + tr_filter_free(filt); return NULL; - } + } + + /* TBD -- parse constraints */ + + if ((NULL == (jfspecs = json_object_get(json_array_get(jfls, i), "filter_specs"))) || + (!json_is_array(jfspecs)) || + (0 == json_array_size(jfspecs))) { + fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing filter specs.\n"); + *rc = TR_CFG_NOPARSE; + tr_filter_free(filt); + return NULL; + } + + if (TR_MAX_FILTER_SPECS < json_array_size(jfspecs)) { + fprintf(stderr, "tr_cfg_parse_one_filter: Filter has too many filter_specs, maximimum of %d.\n", TR_MAX_FILTER_SPECS); + *rc = TR_CFG_NOPARSE; + tr_filter_free(filt); + return NULL; + } - if ((NULL == (jffield = json_object_get(json_array_get(jfspecs, 0), "field"))) || - (!json_is_string(jffield)) || - (strcmp(json_string_value(jffield), "rp_realm")) || - (NULL == (jfrealm = json_object_get(json_array_get(jfspecs, 0), "match"))) || - (!json_is_string(jfrealm))) { - fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing RP client filter field and match.\n"); + if (NULL == (filt->lines[i] = malloc(sizeof(TR_FLINE)))) { + fprintf(stderr, "tr_config_parse_one_filter: Out of memory.\n"); + *rc = TR_CFG_NOMEM; + tr_filter_free(filt); + return NULL; + } + + memset(filt->lines[i], 0, sizeof(TR_FLINE)); + + if (!strcmp(json_string_value(jfaction), "accept")) { + filt->lines[i]->action = TR_FILTER_ACTION_ACCEPT; + } + else if (!strcmp(json_string_value(jfaction), "reject")) { + filt->lines[i]->action = TR_FILTER_ACTION_REJECT; + } + else { + fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing filter action, unknown action' %s'.\n", json_string_value(jfaction)); *rc = TR_CFG_NOPARSE; + tr_filter_free(filt); return NULL; + } + + /*For each filter spec within the filter line... */ + for (j = 0; j lines[i]->specs[j] = malloc(sizeof(TR_FSPEC)))) { + fprintf(stderr, "tr_config_parse_one_filter: Out of memory.\n"); + *rc = TR_CFG_NOMEM; + tr_filter_free(filt); + return NULL; + } + + memset(filt->lines[i]->specs[j], 0, sizeof(TR_FSPEC)); + + if ((NULL == (filt->lines[i]->specs[j]->field = tr_new_name((char *)json_string_value(jffield)))) || + (NULL == (filt->lines[i]->specs[j]->match = tr_new_name((char *)json_string_value(jfmatch))))) { + fprintf(stderr, "tr_config_parse_one_filter: Out of memory.\n"); + *rc = TR_CFG_NOMEM; + tr_filter_free(filt); + return NULL; + } + } } + return filt; +} + +static TR_RP_CLIENT *tr_cfg_parse_one_rp_client (TR_INSTANCE *tr, json_t *jrp, TR_CFG_RC *rc) +{ + TR_RP_CLIENT *rp = NULL; + json_t *jgns = NULL; + json_t *jfilt = NULL; + json_t *jftype = NULL; + int i = 0; - rp->rp_match = tr_new_name((char *)json_string_value(jfrealm)); + if ((!jrp) || (!rc)) { + fprintf(stderr, "tr_cfg_parse_one_rp_realm: Bad parameters.\n"); + if (rc) + *rc = TR_CFG_BAD_PARAMS; + return NULL; + } - if (0 == json_array_size(jgns)) { - fprintf(stderr, "tr_cfg_parse_one_rp_client: RP Client has no GSS Names.\n"); + if ((NULL == (jgns = json_object_get(jrp, "gss_names"))) || + (!json_is_array(jgns))) { + fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing RP client configuration, no GSS names.\n"); + *rc = TR_CFG_NOPARSE; + return NULL; + } + + /* TBD -- Support more than one filter per RP client? */ + if (NULL == (jfilt = json_object_get(jrp, "filter"))) { + fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing RP client configuration, no filter.\n"); + *rc = TR_CFG_NOPARSE; + return NULL; + } + + /* We only support rp_permitted filters for RP clients */ + if ((NULL == (jftype = json_object_get(jfilt, "type"))) || + (!json_is_string(jftype)) || + (strcmp(json_string_value(jftype), "rp_permitted"))) { + fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing RP client filter type.\n"); *rc = TR_CFG_NOPARSE; return NULL; } @@ -186,9 +271,26 @@ static TR_RP_CLIENT *tr_cfg_parse_one_rp_client (TR_INSTANCE *tr, json_t *jrp, T return NULL; } + if (NULL == (rp = malloc(sizeof(TR_RP_CLIENT)))) { + fprintf(stderr, "tr_config_parse_one_rp_realm: Out of memory.\n"); + *rc = TR_CFG_NOMEM; + return NULL; + } + + memset(rp, 0, sizeof(TR_RP_CLIENT)); + + /* TBD -- support more than one filter entry per RP Client? */ + if (NULL == (rp->filters[0] = tr_cfg_parse_one_filter(tr, jfilt, rc))) { + fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing filter.\n"); + free(rp); + *rc = TR_CFG_NOPARSE; + return NULL; + } + for (i = 0; i < json_array_size(jgns); i++) { if (NULL == (rp->gss_names[i] = tr_new_name ((char *)json_string_value(json_array_get(jgns, i))))) { fprintf(stderr, "tr_cfg_parse_one_rp_client: No memory for GSS Name.\n"); + free(rp); *rc = TR_CFG_NOMEM; return NULL; } @@ -217,7 +319,7 @@ static TR_CFG_RC tr_cfg_parse_rp_clients (TR_INSTANCE *tr, json_t *jcfg) { &rc))) { return rc; } - fprintf(stderr, "tr_cfg_parse_rp_clients: RP client configured -- first gss: %s, rp_realm: %s\n", rp->gss_names[0]->buf, rp->rp_match->buf); + fprintf(stderr, "tr_cfg_parse_rp_clients: RP client configured -- first gss: %s", rp->gss_names[0]->buf); rp->next = tr->new_cfg->rp_clients; tr->new_cfg->rp_clients = rp; } diff --git a/common/tr_filter.c b/common/tr_filter.c index adcef7f..0143d89 100644 --- a/common/tr_filter.c +++ b/common/tr_filter.c @@ -33,9 +33,29 @@ */ #include +#include #include #include +void tr_filter_free (TR_FILTER *filt) { + int i = 0, j = 0; + + if (!filt) + return; + + for (i = 0; i < TR_MAX_FILTER_LINES; i++) { + if (filt->lines[i]) { + for (j = 0; j < TR_MAX_FILTER_SPECS; j++) { + if (filt->lines[i]->specs[j]) + free(filt->lines[i]->specs[j]); + } + free(filt->lines[i]); + } + } + + free (filt); +} + /* Returns TRUE (1) if the the string (str) matchs the wildcard string (wc_str), FALSE (0) if not. */ int tr_prefix_wildcard_match (char *str, char *wc_str) { diff --git a/include/tr_filter.h b/include/tr_filter.h index 9d5dc25..4c61888 100644 --- a/include/tr_filter.h +++ b/include/tr_filter.h @@ -35,6 +35,45 @@ #ifndef TR_FILTER_H #define TR_FILTER_H +#include +#include + +#define TR_MAX_FILTERS 5 +#define TR_MAX_FILTER_LINES 8 +#define TR_MAX_FILTER_SPECS 8 + +/* Filter actions */ +#define TR_FILTER_ACTION_REJECT 0 +#define TR_FILTER_ACTION_ACCEPT 1 + +/* Filter types */ +#define TR_FILTER_TYPE_RP_PERMITTED 0 +/* Other types TBD */ + +typedef struct tr_constraint { + struct tr_constraint *next; + TR_NAME values[]; +} TR_CONSTRAINT; + +typedef struct tr_fspec { + TR_NAME *field; + TR_NAME *match; +} TR_FSPEC; + +typedef struct tr_fline { + int action; + TR_FSPEC *specs[TR_MAX_FILTER_SPECS]; + TR_CONSTRAINT *realm_cons; + TR_CONSTRAINT *domain_cons; + json_t *j_constraints; +} TR_FLINE; + +typedef struct tr_filter { + int type; + TR_FLINE *lines[TR_MAX_FILTER_LINES]; +} TR_FILTER; + +void tr_filter_free (TR_FILTER *filt); int tr_prefix_wildcard_match (char *str, char *wc_str); #endif diff --git a/include/tr_rp.h b/include/tr_rp.h index 81a9c14..de9ad98 100644 --- a/include/tr_rp.h +++ b/include/tr_rp.h @@ -36,18 +36,18 @@ #define TR_RP_H #include +#include #define TR_MAX_GSS_NAMES 5 typedef struct tr_rp_client { struct tr_rp_client *next; struct tr_rp_client *comm_next; - TR_NAME *rp_match; TR_NAME *gss_names[TR_MAX_GSS_NAMES]; - // TR_FILTER *filters; + TR_FILTER *filters[TR_MAX_FILTERS]; } TR_RP_CLIENT; -/* Structure to make a link list of RP realms by name for community config */ +/* Structure to make a linked list of RP realms by name for community config */ typedef struct tr_rp_realm { struct tr_rp_realm *next; TR_NAME *realm_name; diff --git a/tr/tr_main.c b/tr/tr_main.c index c71d724..d1bd6e4 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -105,6 +105,7 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids, /* Check that the rp_realm matches the filter for the GSS name that * was received. */ + /* TBD -- rewrite for new filtering system. if ((!((TR_INSTANCE *)tr)->rp_gss) || (!((TR_INSTANCE *)tr)->rp_gss->rp_match)) { fprintf(stderr, "tr_tids_req_handler: No GSS name for incoming request.\n"); @@ -118,6 +119,8 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids, return -1; } + */ + /* Check that the rp_realm and target_realm are members of the community in the request */ if (NULL == (tr_find_comm_rp(cfg_comm, orig_req->rp_realm))) { fprintf(stderr, "tr_tids_req_hander: RP Realm (%s) not member of community (%s).\n", orig_req->rp_realm->buf, orig_req->comm->buf);