From: mrw42 Date: Fri, 4 May 2018 18:50:16 +0000 (-0400) Subject: Merge pull request #62 from painless-security/jennifer/report_incoming_ipaddr X-Git-Tag: 3.4.0~1^2~39 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=trust_router.git;a=commitdiff_plain;h=fc7fb82d2661d977e7bacb4ffe469f3857a06b63;hp=26e3e1459e76a542dbc33896e2e42cd09d2d9198 Merge pull request #62 from painless-security/jennifer/report_incoming_ipaddr Report incoming IP address when a connection comes in --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ae8dba..1221d67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ set(SOURCE_FILES trp/trp_upd.c trp/trpc.c trp/trps.c include/tr_name_internal.h mon/mon_req.c mon/mon_req_encode.c mon/mon_req_decode.c - mon/mon_resp.c mon/mon_common.c mon/mon_resp_encode.c mon/mon_resp_decode.c tr/tr_mon.c mon/mons.c include/tr_socket.h common/tr_gss.c include/tr_gss.h common/tr_config_internal.c mon/mons_handlers.c include/mons_handlers.h tr/tr_tid_mons.c tr/tr_tid_mons.c trp/trp_route.c include/trp_route.h trp/trp_rtable_encoders.c trp/trp_route_encoders.c trp/trp_peer.c include/trp_peer.h trp/trp_peer_encoders.c trp/trp_ptable_encoders.c common/tr_idp_encoders.c common/tr_comm_encoders.c common/tr_rp_client.c include/tr_rp_client.h common/tr_rp_client_encoders.c common/tr_filter_encoders.c common/tr_config_encoders.c common/tr_config_filters.c common/tr_config_realms.c common/tr_config_rp_clients.c common/tr_config_orgs.c common/tr_config_comms.c) + mon/mon_resp.c mon/mon_common.c mon/mon_resp_encode.c mon/mon_resp_decode.c tr/tr_mon.c mon/mons.c include/tr_socket.h common/tr_gss.c include/tr_gss.h common/tr_config_internal.c mon/mons_handlers.c include/mons_handlers.h tr/tr_tid_mons.c tr/tr_tid_mons.c trp/trp_route.c include/trp_route.h trp/trp_rtable_encoders.c trp/trp_route_encoders.c trp/trp_peer.c include/trp_peer.h trp/trp_peer_encoders.c trp/trp_ptable_encoders.c common/tr_idp_encoders.c common/tr_comm_encoders.c common/tr_rp_client.c include/tr_rp_client.h common/tr_rp_client_encoders.c common/tr_filter_encoders.c common/tr_config_encoders.c common/tr_config_filters.c common/tr_config_realms.c common/tr_config_rp_clients.c common/tr_config_orgs.c common/tr_config_comms.c common/tr_list.c include/tr_list.h include/tr_constraint_internal.h) # Does not actually build! add_executable(trust_router ${SOURCE_FILES}) diff --git a/Makefile.am b/Makefile.am index 1c933d6..42179a0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -27,6 +27,7 @@ common_srcs = common/tr_name.c \ common/tr_filter_encoders.c \ common/tr_gss_names.c \ common/tr_socket.c \ + common/tr_list.c \ $(mon_srcs) tid_srcs = tid/tid_resp.c \ @@ -156,6 +157,7 @@ common/tr_name.c \ common/tr_gss_names.c \ common/tr_debug.c \ common/tr_util.c \ +common/tr_list.c \ trp/trp_route.c \ trp/trp_route_encoders.c \ trp/trp_rtable.c \ @@ -277,6 +279,7 @@ noinst_HEADERS = include/gsscon.h include/tr_config.h \ include/tr_cfgwatch.h include/tr_event.h \ include/tr_mq.h include/trp_peer.h include/trp_ptable.h \ include/trp_rtable.h include/tr_util.h \ + include/tr_list.h \ include/tr_name_internal.h include/tr_gss.h pkgdata_DATA=schema.sql diff --git a/common/tests/cfg_test.c b/common/tests/cfg_test.c index 97cd03c..29a949d 100644 --- a/common/tests/cfg_test.c +++ b/common/tests/cfg_test.c @@ -41,6 +41,7 @@ #include #include #include +#include static void tr_talloc_log(const char *msg) { @@ -98,7 +99,6 @@ static int verify_idp_cfg(TR_CFG *cfg) static int verify_rp_cfg(TR_CFG *cfg) { - int ii=0; TR_NAME *name=NULL; assert(cfg!=NULL); @@ -107,11 +107,9 @@ static int verify_rp_cfg(TR_CFG *cfg) assert(cfg->rp_clients->comm_next==NULL); assert(cfg->rp_clients->gss_names!=NULL); - for (ii=1; iirp_clients->gss_names->names[ii]==NULL); - assert(cfg->rp_clients->gss_names->names[0]!=NULL); + assert(tr_gss_names_length(cfg->rp_clients->gss_names) == 1); name=tr_new_name("gss@example.com"); - assert(tr_name_cmp(name, cfg->rp_clients->gss_names->names[0])==0); + assert(tr_name_cmp(name, tr_gss_names_index(cfg->rp_clients->gss_names, 0))==0); return 0; } diff --git a/common/tr_comm_encoders.c b/common/tr_comm_encoders.c index 2655fe5..6f33165 100644 --- a/common/tr_comm_encoders.c +++ b/common/tr_comm_encoders.c @@ -143,10 +143,10 @@ static json_t *tr_comm_memb_sources_to_json(TR_COMM_MEMB *first_memb) goto cleanup; /* Iterate over all the memberships for this realm/comm pair that come from different origins */ - memb = tr_comm_memb_iter_first(iter, first_memb); - while (memb) { + for (memb = tr_comm_memb_iter_first(iter, first_memb); + memb != NULL; + memb = tr_comm_memb_iter_next(iter)) { ARRAY_APPEND_OR_FAIL(jarray, tr_comm_memb_to_json(memb)); - memb = tr_comm_memb_iter_next(iter); } /* success */ @@ -171,23 +171,29 @@ static json_t *tr_comm_realms_to_json(TR_COMM_TABLE *ctable, TR_NAME *comm_name, TR_COMM_MEMB *memb = NULL; iter = tr_comm_iter_new(NULL); - realm = tr_realm_iter_first(iter, ctable, comm_name); + realm = NULL; /* Do not display the full realm json here, only the name and info relevant to the community listing */ - while(realm) { + for (realm = tr_realm_iter_first(iter, ctable, comm_name); + realm != NULL; + realm = tr_realm_iter_next(iter)) { if (realm->role == role) { realm_json = json_object(); OBJECT_SET_OR_FAIL(realm_json, "realm", tr_name_to_json_string(tr_realm_get_id(realm))); - memb = tr_comm_table_find_idp_memb(ctable, - tr_realm_get_id(realm), - comm_name); + memb = tr_comm_table_find_memb(ctable, + tr_realm_get_id(realm), + comm_name); + if (memb == NULL) { + /* This should not happen - there must be a matching membership if we + * believed the realm was in the community in the first place! */ + goto cleanup; + } OBJECT_SET_OR_FAIL(realm_json, "sources", tr_comm_memb_sources_to_json(memb)); json_array_append_new(jarray, realm_json); realm_json = NULL; /* so we don't free this twice during cleanup */ } - realm = tr_realm_iter_next(iter); } /* Success - increment the reference count so return value survives */ @@ -270,15 +276,15 @@ json_t *tr_comm_table_to_json(TR_COMM_TABLE *ctable) goto cleanup; /* Iterate over communities in the table */ - comm = tr_comm_table_iter_first(iter, ctable); - while (comm) { + for (comm = tr_comm_table_iter_first(iter, ctable); + comm != NULL; + comm = tr_comm_table_iter_next(iter)) { comm_json = tr_comm_to_json(ctable, comm); if (comm_json == NULL) goto cleanup; json_array_append_new(ctable_json, comm_json); - comm = tr_comm_table_iter_next(iter); } /* succeeded - set the return value and increment the reference count */ diff --git a/common/tr_config_filters.c b/common/tr_config_filters.c index 4035e68..7d4c615 100644 --- a/common/tr_config_filters.c +++ b/common/tr_config_filters.c @@ -35,33 +35,29 @@ #include #include #include -#include #include +#include #include -#include -#include -#include #include -#include -#include -#include -#include -#include #if JANSSON_VERSION_HEX < 0x020500 #include "jansson_iterators.h" #endif -static TR_CONSTRAINT *tr_cfg_parse_one_constraint(TALLOC_CTX *mem_ctx, char *ctype, json_t *jc, TR_CFG_RC *rc) +static TR_CONSTRAINT *tr_cfg_parse_one_constraint(TALLOC_CTX *mem_ctx, const char *ctype, json_t *jc, TR_CFG_RC *rc) { TR_CONSTRAINT *cons=NULL; - int i=0; + size_t i=0; - if ((!ctype) || (!jc) || (!rc) || + if (!rc) { + tr_err("tr_cfg_parse_one_constraint: rc is null, cannot process constraint."); + return NULL; + } + + if ((!ctype) || (!jc) || (!json_is_array(jc)) || (0 >= json_array_size(jc)) || - (TR_MAX_CONST_MATCHES < json_array_size(jc)) || (!json_is_string(json_array_get(jc, 0)))) { tr_err("tr_cfg_parse_one_constraint: config error."); *rc=TR_CFG_NOPARSE; @@ -82,9 +78,8 @@ static TR_CONSTRAINT *tr_cfg_parse_one_constraint(TALLOC_CTX *mem_ctx, char *cty } for (i=0; i < json_array_size(jc); i++) { - cons->matches[i]=tr_new_name(json_string_value(json_array_get(jc, i))); - if (cons->matches[i]==NULL) { - tr_err("tr_cfg_parse_one_constraint: Out of memory (match %d).", i+1); + if (NULL == tr_constraint_add_match(cons, tr_new_name(json_string_value(json_array_get(jc, i))))) { + tr_err("tr_cfg_parse_one_constraint: Out of memory (match %d).", i); *rc=TR_CFG_NOMEM; tr_constraint_free(cons); return NULL; @@ -98,6 +93,8 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR { 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; @@ -125,13 +122,6 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR } tr_filter_set_type(filt, ftype); - /* make sure we have space to represent the filter */ - if (json_array_size(jfilt) > TR_MAX_FILTER_LINES) { - tr_err("tr_cfg_parse_one_filter: Filter has too many lines, maximum of %d.", TR_MAX_FILTER_LINES); - *rc = TR_CFG_NOPARSE; - goto cleanup; - } - /* For each entry in the filter... */ json_array_foreach(jfilt, i, jfline) { if ((NULL == (jfaction = json_object_get(jfline, "action"))) || @@ -149,24 +139,21 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR 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; - } - - if (NULL == (filt->lines[i] = tr_fline_new(filt))) { - tr_debug("tr_cfg_parse_one_filter: Out of memory allocating filter line %d.", i + 1); + fline = tr_fline_new(tmp_ctx); + if (fline == NULL) { + tr_debug("tr_cfg_parse_one_filter: Out of memory allocating filter line %d.", i); *rc = TR_CFG_NOMEM; goto cleanup; } - if (!strcmp(json_string_value(jfaction), "accept")) { - filt->lines[i]->action = TR_FILTER_ACTION_ACCEPT; + fline->action = TR_FILTER_ACTION_ACCEPT; + tr_debug("tr_cfg_parse_one_filter: Filter action is 'accept'"); + } else if (!strcmp(json_string_value(jfaction), "reject")) { - filt->lines[i]->action = TR_FILTER_ACTION_REJECT; + fline->action = TR_FILTER_ACTION_REJECT; + tr_debug("tr_cfg_parse_one_filter: Filter action is 'reject'"); } else { - tr_debug("tr_cfg_parse_one_filter: Error parsing filter action, unknown action' %s'.", + tr_debug("tr_cfg_parse_one_filter: Error parsing filter action, unknown action '%s'.", json_string_value(jfaction)); *rc = TR_CFG_NOPARSE; goto cleanup; @@ -177,14 +164,9 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR tr_err("tr_cfg_parse_one_filter: cannot parse realm_constraints, not an array."); *rc = TR_CFG_NOPARSE; goto cleanup; - } else if (json_array_size(jrc) > TR_MAX_CONST_MATCHES) { - tr_err("tr_cfg_parse_one_filter: realm_constraints has too many entries, maximum of %d.", - TR_MAX_CONST_MATCHES); - *rc = TR_CFG_NOPARSE; - goto cleanup; } else if (json_array_size(jrc) > 0) { /* ok we actually have entries to process */ - if (NULL == (filt->lines[i]->realm_cons = tr_cfg_parse_one_constraint(filt->lines[i], "realm", jrc, rc))) { + if (NULL == (fline->realm_cons = tr_cfg_parse_one_constraint(fline, "realm", jrc, rc))) { tr_debug("tr_cfg_parse_one_filter: Error parsing realm constraint"); *rc = TR_CFG_NOPARSE; goto cleanup; @@ -197,13 +179,8 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR tr_err("tr_cfg_parse_one_filter: cannot parse domain_constraints, not an array."); *rc = TR_CFG_NOPARSE; goto cleanup; - } else if (json_array_size(jdc) > TR_MAX_CONST_MATCHES) { - tr_err("tr_cfg_parse_one_filter: domain_constraints has too many entries, maximum of %d.", - TR_MAX_CONST_MATCHES); - *rc = TR_CFG_NOPARSE; - goto cleanup; } else if (json_array_size(jdc) > 0) { - if (NULL == (filt->lines[i]->domain_cons = tr_cfg_parse_one_constraint(filt->lines[i], "domain", jdc, rc))) { + if (NULL == (fline->domain_cons = tr_cfg_parse_one_constraint(fline, "domain", jdc, rc))) { tr_debug("tr_cfg_parse_one_filter: Error parsing domain constraint"); *rc = TR_CFG_NOPARSE; goto cleanup; @@ -212,6 +189,7 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR } /*For each filter spec within the filter line... */ + tr_debug("tr_cfg_parse_one_filter: Filter line has %d spec(s)", json_array_size(jfspecs)); json_array_foreach(jfspecs, j, this_jfspec) { if ((NULL == (jfield = json_object_get(this_jfspec, "field"))) || (!json_is_string(jfield))) { @@ -239,14 +217,14 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR } /* allocate the filter spec */ - if (NULL == (filt->lines[i]->specs[j] = tr_fspec_new(filt->lines[i]))) { + 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 == (filt->lines[i]->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; @@ -259,7 +237,7 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR *rc = TR_CFG_NOMEM; goto cleanup; } - tr_fspec_add_match(filt->lines[i]->specs[j], name); + tr_fspec_add_match(fspec, name); } else { /* jmatch is an array (we checked earlier) */ json_array_foreach(jmatch, k, this_jmatch) { @@ -268,19 +246,32 @@ static TR_FILTER *tr_cfg_parse_one_filter(TALLOC_CTX *mem_ctx, json_t *jfilt, TR *rc = TR_CFG_NOMEM; goto cleanup; } - tr_fspec_add_match(filt->lines[i]->specs[j], name); + tr_fspec_add_match(fspec, name); } } - if (!tr_filter_validate_spec_field(ftype, filt->lines[i]->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.", - filt->lines[i]->specs[j]->field->len, - filt->lines[i]->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, tr_filter_type_to_string(filt->type)); + *rc = TR_CFG_NOMEM; + goto cleanup; } + tr_debug("tr_cfg_parse_one_filter: Added line %d to %s filter", i, tr_filter_type_to_string(filt->type)); } /* check that the filter is valid */ @@ -341,12 +332,16 @@ TR_FILTER_SET *tr_cfg_parse_filters(TALLOC_CTX *mem_ctx, json_t *jfilts, TR_CFG_ /* finally, parse the filter */ tr_debug("tr_cfg_parse_filters: Found %s filter.", filt_label); filt = tr_cfg_parse_one_filter(tmp_ctx, jfilt, filt_type, rc); - tr_filter_set_add(filt_set, filt); if (*rc != TR_CFG_SUCCESS) { tr_debug("tr_cfg_parse_filters: Error parsing %s filter.", filt_label); *rc = TR_CFG_NOPARSE; goto cleanup; } + if (tr_filter_set_add(filt_set, filt) != 0) { + tr_debug("tr_cfg_parse_filters: Error adding %s filter to filter set.", filt_label); + *rc = TR_CFG_NOPARSE; + goto cleanup; + } } *rc=TR_CFG_SUCCESS; diff --git a/common/tr_config_rp_clients.c b/common/tr_config_rp_clients.c index 960edce..b263c02 100644 --- a/common/tr_config_rp_clients.c +++ b/common/tr_config_rp_clients.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include @@ -113,6 +113,8 @@ static TR_FILTER_SET *tr_cfg_default_filters(TALLOC_CTX *mem_ctx, TR_NAME *realm { 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; @@ -147,16 +149,18 @@ static TR_FILTER_SET *tr_cfg_default_filters(TALLOC_CTX *mem_ctx, TR_NAME *realm goto cleanup; } tr_filter_set_type(filt, TR_FILTER_TYPE_TID_INBOUND); - filt->lines[0]=tr_fline_new(filt); - if (filt->lines[0]==NULL) { + + fline = tr_fline_new(tmp_ctx); + if (fline==NULL) { tr_debug("tr_cfg_default_filters: could not allocate filter line."); *rc=TR_CFG_NOMEM; goto cleanup; } - filt->lines[0]->action=TR_FILTER_ACTION_ACCEPT; - filt->lines[0]->specs[0]=tr_fspec_new(filt->lines[0]); - filt->lines[0]->specs[0]->field=n_rp_realm_1; + fline->action=TR_FILTER_ACTION_ACCEPT; + + 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); @@ -165,12 +169,18 @@ static TR_FILTER_SET *tr_cfg_default_filters(TALLOC_CTX *mem_ctx, TR_NAME *realm *rc=TR_CFG_NOMEM; goto cleanup; } - tr_fspec_add_match(filt->lines[0]->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 */ - filt->lines[0]->specs[1]=tr_fspec_new(filt->lines[0]); - filt->lines[0]->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))) { @@ -179,11 +189,17 @@ static TR_FILTER_SET *tr_cfg_default_filters(TALLOC_CTX *mem_ctx, TR_NAME *realm goto cleanup; } - tr_fspec_add_match(filt->lines[0]->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(filt->lines[0]))) { + if (NULL==(cons=tr_constraint_new(fline))) { tr_debug("tr_cfg_default_filters: could not allocate domain constraint."); *rc=TR_CFG_NOMEM; goto cleanup; @@ -197,20 +213,28 @@ static TR_FILTER_SET *tr_cfg_default_filters(TALLOC_CTX *mem_ctx, TR_NAME *realm *rc=TR_CFG_NOMEM; goto cleanup; } - cons->matches[0]=name; + if (NULL == tr_constraint_add_match(cons, name)) { + tr_debug("tr_cfg_default_filters: could not add realm name for domain constraint."); + *rc=TR_CFG_NOMEM; + goto cleanup; + } name=tr_name_cat(n_prefix, realm); if (name==NULL) { tr_debug("tr_cfg_default_filters: could not allocate wildcard realm name for domain constraint."); *rc=TR_CFG_NOMEM; goto cleanup; } - cons->matches[1]=name; + if (NULL == tr_constraint_add_match(cons, name)) { + tr_debug("tr_cfg_default_filters: could not add wildcard realm name for domain constraint."); + *rc=TR_CFG_NOMEM; + goto cleanup; + } name=NULL; - filt->lines[0]->domain_cons=cons; + fline->domain_cons=cons; /* realm constraint */ - if (NULL==(cons=tr_constraint_new(filt->lines[0]))) { + if (NULL==(cons=tr_constraint_new(fline))) { tr_debug("tr_cfg_default_filters: could not allocate realm constraint."); *rc=TR_CFG_NOMEM; goto cleanup; @@ -224,16 +248,31 @@ static TR_FILTER_SET *tr_cfg_default_filters(TALLOC_CTX *mem_ctx, TR_NAME *realm *rc=TR_CFG_NOMEM; goto cleanup; } - cons->matches[0]=name; + if (NULL == tr_constraint_add_match(cons, name)) { + tr_debug("tr_cfg_default_filters: could not add realm name for realm constraint."); + *rc=TR_CFG_NOMEM; + goto cleanup; + } name=tr_name_cat(n_prefix, realm); if (name==NULL) { tr_debug("tr_cfg_default_filters: could not allocate wildcard realm name for realm constraint."); *rc=TR_CFG_NOMEM; goto cleanup; } - cons->matches[1]=name; + if (NULL == tr_constraint_add_match(cons, name)) { + tr_debug("tr_cfg_default_filters: could not add wildcard realm name for realm constraint."); + *rc=TR_CFG_NOMEM; + goto cleanup; + } name=NULL; - filt->lines[0]->realm_cons=cons; + fline->realm_cons=cons; + + /* put the fline in the filter */ + if (NULL == tr_filter_add_line(filt, fline)) { + tr_debug("tr_cfg_default_filters: could not add line to filter."); + *rc = TR_CFG_NOMEM; + goto cleanup; + } /* put the filter in a set */ filt_set=tr_filter_set_new(tmp_ctx); diff --git a/common/tr_constraint.c b/common/tr_constraint.c index da5f42e..f9fcf61 100644 --- a/common/tr_constraint.c +++ b/common/tr_constraint.c @@ -38,35 +38,46 @@ #include #include -#include #include #include #include +#include - +/** + * Helper for tr_constraint_destructor - calls tr_free_name on its first argument + * + * @param item void pointer to a TR_NAME + * @param cookie ignored + */ +static void constraint_destruct_helper(void *item, void *cookie) +{ + TR_NAME *name = (TR_NAME *) item; + tr_free_name(name); +} static int tr_constraint_destructor(void *obj) { TR_CONSTRAINT *cons = talloc_get_type_abort(obj, TR_CONSTRAINT); - int ii = 0; - if (cons->type != NULL) + if (cons->type) tr_free_name(cons->type); - for (ii = 0; ii < TR_MAX_CONST_MATCHES; ii++) { - if (cons->matches[ii] != NULL) - tr_free_name(cons->matches[ii]); - } + + if (cons->matches) + tr_list_foreach(cons->matches, constraint_destruct_helper, NULL); + return 0; } TR_CONSTRAINT *tr_constraint_new(TALLOC_CTX *mem_ctx) { TR_CONSTRAINT *cons = talloc(mem_ctx, TR_CONSTRAINT); - int ii = 0; if (cons != NULL) { cons->type = NULL; - for (ii = 0; ii < TR_MAX_CONST_MATCHES; ii++) - cons->matches[ii] = NULL; + cons->matches = tr_list_new(cons); + if (cons->matches == NULL) { + talloc_free(cons); + return NULL; + } talloc_set_destructor((void *) cons, tr_constraint_destructor); } return cons; @@ -77,25 +88,63 @@ void tr_constraint_free(TR_CONSTRAINT *cons) talloc_free(cons); } +/** + * Helper for tr_constraint_dup - duplicates a TR_NAME and adds it as a TR_CONSTRAINT match + * + * No return value. If this succeeds, it will have added a new entry to the TR_CONSTRAINT + * match list. Check the length of that - you won't be able to tell whether the allocation + * of the duplicate TR_NAME or the addition to the list failed, but either of those is probably + * due to a memory allocation failure, in which case the system is probably crashing anyway. + * + * @param item void pointer to a TR_NAME to add as a match + * @param cookie void pointer to a TR_CONSTRAINT to add the match to + */ +static void cons_dup_helper(void *item, void *cookie) +{ + TR_CONSTRAINT *new_cons = talloc_get_type_abort(cookie, TR_CONSTRAINT); + TR_NAME *new_name = tr_dup_name((TR_NAME *) item); + if (new_name) { + /* check that new_name is added, free if it fails */ + if (tr_constraint_add_match(new_cons, new_name) == NULL) + tr_free_name(new_name); + } +} +/** + * Duplicate a TR_CONSTRAINT + * + * @param mem_ctx talloc context for the result + * @param cons TR_CONSTRAINT to duplicate + * @return pointer to the new TR_CONSTRAINT, or NULL on error + */ TR_CONSTRAINT *tr_constraint_dup(TALLOC_CTX *mem_ctx, TR_CONSTRAINT *cons) { - TALLOC_CTX *tmp_ctx = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); TR_CONSTRAINT *new = NULL; - int ii = 0; if (cons == NULL) - return NULL; + goto cleanup; - tmp_ctx = talloc_new(NULL); new = tr_constraint_new(tmp_ctx); + if (new == NULL) + goto cleanup; + + new->type = tr_dup_name(cons->type); + if (new->type == NULL) { + new = NULL; + goto cleanup; + } - if (new != NULL) { - new->type = tr_dup_name(cons->type); - for (ii = 0; ii < TR_MAX_CONST_MATCHES; ii++) - new->matches[ii] = tr_dup_name(cons->matches[ii]); - talloc_steal(mem_ctx, new); + tr_list_foreach(cons->matches, cons_dup_helper, new); /* copies matches to new->matches */ + /* check that we were successful - if we were, then the lists will be the same length */ + if (tr_list_length(new->matches) != tr_list_length(cons->matches)) { + new = NULL; + goto cleanup; /* at least one dup or add failed */ } + /* success */ + talloc_steal(mem_ctx, new); + +cleanup: talloc_free(tmp_ctx); return new; } @@ -165,7 +214,8 @@ void tr_constraint_add_to_set(TR_CONSTRAINT_SET **cset, TR_CONSTRAINT *cons) { json_t *jcons = NULL; json_t *jmatches = NULL; - int i = 0; + TR_NAME *this_match = NULL; + TR_CONSTRAINT_ITER iter = {0}; if ((!cset) || (!cons)) return; @@ -178,8 +228,11 @@ void tr_constraint_add_to_set(TR_CONSTRAINT_SET **cset, TR_CONSTRAINT *cons) jmatches = json_array(); jcons = json_object(); - for (i = 0; ((i < TR_MAX_CONST_MATCHES) && (NULL != cons->matches[i])); i++) { - json_array_append_new(jmatches, json_string(cons->matches[i]->buf)); + for (this_match = tr_constraint_iter_first(&iter, cons); + this_match != NULL; + this_match = tr_constraint_iter_next(&iter)) + { + json_array_append_new(jmatches, tr_name_to_json_string(this_match)); } json_object_set_new(jcons, cons->type->buf, jmatches); @@ -226,7 +279,6 @@ int tr_constraint_set_validate(TR_CONSTRAINT_SET *cset) { return 1; } - /** * Create a new constraint set containing all constraints from #orig * with constraint_type #constraint_type and no others. This constraint set is @@ -244,7 +296,8 @@ TR_CONSTRAINT_SET *tr_constraint_set_filter(TID_REQ *request, tr_debug ("tr_constraint_set_filter: not a valid constraint set\n"); return NULL; } - assert (new_cs = json_array()); + new_cs = json_array(); + assert(new_cs); json_array_foreach(orig_cset, index, set_member) { if (json_object_get(set_member, constraint_type)) json_array_append(new_cs, set_member); @@ -350,12 +403,14 @@ TR_CONSTRAINT_SET *tr_constraint_set_intersect(TID_REQ *request, domain = constraint_intersect_internal(input, "domain"); realm = constraint_intersect_internal(input, "realm"); } - assert(result = json_object()); + result = json_object(); + assert(result); if (domain) json_object_set_new(result, "domain", domain); if (realm) json_object_set_new(result, "realm", realm); - assert(result_array = json_array()); + result_array = json_array(); + assert(result_array); json_array_append_new(result_array, result); tid_req_cleanup_json(request, result_array); return (TR_CONSTRAINT_SET *) result_array; diff --git a/common/tr_filter.c b/common/tr_filter.c index 52dffb4..2b94526 100644 --- a/common/tr_filter.c +++ b/common/tr_filter.c @@ -408,34 +408,34 @@ int tr_filter_apply(TR_FILTER_TARGET *target, TR_CONSTRAINT_SET **constraints, TR_FILTER_ACTION *out_action) { - unsigned int ii=0, jj=0; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + 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; int retval=TR_FILTER_NO_MATCH; /* Default action is reject */ *out_action = TR_FILTER_ACTION_REJECT; /* Validate filter */ - if ((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; + } /* Step through filter lines looking for a match. If a line matches, retval * will be set to TR_FILTER_MATCH, so stop then. */ - for (ii=0, retval=TR_FILTER_NO_MATCH; - iilines[ii]==NULL) - continue; - + for (this_fline = tr_filter_iter_first(filt_iter, filt); + this_fline != NULL; + this_fline = tr_filter_iter_next(filt_iter)) { /* 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; jjlines[ii]->specs[jj]==NULL) - continue; - - if (!tr_fspec_matches(filt->lines[ii]->specs[jj], filt->type, target)) { + for (this_fspec = tr_fline_iter_first(fline_iter, this_fline); + this_fspec != NULL; + this_fspec = tr_fline_iter_next(fline_iter)) { + 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 */ } @@ -443,15 +443,16 @@ int tr_filter_apply(TR_FILTER_TARGET *target, if (retval==TR_FILTER_MATCH) break; + } if (retval==TR_FILTER_MATCH) { /* Matched line ii. Grab its action and constraints. */ - *out_action = filt->lines[ii]->action; + *out_action = this_fline->action; if (constraints!=NULL) { /* if either constraint is missing, these are no-ops */ - tr_constraint_add_to_set(constraints, filt->lines[ii]->realm_cons); - tr_constraint_add_to_set(constraints, filt->lines[ii]->domain_cons); + tr_constraint_add_to_set(constraints, this_fline->realm_cons); + tr_constraint_add_to_set(constraints, this_fline->domain_cons); } } @@ -463,55 +464,65 @@ void tr_fspec_free(TR_FSPEC *fspec) talloc_free(fspec); } +/** + * Helper for tr_fspec_destructor - calls tr_free_name on its first argument + * + * @param item void pointer to a TR_NAME + * @param cookie ignored + */ +static void fspec_destruct_helper(void *item, void *cookie) +{ + TR_NAME *name = (TR_NAME *) item; + tr_free_name(name); +} static int tr_fspec_destructor(void *obj) { TR_FSPEC *fspec = talloc_get_type_abort(obj, TR_FSPEC); - size_t ii; if (fspec->field != NULL) tr_free_name(fspec->field); - for (ii=0; iimatch[ii] != NULL) - tr_free_name(fspec->match[ii]); - } + + if (fspec->match) + tr_list_foreach(fspec->match, fspec_destruct_helper, NULL); + return 0; } TR_FSPEC *tr_fspec_new(TALLOC_CTX *mem_ctx) { TR_FSPEC *fspec = talloc(mem_ctx, TR_FSPEC); - size_t ii=0; if (fspec != NULL) { fspec->field = NULL; - for (ii=0; iimatch[ii] = NULL; - + fspec->match = tr_list_new(fspec); + if (fspec->match == NULL) { + talloc_free(fspec); + return NULL; + } talloc_set_destructor((void *)fspec, tr_fspec_destructor); } return fspec; } -void tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match) +/* Helper function and cookie structure for finding a match. The helper is called + * for every item in the match list, even after a match is found. If a match is found, + * match should be pointed to the matching item. If this is not NULL, do not change it + * because a match has already been found. */ +struct fspec_match_cookie { TR_NAME *name; TR_NAME *match;}; +static void fspec_match_helper(void *item, void *data) { - size_t ii; - for (ii=0; iimatch[ii]==NULL) { - fspec->match[ii]=match; - break; - } + TR_NAME *this_name = (TR_NAME *) item; + struct fspec_match_cookie *cookie = (struct fspec_match_cookie *) data; + if (cookie->match == NULL) { + if (tr_name_prefix_wildcard_match(cookie->name, this_name)) + cookie->match = this_name; } - /* TODO: handle case that adding the match failed */ } - /* returns 1 if the spec matches */ int tr_fspec_matches(TR_FSPEC *fspec, TR_FILTER_TYPE ftype, TR_FILTER_TARGET *target) { struct tr_filter_field_entry *field=NULL; - TR_NAME *name=NULL; - int retval=0; - - size_t ii=0; + struct fspec_match_cookie cookie = {0}; if (fspec==NULL) return 0; @@ -525,32 +536,27 @@ int tr_fspec_matches(TR_FSPEC *fspec, TR_FILTER_TYPE ftype, TR_FILTER_TARGET *ta return 0; } - name=field->get(target); - if (name==NULL) + cookie.name = field->get(target); + if (cookie.name==NULL) return 0; /* if there's no value, there's no match */ - for (ii=0; iimatch[ii]!=NULL) { - if (tr_name_prefix_wildcard_match(name, fspec->match[ii])) { - retval=1; - tr_debug("tr_fspec_matches: Field %.*s value \"%.*s\" matches \"%.*s\" for %s filter.", - fspec->field->len, fspec->field->buf, - name->len, name->buf, - fspec->match[ii]->len, fspec->match[ii]->buf, - tr_filter_type_to_string(ftype)); - break; - } - } - } - - if (!retval) { + cookie.match = NULL; + tr_list_foreach(fspec->match, + fspec_match_helper, + &cookie); + if (cookie.match) { + tr_debug("tr_fspec_matches: Field %.*s value \"%.*s\" matches \"%.*s\" for %s filter.", + fspec->field->len, fspec->field->buf, + cookie.name->len, cookie.name->buf, + cookie.match->len, cookie.match->buf, + tr_filter_type_to_string(ftype)); + } else { tr_debug("tr_fspec_matches: Field %.*s value \"%.*s\" does not match for %s filter.", fspec->field->len, fspec->field->buf, - name->len, name->buf, + cookie.name->len, cookie.name->buf, tr_filter_type_to_string(ftype)); } - tr_free_name(name); - return retval; + return (cookie.match != NULL); } void tr_fline_free(TR_FLINE *fline) @@ -561,14 +567,16 @@ void tr_fline_free(TR_FLINE *fline) 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 = tr_list_new(fl); + if (fl->specs == NULL) { + talloc_free(fl); + return NULL; + } } return fl; } @@ -576,12 +584,14 @@ TR_FLINE *tr_fline_new(TALLOC_CTX *mem_ctx) TR_FILTER *tr_filter_new(TALLOC_CTX *mem_ctx) { TR_FILTER *f = talloc(mem_ctx, TR_FILTER); - int ii = 0; if (f != NULL) { f->type = TR_FILTER_TYPE_UNKNOWN; - for (ii = 0; ii < TR_MAX_FILTER_LINES; ii++) - f->lines[ii] = NULL; + f->lines = tr_list_new(f); + if (f->lines == NULL) { + talloc_free(f); + return NULL; + } } return f; } @@ -609,10 +619,16 @@ TR_FILTER_TYPE tr_filter_get_type(TR_FILTER *filt) */ int tr_filter_validate(TR_FILTER *filt) { - size_t ii=0, jj=0, kk=0; - - if (!filt) + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + 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) || (!filt_iter) || (!fline_iter)) { + talloc_free(tmp_ctx); return 0; + } /* check that we recognize the type */ switch(filt->type) { @@ -622,41 +638,43 @@ int tr_filter_validate(TR_FILTER *filt) break; default: + talloc_free(tmp_ctx); return 0; /* if we get here, either TR_FILTER_TYPE_UNKNOWN or an invalid value was found */ } - for (ii=0; iilines[ii]==NULL) - continue; /* an empty filter line is valid */ - + + for (this_fline = tr_filter_iter_first(filt_iter, filt); + this_fline != NULL; + this_fline = tr_filter_iter_next(filt_iter)) { /* check that we recognize the action */ - switch(filt->lines[ii]->action) { + switch(this_fline->action) { case TR_FILTER_ACTION_ACCEPT: case TR_FILTER_ACTION_REJECT: break; default: /* if we get here, either TR_FILTER_ACTION_UNKNOWN or an invalid value was found */ + talloc_free(tmp_ctx); return 0; } - for (jj=0; jjlines[ii]->specs[jj]==NULL) - continue; /* an empty filter spec is valid */ - - if (!tr_filter_validate_spec_field(filt->type, filt->lines[ii]->specs[jj])) + for (this_fspec = tr_fline_iter_first(fline_iter, this_fline); + this_fspec != NULL; + this_fspec = tr_fline_iter_next(fline_iter)) { + if (!tr_filter_validate_spec_field(filt->type, this_fspec)) { + talloc_free(tmp_ctx); return 0; - - /* check that at least one match is non-null */ - for (kk=0; kklines[ii]->specs[jj]->match[kk]!=NULL) - break; } - if (kk==TR_MAX_FILTER_SPEC_MATCHES) + + /* check that at least one match is defined*/ + if (tr_list_length(this_fspec->match) == 0) { + talloc_free(tmp_ctx); return 0; + } } } /* We ran the gauntlet. Success! */ + talloc_free(tmp_ctx); return 1; } diff --git a/common/tr_filter_encoders.c b/common/tr_filter_encoders.c index cc22b02..932be9e 100644 --- a/common/tr_filter_encoders.c +++ b/common/tr_filter_encoders.c @@ -36,6 +36,7 @@ #include #include +#include /* helper for below */ #define OBJECT_SET_OR_FAIL(jobj, key, val) \ @@ -57,18 +58,48 @@ do { \ typedef json_t *(ITEM_ENCODER_FUNC)(void *); -static json_t *items_to_json_array(void *items[], ITEM_ENCODER_FUNC *item_encoder, size_t max_items) +enum array_type { + ARRAY_TYPE_FSPEC, + ARRAY_TYPE_CONSTRAINT +}; +/** + * Make an array of matches from a TR_FSPEC or TR_CONSTRAINT + * + * @param obj + * @param type + * @return + */ +static json_t *tr_names_to_json_array(void *obj, enum array_type type) { - size_t ii; json_t *jarray = json_array(); json_t *retval = NULL; + TR_FSPEC_ITER fspec_iter = {0}; + TR_CONSTRAINT_ITER cons_iter = {0}; + TR_NAME *this_match = NULL; if (jarray == NULL) goto cleanup; - for (ii=0; iifield)); OBJECT_SET_OR_FAIL(fspec_json, "matches", - items_to_json_array((void **)fspec->match, - (ITEM_ENCODER_FUNC *) tr_name_to_json_string, - TR_MAX_FILTER_SPEC_MATCHES)); + tr_names_to_json_array(fspec, ARRAY_TYPE_FSPEC)); /* succeeded - set the return value and increment the reference count */ retval = fspec_json; @@ -107,6 +136,34 @@ cleanup: 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; + + for (this_fspec = tr_fline_iter_first(iter, fline); + this_fspec != NULL; + this_fspec = tr_fline_iter_next(iter)) { + ARRAY_APPEND_OR_FAIL(jarray, tr_fspec_to_json(this_fspec)); + } + /* 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; @@ -119,20 +176,14 @@ static json_t *tr_fline_to_json(TR_FLINE *fline) 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, - (ITEM_ENCODER_FUNC *) tr_name_to_json_string, - TR_MAX_CONST_MATCHES)); + tr_names_to_json_array(fline->realm_cons, ARRAY_TYPE_CONSTRAINT)); } if (fline->domain_cons) { OBJECT_SET_OR_FAIL(fline_json, "domain_constraints", - items_to_json_array((void **) fline->domain_cons->matches, - (ITEM_ENCODER_FUNC *) tr_name_to_json_string, - TR_MAX_CONST_MATCHES)); + tr_names_to_json_array(fline->domain_cons, ARRAY_TYPE_CONSTRAINT)); } /* succeeded - set the return value and increment the reference count */ @@ -145,6 +196,33 @@ cleanup: return retval; } +static json_t *tr_flines_to_json_array(TR_FILTER *filt) +{ + json_t *jarray = json_array(); + json_t *retval = NULL; + TR_FILTER_ITER *iter = tr_filter_iter_new(NULL); + TR_FLINE *this_fline = NULL; + + if ((jarray == NULL) || (iter == NULL)) + goto cleanup; + + for(this_fline = tr_filter_iter_first(iter, filt); + this_fline != NULL; + this_fline = tr_filter_iter_next(iter)) { + ARRAY_APPEND_OR_FAIL(jarray, tr_fline_to_json(this_fline)); + } + /* success */ + retval = jarray; + json_incref(retval); + +cleanup: + if (jarray) + json_decref(jarray); + if (iter) + tr_filter_iter_free(iter); + + return retval; +} json_t *tr_filter_set_to_json(TR_FILTER_SET *filter_set) { json_t *fset_json = NULL; @@ -166,9 +244,7 @@ json_t *tr_filter_set_to_json(TR_FILTER_SET *filter_set) filt = tr_filter_set_get(filter_set, *filt_type); if (filt) { OBJECT_SET_OR_FAIL(fset_json, tr_filter_type_to_string(*filt_type), - items_to_json_array((void **)filt->lines, - (ITEM_ENCODER_FUNC *) tr_fline_to_json, - TR_MAX_FILTER_LINES)); + tr_flines_to_json_array(filt)); } } diff --git a/common/tr_gss_names.c b/common/tr_gss_names.c index df15202..416ba8c 100644 --- a/common/tr_gss_names.c +++ b/common/tr_gss_names.c @@ -33,29 +33,38 @@ */ #include +#include #include #include +/** + * Helper for tr_gss_names_destructor - calls tr_free_name on its first argument + * + * @param item void pointer to a TR_NAME + * @param cookie ignored + */ +static void gss_names_destruct_helper(void *item, void *cookie) +{ + TR_NAME *name = (TR_NAME *) item; + tr_free_name(name); +} static int tr_gss_names_destructor(void *obj) { TR_GSS_NAMES *gss_names=talloc_get_type_abort(obj, TR_GSS_NAMES); - int ii=0; - - for (ii=0; iinames[ii]!=NULL) - tr_free_name(gss_names->names[ii]); - } + if (gss_names->names) + tr_list_foreach(gss_names->names, gss_names_destruct_helper, NULL); return 0; } TR_GSS_NAMES *tr_gss_names_new(TALLOC_CTX *mem_ctx) { - TR_GSS_NAMES *gn=talloc(mem_ctx, TR_GSS_NAMES); - int ii=0; - - if (gn!=NULL) { - for (ii=0; iinames[ii]=NULL; + TR_GSS_NAMES *gn = talloc(mem_ctx, TR_GSS_NAMES); + if (gn != NULL) { + gn->names = tr_list_new(gn); + if (gn->names == NULL) { + talloc_free(gn); + return NULL; + } talloc_set_destructor((void *)gn, tr_gss_names_destructor); } return gn; @@ -69,17 +78,7 @@ void tr_gss_names_free(TR_GSS_NAMES *gn) /* returns 0 on success */ int tr_gss_names_add(TR_GSS_NAMES *gn, TR_NAME *new) { - int ii=0; - - for (ii=0; iinames[ii]==NULL) - break; - } - if (ii!=TR_MAX_GSS_NAMES) { - gn->names[ii]=new; - return 0; - } else - return -1; + return (NULL == tr_list_add(gn->names, new, 0)); /* nonzero if the add failed */ } /** @@ -100,68 +99,36 @@ TR_GSS_NAMES *tr_gss_names_dup(TALLOC_CTX *mem_ctx, TR_GSS_NAMES *orig) talloc_free(tmp_ctx); return NULL; } - this = tr_gss_names_iter_first(iter, orig); - while (this) { + for (this = tr_gss_names_iter_first(iter, orig); + this != NULL; + this = tr_gss_names_iter_next(iter)) { if (tr_gss_names_add(new, tr_dup_name(this)) != 0) { talloc_free(tmp_ctx); return NULL; } - this = tr_gss_names_iter_next(iter); } /* success */ talloc_steal(mem_ctx, new); return new; } + int tr_gss_names_matches(TR_GSS_NAMES *gn, TR_NAME *name) { - int ii=0; + TR_GSS_NAMES_ITER iter={0}; + TR_NAME *this = NULL; - if (!gn) + if ((!gn) || (!name)) return 0; - for (ii=0; iinames[ii]!=NULL) && - (0==tr_name_cmp(gn->names[ii], name))) + for (this = tr_gss_names_iter_first(&iter, gn); + this != NULL; + this = tr_gss_names_iter_next(&iter)) { + if (tr_name_cmp(name, this) == 0) return 1; } return 0; } -/* iterators */ -TR_GSS_NAMES_ITER *tr_gss_names_iter_new(TALLOC_CTX *mem_ctx) -{ - TR_GSS_NAMES_ITER *iter=talloc(mem_ctx, TR_GSS_NAMES_ITER); - if (iter!=NULL) { - iter->gn=NULL; - iter->ii=0; - } - return iter; -} - -TR_NAME *tr_gss_names_iter_first(TR_GSS_NAMES_ITER *iter, TR_GSS_NAMES *gn) -{ - iter->gn=gn; - iter->ii=-1; - return tr_gss_names_iter_next(iter); -} - -TR_NAME *tr_gss_names_iter_next(TR_GSS_NAMES_ITER *iter) -{ - for (iter->ii++; - (iter->ii < TR_MAX_GSS_NAMES) && (iter->gn->names[iter->ii]==NULL); - iter->ii++) { } - - if (iter->iign->names[iter->ii]; - - return NULL; -} - -void tr_gss_names_iter_free(TR_GSS_NAMES_ITER *iter) -{ - talloc_free(iter); -} - json_t *tr_gss_names_to_json_array(TR_GSS_NAMES *gss_names) { TR_GSS_NAMES_ITER *iter = tr_gss_names_iter_new(NULL); diff --git a/common/tr_idp_encoders.c b/common/tr_idp_encoders.c index fec129a..2167ea9 100644 --- a/common/tr_idp_encoders.c +++ b/common/tr_idp_encoders.c @@ -148,10 +148,10 @@ static json_t *tr_apcs_to_json(TR_APC *apcs) if ((jarray == NULL) || (iter == NULL)) goto cleanup; - apc = tr_apc_iter_first(iter, apcs); - while (apc) { + for (apc = tr_apc_iter_first(iter, apcs); + apc != NULL; + apc = tr_apc_iter_next(iter)) { ARRAY_APPEND_OR_FAIL(jarray, tr_name_to_json_string(tr_apc_get_id(apc))); - apc = tr_apc_iter_next(iter); } /* success */ @@ -192,10 +192,10 @@ static json_t *tr_aaa_servers_to_json(TR_AAA_SERVER *aaas) if ((jarray == NULL) || (iter == NULL)) goto cleanup; - aaa = tr_aaa_server_iter_first(iter, aaas); - while (aaa) { + for (aaa = tr_aaa_server_iter_first(iter, aaas); + aaa != NULL; + aaa = tr_aaa_server_iter_next(iter)) { ARRAY_APPEND_OR_FAIL(jarray, tr_aaa_server_to_json(aaa)); - aaa = tr_aaa_server_iter_next(iter); } /* success */ diff --git a/common/tr_list.c b/common/tr_list.c new file mode 100644 index 0000000..e3269f4 --- /dev/null +++ b/common/tr_list.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2018 JANET(UK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of JANET(UK) nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include +#include + +static int tr_list_destructor(void *object) +{ + TR_LIST *list = talloc_get_type_abort(object, TR_LIST); + if (*list) + g_ptr_array_unref(*list); + return 0; +} + +/* Note that the TR_LIST type is a pointer-to-pointer to + * a GPtrArray. This is done so that we can hook a talloc destructor + * to the list to ensure that the GLib reference count is handled correctly + * when used with talloc. */ +TR_LIST *tr_list_new(TALLOC_CTX *mem_ctx) +{ + TR_LIST *list = talloc(mem_ctx, TR_LIST); + if (list) { + *list = g_ptr_array_new(); + if (*list == NULL) { + talloc_free(list); + return NULL; + } + talloc_set_destructor((void *)list, tr_list_destructor); + } + return list; +} + +void tr_list_free(TR_LIST *list) +{ + talloc_free(list); +} + +/** + * Add an item to the list + * + * If steal != 0, performs a talloc_steal() to put the new item in the + * list's context. If steal == 0, does not do this - in that case, you'll + * need to be sure that the memory is cleaned up through some other means. + * (This allows the list to represent non-talloc'ed items.) + * + * @param list list to add an item to + * @param item pointer to the item to add + * @param steal if non-zero, the item will be added to the list's context with talloc_steal() + * @return pointer to the added item or null if there was an error + */ +void *tr_list_add(TR_LIST *list, void *item, int steal) +{ + guint old_len = (*list)->len; + g_ptr_array_add((*list), item); + + if ((*list)->len == old_len) + return NULL; /* failed to add */ + + if (steal) + talloc_steal(list, item); + + return item; +} + +/** + * Call func(item, cookie) on each item in the list. + * + * @param list list to iterate over + * @param func function, takes two void pointer arguments, first is the item, second the cookie + * @param cookie + */ +void tr_list_foreach(TR_LIST *list, TR_LIST_FOREACH_FUNC *func, void *cookie) +{ + g_ptr_array_foreach((*list), func, cookie); +} + +TR_LIST_ITER *tr_list_iter_new(TALLOC_CTX *mem_ctx) +{ + TR_LIST_ITER *iter = talloc(mem_ctx, TR_LIST_ITER); + if (iter) + iter->list = NULL; + return iter; +} + +void tr_list_iter_free(TR_LIST_ITER *iter) +{ + talloc_free(iter); +} + +void *tr_list_iter_first(TR_LIST_ITER *iter, TR_LIST *list) +{ + if (!iter || !list || (!(*list))) + return NULL; + + iter->list = list; + iter->index = 0; + return tr_list_iter_next(iter); +} + +void *tr_list_iter_next(TR_LIST_ITER *iter) +{ + if (!iter) + return NULL; + + if (iter->index < (*(iter->list))->len) + return g_ptr_array_index(*(iter->list), iter->index++); + return NULL; +} diff --git a/common/tr_name.c b/common/tr_name.c index 84f0c1f..e1f81b4 100644 --- a/common/tr_name.c +++ b/common/tr_name.c @@ -52,9 +52,11 @@ TR_NAME *tr_new_name (const char *name) { TR_NAME *new; - if (new = malloc(sizeof(TR_NAME))) { - new->len = strlen(name); - if (new->buf = malloc((new->len)+1)) { + new = malloc(sizeof(TR_NAME)); + if (new) { + new->len = (int) strlen(name); + new->buf = malloc(1 + (size_t) new->len); + if (new->buf) { strcpy(new->buf, name); } else { free(new); @@ -64,7 +66,7 @@ TR_NAME *tr_new_name (const char *name) return new; } -TR_NAME *tr_dup_name (TR_NAME *from) +TR_NAME *tr_dup_name (const TR_NAME *from) { TR_NAME *to; @@ -74,15 +76,15 @@ TR_NAME *tr_dup_name (TR_NAME *from) if (NULL != (to = malloc(sizeof(TR_NAME)))) { to->len = from->len; - if (NULL != (to->buf = malloc(to->len+1))) { - strncpy(to->buf, from->buf, from->len); + if (NULL != (to->buf = malloc(1 + (size_t) to->len))) { + strncpy(to->buf, from->buf, (size_t) from->len); to->buf[to->len] = 0; /* NULL terminate for debugging printf()s */ } } return to; } -int tr_name_cmp(TR_NAME *one, TR_NAME *two) +int tr_name_cmp(const TR_NAME *one, const TR_NAME *two) { int len=one->len; int cmp=0; @@ -90,7 +92,7 @@ int tr_name_cmp(TR_NAME *one, TR_NAME *two) if (two->lenlen) len=two->len; /* len now min(one->len,two->len) */ - cmp=strncmp(one->buf, two->buf, len); + cmp=strncmp(one->buf, two->buf, (size_t) len); if (cmp==0) { if (one->lenlen) return -1; @@ -109,7 +111,7 @@ int tr_name_cmp(TR_NAME *one, TR_NAME *two) * @param two_str Ordinary C null-terminated string * @return 0 on match, <0 if one precedes two, >0 if two precedes one */ -int tr_name_cmp_str(TR_NAME *one, const char *two_str) +int tr_name_cmp_str(const TR_NAME *one, const char *two_str) { TR_NAME *two=tr_new_name(two_str); int cmp=tr_name_cmp(one, two); @@ -126,7 +128,7 @@ int tr_name_cmp_str(TR_NAME *one, const char *two_str) * @return 1 if the the string (str) matches the wildcard string (wc_str), 0 if not. * */ -int tr_name_prefix_wildcard_match(TR_NAME *str, TR_NAME *wc_str) +int tr_name_prefix_wildcard_match(const TR_NAME *str, const TR_NAME *wc_str) { const char *wc_post=NULL; size_t wc_len = 0; @@ -134,7 +136,8 @@ int tr_name_prefix_wildcard_match(TR_NAME *str, TR_NAME *wc_str) if ((!str) || (!wc_str)) return 0; - if (0 == (wc_len = wc_str->len)) + wc_len = (size_t) wc_str->len; + if (wc_len == 0) return 0; if ('*' == wc_str->buf[0]) { @@ -145,7 +148,7 @@ int tr_name_prefix_wildcard_match(TR_NAME *str, TR_NAME *wc_str) /* No wildcard, but the strings are the same length so may match. * Compare the full strings. */ wc_post=wc_str->buf; - wc_len=wc_str->len; + wc_len = (size_t) wc_str->len; } else { /* No wildcard and strings are different length, so no match */ return 0; @@ -165,24 +168,25 @@ void tr_name_strlcat(char *dest, const TR_NAME *src, size_t len) size_t used_len; if (src->len >= len) used_len = len-1; - else used_len = src->len; + else + used_len = (size_t) src->len; if (used_len > 0) strncat(dest, src->buf, used_len); else dest[0] = '\0'; } -char * tr_name_strdup(TR_NAME *src) +char * tr_name_strdup(const TR_NAME *src) { - char *s = calloc(src->len+1, 1); + char *s = calloc(1 + (size_t) src->len, 1); if (s) { - memcpy(s, src->buf, src->len); + memcpy(s, src->buf, (size_t) src->len); s[src->len] = '\0'; } return s; } -json_t *tr_name_to_json_string(TR_NAME *src) +json_t *tr_name_to_json_string(const TR_NAME *src) { char *s=tr_name_strdup(src); json_t *js=json_string(s); @@ -191,16 +195,16 @@ json_t *tr_name_to_json_string(TR_NAME *src) return js; } -TR_NAME *tr_name_cat(TR_NAME *n1, TR_NAME *n2) +TR_NAME *tr_name_cat(const TR_NAME *n1, const TR_NAME *n2) { - char *s=malloc(n1->len+n2->len+1); + char *s=malloc((size_t) n1->len + (size_t) n2->len + 1); TR_NAME *name=NULL; if (s==NULL) return NULL; *s=0; - strncat(s, n1->buf, n1->len); - strncat(s, n2->buf, n2->len); + strncat(s, n1->buf, (size_t) n1->len); + strncat(s, n2->buf, (size_t) n2->len); name=tr_new_name(s); free(s); return name; diff --git a/common/tr_rp_client_encoders.c b/common/tr_rp_client_encoders.c index d0a5cd0..6a7bda9 100644 --- a/common/tr_rp_client_encoders.c +++ b/common/tr_rp_client_encoders.c @@ -87,10 +87,10 @@ json_t *tr_rp_clients_to_json(TR_RP_CLIENT *rp_clients) if ((jarray == NULL) || (iter == NULL)) goto cleanup; - rp_client = tr_rp_client_iter_first(iter, rp_clients); - while (rp_client) { + for (rp_client = tr_rp_client_iter_first(iter, rp_clients); + rp_client != NULL; + rp_client = tr_rp_client_iter_next(iter)) { ARRAY_APPEND_OR_FAIL(jarray, tr_rp_client_to_json(rp_client)); - rp_client = tr_rp_client_iter_next(iter); } /* succeeded - set the return value and increment the reference count */ diff --git a/include/tr_constraint_internal.h b/include/tr_constraint_internal.h new file mode 100644 index 0000000..2182781 --- /dev/null +++ b/include/tr_constraint_internal.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018, JANET(UK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of JANET(UK) nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef TRUST_ROUTER_TR_CONSTRAINT_INTERNAL_H +#define TRUST_ROUTER_TR_CONSTRAINT_INTERNAL_H + +#include + +#include +#include +#include + + +struct tr_constraint { + TR_NAME *type; + TR_LIST *matches; +}; + +TR_CONSTRAINT *tr_constraint_new(TALLOC_CTX *mem_ctx); +void tr_constraint_free(TR_CONSTRAINT *cons); +TR_CONSTRAINT *tr_constraint_dup(TALLOC_CTX *mem_ctx, TR_CONSTRAINT *cons); + +/* Iterator for TR_CONS matches */ +typedef TR_LIST_ITER TR_CONSTRAINT_ITER; +#define tr_constraint_iter_new(CTX) (tr_list_iter_new(CTX)) +#define tr_constraint_iter_free(ITER) (tr_list_iter_free(ITER)) +#define tr_constraint_iter_first(ITER, CONS) ((TR_NAME *) tr_list_iter_first((ITER), (CONS)->matches)) +#define tr_constraint_iter_next(ITER) ((TR_NAME *) tr_list_iter_next(ITER)) +#define tr_constraint_add_match(CONS, MATCH) ((TR_NAME *) tr_list_add((CONS)->matches, (MATCH), 0)) + +#endif //TRUST_ROUTER_TR_CONSTRAINT_INTERNAL_H diff --git a/include/tr_filter.h b/include/tr_filter.h index ece3650..d241a50 100644 --- a/include/tr_filter.h +++ b/include/tr_filter.h @@ -37,17 +37,14 @@ #include #include +#include +#include #include #include #include #include -#define TR_MAX_FILTERS 5 -#define TR_MAX_FILTER_LINES 8 -#define TR_MAX_FILTER_SPECS 8 -#define TR_MAX_FILTER_SPEC_MATCHES 64 - /* Filter actions */ typedef enum tr_filter_action { TR_FILTER_ACTION_REJECT = 0, @@ -69,22 +66,21 @@ typedef enum { typedef struct tr_fspec { TR_NAME *field; - TR_NAME *match[TR_MAX_FILTER_SPEC_MATCHES]; + TR_LIST *match; } TR_FSPEC; typedef struct tr_fline { TR_FILTER_ACTION action; - TR_FSPEC *specs[TR_MAX_FILTER_SPECS]; + TR_LIST *specs; TR_CONSTRAINT *realm_cons; TR_CONSTRAINT *domain_cons; } TR_FLINE; typedef struct tr_filter { TR_FILTER_TYPE type; - TR_FLINE *lines[TR_MAX_FILTER_LINES]; + TR_LIST *lines; } TR_FILTER; - typedef struct tr_filter_set TR_FILTER_SET; struct tr_filter_set { TR_FILTER *this; @@ -109,25 +105,45 @@ int tr_filter_set_add(TR_FILTER_SET *set, TR_FILTER *new); TR_FILTER *tr_filter_set_get(TR_FILTER_SET *set, TR_FILTER_TYPE type); TR_FILTER *tr_filter_new(TALLOC_CTX *mem_ctx); - void tr_filter_free(TR_FILTER *filt); void tr_filter_set_type(TR_FILTER *filt, TR_FILTER_TYPE type); - TR_FILTER_TYPE tr_filter_get_type(TR_FILTER *filt); +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); - -void tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match); +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); +/* Iterator for TR_FILTER lines */ +typedef TR_LIST_ITER TR_FILTER_ITER; +#define tr_filter_iter_new(CTX) (tr_list_iter_new(CTX)) +#define tr_filter_iter_free(ITER) (tr_list_iter_free(ITER)) +#define tr_filter_iter_first(ITER, FILT) ((TR_FLINE *) tr_list_iter_first((ITER), (FILT)->lines)) +#define tr_filter_iter_next(ITER) ((TR_FLINE *) tr_list_iter_next(ITER)) +#define tr_filter_add_line(FILT, LINE) ((TR_FLINE *) tr_list_add((FILT)->lines, (LINE), 1)) + +/* Iterator for TR_FSPEC matches */ +typedef TR_LIST_ITER TR_FSPEC_ITER; +#define tr_fspec_iter_new(CTX) (tr_list_iter_new(CTX)) +#define tr_fspec_iter_free(ITER) (tr_list_iter_free(ITER)) +#define tr_fspec_iter_first(ITER, SPEC) (tr_list_iter_first((ITER), (SPEC)->match)) +#define tr_fspec_iter_next(ITER) (tr_list_iter_next(ITER)) +#define tr_fspec_add_match(SPEC, MATCH) ((TR_NAME *) tr_list_add((SPEC)->match, (MATCH), 0)) + +/* Iterator for TR_FLINE specs */ +typedef TR_LIST_ITER TR_FLINE_ITER; +#define tr_fline_iter_new(CTX) (tr_list_iter_new(CTX)) +#define tr_fline_iter_free(ITER) (tr_list_iter_free(ITER)) +#define tr_fline_iter_first(ITER, LINE) (tr_list_iter_first((ITER), (LINE)->specs)) +#define tr_fline_iter_next(ITER) (tr_list_iter_next(ITER)) +#define tr_fline_add_spec(LINE, SPEC) ((TR_NAME *) tr_list_add((LINE)->specs, (SPEC), 1)) /*In tr_constraint.c and exported, but not really a public symbol; needed by tr_filter.c and by tr_constraint.c*/ int TR_EXPORT tr_prefix_wildcard_match(const char *str, const char *wc_str); diff --git a/include/tr_gss_names.h b/include/tr_gss_names.h index f8f97a2..c6192be 100644 --- a/include/tr_gss_names.h +++ b/include/tr_gss_names.h @@ -36,29 +36,29 @@ #define __TR_GSS_H__ #include -#include +#include -#define TR_MAX_GSS_NAMES 5 +#include typedef struct tr_gss_names { - TR_NAME *names[TR_MAX_GSS_NAMES]; + TR_LIST *names; } TR_GSS_NAMES; -typedef struct tr_gss_names_iter { - TR_GSS_NAMES *gn; - int ii; /* which entry did we last output? */ -} TR_GSS_NAMES_ITER; +typedef TR_LIST_ITER TR_GSS_NAMES_ITER; + +/* Iterator for TR_FILTER lines */ +#define tr_gss_names_iter_new(CTX) (tr_list_iter_new(CTX)) +#define tr_gss_names_iter_free(ITER) (tr_list_iter_free(ITER)) +#define tr_gss_names_iter_first(ITER, GSSN) ((TR_NAME *) tr_list_iter_first((ITER), (GSSN)->names)) +#define tr_gss_names_iter_next(ITER) ((TR_NAME *) tr_list_iter_next(ITER)) TR_GSS_NAMES *tr_gss_names_new(TALLOC_CTX *mem_ctx); void tr_gss_names_free(TR_GSS_NAMES *gn); int tr_gss_names_add(TR_GSS_NAMES *gn, TR_NAME *new); TR_GSS_NAMES *tr_gss_names_dup(TALLOC_CTX *mem_ctx, TR_GSS_NAMES *orig); int tr_gss_names_matches(TR_GSS_NAMES *gn, TR_NAME *name); - -TR_GSS_NAMES_ITER *tr_gss_names_iter_new(TALLOC_CTX *mem_ctx); -TR_NAME *tr_gss_names_iter_first(TR_GSS_NAMES_ITER *iter, TR_GSS_NAMES *gn); -TR_NAME *tr_gss_names_iter_next(TR_GSS_NAMES_ITER *iter); -void tr_gss_names_iter_free(TR_GSS_NAMES_ITER *iter); +#define tr_gss_names_length(GSSN) (tr_list_length((GSSN)->names)) +#define tr_gss_names_index(GSSN, INDEX) (tr_list_index((GSSN)->names, (INDEX))) json_t *tr_gss_names_to_json_array(TR_GSS_NAMES *gss_names); diff --git a/include/tr_list.h b/include/tr_list.h new file mode 100644 index 0000000..8bfca38 --- /dev/null +++ b/include/tr_list.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018 JANET(UK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of JANET(UK) nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TRUST_ROUTER_TR_LIST_H +#define TRUST_ROUTER_TR_LIST_H + +#include +#include + +typedef GPtrArray *TR_LIST; + +typedef void (TR_LIST_FOREACH_FUNC)(void *item, void *cookie); + +typedef struct tr_list_iter{ + TR_LIST *list; + guint index; +} TR_LIST_ITER; + +#define tr_list_index(LIST, INDEX) (g_ptr_array_index(*(LIST),(INDEX))) +#define tr_list_length(LIST) ((size_t)((*(LIST))->len)) + +TR_LIST *tr_list_new(TALLOC_CTX *mem_ctx); +void tr_list_free(TR_LIST *list); +void *tr_list_add(TR_LIST *list, void *item, int steal); + +TR_LIST_ITER *tr_list_iter_new(TALLOC_CTX *mem_ctx); +void tr_list_iter_free(TR_LIST_ITER *iter); +void *tr_list_iter_first(TR_LIST_ITER *iter, TR_LIST *list); +void *tr_list_iter_next(TR_LIST_ITER *iter); +void tr_list_foreach(TR_LIST *list, TR_LIST_FOREACH_FUNC *func, void *cookie); + +#endif //TRUST_ROUTER_TR_LIST_H diff --git a/include/tr_name_internal.h b/include/tr_name_internal.h index 02c78f8..a67a64d 100644 --- a/include/tr_name_internal.h +++ b/include/tr_name_internal.h @@ -40,15 +40,14 @@ */ #ifndef TR_NAME_INTERNAL_H +#define TR_NAME_INTERNAL_H #include #include /** Prototypes */ -json_t *tr_name_to_json_string(TR_NAME *src); -int tr_name_cmp_str(TR_NAME *one, const char *two_str); -int tr_name_prefix_wildcard_match(TR_NAME *str, TR_NAME *wc_str); - -#define TR_NAME_INTERNAL_H +json_t *tr_name_to_json_string(const TR_NAME *src); +int tr_name_cmp_str(const TR_NAME *one, const char *two_str); +int tr_name_prefix_wildcard_match(const TR_NAME *str, const TR_NAME *wc_str); #endif //TRUST_ROUTER_TR_NAME_INTERNAL_H diff --git a/include/trust_router/tr_constraint.h b/include/trust_router/tr_constraint.h index 2594b36..88619e4 100644 --- a/include/trust_router/tr_constraint.h +++ b/include/trust_router/tr_constraint.h @@ -35,23 +35,10 @@ #ifndef TR_CONSTRAINT_H #define TR_CONSTRAINT_H -#include - #include #include - -#define TR_MAX_CONST_MATCHES 24 - - -typedef struct tr_constraint { - TR_NAME *type; - TR_NAME *matches[TR_MAX_CONST_MATCHES]; -} TR_CONSTRAINT; - -TR_CONSTRAINT *tr_constraint_new(TALLOC_CTX *mem_ctx); -void tr_constraint_free(TR_CONSTRAINT *cons); -TR_CONSTRAINT *tr_constraint_dup(TALLOC_CTX *mem_ctx, TR_CONSTRAINT *cons); +typedef struct tr_constraint TR_CONSTRAINT; void TR_EXPORT tr_constraint_add_to_set (TR_CONSTRAINT_SET **cs, TR_CONSTRAINT *c); int TR_EXPORT tr_constraint_set_validate( TR_CONSTRAINT_SET *); @@ -65,6 +52,4 @@ int TR_EXPORT tr_constraint_set_get_match_strings(TID_REQ *, const char * constraint_type, tr_const_string **output, size_t *output_len); - - #endif diff --git a/include/trust_router/tr_name.h b/include/trust_router/tr_name.h index 052d291..797a3be 100644 --- a/include/trust_router/tr_name.h +++ b/include/trust_router/tr_name.h @@ -45,11 +45,11 @@ typedef struct tr__name { } TR_NAME; TR_EXPORT TR_NAME *tr_new_name (const char *name); -TR_EXPORT TR_NAME *tr_dup_name (TR_NAME *from); +TR_EXPORT TR_NAME *tr_dup_name (const TR_NAME *from); TR_EXPORT void tr_free_name (TR_NAME *name); -TR_EXPORT int tr_name_cmp (TR_NAME *one, TR_NAME *two); +TR_EXPORT int tr_name_cmp (const TR_NAME *one, const TR_NAME *two); TR_EXPORT void tr_name_strlcat(char *dest, const TR_NAME *src, size_t len); -TR_EXPORT char *tr_name_strdup(TR_NAME *); -TR_EXPORT TR_NAME *tr_name_cat(TR_NAME *n1, TR_NAME *n2); +TR_EXPORT char *tr_name_strdup(const TR_NAME *); +TR_EXPORT TR_NAME *tr_name_cat(const TR_NAME *n1, const TR_NAME *n2); #endif diff --git a/mon/mon_req_decode.c b/mon/mon_req_decode.c index 0c7e7f4..21bb64b 100644 --- a/mon/mon_req_decode.c +++ b/mon/mon_req_decode.c @@ -126,7 +126,7 @@ MON_REQ *mon_req_parse(TALLOC_CTX *mem_ctx, const char *input) * * (options are optional) * - * Caller must free the return value with MON_REQ_free(). + * Caller must free the return value with mon_req_free(). * * @param mem_ctx talloc context for the returned struct * @param req_json reference to JSON request object @@ -171,8 +171,6 @@ MON_REQ *mon_req_decode(TALLOC_CTX *mem_ctx, json_t *req_json) cleanup: talloc_free(tmp_ctx); - if (req_json) - json_decref(req_json); return req; } diff --git a/mon/mon_resp_encode.c b/mon/mon_resp_encode.c index 23c3dd8..7e41c65 100644 --- a/mon/mon_resp_encode.c +++ b/mon/mon_resp_encode.c @@ -79,6 +79,7 @@ json_t *mon_resp_encode(MON_RESP *resp) /* If we have a payload, add it */ if (resp->payload) { object_set_or_free_and_return(resp_json, jval, "payload", resp->payload); + json_incref(resp->payload); /* we just created a second reference to the payload */ } return resp_json; diff --git a/tr/tr_main.c b/tr/tr_main.c index 5f8215d..ba738c7 100644 --- a/tr/tr_main.c +++ b/tr/tr_main.c @@ -81,13 +81,15 @@ static const char arg_doc[]=""; /* string describing arguments, if any */ * { long-name, short-name, variable name, options, help description } */ static const struct argp_option cmdline_options[] = { { "config-dir", 'c', "DIR", 0, "Specify configuration file location (default is current directory)"}, - { "version", 'v', NULL, 0, "Print version information and exit"}, + { "config-validate", 'C', NULL, 0, "Validate configuration files and exit"}, + { "version", 1, NULL, 0, "Print version information and exit"}, { NULL } }; /* structure for communicating with option parser */ struct cmdline_args { int version_requested; + int validate_config_and_exit; char *config_dir; }; @@ -106,10 +108,14 @@ static error_t parse_option(int key, char *arg, struct argp_state *state) arguments->config_dir=arg; break; - case 'v': + case 1: arguments->version_requested=1; break; + case 'C': + arguments->validate_config_and_exit=1; + break; + default: return ARGP_ERR_UNKNOWN; } @@ -207,6 +213,7 @@ int main(int argc, char *argv[]) /***** parse command-line arguments *****/ /* set defaults */ opts.version_requested=0; + opts.validate_config_and_exit=0; opts.config_dir="."; /* parse the command line*/ @@ -271,6 +278,11 @@ int main(int argc, char *argv[]) return 1; } + /***** Exit here if we are just validating our configuration *****/ + if (opts.validate_config_and_exit) { + printf("Valid configuration found in %s.\n", opts.config_dir); + return 0; + } /***** Set up the event loop *****/ ev_base=tr_event_loop_init(); /* Set up the event loop */ if (ev_base==NULL) { diff --git a/trp/trp_ptable_encoders.c b/trp/trp_ptable_encoders.c index 2ff8c9c..ea97a10 100644 --- a/trp/trp_ptable_encoders.c +++ b/trp/trp_ptable_encoders.c @@ -60,10 +60,12 @@ json_t *trp_ptable_to_json(TRP_PTABLE *ptbl) { TRP_PTABLE_ITER *iter = trp_ptable_iter_new(NULL); json_t *ptbl_json = json_array(); - TRP_PEER *peer = trp_ptable_iter_first(iter, ptbl); - while(peer) { + TRP_PEER *peer = NULL; + + for (trp_ptable_iter_first(iter, ptbl); + peer != NULL; + peer = trp_ptable_iter_next(iter)) { json_array_append_new(ptbl_json, trp_peer_to_json(peer)); - peer = trp_ptable_iter_next(iter); } trp_ptable_iter_free(iter); return ptbl_json;