config.*
tr/trust_router
common/dh_test/tr_dh_test
+common/t_constraint
tid/example/tids
tid/example/tidc
\ No newline at end of file
+DISTCHECK_CONFIGURE_FLAGS = \
+ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
bin_PROGRAMS= tr/trust_router tid/example/tidc tid/example/tids common/dh_test/tr_dh_test
AM_CPPFLAGS=-I$(srcdir)/include
-AM_CFLAGS = -Wall -Werror=missing-prototypes -Werror=strict-prototypes -Wno-parentheses
+AM_CFLAGS = -Wall -Werror=missing-prototypes -Werror -Wno-parentheses
SUBDIRS = gsscon
common_srcs = common/tr_name.c \
-common/tr_msg.c \
-common/tr_dh.c \
+ common/tr_constraint.c \
+ common/jansson_iterators.h \
+ common/tr_msg.c \
+ common/tr_dh.c \
common/tr_util.c
+check_PROGRAMS = common/t_constraint
+TESTS = common/t_constraint
+
lib_LTLIBRARIES = libtr_tid.la
+common_t_constraint_SOURCES = common/t_constraint.c
+common_t_constraint_CPPFLAGS = $(AM_CPPFLAGS) -DTESTS=\"$(srcdir)/common/tests.json\"
+common_t_constraint_LDADD = gsscon/libgsscon.la libtr_tid.la
+
tr_trust_router_SOURCES = tr/tr_main.c \
common/tr_config.c \
common/tr_idp.c \
common/tr_comm.c \
common/tr_filter.c \
-common/tr_constraint.c \
common/tr_rp.c \
tr/tr.c
libtr_tid_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden
libtr_tid_la_LIBADD = gsscon/libgsscon.la
-libtr_tid_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1 -no-undefined
+libtr_tid_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2 -no-undefined
pkginclude_HEADERS = include/trust_router/tid.h include/trust_router/tr_name.h \
include/trust_router/tr_dh.h \
include/trust_router/tr_versioning.h
noinst_HEADERS = include/gsscon.h include/tr_config.h \
+ include/tr_debug.h \
include/tr_msg.h include/tr.h \
include/tr_idp.h include/tr_rp.h \
include/tr_comm.h include/tr_apc.h \
- include/tr_filter.h
+ include/tr_filter.h \
+ include/tid_internal.h
+
+pkgdata_DATA=schema.sql
+nobase_dist_pkgdata_DATA=redhat/init redhat/sysconfig redhat/trusts.cfg redhat/tidc-wrapper redhat/trust_router-wrapper redhat/tr-test-main.cfg redhat/default-main.cfg
+if HAVE_SYSTEMD
+systemdsystemunit_DATA = tids.service
+endif
-EXTRA_DIST = trust_router.spec
+EXTRA_DIST = trust_router.spec common/tests.json schema.sql tids.service
--- /dev/null
+/*
+ * Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org>
+ *
+ * Jansson is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+/*See the LICENSE file in the jansson source distribution.
+ */
+
+#ifndef json_object_foreach
+#define json_object_foreach(object, key, value) \
+ for(key = json_object_iter_key(json_object_iter(object)); \
+ key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
+ key = json_object_iter_key(json_object_iter_next(object, json_object_key_to_iter(key))))
+#endif
+
+#ifndef json_array_foreach
+#define json_array_foreach(array, index, value) \
+ for(index = 0; \
+ index < json_array_size(array) && (value = json_array_get(array, index)); \
+ index++)
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2012, 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 <jansson.h>
+#include "jansson_iterators.h"
+#include <stdio.h>
+#include <assert.h>
+
+#include <tid_internal.h>
+#include <trust_router/tr_constraint.h>
+#include <tr_debug.h>
+
+static TID_REQ *request = NULL;
+
+static int handle_test_case(
+ json_t *tc)
+{
+ json_t *constraints, *valid, *expected;
+ int validp;
+ json_t *result;
+ assert(constraints = json_object_get(tc, "constraints"));
+ assert( valid = json_object_get(tc, "valid"));
+ validp = tr_constraint_set_validate((TR_CONSTRAINT_SET *)constraints);
+ if (validp != json_is_true(valid)) {
+ tr_debug("Unexpected validation result for \n");
+ json_dumpf( constraints, stderr, JSON_INDENT(4));
+ return 0;
+ }
+ if (!validp)
+ return 1;
+ assert( expected = json_object_get(tc, "expected"));
+ result = (json_t *) tr_constraint_set_intersect(request, (TR_CONSTRAINT_SET *) constraints);
+ if (!json_equal(result, expected)) {
+ tr_debug("Unexpected intersection; actual:\n");
+ json_dumpf(result, stderr, JSON_INDENT(4));
+ tr_debug("Expected: \n");
+ json_dumpf(expected, stderr, JSON_INDENT(4));
+ return 0;
+ }
+ return 1;
+}
+
+int main(void) {
+ json_t *tests;
+ int error=0;
+ json_t *tc;
+ size_t index;
+ request = tid_req_new();
+ tests = json_load_file(TESTS, JSON_REJECT_DUPLICATES|JSON_DISABLE_EOF_CHECK, NULL);
+ json_array_foreach(tests, index, tc)
+ if (!handle_test_case(tc))
+ error = 1;
+ if (error)
+ return 1;
+ return 0;
+}
--- /dev/null
+[
+ {
+ "constraints": [{}],
+ "valid": true,
+ "expected": [{}]
+ },
+ {
+ "constraints": [33],
+ "valid": false
+ },
+ {
+ "constraints": [{
+ "domain": ["ja.net", "*.ja.net", "foo.ja.net"]
+ }],
+ "valid": true,
+ "expected": [{
+ "domain": ["ja.net", "*.ja.net"]
+ }]
+ },
+ {
+ "constraints": [{
+ "domain": ["*"],
+ "realm": ["*"]
+ },
+ {
+ "domain": ["*.cam.ac.uk"]
+ }],
+ "expected": [{
+ "domain": ["*.cam.ac.uk"],
+ "realm": ['*']
+ }],
+ "valid": true
+ },
+ {"constraints": [
+ {"realm": ["painless-security.com", "*.painless-security.com"]},
+ {"domain": ["painless-security.com"]
+ }],
+ "expected": [{"realm": ["painless-security.com", "*.painless-security.com"],
+ "domain": ["painless-security.com"]
+ }],
+ "valid": true
+ }
+
+ ]
#include <string.h>
#include <jansson.h>
#include <dirent.h>
+#include <talloc.h>
#include <tr_config.h>
#include <tr.h>
#include <tr_filter.h>
#include <trust_router/tr_constraint.h>
+
void tr_print_config (FILE *stream, TR_CFG *cfg) {
fprintf(stream, "tr_print_config: Not yet implemented.\n");
return;
}
void tr_cfg_free (TR_CFG *cfg) {
- /* TBD -- need to deallocate memory as part of dynamic config */
+ talloc_free(cfg);
return;
}
TR_CFG_RC tr_apply_new_config (TR_INSTANCE *tr) {
-
if (!tr)
return TR_CFG_BAD_PARAMS;
return TR_CFG_SUCCESS;
}
-static TR_CFG_RC tr_cfg_parse_internal (TR_INSTANCE *tr, json_t *jcfg) {
+static TR_CFG_RC tr_cfg_parse_internal (TR_CFG *trc, json_t *jcfg) {
json_t *jint = NULL;
json_t *jmtd = NULL;
json_t *jtp = NULL;
json_t *jhname = NULL;
- if ((!tr) || (!tr->new_cfg) || (!jcfg))
+ if ((!trc) || (!jcfg))
return TR_CFG_BAD_PARAMS;
- if (NULL == (tr->new_cfg->internal = malloc(sizeof(TR_CFG_INTERNAL))))
- return TR_CFG_NOMEM;
+ if (NULL == trc->internal) {
+ if (NULL == (trc->internal = talloc(trc, TR_CFG_INTERNAL)))
+ return TR_CFG_NOMEM;
- memset(tr->new_cfg->internal, 0, sizeof(TR_CFG_INTERNAL));
+ memset(trc->internal, 0, sizeof(TR_CFG_INTERNAL));
+ }
if (NULL != (jint = json_object_get(jcfg, "tr_internal"))) {
if (NULL != (jmtd = json_object_get(jint, "max_tree_depth"))) {
if (json_is_number(jmtd)) {
- tr->new_cfg->internal->max_tree_depth = json_integer_value(jmtd);
+ trc->internal->max_tree_depth = json_integer_value(jmtd);
} else {
fprintf(stderr,"tr_cfg_parse_internal: Parsing error, max_tree_depth is not a number.\n");
return TR_CFG_NOPARSE;
}
} else {
/* If not configured, use the default */
- tr->new_cfg->internal->max_tree_depth = TR_DEFAULT_MAX_TREE_DEPTH;
+ trc->internal->max_tree_depth = TR_DEFAULT_MAX_TREE_DEPTH;
}
if (NULL != (jtp = json_object_get(jint, "tids_port"))) {
if (json_is_number(jtp)) {
- tr->new_cfg->internal->tids_port = json_integer_value(jtp);
+ trc->internal->tids_port = json_integer_value(jtp);
} else {
fprintf(stderr,"tr_cfg_parse_internal: Parsing error, port is not a number.\n");
return TR_CFG_NOPARSE;
}
} else {
/* If not configured, use the default */
- tr->new_cfg->internal->tids_port = TR_DEFAULT_TIDS_PORT;
+ trc->internal->tids_port = TR_DEFAULT_TIDS_PORT;
}
if (NULL != (jhname = json_object_get(jint, "hostname"))) {
if (json_is_string(jhname)) {
- tr->new_cfg->internal->hostname = json_string_value(jhname);
+ trc->internal->hostname = json_string_value(jhname);
} else {
fprintf(stderr,"tr_cfg_parse_internal: Parsing error, hostname is not a string.\n");
return TR_CFG_NOPARSE;
}
}
- else {
- fprintf(stderr, "tr_cfg_parse_internal: Parsing error, hostname is not found.\n");
- return TR_CFG_NOPARSE;
- }
- fprintf(stderr, "tr_cfg_parse_internal: Internal config parsed.\n");
- return TR_CFG_SUCCESS;
- }
- else {
- fprintf(stderr, "tr_cfg_parse_internal: Parsing error, tr_internal configuration section not found.\n");
- return TR_CFG_NOPARSE;
+ fprintf(stderr, "tr_cfg_parse_internal: Internal config parsed.\n");
+ return TR_CFG_SUCCESS;
}
+ return TR_CFG_SUCCESS;
}
-static TR_CONSTRAINT *tr_cfg_parse_one_constraint (TR_INSTANCE *tr, char *ctype, json_t *jc, TR_CFG_RC *rc)
+static TR_CONSTRAINT *tr_cfg_parse_one_constraint (TR_CFG *trc, char *ctype, json_t *jc, TR_CFG_RC *rc)
{
TR_CONSTRAINT *cons;
int i;
- if ((!tr) || (!ctype) || (!jc) || (!rc) ||
+ if ((!trc) || (!ctype) || (!jc) || (!rc) ||
(!json_is_array(jc)) ||
(0 >= json_array_size(jc)) ||
(TR_MAX_CONST_MATCHES < json_array_size(jc)) ||
return NULL;
}
- if (NULL == (cons = malloc(sizeof(TR_CONSTRAINT)))) {
+ if (NULL == (cons = talloc(trc, TR_CONSTRAINT))) {
fprintf(stderr, "tr_cfg_parse_one_constraint: Out of memory (cons).\n");
*rc = TR_CFG_NOMEM;
return NULL;
return cons;
}
-static TR_FILTER *tr_cfg_parse_one_filter (TR_INSTANCE *tr, json_t *jfilt, TR_CFG_RC *rc)
+static TR_FILTER *tr_cfg_parse_one_filter (TR_CFG *trc, json_t *jfilt, TR_CFG_RC *rc)
{
TR_FILTER *filt = NULL;
json_t *jftype = NULL;
return NULL;
}
- if (NULL == (filt = malloc(sizeof(TR_FILTER)))) {
- fprintf(stderr, "tr_config_parse_one_filter: Out of memory.\n");
+ if (NULL == (filt = talloc(trc, TR_FILTER))) {
+ fprintf(stderr, "tr_cfg_parse_one_filter: Out of memory.\n");
*rc = TR_CFG_NOMEM;
return NULL;
}
return NULL;
}
- if (NULL == (filt->lines[i] = malloc(sizeof(TR_FLINE)))) {
- fprintf(stderr, "tr_config_parse_one_filter: Out of memory (fline).\n");
+ if (NULL == (filt->lines[i] = talloc(trc, TR_FLINE))) {
+ fprintf(stderr, "tr_cfg_parse_one_filter: Out of memory (fline).\n");
*rc = TR_CFG_NOMEM;
tr_filter_free(filt);
return NULL;
(0 != json_array_size(jrc)) &&
(TR_MAX_CONST_MATCHES >= json_array_size(jrc))) {
- if (NULL == (filt->lines[i]->realm_cons = tr_cfg_parse_one_constraint(tr, "realm", jrc, rc))) {
+ if (NULL == (filt->lines[i]->realm_cons = tr_cfg_parse_one_constraint(trc, "realm", jrc, rc))) {
fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing realm constraint");
tr_filter_free(filt);
return NULL;
(0 != json_array_size(jdc)) &&
(TR_MAX_CONST_MATCHES >= json_array_size(jdc))) {
- if (NULL == (filt->lines[i]->domain_cons = tr_cfg_parse_one_constraint(tr, "domain", jdc, rc))) {
+ if (NULL == (filt->lines[i]->domain_cons = tr_cfg_parse_one_constraint(trc, "domain", jdc, rc))) {
fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing domain constraint");
tr_filter_free(filt);
return NULL;
return NULL;
}
- if (NULL == (filt->lines[i]->specs[j] = malloc(sizeof(TR_FSPEC)))) {
- fprintf(stderr, "tr_config_parse_one_filter: Out of memory.\n");
+ if (NULL == (filt->lines[i]->specs[j] = talloc(trc, TR_FSPEC))) {
+ fprintf(stderr, "tr_cfg_parse_one_filter: Out of memory.\n");
*rc = TR_CFG_NOMEM;
tr_filter_free(filt);
return NULL;
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");
+ fprintf(stderr, "tr_cfg_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)
+static TR_RP_CLIENT *tr_cfg_parse_one_rp_client (TR_CFG *trc, json_t *jrp, TR_CFG_RC *rc)
{
TR_RP_CLIENT *rp = NULL;
json_t *jgns = NULL;
json_t *jftype = NULL;
int i = 0;
- if ((!jrp) || (!rc)) {
+ if ((!trc) || (!jrp) || (!rc)) {
fprintf(stderr, "tr_cfg_parse_one_rp_realm: Bad parameters.\n");
if (rc)
*rc = TR_CFG_BAD_PARAMS;
return NULL;
}
- if (NULL == (rp = malloc(sizeof(TR_RP_CLIENT)))) {
- fprintf(stderr, "tr_config_parse_one_rp_realm: Out of memory.\n");
+ if (NULL == (rp = talloc(trc, TR_RP_CLIENT))) {
+ fprintf(stderr, "tr_cfg_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->filter = tr_cfg_parse_one_filter(tr, jfilt, rc))) {
+ if (NULL == (rp->filter = tr_cfg_parse_one_filter(trc, jfilt, rc))) {
fprintf(stderr, "tr_cfg_parse_one_rp_client: Error parsing filter.\n");
free(rp);
*rc = TR_CFG_NOPARSE;
return rp;
}
-static TR_CFG_RC tr_cfg_parse_rp_clients (TR_INSTANCE *tr, json_t *jcfg) {
+static TR_CFG_RC tr_cfg_parse_rp_clients (TR_CFG *trc, json_t *jcfg) {
json_t *jrps = NULL;
TR_RP_CLIENT *rp = NULL;
TR_CFG_RC rc = TR_CFG_SUCCESS;
int i = 0;
- if ((!tr) || (!tr->new_cfg) || (!jcfg))
+ if ((!trc) || (!jcfg))
return TR_CFG_BAD_PARAMS;
- if ((NULL == (jrps = json_object_get(jcfg, "rp_clients"))) ||
- (!json_is_array(jrps))) {
- return TR_CFG_NOPARSE;
- }
+ if (NULL != (jrps = json_object_get(jcfg, "rp_clients"))) {
- for (i = 0; i < json_array_size(jrps); i++) {
- if (NULL == (rp = tr_cfg_parse_one_rp_client(tr,
- json_array_get(jrps, i),
- &rc))) {
- return rc;
+ if (!json_is_array(jrps)) {
+ return TR_CFG_NOPARSE;
+ }
+
+ for (i = 0; i < json_array_size(jrps); i++) {
+ if (NULL == (rp = tr_cfg_parse_one_rp_client(trc,
+ json_array_get(jrps, i),
+ &rc))) {
+ return rc;
+ }
+ fprintf(stderr, "tr_cfg_parse_rp_clients: RP client configured -- first gss: %s", rp->gss_names[0]->buf);
+ rp->next = trc->rp_clients;
+ trc->rp_clients = rp;
}
- 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;
}
return rc;
}
-static TR_AAA_SERVER *tr_cfg_parse_one_aaa_server (TR_INSTANCE *tr, json_t *jaddr, TR_CFG_RC *rc) {
+static TR_AAA_SERVER *tr_cfg_parse_one_aaa_server (TR_CFG *trc, json_t *jaddr, TR_CFG_RC *rc) {
TR_AAA_SERVER *aaa = NULL;
- if ((!tr) || (!tr->new_cfg) || (!jaddr) || (!json_is_string(jaddr))) {
+ if ((!trc) || (!jaddr) || (!json_is_string(jaddr))) {
fprintf(stderr, "tr_cfg_parse_one_aaa_server: Bad parameters.\n");
*rc = TR_CFG_BAD_PARAMS;
return NULL;
}
- if (NULL == (aaa = malloc(sizeof(TR_AAA_SERVER)))) {
- fprintf(stderr, "tr_config_parse_one_aaa_server: Out of memory.\n");
+ if (NULL == (aaa = talloc(trc, TR_AAA_SERVER))) {
+ fprintf(stderr, "tr_cfg_parse_one_aaa_server: Out of memory.\n");
*rc = TR_CFG_NOMEM;
return NULL;
}
return aaa;
}
-
-static TR_AAA_SERVER *tr_cfg_parse_aaa_servers (TR_INSTANCE *tr, json_t *jaaas, TR_CFG_RC *rc)
+static TR_AAA_SERVER *tr_cfg_parse_aaa_servers (TR_CFG *trc, json_t *jaaas, TR_CFG_RC *rc)
{
TR_AAA_SERVER *aaa = NULL;
TR_AAA_SERVER *temp_aaa = NULL;
int i = 0;
for (i = 0; i < json_array_size(jaaas); i++) {
- if (NULL == (temp_aaa = tr_cfg_parse_one_aaa_server(tr, json_array_get(jaaas, i), rc))) {
+ if (NULL == (temp_aaa = tr_cfg_parse_one_aaa_server(trc, json_array_get(jaaas, i), rc))) {
return NULL;
}
/* TBD -- IPv6 addresses */
return aaa;
}
-static TR_APC *tr_cfg_parse_apcs (TR_INSTANCE *tr, json_t *japcs, TR_CFG_RC *rc)
+static TR_APC *tr_cfg_parse_apcs (TR_CFG *trc, json_t *japcs, TR_CFG_RC *rc)
{
TR_APC *apc;
*rc = TR_CFG_SUCCESS; /* presume success */
- if ((!japcs) || (!rc)) {
+ if ((!trc) || (!japcs) || (!rc)) {
fprintf(stderr, "tr_cfg_parse_apcs: Bad parameters.\n");
if (rc)
*rc = TR_CFG_BAD_PARAMS;
return NULL;
}
- if (NULL == (apc = malloc(sizeof(TR_APC)))) {
+ if (NULL == (apc = talloc(trc, TR_APC))) {
fprintf (stderr, "tr_cfg_parse_apcs: Out of memory.\n");
*rc = TR_CFG_NOMEM;
return NULL;
return apc;
}
-static TR_IDP_REALM *tr_cfg_parse_one_idp_realm (TR_INSTANCE *tr, json_t *jidp, TR_CFG_RC *rc) {
+static TR_IDP_REALM *tr_cfg_parse_one_idp_realm (TR_CFG *trc, json_t *jidp, TR_CFG_RC *rc) {
TR_IDP_REALM *idp = NULL;
json_t *jrid = NULL;
json_t *jscfg = NULL;
json_t *jsrvrs = NULL;
json_t *japcs = NULL;
- if ((!jidp) || (!rc)) {
+ if ((!trc) || (!jidp) || (!rc)) {
fprintf(stderr, "tr_cfg_parse_one_idp_realm: Bad parameters.\n");
if (rc)
*rc = TR_CFG_BAD_PARAMS;
return NULL;
}
- if (NULL == (idp = malloc(sizeof(TR_IDP_REALM)))) {
- fprintf(stderr, "tr_config_parse_one_idp_realm: Out of memory.\n");
+ if (NULL == (idp = talloc(trc, TR_IDP_REALM))) {
+ fprintf(stderr, "tr_cfg_parse_one_idp_realm: Out of memory.\n");
*rc = TR_CFG_NOMEM;
return NULL;
}
return NULL;
}
- if (NULL == (idp->aaa_servers = tr_cfg_parse_aaa_servers(tr, jsrvrs, rc))) {
+ if (NULL == (idp->aaa_servers = tr_cfg_parse_aaa_servers(trc, jsrvrs, rc))) {
fprintf(stderr, "tr_cfg_parse_one_idp_realm: Can't parse AAA servers for realm %s.\n", idp->realm_id->buf);
tr_free_name(idp->realm_id);
free(idp);
if ((NULL != (japcs = json_object_get(jidp, "apcs"))) &&
(json_is_array(japcs))) {
- if (NULL == (idp->apcs = tr_cfg_parse_apcs(tr, japcs, rc))) {
+ if (NULL == (idp->apcs = tr_cfg_parse_apcs(trc, japcs, rc))) {
fprintf(stderr, "tr_cfg_parse_one_idp_realm: Can't parse APCs for realm %s .\n", idp->realm_id->buf);
tr_free_name(idp->realm_id);
/* TBD -- free aaa_servers */;
return idp;
}
-static TR_CFG_RC tr_cfg_parse_idp_realms (TR_INSTANCE *tr, json_t *jcfg)
+static TR_CFG_RC tr_cfg_parse_default_servers (TR_CFG *trc, json_t *jcfg)
{
- json_t *jidps = NULL;
+ json_t *jdss = NULL;
TR_CFG_RC rc = TR_CFG_SUCCESS;
- TR_IDP_REALM *idp = NULL;
+ TR_AAA_SERVER *ds = NULL;
int i = 0;
- if ((!tr) || (!tr->new_cfg) || (!jcfg))
+ if ((!trc) || (!jcfg))
return TR_CFG_BAD_PARAMS;
- if ((NULL == (jidps = json_object_get(jcfg, "idp_realms"))) ||
- (!json_is_array(jidps))) {
- return TR_CFG_NOPARSE;
- }
+ /* If there are default servers, store them */
+ if ((NULL != (jdss = json_object_get(jcfg, "default_servers"))) &&
+ (json_is_array(jdss)) &&
+ (0 < json_array_size(jdss))) {
- for (i = 0; i < json_array_size(jidps); i++) {
- if (NULL == (idp = tr_cfg_parse_one_idp_realm(tr,
- json_array_get(jidps, i),
+ for (i = 0; i < json_array_size(jdss); i++) {
+ if (NULL == (ds = tr_cfg_parse_one_aaa_server(trc,
+ json_array_get(jdss, i),
&rc))) {
- return rc;
+ return rc;
+ }
+ fprintf(stderr, "tr_cfg_parse_default_servers: Default server configured.\n");
+ ds->next = trc->default_servers;
+ trc->default_servers = ds;
+ }
+ }
+
+ return rc;
+}
+
+static TR_CFG_RC tr_cfg_parse_idp_realms (TR_CFG *trc, json_t *jcfg)
+{
+ json_t *jidps = NULL;
+ TR_CFG_RC rc = TR_CFG_SUCCESS;
+ TR_IDP_REALM *idp = NULL;
+ int i = 0;
+
+ if ((!trc) || (!jcfg))
+ return TR_CFG_BAD_PARAMS;
+
+ /* If there are any IDP Realms, parse them */
+ if ((NULL != (jidps = json_object_get(jcfg, "idp_realms"))) &&
+ (json_is_array(jidps))) {
+ for (i = 0; i < json_array_size(jidps); i++) {
+ if (NULL == (idp = tr_cfg_parse_one_idp_realm(trc,
+ json_array_get(jidps, i),
+ &rc))) {
+ return rc;
+ }
+ fprintf(stderr, "tr_cfg_parse_idp_realms: IDP realm configured: %s.\n", idp->realm_id->buf);
+ idp->next = trc->idp_realms;
+ trc->idp_realms = idp;
}
- fprintf(stderr, "tr_cfg_parse_idp_realms: IDP realm configured: %s.\n", idp->realm_id->buf);
- idp->next = tr->new_cfg->idp_realms;
- tr->new_cfg->idp_realms = idp;
}
+
return rc;
}
-static TR_IDP_REALM *tr_cfg_parse_comm_idps (TR_INSTANCE *tr, json_t *jidps, TR_CFG_RC *rc)
+static TR_IDP_REALM *tr_cfg_parse_comm_idps (TR_CFG *trc, json_t *jidps, TR_CFG_RC *rc)
{
TR_IDP_REALM *idp = NULL;
TR_IDP_REALM *temp_idp = NULL;
int i = 0;
- if ((!tr) ||
+ if ((!trc) ||
(!jidps) ||
(!json_is_array(jidps))) {
if (rc)
}
for (i = 0; i < json_array_size(jidps); i++) {
- if (NULL == (temp_idp = (tr_cfg_find_idp(tr->new_cfg,
+ if (NULL == (temp_idp = (tr_cfg_find_idp(trc,
tr_new_name((char *)json_string_value(json_array_get(jidps, i))),
rc)))) {
fprintf(stderr, "tr_cfg_parse_comm_idps: Unknown IDP %s.\n",
return idp;
}
-static TR_RP_REALM *tr_cfg_parse_comm_rps (TR_INSTANCE *tr, json_t *jrps, TR_CFG_RC *rc)
+static TR_RP_REALM *tr_cfg_parse_comm_rps (TR_CFG *trc, json_t *jrps, TR_CFG_RC *rc)
{
TR_RP_REALM *rp = NULL;
TR_RP_REALM *temp_rp = NULL;
int i = 0;
- if ((!tr) ||
+ if ((!trc) ||
(!jrps) ||
(!json_is_array(jrps))) {
if (rc)
}
for (i = (json_array_size(jrps)-1); i >= 0; i--) {
- if (NULL == (temp_rp = malloc(sizeof(TR_RP_REALM)))) {
+ if (NULL == (temp_rp = talloc(trc, TR_RP_REALM))) {
fprintf(stderr, "tr_cfg_parse_comm_rps: Can't allocate memory for RP Realm.\n");
if (rc)
*rc = TR_CFG_NOMEM;
return rp;
}
-static TR_COMM *tr_cfg_parse_one_comm (TR_INSTANCE *tr, json_t *jcomm, TR_CFG_RC *rc) {
+static TR_COMM *tr_cfg_parse_one_comm (TR_CFG *trc, json_t *jcomm, TR_CFG_RC *rc) {
TR_COMM *comm = NULL;
json_t *jid = NULL;
json_t *jtype = NULL;
json_t *jidps = NULL;
json_t *jrps = NULL;
- if ((!jcomm) || (!rc)) {
+ if ((!trc) || (!jcomm) || (!rc)) {
fprintf(stderr, "tr_cfg_parse_one_comm: Bad parameters.\n");
if (rc)
*rc = TR_CFG_BAD_PARAMS;
return NULL;
}
- if (NULL == (comm = malloc(sizeof(TR_COMM)))) {
- fprintf(stderr, "tr_config_parse_one_comm: Out of memory.\n");
+ if (NULL == (comm = talloc(trc, TR_COMM))) {
+ fprintf(stderr, "tr_cfg_parse_one_comm: Out of memory.\n");
*rc = TR_CFG_NOMEM;
return NULL;
}
comm->type = TR_COMM_APC;
} else if (0 == strcmp(json_string_value(jtype), "coi")) {
comm->type = TR_COMM_COI;
- if (NULL == (comm->apcs = tr_cfg_parse_apcs(tr, japcs, rc))) {
+ if (NULL == (comm->apcs = tr_cfg_parse_apcs(trc, japcs, rc))) {
fprintf(stderr, "tr_cfg_parse_one_comm: Can't parse APCs for COI %s.\n", comm->id->buf);
tr_free_name(comm->id);
free(comm);
return NULL;
}
- comm->idp_realms = tr_cfg_parse_comm_idps(tr, jidps, rc);
+ comm->idp_realms = tr_cfg_parse_comm_idps(trc, jidps, rc);
if (TR_CFG_SUCCESS != *rc) {
fprintf(stderr, "tr_cfg_parse_one_comm: Can't parse IDP realms for comm %s.\n", comm->id->buf);
tr_free_name(comm->id);
return NULL;
}
- comm->rp_realms = tr_cfg_parse_comm_rps(tr, jrps, rc);
+ comm->rp_realms = tr_cfg_parse_comm_rps(trc, jrps, rc);
if (TR_CFG_SUCCESS != *rc) {
fprintf(stderr, "tr_cfg_parse_comm: Can't parse RP realms for comm %s .\n", comm->id->buf);
tr_free_name(comm->id);
return comm;
}
-static TR_CFG_RC tr_cfg_parse_comms (TR_INSTANCE *tr, json_t *jcfg)
+static TR_CFG_RC tr_cfg_parse_comms (TR_CFG *trc, json_t *jcfg)
{
json_t *jcomms = NULL;
TR_CFG_RC rc = TR_CFG_SUCCESS;
TR_COMM *comm = NULL;
int i = 0;
- if ((!tr) || (!tr->new_cfg) || (!jcfg)) {
- fprintf(stderr, "tr_config_parse_comms: Bad Parameters.\n");
+ if ((!trc) || (!jcfg)) {
+ fprintf(stderr, "tr_cfg_parse_comms: Bad Parameters.\n");
return TR_CFG_BAD_PARAMS;
}
- if (NULL == (comm = malloc(sizeof(TR_COMM)))) {
- fprintf(stderr, "tr_cfg_parse_comms: Out of Memory\n");
- return TR_CFG_NOMEM;
+ if (NULL != (jcomms = json_object_get(jcfg, "communities"))) {
+ if (!json_is_array(jcomms)) {
+ return TR_CFG_NOPARSE;
+ }
+
+ for (i = 0; i < json_array_size(jcomms); i++) {
+ if (NULL == (comm = tr_cfg_parse_one_comm(trc,
+ json_array_get(jcomms, i),
+ &rc))) {
+ return rc;
+ }
+ fprintf(stderr, "tr_cfg_parse_comms: Community configured: %s.\n", comm->id->buf);
+ comm->next = trc->comms;
+ trc->comms = comm;
+ }
}
- memset (comm, 0, sizeof(TR_COMM));
+ return rc;
+}
+
+TR_CFG_RC tr_cfg_validate (TR_CFG *trc) {
+ TR_CFG_RC rc = TR_CFG_SUCCESS;
- if ((NULL == (jcomms = json_object_get(jcfg, "communities"))) ||
- (!json_is_array(jcomms))) {
- return TR_CFG_NOPARSE;
+ if (!trc)
+ return TR_CFG_BAD_PARAMS;
+
+ if ((NULL == trc->internal)||
+ (NULL == trc->internal->hostname)) {
+ fprintf(stderr, "tr_cfg_validate: Error: No internal configuration, or no hostname.\n");
+ rc = TR_CFG_ERROR;
}
- for (i = 0; i < json_array_size(jcomms); i++) {
- if (NULL == (comm = tr_cfg_parse_one_comm(tr,
- json_array_get(jcomms, i),
- &rc))) {
- return rc;
- }
- fprintf(stderr, "tr_cfg_parse_comms: Community configured: %s.\n", comm->id->buf);
- comm->next = tr->new_cfg->comms;
- tr->new_cfg->comms = comm;
+ if (NULL == trc->rp_clients) {
+ fprintf(stderr, "tr_cfg_validate: Error: No RP Clients configured\n");
+ rc = TR_CFG_ERROR;
}
+
+ if (NULL == trc->comms) {
+ fprintf(stderr, "tr_cfg_validate: Error: No Communities configured\n");
+ rc = TR_CFG_ERROR;
+ }
+
+ if ((NULL == trc->default_servers) && (NULL == trc->idp_realms)) {
+ fprintf(stderr, "tr_cfg_validate: Error: No default servers or IDPs configured.\n");
+ rc = TR_CFG_ERROR;
+ }
+
return rc;
}
-TR_CFG_RC tr_parse_config (TR_INSTANCE *tr, json_t *jcfg) {
+TR_CFG_RC tr_parse_config (TR_INSTANCE *tr, struct dirent **cfg_files) {
+ json_t *jcfg;
+ json_error_t rc;
+ int n;
+
+ if ((!tr) || (!cfg_files))
+ return TR_CFG_BAD_PARAMS;
/* If there is a partial/abandoned config lying around, free it */
- if (tr->new_cfg) {
+ if (tr->new_cfg)
tr_cfg_free(tr->new_cfg);
- }
- if (NULL == (tr->new_cfg = malloc(sizeof(TR_CFG))))
+ if (NULL == (tr->new_cfg = talloc(NULL, TR_CFG)))
return TR_CFG_NOMEM;
memset(tr->new_cfg, 0, sizeof(TR_CFG));
- if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(tr, jcfg)) ||
- (TR_CFG_SUCCESS != tr_cfg_parse_rp_clients(tr, jcfg)) ||
- (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(tr, jcfg)) ||
- (TR_CFG_SUCCESS != tr_cfg_parse_comms(tr, jcfg))) {
- tr_cfg_free(tr->new_cfg);
+ /* Parse configuration information from each config file */
+ while (n--) {
+ fprintf(stderr, "tr_read_config: Parsing %s.\n", cfg_files[n]->d_name);
+ if (NULL == (jcfg = json_load_file(cfg_files[n]->d_name,
+ JSON_DISABLE_EOF_CHECK, &rc))) {
+ fprintf (stderr, "tr_read_config: Error parsing config file %s.\n",
+ cfg_files[n]->d_name);
+ return TR_CFG_NOPARSE;
+ }
+
+ if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(tr->new_cfg, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_rp_clients(tr->new_cfg, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(tr->new_cfg, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_default_servers(tr->new_cfg, jcfg)) ||
+ (TR_CFG_SUCCESS != tr_cfg_parse_comms(tr->new_cfg, jcfg))) {
+ tr_cfg_free(tr->new_cfg);
+ return TR_CFG_ERROR;
+ }
+ }
+
+ /* make sure we got a complete, consistent configuration */
+ if (TR_CFG_SUCCESS != tr_cfg_validate(tr->new_cfg)) {
+ fprintf(stderr, "tr_parse_config: Error: INVALID CONFIGURATION, EXITING\n");
return TR_CFG_ERROR;
}
+
return TR_CFG_SUCCESS;
}
return NULL;
}
+#if 0
json_t *tr_read_config (int n, struct dirent **cfg_files) {
json_t *jcfg = NULL;
json_t *temp = NULL;
return NULL;
}
- /* TBD -- instead of using json_object_update, iterate through files for non-overlap config? */
if (!jcfg) {
jcfg = temp;
}else {
return jcfg;
}
+#endif
static int is_cfg_file(const struct dirent *dent) {
int n;
/*
- * Copyright (c) 2012, JANET(UK)
+ * Copyright (c) 2012-2014, JANET(UK)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
*
*/
#include <jansson.h>
+#include "jansson_iterators.h"
+#include <assert.h>
+#include <talloc.h>
#include <tr_filter.h>
+#include <tr_debug.h>
+
#include <trust_router/tr_constraint.h>
+#include <tid_internal.h>
+
+/* Returns TRUE (1) if the the string (str) matchs the wildcard string (wc_str), FALSE (0) if not.
+ */
+int tr_prefix_wildcard_match (const char *str, const char *wc_str) {
+ const char *wc_post = wc_str;
+ size_t len = 0;
+ size_t wc_len = 0;
+
+ if ((!str) || (!wc_str))
+ return 0;
+
+ len = strlen(str);
+ if (0 == (wc_len = strlen(wc_str)))
+ return 0;
+
+ /* TBD -- skip leading white space? */
+ if ('*' == wc_str[0]) {
+ wc_post = &(wc_str[1]);
+ wc_len--;
+ }else if (len != wc_len)
+ return 0;
+
+
+ if (wc_len > len)
+ return 0;
+
+ if (0 == strcmp(&(str[len-wc_len]), wc_post)) {
+ return 1;
+ }
+ else
+ return 0;
+ }
TR_CONSTRAINT_SET *tr_constraint_set_from_fline (TR_FLINE *fline)
{
if (fline->domain_cons)
tr_constraint_add_to_set((TR_CONSTRAINT_SET **)&cset, fline->domain_cons);
- return cset;
+ return (TR_CONSTRAINT_SET *) cset;
}
/* A constraint set is represented in json as an array of constraint
/* If we don't already have a json object, create one */
if (!(*cset))
- *cset = json_array();
+ *cset = (TR_CONSTRAINT_SET *) json_array();
/* Create a json object representing cons */
jmatches = json_array();
json_object_set_new(jcons, cons->type->buf, jmatches);
/* Add the created object to the cset object */
- json_array_append_new(*cset, jcons);
+ json_array_append_new((json_t *) *cset, jcons);
}
+ int tr_constraint_set_validate(TR_CONSTRAINT_SET *cset)
+{
+ json_t *json = (json_t *) cset;
+ size_t i;
+ json_t *set_member;
+ if (!json_is_array(json)){
+ tr_debug("Constraint_set is not an array");
+ return 0;
+ }
+ json_array_foreach(json, i, set_member) {
+ json_t *value;
+ const char *key;
+ if (!json_is_object(set_member)) {
+ tr_debug("Constraint member at %zu is not an object\n", i);
+ return 0;
+ }
+ json_object_foreach( set_member, key, value) {
+ size_t inner_index;
+ json_t *inner_value;
+ if (!json_is_array(value)) {
+ tr_debug("Constraint type %s at index %zu in constraint set is not an array\n", key,
+ i);
+ return 0;
+ }
+ json_array_foreach(value, inner_index, inner_value) {
+ if (!json_is_string(inner_value)) {
+ tr_debug("Constraint type %s at index %zu in constraint set has non-string element %zu\n",
+ key, i, inner_index);
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+
+TR_CONSTRAINT_SET *tr_constraint_set_filter( TID_REQ *request,
+ TR_CONSTRAINT_SET *orig,
+ const char *constraint_type)
+{
+ json_t *orig_cset = (json_t*) orig;
+ json_t *new_cs = NULL;
+ size_t index;
+ json_t *set_member;
+ if (!tr_constraint_set_validate( (TR_CONSTRAINT_SET *) orig_cset)) {
+ tr_debug ("tr_constraint_set_filter: not a valid constraint set\n");
+ return NULL;
+ }
+ assert (new_cs = json_array());
+ json_array_foreach(orig_cset, index, set_member) {
+ if (json_object_get( set_member, constraint_type))
+ json_array_append(new_cs, set_member);
+ }
+ return (TR_CONSTRAINT_SET *) new_cs;
+}
+
+/**
+ * Within a given constraint object merge any overlapping domain or
+ * realm constraints. For example ['*','*.net'] can be simplified to
+ * ['*']
+ */
+static void merge_constraints(json_t *constraint, const char *key)
+{
+ json_t *value_1, *value_2, *constraint_array;
+ size_t index_1, index_2;
+ /*
+ * Go through the loop pairwise linear, removing elements where one
+ * element is a subset of the other. Always shrik the array from
+ * the end so that index_1 never becomes invalid (swapping if
+ * needed).
+ */
+ constraint_array = json_object_get(constraint, key);
+ if (NULL == constraint_array)
+ return;
+ json_array_foreach( constraint_array, index_1, value_1)
+ json_array_foreach( constraint_array, index_2, value_2) {
+ if (index_2 <= index_1)
+ continue;
+ if ( tr_prefix_wildcard_match( json_string_value(value_2),
+ json_string_value(value_1))) {
+ json_array_remove(constraint_array, index_2);
+ index_2--;
+ }else if (tr_prefix_wildcard_match( json_string_value(value_1),
+ json_string_value(value_2))) {
+ json_array_set(constraint_array, index_1, value_2);
+ json_array_remove(constraint_array, index_2);
+ index_2--;
+ }
+ }
+}
+
+/**
+ * Returns an array of constraint strings that is the intersection of
+ * all constraints in the constraint_set of type #type
+ */
+static json_t *constraint_intersect_internal( TR_CONSTRAINT_SET *constraints,
+ const char *constraint_type)
+{
+ json_t *constraint, *result = NULL;
+ size_t i;
+ json_array_foreach( (json_t *) constraints, i, constraint) {
+ merge_constraints( constraint, constraint_type);
+ if (NULL == result) {
+ result = json_object_get(constraint, constraint_type);
+ if (NULL != result)
+ result = json_copy(result);
+ } else {
+ json_t *intersect, *value_1, *value_2;
+ size_t index_1, index_2;
+ intersect = json_object_get(constraint, constraint_type);
+ /*If an element of the constraint set doesn't have a particular
+ * constraint type, we ignore that element of the constraint set.
+ * However, if no element of the constraint set has a particular
+ * constraint type we return empty (no access) rather than universal
+ * access.*/
+ if (!intersect)
+ continue;
+ result_loop:
+ json_array_foreach(result, index_1, value_1) {
+ json_array_foreach(intersect, index_2, value_2) {
+ if (tr_prefix_wildcard_match( json_string_value(value_1),
+ json_string_value(value_2)))
+ goto result_acceptable;
+ else if (tr_prefix_wildcard_match(json_string_value( value_2),
+ json_string_value(value_1))) {
+ json_array_set(result, index_1, value_2);
+ goto result_acceptable;
+ }
+ }
+ json_array_remove(result, index_1);
+ if (index_1 == 0)
+ goto result_loop;
+ index_1--;
+ result_acceptable: continue;
+ }
+ }
+ }
+ return result;
+}
+
+/**
+ * Return the intersection of domain and realm constraints.
+ * Return is live until #request is freed.
+ */
+TR_CONSTRAINT_SET *tr_constraint_set_intersect( TID_REQ *request,
+ TR_CONSTRAINT_SET *input)
+{
+ json_t *domain=NULL, *realm=NULL;
+ json_t *result = NULL, *result_array = NULL;
+ if (tr_constraint_set_validate(input)) {
+ domain = constraint_intersect_internal(input, "domain");
+ realm = constraint_intersect_internal(input, "realm");
+ }
+ assert(result = json_object());
+ if (domain)
+ json_object_set_new(result, "domain", domain);
+ if (realm)
+ json_object_set_new(result, "realm", realm);
+ assert(result_array = json_array());
+ json_array_append_new(result_array, result);
+ tid_req_cleanup_json( request, result_array);
+ return (TR_CONSTRAINT_SET *) result_array;
+}
+
+
+int tr_constraint_set_get_match_strings(
+ TID_REQ *request,
+ TR_CONSTRAINT_SET *constraints,
+ const char *constraint_type,
+ tr_const_string **output,
+ size_t *output_len)
+{
+ json_t *cset = (json_t *) constraints;
+ json_t *member, *matches, *value;;
+ size_t index, array_size;
+ assert (output && output_len);
+ *output = NULL;
+ *output_len = 0;
+ if (json_array_size(cset) != 1) {
+ tr_debug("Constraint set for get_match_strings has more than one member\n");
+ return -1;
+ }
+ member = json_array_get(cset, 0);
+ matches = json_object_get(member, constraint_type);
+ if (!matches)
+ return -1;
+ array_size = json_array_size(matches);
+ if (array_size == 0)
+ return -1;
+ *output = talloc_array_ptrtype(request, *output, array_size);
+ json_array_foreach( matches, index, value)
+ (*output)[index] = json_string_value(value);
+ *output_len = array_size;
+ return 0;
+}
/*
- * Copyright (c) 2012, JANET(UK)
+ * Copyright (c) 2012, 2014, JANET(UK)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <openssl/dh.h>
#include <trust_router/tr_dh.h>
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include <talloc.h>
+#include <assert.h>
+#include <tid_internal.h>
+
unsigned char tr_2048_dhprime[2048/8] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+int tr_dh_pub_hash(TID_REQ *request,
+ unsigned char **out_digest,
+ size_t *out_len)
+{
+ const BIGNUM *pub = request->tidc_dh->pub_key;
+ unsigned char *bn_bytes = talloc_zero_size(request, BN_num_bytes(pub));
+ unsigned char *digest = talloc_zero_size(request, SHA_DIGEST_LENGTH+1);
+ assert(bn_bytes && digest);
+ BN_bn2bin(pub, bn_bytes);
+ SHA1(bn_bytes, BN_num_bytes(pub), digest);
+ *out_digest = digest;
+ *out_len = SHA_DIGEST_LENGTH;
+ return 0;
+}
+
+void tr_dh_free(unsigned char *dh_buf)
+{
+ free(dh_buf);
+}
#include <string.h>
#include <tr_filter.h>
-/* 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) {
- char *wc_post = wc_str;
- size_t len = 0;
- size_t wc_len = 0;
-
- if ((!str) || (!wc_str))
- return 0;
-
- len = strlen(str);
- if (0 == (wc_len = strlen(wc_str)))
- return 0;
-
- /* TBD -- skip leading white space? */
- if ('*' == wc_str[0]) {
- wc_post = &(wc_str[1]);
- wc_len--;
- }
-
- if (wc_len > len)
- return 0;
-
- if (0 == strcmp(&(str[len-wc_len]), wc_post)) {
- return 1;
- }
- else
- return 0;
- }
int tr_filter_process_rp_permitted (TR_NAME *rp_realm, TR_FILTER *rpp_filter, TR_CONSTRAINT_SET *in_constraints, TR_CONSTRAINT_SET **out_constraints, int *out_action)
{
else
return NULL;
}
+
+TR_AAA_SERVER *tr_default_server_lookup(TR_INSTANCE *tr, TR_NAME *comm)
+{
+ if ((!tr) || (!(tr->active_cfg)))
+ return NULL;
+
+ return(tr->active_cfg->default_servers);
+}
/*
- * Copyright (c) 2012, JANET(UK)
+ * Copyright (c) 2012-2014 , JANET(UK)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <string.h>
#include <openssl/dh.h>
#include <jansson.h>
+#include <assert.h>
+#include <talloc.h>
+
#include <tr_msg.h>
#include <trust_router/tr_name.h>
-#include <trust_router/tid.h>
+#include <tid_internal.h>
+#include <trust_router/tr_constraint.h>
+#include <tr_debug.h>
enum msg_type tr_msg_get_msg_type(TR_MSG *msg)
{
TID_REQ *tr_msg_get_req(TR_MSG *msg)
{
- return msg->tid_req;
+ if (msg->msg_type == TID_REQUEST)
+ return (TID_REQ *)msg->msg_rep;
+ return NULL;
}
void tr_msg_set_req(TR_MSG *msg, TID_REQ *req)
{
- msg->tid_req = req;
+ msg->msg_rep = req;
+ msg->msg_type = TID_REQUEST;
}
TID_RESP *tr_msg_get_resp(TR_MSG *msg)
{
- return msg->tid_resp;
+ if (msg->msg_type == TID_RESPONSE)
+ return (TID_RESP *)msg->msg_rep;
+ return NULL;
}
void tr_msg_set_resp(TR_MSG *msg, TID_RESP *resp)
{
- msg->tid_resp = resp;
+ msg->msg_rep = resp;
+ msg->msg_type = TID_RESPONSE;
}
static json_t *tr_msg_encode_dh(DH *dh)
if ((!req) || (!req->rp_realm) || (!req->realm) || !(req->comm))
return NULL;
- jreq = json_object();
+ assert(jreq = json_object());
jstr = json_string(req->rp_realm->buf);
json_object_set_new(jreq, "rp_realm", jstr);
}
json_object_set_new(jreq, "dh_info", tr_msg_encode_dh(req->tidc_dh));
-
+
+ if (req->cons)
+ json_object_set(jreq, "constraints", (json_t *) req->cons);
+
return jreq;
}
json_t *jorig_coi = NULL;
json_t *jdh = NULL;
- if (!(treq = malloc(sizeof(TID_REQ)))) {
+ if (!(treq =tid_req_new())) {
fprintf (stderr, "tr_msg_decode_tidreq(): Error allocating TID_REQ structure.\n");
return NULL;
}
- memset(treq, 0, sizeof(TID_REQ));
-
/* store required fields from request */
if ((NULL == (jrp_realm = json_object_get(jreq, "rp_realm"))) ||
(NULL == (jrealm = json_object_get(jreq, "target_realm"))) ||
(NULL == (jcomm = json_object_get(jreq, "community")))) {
fprintf (stderr, "tr_msg_decode(): Error parsing required fields.\n");
- free(treq);
+ tid_req_free(treq);
return NULL;
}
/* Get DH Info from the request */
if (NULL == (jdh = json_object_get(jreq, "dh_info"))) {
fprintf (stderr, "tr_msg_decode(): Error parsing dh_info.\n");
- free(treq);
+ tid_req_free(treq);
return NULL;
}
treq->tidc_dh = tr_msg_decode_dh(jdh);
treq->orig_coi = tr_new_name((char *)json_string_value(jorig_coi));
}
+ treq->cons = (TR_CONSTRAINT_SET *) json_object_get(jreq, "constraints");
+ if (treq->cons) {
+ if (!tr_constraint_set_validate(treq->cons)) {
+ tr_debug("Constraint set validation failed\n");
+ tid_req_free(treq);
+ return NULL;
+ }
+ json_incref((json_t *) treq->cons);
+ tid_req_cleanup_json(treq, (json_t *) treq->cons);
+ }
return treq;
}
return jsrvr;
}
-static TID_SRVR_BLK *tr_msg_decode_one_server(json_t *jsrvr)
+static int tr_msg_decode_one_server(json_t *jsrvr, TID_SRVR_BLK *srvr)
{
- TID_SRVR_BLK *srvr;
json_t *jsrvr_addr = NULL;
json_t *jsrvr_kn = NULL;
json_t *jsrvr_dh = NULL;
if (jsrvr == NULL)
- return NULL;
+ return -1;
- if (NULL == (srvr = malloc(sizeof(TID_SRVR_BLK))))
- return NULL;
- memset(srvr, 0, sizeof(TID_SRVR_BLK));
if ((NULL == (jsrvr_addr = json_object_get(jsrvr, "server_addr"))) ||
(NULL == (jsrvr_kn = json_object_get(jsrvr, "key_name"))) ||
(NULL == (jsrvr_dh = json_object_get(jsrvr, "server_dh")))) {
- fprintf (stderr, "tr_msg_decode_one_server(): Error parsing required fields.\n");
- free(srvr);
- return NULL;
+ tr_debug("tr_msg_decode_one_server(): Error parsing required fields.\n");
+ return -1;
}
/* TBD -- handle IPv6 Addresses */
inet_aton(json_string_value(jsrvr_addr), &(srvr->aaa_server_addr));
srvr->key_name = tr_new_name((char *)json_string_value(jsrvr_kn));
srvr->aaa_server_dh = tr_msg_decode_dh(jsrvr_dh);
-
- return srvr;
+ return 0;
}
-static json_t *tr_msg_encode_servers(TID_SRVR_BLK *servers)
+static json_t *tr_msg_encode_servers(TID_RESP *resp)
{
json_t *jservers = NULL;
json_t *jsrvr = NULL;
TID_SRVR_BLK *srvr = NULL;
+ size_t index;
jservers = json_array();
- for (srvr = servers; srvr != NULL; srvr = srvr->next) {
+ tid_resp_servers_foreach(resp, srvr, index) {
if ((NULL == (jsrvr = tr_msg_encode_one_server(srvr))) ||
(-1 == json_array_append_new(jservers, jsrvr))) {
return NULL;
return jservers;
}
-static TID_SRVR_BLK *tr_msg_decode_servers(json_t *jservers)
+static TID_SRVR_BLK *tr_msg_decode_servers(void * ctx, json_t *jservers, size_t *out_len)
{
TID_SRVR_BLK *servers = NULL;
- TID_SRVR_BLK *next = NULL;
- TID_SRVR_BLK *srvr = NULL;
json_t *jsrvr;
size_t i, num_servers;
fprintf(stderr, "tr_msg_decode_servers(): Server array is empty.\n");
return NULL;
}
+ servers = talloc_zero_array(ctx, TID_SRVR_BLK, num_servers);
for (i = 0; i < num_servers; i++) {
jsrvr = json_array_get(jservers, i);
- srvr = tr_msg_decode_one_server(jsrvr);
-
- /* skip to the end of the list, and add srvr to list of servers */
- if (NULL == servers) {
- servers = srvr;
- }
- else {
- for (next = servers; next->next != NULL; next = next->next);
- next->next = srvr;
+ if (0 != tr_msg_decode_one_server(jsrvr, &servers[i])) {
+ talloc_free(servers);
+ return NULL;
}
- }
+
+ }
+ *out_len = num_servers;
return servers;
}
fprintf(stderr, "tr_msg_encode_tidresp(): No servers to encode.\n");
return jresp;
}
- jservers = tr_msg_encode_servers(resp->servers);
+ jservers = tr_msg_encode_servers(resp);
json_object_set_new(jresp, "servers", jservers);
return jresp;
json_t *jservers = NULL;
json_t *jerr_msg = NULL;
- if (!(tresp = malloc(sizeof(TID_RESP)))) {
+ if (!(tresp = talloc_zero(NULL, TID_RESP))) {
fprintf (stderr, "tr_msg_decode_tidresp(): Error allocating TID_RESP structure.\n");
return NULL;
}
- memset(tresp, 0, sizeof(TID_RESP));
/* store required fields from response */
if ((NULL == (jresult = json_object_get(jresp, "result"))) ||
(NULL == (jcomm = json_object_get(jresp, "comm"))) ||
(!json_is_string(jcomm))) {
fprintf (stderr, "tr_msg_decode_tidresp(): Error parsing response.\n");
- free(tresp);
+ talloc_free(tresp);
return NULL;
}
fprintf(stderr, "tr_msg_decode_tidresp(): Success! result = %s.\n", json_string_value(jresult));
if ((NULL != (jservers = json_object_get(jresp, "servers"))) ||
(!json_is_array(jservers))) {
- tresp->servers = tr_msg_decode_servers(jservers);
+ tresp->servers = tr_msg_decode_servers(tresp, jservers, &tresp->num_servers);
}
else {
+ talloc_free(tresp);
return NULL;
}
tresp->result = TID_SUCCESS;
case TID_REQUEST:
jmsg_type = json_string("tid_request");
json_object_set_new(jmsg, "msg_type", jmsg_type);
- json_object_set_new(jmsg, "msg_body", tr_msg_encode_tidreq(msg->tid_req));
+ json_object_set_new(jmsg, "msg_body", tr_msg_encode_tidreq(tr_msg_get_req(msg)));
break;
case TID_RESPONSE:
jmsg_type = json_string("tid_response");
json_object_set_new(jmsg, "msg_type", jmsg_type);
- json_object_set_new(jmsg, "msg_body", tr_msg_encode_tidresp(msg->tid_resp));
+ json_object_set_new(jmsg, "msg_body", tr_msg_encode_tidresp(tr_msg_get_resp(msg)));
break;
/* TBD -- Add TR message types */
if (0 == strcmp(mtype, "tid_request")) {
msg->msg_type = TID_REQUEST;
- msg->tid_req = tr_msg_decode_tidreq(jbody);
+ tr_msg_set_req(msg, tr_msg_decode_tidreq(jbody));
}
else if (0 == strcmp(mtype, "tid_response")) {
msg->msg_type = TID_RESPONSE;
- msg->tid_resp = tr_msg_decode_tidresp(jbody);
+ tr_msg_set_resp(msg, tr_msg_decode_tidresp(jbody));
}
else {
msg->msg_type = TR_UNKNOWN;
- msg->tid_req = NULL;
+ msg->msg_rep = NULL;
}
return msg;
}
AC_PREREQ(2.63)
-AC_INIT([trust_router],[1.2],
+AC_INIT([trust_router],[1.3.1],
[bugs@project-moonshot.org])
AC_CONFIG_MACRO_DIR(m4)
AC_CONFIG_AUX_DIR(build-aux)
AC_USE_SYSTEM_EXTENSIONS
-AM_INIT_AUTOMAKE([1.11 foreign])
+AM_INIT_AUTOMAKE([1.11 foreign subdir-objects])
AM_SILENT_RULES
AM_MAINTAINER_MODE
LT_INIT()
AC_PROG_CC
-AC_PROG_RANLIB
+ PKG_PROG_PKG_CONFIG
+ AC_ARG_WITH([systemdsystemunitdir],
+ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
+ [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
+ if test "x$with_systemdsystemunitdir" != xno; then
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+ fi
+ AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
AC_CHECK_LIB([gssapi_krb5], [gss_init_sec_context])
-AC_CHECK_LIB([com_err], [error_message])AC_CHECK_LIB([sqlite3], [sqlite3_open],,
+AC_CHECK_LIB([com_err], [error_message])
+AC_CHECK_LIB(talloc, talloc_init,,
+[AC_MSG_ERROR([Please install talloc development])])
+AC_CHECK_LIB([sqlite3], [sqlite3_open],,
[AC_MSG_ERROR([Please install sqlite3 development])])
-
AC_CHECK_LIB([jansson], [json_object])
AC_CHECK_LIB([crypto], [DH_new])
-AC_CHECK_HEADERS(gssapi.h gssapi_ext.h jansson.h openssl/dh.h openssl/bn.h)
+AC_CHECK_HEADERS(gssapi.h gssapi_ext.h jansson.h talloc.h openssl/dh.h openssl/bn.h)
AC_CONFIG_FILES([Makefile gsscon/Makefile])
AC_OUTPUT
+++ /dev/null
-mrw@lilac-moonshot.suchdamage.org.13738:1346036289
\ No newline at end of file
return err;
}
-/* --------------------------------------------------------------------------- */
-
-static int ServicePrincipalIsValidForService (const char *inServicePrincipal)
-{
- int err = 0;
- krb5_context context = NULL;
- krb5_principal principal = NULL;
-
- if (!inServicePrincipal) { err = EINVAL; }
-
- if (!err) {
- err = krb5_init_context (&context);
- }
-
- if (!err) {
- err = krb5_parse_name (context, inServicePrincipal, &principal);
- }
- if (!err) {
- /*
- * Here is where we check to see if the service principal the client
- * used is valid. Typically we would just check that the first component
- * is the name of the service provided by the server. This check exists
- * to make sure the server is using the correct key in its keytab since
- * we passed GSS_C_NO_CREDENTIAL into gss_accept_sec_context().
- */
- if (gServiceName && strcmp (gServiceName,
- krb5_princ_name (context, principal)->data) != 0) {
- err = KRB5KRB_AP_WRONG_PRINC;
- }
- }
-
- if (principal) { krb5_free_principal (context, principal); }
- if (context ) { krb5_free_context (context); }
-
- return err;
-}
/* --------------------------------------------------------------------------- */
// if (nameToken.value) { gss_release_buffer (&minorStatus, &nameToken); }
// }
-// if (!err) {
-// int authorizationErr = ServicePrincipalIsValidForService (servicePr// incipal);
-//
-// if (!authorizationErr) {
int authorizationErr = 0;
authorizationErr = ClientPrincipalIsAuthorizedForService (clientPrincipal);
-// }
+
// printf ("'%s' is%s authorized for service '%s'\n",
// clientPrincipal, authorizationErr ? " NOT" : "", servicePrincipal);
--- /dev/null
+/*
+ * Copyright (c) 2012-2014, 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.
+ *
+ */
+/*
+ * Copyright (c) 2012, 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 TID_INTERNAL_H
+#define TID_INTERNAL_H
+#include <trust_router/tid.h>
+
+#include <jansson.h>
+struct tid_srvr_blk {
+ struct in_addr aaa_server_addr;
+ TR_NAME *key_name;
+ DH *aaa_server_dh; /* AAA server's public dh information */
+};
+
+struct tid_resp {
+ TID_RC result;
+ TR_NAME *err_msg;
+ TR_NAME *rp_realm;
+ TR_NAME *realm;
+ TR_NAME *comm;
+ TR_CONSTRAINT_SET *cons;
+ TR_NAME *orig_coi;
+ TID_SRVR_BLK *servers; /* array of servers */
+ size_t num_servers;
+ /* TBD -- Trust Path Used */
+};
+struct tid_req {
+ struct tid_req *next_req;
+ int resp_sent;
+ int conn;
+ gss_ctx_id_t gssctx;
+ int resp_rcvd;
+ TR_NAME *rp_realm;
+ TR_NAME *realm;
+ TR_NAME *comm;
+ TR_CONSTRAINT_SET *cons;
+ TR_NAME *orig_coi;
+ DH *tidc_dh; /* Client's public dh information */
+ TIDC_RESP_FUNC *resp_func;
+ void *cookie;
+ json_t *json_references; /** References to objects dereferenced on request destruction*/
+};
+struct tidc_instance {
+ TID_REQ *req_list;
+ // TBD -- Do we still need a separate private key */
+ // char *priv_key;
+ // int priv_len;
+ DH *client_dh; /* Client's DH struct with priv and pub keys */
+};
+struct tids_instance {
+ int req_count;
+ char *priv_key;
+ char *ipaddr;
+ const char *hostname;
+ TIDS_REQ_FUNC *req_handler;
+ tids_auth_func *auth_handler;
+ void *cookie;
+};
+
+
+/** Decrement a reference to #json when this tid_req is cleaned up. A
+ new reference is not created; in effect the caller is handing a
+ reference they already hold to the TID_REQ.*/
+void tid_req_cleanup_json(TID_REQ *, json_t *json);
+
+#endif
#ifndef TR_H
#define TR_H
-#include <trust_router/tid.h>
+#include <tid_internal.h>
#include <trust_router/tr_name.h>
#include <tr_msg.h>
#include <tr_rp.h>
} TR_CFG_INTERNAL;
typedef struct tr_cfg {
- TR_CFG_INTERNAL *internal; /* internal trust router config */
- TR_IDP_REALM *idp_realms; /* locally associated IDP Realms */
- TR_RP_CLIENT *rp_clients; /* locally associated RP Clients */
- TR_COMM *comms; /* locally-known communities */
+ TR_CFG_INTERNAL *internal; /* internal trust router config */
+ TR_IDP_REALM *idp_realms; /* locally associated IDP Realms */
+ TR_RP_CLIENT *rp_clients; /* locally associated RP Clients */
+ TR_COMM *comms; /* locally-known communities */
+ TR_AAA_SERVER *default_servers; /* default server list */
/* TBD -- Global Filters */
/* TBD -- Trust Router Peers */
/* TBD -- Trust Links */
} TR_CFG;
int tr_find_config_files (struct dirent ***cfg_files);
-json_t *tr_read_config (int n, struct dirent **cfgfiles);
-TR_CFG_RC tr_parse_config (TR_INSTANCE *tr, json_t *jcfg);
+TR_CFG_RC tr_parse_config (TR_INSTANCE *tr, struct dirent **cfg_files);
TR_CFG_RC tr_apply_new_config (TR_INSTANCE *tr);
+TR_CFG_RC tr_cfg_validate (TR_CFG *trc);
void tr_cfg_free(TR_CFG *cfg);
void tr_print_config(FILE *stream, TR_CFG *cfg);
--- /dev/null
+/*
+ * Copyright (c) 2014, 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 _TR_DEBUG_H
+#define _TR_DEBUG_H
+
+#define tr_debug(...) fprintf( stderr, __VA_ARGS__)
+
+#endif
} TR_FILTER;
void tr_filter_free (TR_FILTER *filt);
-int tr_prefix_wildcard_match (char *str, char *wc_str);
+/*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);
int tr_filter_process_rp_permitted (TR_NAME *rp_realm, TR_FILTER *rpp_filter, TR_CONSTRAINT_SET *in_constraints, TR_CONSTRAINT_SET **out_constraints, int *out_action);
TR_CONSTRAINT_SET *tr_constraint_set_from_fline (TR_FLINE *fline);
#endif
typedef struct tr_idp_realm {
struct tr_idp_realm *next;
- struct tr_idp_realm *comm_next; /* for link list in comm config */
+ struct tr_idp_realm *comm_next; /* for linked list in comm config */
TR_NAME *realm_id;
int shared_config;
TR_AAA_SERVER *aaa_servers;
} TR_IDP_REALM;
TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_INSTANCE *tr, TR_NAME *idp_realm, TR_NAME *comm);
-
+TR_AAA_SERVER *tr_default_server_lookup(TR_INSTANCE *tr, TR_NAME *comm);
#endif
/*
- * Copyright (c) 2012, JANET(UK)
+ * Copyright (c) 2012-2014, JANET(UK)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/* Union of TR message types to hold message of any type. */
struct tr_msg {
enum msg_type msg_type;
- union {
- TID_REQ *tid_req;
- TID_RESP *tid_resp;
- };
+ void *msg_rep;
};
/* Accessors */
/*
- * Copyright (c) 2012, JANET(UK)
+ * Copyright (c) 2012-2014, JANET(UK)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <trust_router/tr_name.h>
#include <trust_router/tr_versioning.h>
-#include <trust_router/tr_constraint.h>
#include <gssapi.h>
+
#define TID_PORT 12309
typedef enum tid_rc {
TID_ERROR
} TID_RC;
-typedef struct tid_srvr_blk {
- struct tid_srvr_blk *next;
- struct in_addr aaa_server_addr;
- TR_NAME *key_name;
- DH *aaa_server_dh; /* AAA server's public dh information */
-} TID_SRVR_BLK;
-
-typedef struct tid_resp {
- TID_RC result;
- TR_NAME *err_msg;
- TR_NAME *rp_realm;
- TR_NAME *realm;
- TR_NAME *comm;
- TR_CONSTRAINT_SET *cons;
- TR_NAME *orig_coi;
- TID_SRVR_BLK *servers; /* Linked list of servers */
- /* TBD -- Trust Path Used */
-} TID_RESP;
+typedef struct tid_srvr_blk TID_SRVR_BLK;
+
+
+typedef struct _tr_constraint_set TR_CONSTRAINT_SET;
+
+typedef struct tid_resp TID_RESP;
typedef struct tidc_instance TIDC_INSTANCE;
typedef struct tids_instance TIDS_INSTANCE;
typedef struct tid_req TID_REQ;
+
typedef void (TIDC_RESP_FUNC)(TIDC_INSTANCE *, TID_REQ *, TID_RESP *, void *);
-struct tid_req {
- struct tid_req *next_req;
- int resp_sent;
- int conn;
- gss_ctx_id_t gssctx;
- int resp_rcvd;
- TR_NAME *rp_realm;
- TR_NAME *realm;
- TR_NAME *comm;
- TR_CONSTRAINT_SET *cons;
- TR_NAME *orig_coi;
- DH *tidc_dh; /* Client's public dh information */
- TIDC_RESP_FUNC *resp_func;
- void *cookie;
-};
-
-struct tidc_instance {
- TID_REQ *req_list;
- // TBD -- Do we still need a separate private key */
- // char *priv_key;
- // int priv_len;
- DH *client_dh; /* Client's DH struct with priv and pub keys */
-};
-
-typedef int (TIDS_REQ_FUNC)(TIDS_INSTANCE *, TID_REQ *, TID_RESP **, void *);
+
+
+typedef int (TIDS_REQ_FUNC)(TIDS_INSTANCE *, TID_REQ *, TID_RESP *, void *);
typedef int (tids_auth_func)(gss_name_t client_name, TR_NAME *display_name, void *cookie);
-struct tids_instance {
- int req_count;
- char *priv_key;
- char *ipaddr;
- const char *hostname;
- TIDS_REQ_FUNC *req_handler;
- tids_auth_func *auth_handler;
- void *cookie;
-};
-/* Utility funciton for TID_REQ structures, in tid/tid_req.c */
+/* Utility functions for TID_REQ structures, in tid/tid_req.c */
+TR_EXPORT TID_REQ *tid_req_new(void);
TR_EXPORT TID_REQ *tid_req_get_next_req(TID_REQ *req);
void tid_req_set_next_req(TID_REQ *req, TID_REQ *next_req);
TR_EXPORT int tid_req_get_resp_sent(TID_REQ *req);
TR_EXPORT void *tid_req_get_cookie(TID_REQ *req);
void tid_req_set_cookie(TID_REQ *req, void *cookie);
TR_EXPORT TID_REQ *tid_dup_req (TID_REQ *orig_req);
+void TR_EXPORT tid_req_free( TID_REQ *req);
/* Utility functions for TID_RESP structure, in tid/tid_resp.c */
-TR_EXPORT TID_RC tid_resp_get_result(TID_RESP *resp);
-void tid_resp_set_result(TID_RESP *resp, TID_RC result);
+TR_EXPORT int tid_resp_get_result(TID_RESP *resp);
+void tid_resp_set_result(TID_RESP *resp, int result);
TR_EXPORT TR_NAME *tid_resp_get_err_msg(TID_RESP *resp);
void tid_resp_set_err_msg(TID_RESP *resp, TR_NAME *err_msg);
TR_EXPORT TR_NAME *tid_resp_get_rp_realm(TID_RESP *resp);
void tid_resp_set_comm(TID_RESP *resp, TR_NAME *comm);
TR_EXPORT TR_NAME *tid_resp_get_orig_coi(TID_RESP *resp);
void tid_resp_set_orig_coi(TID_RESP *resp, TR_NAME *orig_coi);
-TR_EXPORT TID_SRVR_BLK *tid_resp_get_servers(TID_RESP *resp);
-void tid_resp_set_servers(TID_RESP *resp, TID_SRVR_BLK *servers);
-// TBD -- add function to add/remove items from linked list of servers?
+TR_EXPORT TID_SRVR_BLK *tid_resp_get_server(TID_RESP *resp, size_t index);
+TR_EXPORT size_t tid_resp_get_num_servers(const TID_RESP *resp);
+/* Server blocks*/
+TR_EXPORT void tid_srvr_get_address(const TID_SRVR_BLK *,
+ const struct sockaddr **out_addr, size_t *out_sa_len);
+TR_EXPORT DH *tid_srvr_get_dh(TID_SRVR_BLK *);
+TR_EXPORT const TR_NAME *tid_srvr_get_key_name(const TID_SRVR_BLK *);
+
+#define tid_resp_servers_foreach(RESP, SERVER, INDEX) \
+ for (INDEX=0,SERVER=NULL; \
+ ((INDEX < tid_resp_get_num_servers(RESP))&&(SERVER = tid_resp_get_server(resp, INDEX))); \
+ INDEX++)
+
/* TID Client functions, in tid/tidc.c */
TR_EXPORT TIDC_INSTANCE *tidc_create (void);
TR_EXPORT int tidc_open_connection (TIDC_INSTANCE *tidc, char *server, unsigned int port, gss_ctx_id_t *gssctx);
TR_EXPORT int tidc_send_request (TIDC_INSTANCE *tidc, int conn, gss_ctx_id_t gssctx, char *rp_realm, char *realm, char *coi, TIDC_RESP_FUNC *resp_handler, void *cookie);
TR_EXPORT int tidc_fwd_request (TIDC_INSTANCE *tidc, TID_REQ *req, TIDC_RESP_FUNC *resp_handler, void *cookie);
+TR_EXPORT DH *tidc_get_dh(TIDC_INSTANCE *);
+TR_EXPORT DH *tidc_set_dh(TIDC_INSTANCE *, DH *);
TR_EXPORT void tidc_destroy (TIDC_INSTANCE *tidc);
/* TID Server functions, in tid/tids.c */
#ifndef TR_CONSTRAINT_H
#define TR_CONSTRAINT_H
-
#include <trust_router/tr_name.h>
+#include <trust_router/tid.h>
+
#define TR_MAX_CONST_MATCHES 24
-typedef void TR_CONSTRAINT_SET;
typedef struct tr_constraint {
TR_NAME *type;
TR_NAME *matches[TR_MAX_CONST_MATCHES];
} TR_CONSTRAINT;
-void tr_constraint_add_to_set (TR_CONSTRAINT_SET **cs, TR_CONSTRAINT *c);
+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 *);
+/**
+ * Create a new constraint set containing all constraints from #orig
+ * with constraint_type #constraint_type and no others. This constraint set is
+ * live until #request is freed.
+ */
+TR_EXPORT TR_CONSTRAINT_SET *tr_constraint_set_filter(TID_REQ *request,
+ TR_CONSTRAINT_SET *orig,
+ const char * constraint_type);
+
+TR_EXPORT TR_CONSTRAINT_SET
+*tr_constraint_set_intersect(TID_REQ *request,
+ TR_CONSTRAINT_SET *input);
+
+/** Get the set of wildcard strings that matches a fully intersected
+ * constraint set. Requires that the constraint set only have one
+ * constraint in it, but the constraint may have multiple matches for
+ * a given type. Returns true on success false on failure. The
+ * output is live as long as the request is live.
+ */
+int TR_EXPORT tr_constraint_set_get_match_strings(TID_REQ *,
+ TR_CONSTRAINT_SET *,
+ const char * constraint_type,
+ tr_const_string **output,
+ size_t *output_len);
+
#endif
#include <openssl/dh.h>
#include <openssl/bn.h>
#include <trust_router/tr_versioning.h>
+#include <trust_router/tid.h>
+
TR_EXPORT DH *tr_create_dh_params(unsigned char *key, size_t len);
TR_EXPORT DH *tr_create_matching_dh(unsigned char *key, size_t len, DH *in_dh);
TR_EXPORT void tr_destroy_dh_params(DH *dh);
TR_EXPORT int tr_compute_dh_key(unsigned char **pbuf, BIGNUM *pub_key, DH *priv_dh);
+TR_EXPORT void tr_dh_free(unsigned char *dh_buf);
+int TR_EXPORT tr_dh_pub_hash(TID_REQ *request,
+ unsigned char **out_digest,
+ size_t *out_llen);
+
TR_EXPORT void tr_bin_to_hex(const unsigned char * bin, size_t binlen,
char * hex_out, size_t hex_len);
#include <string.h>
#include <trust_router/tr_versioning.h>
+typedef const char *tr_const_string;
+
typedef struct tr__name {
char *buf;
int len;
--- /dev/null
+{"tr_internal":{"max_tree_depth": 4,
+ "hostname":"tr.moonshot.local",
+ "tids_port" : 12309
+ }
+}
--- /dev/null
+#!/bin/bash
+#
+# ntpd This shell script takes care of starting and stopping
+# trust_router.
+#
+# chkconfig: - 58 74
+# description: trust_router is the GSS-EAP trust routing daemon. \
+# GSS-EAP is an IETF standard for providing authentication across \
+# an insecure WAN. \
+
+### BEGIN INIT INFO
+# Provides: trust_router
+# Required-Start: $network $local_fs $remote_fs
+# Required-Stop: $network $local_fs $remote_fs
+# Should-Start: $syslog $named ntpdate
+# Should-Stop: $syslog $named
+# Short-Description: start and stop trust_router
+# Description: trust_router is the GSS-EAP trust routing daemon.
+# GSS-EAP is an IETF standard for providing authentication
+# across an insecure WAN.
+### END INIT INFO
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+# Load the instance configuration
+[ -f /etc/sysconfig/trust_router ] || exit 6
+. /etc/sysconfig/trust_router
+
+# Create the pidfile directory
+mkdir -p /var/run/trust_router
+chown trustrouter:trustrouter /var/run/trust_router
+
+# Does the trust router and wrapper exist
+[ -x /usr/bin/trust_router ] || exit 5
+[ -x /usr/bin/trust_router-wrapper ] || exit 5
+
+# Does the tidc client exist
+[ -x /usr/bin/tidc ] || exit 5
+[ -x /usr/bin/tidc-wrapper ] || exit 5
+
+prog="trust_router-wrapper"
+
+array_contains() {
+ local i
+
+ for i in "${@:2}" ;
+ do
+ [ "${i}" == "${1}" ] && return 0
+ done
+
+ return 1
+}
+
+execute-tidc() {
+ echo -n "Attempting to authenticate to instance ${current_instance}:${current_port}"
+
+ daemon --user="${current_user}" /usr/bin/tidc-wrapper "${current_test_acceptor}" "${current_test_rprealm}" "${current_test_community}" "${current_test_realm}" "${current_port}"
+ tidc_ret=$?
+
+ echo
+
+ return ${tidc_ret}
+}
+
+get-config() {
+ current_instance=${1}
+
+ if [ "${TR_CONFIG_USER[${current_instance}]+abc}" ] ;
+ then
+ current_user=${TR_CONFIG_USER[${current_instance}]}
+ else
+ current_user=${TR_DEFAULT_USER}
+ fi
+
+ if [ "${TR_CONFIG_PIDDIR[${current_instance}]+abc}" ] ;
+ then
+ current_piddir=${TR_CONFIG_PIDDIR[${current_instance}]}
+ else
+ current_piddir=${TR_DEFAULT_PIDDIR}
+ fi
+
+ if [ "${TR_CONFIG_CFGDIR[${current_instance}]+abc}" ] ;
+ then
+ current_cfgdir=${TR_CONFIG_CFGDIR[${current_instance}]}
+ else
+ current_cfgdir=${TR_DEFAULT_CFGDIR}
+ fi
+
+ if [ "${TR_CONFIG_LOGDIR[${current_instance}]+abc}" ] ;
+ then
+ current_logdir=${TR_CONFIG_LOGDIR[${current_instance}]}
+ else
+ current_logdir=${TR_DEFAULT_LOGDIR}
+ fi
+
+ if [ "${TR_CONFIG_PORT[${current_instance}]+abc}" ] ;
+ then
+ current_port=${TR_CONFIG_PORT[${current_instance}]}
+ else
+ current_port=${TR_DEFAULT_PORT}
+ fi
+
+ if [ "${TR_CONFIG_AUTOSTART[${current_instance}]+abc}" ] ;
+ then
+ current_autostart=${TR_CONFIG_AUTOSTART[${current_instance}]}
+ else
+ current_autostart=${TR_DEFAULT_AUTOSTART}
+ fi
+
+ if [ "${TR_CONFIG_ACCEPTOR[${current_instance}]+abc}" ] ;
+ then
+ current_test_acceptor=${TR_CONFIG_TEST_ACCEPTOR[${current_instance}]}
+ else
+ current_test_acceptor=${TR_DEFAULT_TEST_ACCEPTOR}
+ fi
+
+ if [ "${TR_CONFIG_RPREALM[${current_instance}]+abc}" ] ;
+ then
+ current_test_rprealm=${TR_CONFIG_TEST_RPREALM[${current_instance}]}
+ else
+ current_test_rprealm=${TR_DEFAULT_TEST_RPREALM}
+ fi
+
+ if [ "${TR_CONFIG_TEST_COMMUNITY[${current_instance}]+abc}" ] ;
+ then
+ current_test_community=${TR_CONFIG_TEST_COMMUNITY[${current_instance}]}
+ else
+ current_test_community=${TR_DEFAULT_TEST_COMMUNITY}
+ fi
+
+ if [ "${TR_CONFIG_TEST_REALM[${current_instance}]+abc}" ] ;
+ then
+ current_test_realm=${TR_CONFIG_TEST_REALM[${current_instance}]}
+ else
+ current_test_realm=${TR_DEFAULT_TEST_REALM}
+ fi
+}
+
+get-pidfile() {
+ echo "${current_piddir}/${current_instance}.pid"
+}
+
+start() {
+ [ "${EUID}" != "0" ] && exit 4
+ [ "${NETWORKING}" = "no" ] && exit 1
+
+ start_ret=0
+
+ for i in "${TR_INSTANCES[@]}"
+ do
+ get-config "${i}"
+
+ if ${current_autostart} ;
+ then
+ start-instance
+ let "start_ret+=$?"
+ else
+ echo "Skipping instance ${current_instance}"
+ fi
+ done
+
+ return "${start_ret}"
+}
+
+start-single() {
+ if array_contains "${1}" "${TR_INSTANCES[@]}" ;
+ then
+ get-config "${1}"
+
+ start-instance
+ return $?
+ else
+ echo "Instance ${1} not found..."
+
+ return 1
+ fi
+}
+
+start-instance() {
+ pidfile=$(get-pidfile)
+ logfile="${current_logdir}/${current_instance}.log"
+ cfgdir="${current_cfgdir}/${current_instance}/"
+
+ OPTIONS="${pidfile} ${cfgdir} ${logfile}"
+
+ if [ -f "${pidfile}" ] ;
+ then
+ local OLD_PID=$(cat "${pidfile}")
+
+ if [ -d "/proc/${OLD_PID}" ] ;
+ then
+ echo "Instance ${current_instance} is already running..."
+ else
+ echo "Removing stale PID file..."
+ rm "${pidfile}"
+
+ start-instance
+ return $?
+ fi
+ else
+ echo -n "Starting instance ${current_instance}..."
+ daemon --user="${current_user}" --pidfile="${pidfile}" "${prog}" "${OPTIONS}"
+ echo
+ fi
+
+ # Give it a few seconds for things to settle
+ sleep 2
+
+ execute-tidc
+ return $?
+}
+
+stop() {
+ [ "${EUID}" != "0" ] && exit 4
+ [ "${NETWORKING}" = "no" ] && exit 1
+
+ for i in "${TR_INSTANCES[@]}"
+ do
+ get-config "${i}"
+
+ pidfile=$(get-pidfile)
+
+ if [ -f "${pidfile}" ] ;
+ then
+ stop-instance
+ else
+ echo "Instance ${i} does not appear to be running..."
+ fi
+ done
+}
+
+stop-single() {
+ if array_contains "${1}" "${TR_INSTANCES[@]}" ;
+ then
+ get-config "${1}"
+
+ stop-instance
+ else
+ echo "Instance ${1} not found..."
+
+ return 1
+ fi
+
+ return 0
+}
+
+stop-instance() {
+ if [ -f "$(get-pidfile)" ] ;
+ then
+ echo -n "Stopping instance ${current_instance}..."
+
+ killproc -p "$(get-pidfile)" "${prog}"
+ echo
+ else
+ echo "Instance ${current_instance} does not appear to be running..."
+ fi
+}
+
+status() {
+ [ "${EUID}" != "0" ] && exit 4
+ [ "${NETWORKING}" = "no" ] && exit 1
+
+ start_ret=0
+
+ for i in "${TR_INSTANCES[@]}"
+ do
+ get-config "${i}"
+
+ execute-tidc
+ let "exec_ret+=$?"
+ done
+
+ return "${exec_ret}"
+}
+
+
+# See how we were called.
+case "${1}" in
+ start)
+ start
+ ;;
+ start-single)
+ start-single "${2}"
+ ;;
+ stop)
+ stop
+ ;;
+ stop-single)
+ stop-single "${2}"
+ ;;
+ status)
+ status "${prog}"
+ ;;
+ restart|force-reload)
+ stop
+ start
+ ;;
+ reload)
+ exit 3
+ ;;
+ *)
+ echo "Usage: ${0} {start|start-single|stop|stop-single|status|restart|force-reload}"
+ exit 2
+esac
--- /dev/null
+##
+## Declare an id tag for each trust router instance
+##
+
+TR_INSTANCES[0]="default"
+TR_INSTANCES[1]="tr-test"
+
+##
+## Declare the default configuration
+##
+
+TR_DEFAULT_USER="trustrouter" # Username to execute the trust router as
+TR_DEFAULT_PIDDIR="/var/run/trust_router" # Directory to store PIDFile in
+TR_DEFAULT_CFGDIR="/etc/trust_router/conf.d" # Config directory
+TR_DEFAULT_LOGDIR="/var/log/trust_router" # Trust router log directories
+TR_DEFAULT_AUTOSTART=true # Default autostart state
+TR_DEFAULT_PORT=12309 # Port instance should be running on
+TR_DEFAULT_TEST_ACCEPTOR="tr.moonshot.local" # Acceptor name to expect when testing
+TR_DEFAULT_TEST_RPREALM="apc.moonshot.local" # RP Realm to assert when testing
+TR_DEFAULT_TEST_COMMUNITY="apc.moonshot.local" # Community to query when testing
+TR_DEFAULT_TEST_REALM="apc.moonshot.local" # Realm to request when testing
+
+##
+## Declare the configuration arrays
+##
+
+declare -A TR_CONFIG_USER
+declare -A TR_CONFIG_PIDDIR
+declare -A TR_CONFIG_CFGDIR
+declare -A TR_CONFIG_LOGDIR
+declare -A TR_CONFIG_PORT
+declare -A TR_CONFIG_AUTOSTART
+declare -A TR_CONFIG_TEST_ACCEPTOR
+declare -A TR_CONFIG_TEST_RPREALM
+declare -A TR_CONFIG_TEST_COMMUNITY
+declare -A TR_CONFIG_TEST_REALM
+
+##
+## Override the default configuation for each instance as required
+##
+
+TR_CONFIG_PORT[tr-test]=12345
+TR_CONFIG_AUTOSTART[tr-test]=false
+
--- /dev/null
+#! /usr/bin/env bash
+
+tidc "$@" > /dev/null 2>&1
+exit "${?}"
--- /dev/null
+{"tr_internal":{"max_tree_depth": 4,
+ "hostname":"tr.moonshot.local",
+ "tids_port" : 12345
+ }
+}
--- /dev/null
+#! /usr/bin/env bash
+
+cd "${2}"
+
+/usr/bin/trust_router > "${3}.$(date +'%Y%m%d%H%M')" 2>&1 &
+BGPID=$!
+RET=$?
+
+echo "${BGPID}" > "${1}"
+
+exit "${RET}"
--- /dev/null
+{
+ "communities": [
+ {
+ "apcs": [
+ "pci-community.ja.net"
+ ],
+ "community_id": "comm.offcenter.org",
+ "idp_realms": [
+ "idr2.offcenter.org"
+ ],
+ "rp_realms": [
+ "sr3.offcenter.org"
+ ],
+ "type": "coi"
+ },
+ {
+ "apcs": [
+
+ ],
+ "community_id": "pci-community.ja.net",
+ "idp_realms": [
+ "idr1.offcenter.org",
+ "idr2.offcenter.org",
+ "ja.net",
+ "no-longer-untitled.offcenter.org"
+ ],
+ "rp_realms": [
+ "exchange.ja.net",
+ "sr3.offcenter.org"
+ ],
+ "type": "apc"
+ }
+ ],
+ "idp_realms": [
+ {
+ "aaa_servers": [
+ "127.0.0.1"
+ ],
+ "apcs": [
+ "pci-community.ja.net"
+ ],
+ "realm_id": "idr1.offcenter.org",
+ "shared_config": "yes"
+ },
+ {
+ "aaa_servers": [
+ "127.0.0.1"
+ ],
+ "apcs": [
+ "pci-community.ja.net"
+ ],
+ "realm_id": "idr2.offcenter.org",
+ "shared_config": "no"
+ },
+ {
+ "aaa_servers": [
+ "10.1.10.90"
+ ],
+ "apcs": [
+ "pci-community.ja.net"
+ ],
+ "realm_id": "ja.net",
+ "shared_config": "no"
+ },
+ {
+ "aaa_servers": [
+ "127.0.0.1"
+ ],
+ "apcs": [
+ "pci-community.ja.net"
+ ],
+ "realm_id": "no-longer-untitled.offcenter.org",
+ "shared_config": "yes"
+ }
+ ],
+ "rp_clients": [
+ {
+ "filter": {
+ "filter_lines": [
+ {
+ "action": "accept",
+ "domain_constraints": ["*.exchange.ja.net"],
+ "filter_specs": [
+ {
+ "field": "rp_realm",
+ "match": "exchange.ja.net"
+ },
+ {
+ "field": "rp_realm",
+ "match": "*.exchange.ja.net"
+ }
+ ],
+ "realm_constraints": ["*.exchange.ja.net", "a.com"]
+ }
+ ],
+ "type": "rp_permitted"
+ },
+ "gss_names": [
+ "01b80aa9-8753-4691-8f8a-f49f7793546f@portal-realm.ja.net"
+ ]
+ },
+ {
+ "filter": {
+ "filter_lines": [
+ {
+ "action": "accept",
+ "domain_constraints": ["*.bob.sr3.offcenter.org"],
+ "filter_specs": [
+ {
+ "field": "rp_realm",
+ "match": "sr3.offcenter.org"
+ },
+ {
+ "field": "rp_realm",
+ "match": "*.sr3.offcenter.org"
+ }
+ ],
+ "realm_constraints": ["*.sr3.offcenter.org" ]
+ }
+ ],
+ "type": "rp_permitted"
+ },
+ "gss_names": [
+ "895c308a-5624-4055-bb4f-ea24b77e6637@portal-realm.ja.net"
+ ]
+ }
+ ]
+}
--- /dev/null
+create table if not exists psk_keys (keyid text primary key, key blob, client_dh_pub raw(20));
+create table if not exists authorizations( client_dh_pub raw(20), coi string, acceptor_realm string, hostname string, apc string);
+create index if not exists authorizations_dhpub on authorizations( client_dh_pub);
+CREATE VIEW if not exists authorizations_keys as select keyid, authorizations.* from psk_keys join authorizations on psk_keys.client_dh_pub = authorizations.client_dh_pub;
+
+
+.quit
+
+
#include <stdlib.h>
#include <stdio.h>
+#include <talloc.h>
#include <gsscon.h>
-#include <trust_router/tid.h>
+#include <tid_internal.h>
#include <trust_router/tr_dh.h>
void static tidc_print_usage (const char *name)
{
- printf("Usage: %s <server> <RP-realm> <target-realm> <community>\n", name);
+ printf("Usage: %s <server> <RP-realm> <target-realm> <community> [<port>]\n", name);
}
static void tidc_resp_handler (TIDC_INSTANCE * tidc,
char *rp_realm = NULL;
char *realm = NULL;
char *coi = NULL;
+ int port = TID_PORT;
int conn = 0;
int rc;
gss_ctx_id_t gssctx;
+ talloc_set_log_stderr();
/* Parse command-line arguments */
- if (argc != 5) {
+ if (argc < 5 || argc > 6) {
tidc_print_usage(argv[0]);
exit(1);
}
realm = (char *)argv[3];
coi = (char *)argv[4];
- printf("TIDC Client:\nServer = %s, rp_realm = %s, target_realm = %s, community = %s\n", server, rp_realm, realm, coi);
+ if (argc > 5) {
+ port = strtol(argv[5], NULL, 10);
+ }
+
+ printf("TIDC Client:\nServer = %s, rp_realm = %s, target_realm = %s, community = %s, port = %i\n", server, rp_realm, realm, coi, port);
/* Create a TID client instance & the client DH */
tidc = tidc_create();
}
/* Set-up TID connection */
- if (-1 == (conn = tidc_open_connection(tidc, server, TID_PORT, &gssctx))) {
+ if (-1 == (conn = tidc_open_connection(tidc, server, port, &gssctx))) {
/* Handle error */
printf("Error in tidc_open_connection.\n");
return 1;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <talloc.h>
#include <sqlite3.h>
-#include <trust_router/tid.h>
+#include <tr_debug.h>
+#include <tid_internal.h>
+#include <trust_router/tr_constraint.h>
#include <trust_router/tr_dh.h>
#include <openssl/rand.h>
static sqlite3 *db = NULL;
static sqlite3_stmt *insert_stmt = NULL;
+static sqlite3_stmt *authorization_insert = NULL;
static int create_key_id(char *out_id, size_t len)
{
out_id[bin_len*2] = '\0';
return 0;
}
-
+
+static int sqlify_wc(
+ TID_REQ *req,
+ const char **wc,
+ size_t len,
+ char **error)
+{
+ size_t lc;
+ *error = NULL;
+ for (lc = 0; lc < len; lc++) {
+ if (strchr(wc[lc], '%')) {
+ *error = talloc_asprintf( req, "Constraint match `%s' is not appropriate for SQL",
+ wc[lc]);
+ return -1;
+ }
+ if ('*' ==wc[lc][0]) {
+ char *s;
+ s = talloc_strdup(req, wc[lc]);
+ s[0] = '%';
+ wc[lc] = s;
+ }
+ }
+ return 0;
+}
+
+
+
+static int handle_authorizations(TID_REQ *req, const unsigned char *dh_hash,
+ size_t hash_len)
+{
+ TR_CONSTRAINT_SET *intersected = NULL;
+ const char **domain_wc, **realm_wc;
+ size_t domain_len, realm_len;
+ size_t domain_index, realm_index;
+ char *error;
+ int sqlite3_result;
+
+ if (!req->cons) {
+ tr_debug("Request has no constraints, so no authorizations.\n");
+ return 0;
+ }
+ intersected = tr_constraint_set_intersect(req, req->cons);
+ if (!intersected)
+ return -1;
+ if (0 != tr_constraint_set_get_match_strings(req,
+ intersected, "domain",
+ &domain_wc, &domain_len))
+ return -1;
+ if (0 != tr_constraint_set_get_match_strings(req,
+ intersected, "realm",
+ &realm_wc, &realm_len))
+ return -1;
+ tr_debug(" %u domain constraint matches and %u realm constraint matches\n",
+ (unsigned) domain_len, (unsigned) realm_len);
+ if (0 != sqlify_wc(req, domain_wc, domain_len, &error)) {
+ tr_debug("Processing domain constraints: %s\n", error);
+ return -1;
+ }else if (0 != sqlify_wc(req, realm_wc, realm_len, &error)) {
+ tr_debug("Processing realm constraints: %s\n", error);
+ return -1;
+ }
+ if (!authorization_insert) {
+ tr_debug( " No database, no authorizations inserted\n");
+ return 0;
+ }
+ for (domain_index = 0; domain_index < domain_len; domain_index++)
+ for (realm_index = 0; realm_index < realm_len; realm_index++) {
+ TR_NAME *community = req->orig_coi;
+ if (!community)
+ community = req->comm;
+ sqlite3_bind_blob(authorization_insert, 1, dh_hash, hash_len, SQLITE_TRANSIENT);
+ sqlite3_bind_text(authorization_insert, 2, community->buf, community->len, SQLITE_TRANSIENT);
+ sqlite3_bind_text(authorization_insert, 3, realm_wc[realm_index], -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(authorization_insert, 4, domain_wc[domain_index], -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(authorization_insert, 5, req->comm->buf, req->comm->len, SQLITE_TRANSIENT);
+ sqlite3_result = sqlite3_step(authorization_insert);
+ if (SQLITE_DONE != sqlite3_result)
+ printf("sqlite3: failed to write to database\n");
+ sqlite3_reset(authorization_insert);
+ }
+ return 0;
+}
+
+
static int tids_req_handler (TIDS_INSTANCE *tids,
TID_REQ *req,
- TID_RESP **resp,
+ TID_RESP *resp,
void *cookie)
{
unsigned char *s_keybuf = NULL;
int s_keylen = 0;
char key_id[12];
+ unsigned char *pub_digest;
+ size_t pub_digest_len;
fprintf(stdout, "tids_req_handler: Request received! target_realm = %s, community = %s\n", req->realm->buf, req->comm->buf);
if (tids)
tids->req_count++;
- if (!(resp) || !(*resp)) {
+ if (!(resp) || !resp) {
fprintf(stderr, "tids_req_handler: No response structure.\n");
return -1;
}
/* Allocate a new server block */
- if (NULL == ((*resp)->servers = malloc(sizeof(TID_SRVR_BLK)))){
+ if (NULL == (resp->servers = malloc(sizeof(TID_SRVR_BLK)))){
fprintf(stderr, "tids_req_handler(): malloc failed.\n");
return -1;
}
- memset((*resp)->servers, 0, sizeof(TID_SRVR_BLK));
+ memset(resp->servers, 0, sizeof(TID_SRVR_BLK));
+ resp->num_servers = 1;
/* TBD -- Set up the server IP Address */
// fprintf(stderr, "Generating the server DH block.\n");
// fprintf(stderr, "...from client DH block, dh_g = %s, dh_p = %s.\n", BN_bn2hex(req->tidc_dh->g), BN_bn2hex(req->tidc_dh->p));
- if (NULL == ((*resp)->servers->aaa_server_dh = tr_create_matching_dh(NULL, 0, req->tidc_dh))) {
+ if (NULL == (resp->servers->aaa_server_dh = tr_create_matching_dh(NULL, 0, req->tidc_dh))) {
fprintf(stderr, "tids_req_handler(): Can't create server DH params.\n");
return -1;
}
- if (0 == inet_aton(tids->ipaddr, &((*resp)->servers->aaa_server_addr))) {
+ if (0 == inet_aton(tids->ipaddr, &(resp->servers->aaa_server_addr))) {
fprintf(stderr, "tids_req_handler(): inet_aton() failed.\n");
return -1;
}
/* Set the key name */
if (-1 == create_key_id(key_id, sizeof(key_id)))
return -1;
- (*resp)->servers->key_name = tr_new_name(key_id);
+ resp->servers->key_name = tr_new_name(key_id);
/* Generate the server key */
// fprintf(stderr, "Generating the server key.\n");
if (0 > (s_keylen = tr_compute_dh_key(&s_keybuf,
req->tidc_dh->pub_key,
- (*resp)->servers->aaa_server_dh))) {
+ resp->servers->aaa_server_dh))) {
fprintf(stderr, "tids_req_handler(): Key computation failed.");
return -1;
}
+ if (0 != tr_dh_pub_hash(req,
+ &pub_digest, &pub_digest_len)) {
+ tr_debug("Unable to digest client public key\n");
+ return -1;
+ }
+ if (0 != handle_authorizations(req, pub_digest, pub_digest_len))
+ return -1;
if (NULL != insert_stmt) {
int sqlite3_result;
sqlite3_bind_text(insert_stmt, 1, key_id, -1, SQLITE_TRANSIENT);
sqlite3_bind_blob(insert_stmt, 2, s_keybuf, s_keylen, SQLITE_TRANSIENT);
+ sqlite3_bind_blob(insert_stmt, 3, pub_digest, pub_digest_len, SQLITE_TRANSIENT);
sqlite3_result = sqlite3_step(insert_stmt);
if (SQLITE_DONE != sqlite3_result)
printf("sqlite3: failed to write to database\n");
const char *hostname = NULL;
TR_NAME *gssname = NULL;
+ talloc_set_log_stderr();
/* Parse command-line arguments */
if (argc != 5) {
fprintf(stdout, "Usage: %s <ip-address> <gss-name> <hostname> <database-name>\n", argv[0]);
fprintf(stdout, "Error opening database %s\n", argv[4]);
exit(1);
}
- sqlite3_prepare_v2(db, "insert into psk_keys (keyid, key) values(?, ?)",
+ sqlite3_prepare_v2(db, "insert into psk_keys (keyid, key, client_dh_pub) values(?, ?, ?)",
-1, &insert_stmt, NULL);
+ sqlite3_prepare_v2(db, "insert into authorizations (client_dh_pub, coi, acceptor_realm, hostname, apc) values(?, ?, ?, ?, ?)",
+ -1, &authorization_insert, NULL);
/* Create a TID server instance */
if (NULL == (tids = tids_create())) {
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
+#include <talloc.h>
+
+#include <tid_internal.h>
+#include <jansson.h>
+
+static int destroy_tid_req(TID_REQ *req)
+{
+ if (req->json_references)
+ json_decref(req->json_references);
+ return 0;
+}
+
+TID_REQ *tid_req_new()
+{
+ TID_REQ *req = talloc_zero(NULL, TID_REQ);
+ if(!req)
+ return NULL;
+ talloc_set_destructor(req, destroy_tid_req);
+ req->json_references = json_array();
+ assert(req->json_references);
+ req->conn = -1;
+ return req;
+}
-#include <trust_router/tid.h>
TID_REQ *tid_req_get_next_req(TID_REQ *req)
{
return(req->next_req);
/* Memcpy for flat fields, not valid until names are duped. */
memcpy(new_req, orig_req, sizeof(TID_REQ));
+ json_incref(new_req->json_references);
if ((NULL == (new_req->rp_realm = tr_dup_name(orig_req->rp_realm))) ||
(NULL == (new_req->realm = tr_dup_name(orig_req->realm))) ||
return new_req;
}
+
+void tid_req_cleanup_json( TID_REQ *req, json_t *ref)
+{
+ (void) json_array_append_new(req->json_references, ref);
+}
+
+void tid_req_free(TID_REQ *req)
+{
+ talloc_free(req);
+}
+
+
+void tid_srvr_get_address(const TID_SRVR_BLK *blk,
+ const struct sockaddr **out_addr,
+ size_t *out_len)
+{
+ struct sockaddr_in *sa = NULL;
+ assert(blk);
+ sa = talloc_zero(blk, struct sockaddr_in);
+ sa->sin_family = AF_INET;
+ sa->sin_addr = blk->aaa_server_addr;
+ sa->sin_port = htons(2083);
+ *out_addr = (struct sockaddr *) sa;
+ *out_len = sizeof( struct sockaddr_in);
+}
+
+DH *tid_srvr_get_dh( TID_SRVR_BLK *blk)
+{
+ assert(blk);
+ return blk->aaa_server_dh;
+}
+
+const TR_NAME *tid_srvr_get_key_name(
+ const TID_SRVR_BLK *blk)
+{
+ assert(blk);
+ return blk->key_name;
+}
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
-#include <trust_router/tid.h>
+#include <tid_internal.h>
-TR_EXPORT TID_RC tid_resp_get_result(TID_RESP *resp)
+TR_EXPORT int tid_resp_get_result(TID_RESP *resp)
{
return(resp->result);
}
-void tid_resp_set_result(TID_RESP *resp, TID_RC result)
+void tid_resp_set_result(TID_RESP *resp, int result)
{
resp->result = result;
}
resp->orig_coi = orig_coi;
}
-TR_EXPORT TID_SRVR_BLK *tid_resp_get_servers(TID_RESP *resp)
+TR_EXPORT TID_SRVR_BLK *tid_resp_get_server(TID_RESP *resp,
+ size_t index)
{
- return(resp->servers);
+ assert(resp);
+ assert(index < resp->num_servers);
+ return(&(resp->servers[index]));
}
-void tid_resp_set_servers(TID_RESP *resp, TID_SRVR_BLK *servers)
+size_t tid_resp_get_num_servers(const TID_RESP *resp)
{
- resp->servers = servers;
+ assert(resp);
+ return resp->num_servers;
}
+
#include <jansson.h>
#include <trust_router/tr_dh.h>
-#include <trust_router/tid.h>
+#include <tid_internal.h>
#include <tr_msg.h>
#include <gsscon.h>
TID_REQ *tid_req = NULL;
/* Create and populate a TID req structure */
- if (!(tid_req = malloc(sizeof(TID_REQ))))
+ if (!(tid_req = tid_req_new()))
return -1;
- memset(tid_req, 0, sizeof(TID_REQ));
-
tid_req->conn = conn;
tid_req->gssctx = gssctx;
return -1;
msg->msg_type = TID_REQUEST;
- msg->tid_req = tid_req;
+ tr_msg_set_req(msg, tid_req);
/* store the response function and cookie */
// tid_req->resp_func = resp_handler;
}
/* TBD -- Check if this is actually a valid response */
- if (!resp_msg->tid_resp) {
+ if (TID_RESPONSE != tr_msg_get_msg_type(resp_msg)) {
fprintf(stderr, "tidc_fwd_request: Error, no response in the response!\n");
return -1;
}
if (resp_handler)
/* Call the caller's response function */
- (*resp_handler)(tidc, tid_req, resp_msg->tid_resp, cookie);
+ (*resp_handler)(tidc, tid_req, tr_msg_get_resp(resp_msg), cookie);
else
fprintf(stderr, "tidc_fwd_request: NULL response function.\n");
if (msg)
free(msg);
if (tid_req)
- free(tid_req);
+ tid_req_free(tid_req);
if (req_buf)
free(req_buf);
if (resp_buf)
}
+DH * tidc_get_dh(TIDC_INSTANCE *inst)
+{
+ return inst->client_dh;
+}
-
-
+DH *tidc_set_dh(TIDC_INSTANCE *inst, DH *dh)
+{
+ inst->client_dh = dh;
+ return dh;
+}
#include <sys/socket.h>
#include <netinet/in.h>
#include <jansson.h>
-
-#include <trust_router/tid.h>
+#include <talloc.h>
+#include <tid_internal.h>
#include <gsscon.h>
#include <tr_msg.h>
{
TID_RESP *resp;
- if ((NULL == (resp = calloc(sizeof(TID_RESP), 1)))) {
+ if ((NULL == (resp = talloc_zero(req, TID_RESP)))) {
fprintf(stderr, "tids_create_response: Error allocating response structure.\n");
return NULL;
}
tr_free_name(resp->comm);
if (resp->orig_coi)
tr_free_name(resp->orig_coi);
- free (resp);
+ talloc_free(resp);
}
}
return buflen;
}
-static int tids_handle_request (TIDS_INSTANCE *tids, TR_MSG *mreq, TID_RESP **resp)
+static int tids_handle_request (TIDS_INSTANCE *tids, TR_MSG *mreq, TID_RESP *resp)
{
int rc;
/* Check that this is a valid TID Request. If not, send an error return. */
- if ((!mreq->tid_req) ||
- (!mreq->tid_req->rp_realm) ||
- (!mreq->tid_req->realm) ||
- (!mreq->tid_req->comm)) {
+ if ((!tr_msg_get_req(mreq)) ||
+ (!tr_msg_get_req(mreq)->rp_realm) ||
+ (!tr_msg_get_req(mreq)->realm) ||
+ (!tr_msg_get_req(mreq)->comm)) {
fprintf(stderr, "tids_handle_request():Not a valid TID Request.\n");
- (*resp)->result = TID_ERROR;
- (*resp)->err_msg = tr_new_name("Bad request format");
+ resp->result = TID_ERROR;
+ resp->err_msg = tr_new_name("Bad request format");
return -1;
}
/* Call the caller's request handler */
/* TBD -- Handle different error returns/msgs */
- if (0 > (rc = (*tids->req_handler)(tids, mreq->tid_req, &(*resp), tids->cookie))) {
+ if (0 > (rc = (*tids->req_handler)(tids, tr_msg_get_req(mreq), resp, tids->cookie))) {
/* set-up an error response */
- (*resp)->result = TID_ERROR;
- if (!(*resp)->err_msg) /* Use msg set by handler, if any */
- (*resp)->err_msg = tr_new_name("Internal processing error");
+ resp->result = TID_ERROR;
+ if (!resp->err_msg) /* Use msg set by handler, if any */
+ resp->err_msg = tr_new_name("Internal processing error");
}
else {
/* set-up a success response */
- (*resp)->result = TID_SUCCESS;
- (*resp)->err_msg = NULL; /* No error msg on successful return */
+ resp->result = TID_SUCCESS;
+ resp->err_msg = NULL; /* No error msg on successful return */
}
return rc;
return 0;
mresp.msg_type = TID_RESPONSE;
- mresp.tid_resp = resp;
+ tr_msg_set_resp(&mresp, resp);
if (NULL == (resp_buf = tr_msg_encode(&mresp))) {
fprintf(stderr, "tids_send_response: Error encoding json response.\n");
}
/* Put connection information into the request structure */
- mreq->tid_req->conn = conn;
- mreq->tid_req->gssctx = gssctx;
+ tr_msg_get_req(mreq)->conn = conn;
+ tr_msg_get_req(mreq)->gssctx = gssctx;
/* Allocate a response structure and populate common fields */
- if (NULL == (resp = tids_create_response (tids, mreq->tid_req))) {
+ if (NULL == (resp = tids_create_response (tids, tr_msg_get_req(mreq)))) {
fprintf(stderr, "tids_handle_connection: Error creating response structure.\n");
/* try to send an error */
- tids_send_err_response(tids, mreq->tid_req, "Error creating response.\n");
+ tids_send_err_response(tids, tr_msg_get_req(mreq), "Error creating response.\n");
return;
}
- if (0 > (rc = tids_handle_request(tids, mreq, &resp))) {
+ if (0 > (rc = tids_handle_request(tids, mreq, resp))) {
fprintf(stderr, "tids_handle_connection: Error from tids_handle_request(), rc = %d.\n", rc);
/* Fall through, to send the response, either way */
}
- if (0 > (rc = tids_send_response(tids, mreq->tid_req, resp))) {
+ if (0 > (rc = tids_send_response(tids, tr_msg_get_req(mreq), resp))) {
fprintf(stderr, "tids_handle_connection: Error from tids_send_response(), rc = %d.\n", rc);
/* if we didn't already send a response, try to send a generic error. */
- if (!mreq->tid_req->resp_sent)
- tids_send_err_response(tids, mreq->tid_req, "Error sending response.\n");
+ if (!tr_msg_get_req(mreq)->resp_sent)
+ tids_send_err_response(tids, tr_msg_get_req(mreq), "Error sending response.\n");
/* Fall through to free the response, either way. */
}
--- /dev/null
+[Unit]
+Description = Trust Identity Protocol Server
+Before=freeradius.service
+
+[Service]
+EnvironmentFile=/etc/default/trust_router
+ExecStartPre=/bin/sh -c "/usr/bin/sqlite3 </usr/share/trust_router/schema.sql /var/lib/trust_router/keys"
+ExecStart=/usr/bin/tids ${ipaddr} ${gssname} ${hostname} /var/lib/trust_router/keys
+Restart=always
+StandardOutput=syslog
+StandardError=inherit
+User=trustrouter
+
+[Install]
+WantedBy=multi-user.target
#include <tr.h>
#include <tr_filter.h>
-#include <trust_router/tid.h>
+#include <tid_internal.h>
#include <tr_config.h>
#include <tr_comm.h>
#include <tr_idp.h>
static int tr_tids_req_handler (TIDS_INSTANCE *tids,
TID_REQ *orig_req,
- TID_RESP **resp,
+ TID_RESP *resp,
void *tr)
{
TIDC_INSTANCE *tidc = NULL;
int oaction = TR_FILTER_ACTION_REJECT;
int rc = 0;
- if ((!tids) || (!orig_req) || (!resp) || (!(*resp)) || (!tr)) {
+ if ((!tids) || (!orig_req) || (!resp) || (!tr)) {
fprintf(stderr, "tids_req_handler: Bad parameters\n");
return -1;
}
if (NULL == (aaa_servers = tr_idp_aaa_server_lookup((TR_INSTANCE *)tids->cookie,
orig_req->realm,
orig_req->comm))) {
- fprintf(stderr, "tr_tids_req_handler: No AAA Servers for realm %s.\n", orig_req->realm->buf);
+ fprintf(stderr, "tr_tids_req_handler: No AAA Servers for realm %s, defaulting.\n", orig_req->realm->buf);
+ if (NULL == (aaa_servers = tr_default_server_lookup ((TR_INSTANCE *)tids->cookie,
+ orig_req->comm))) {
+ fprintf(stderr, "tr_tids_req_handler: No default AAA servers, discarded.\n");
tids_send_err_response(tids, orig_req, "No path to AAA Server(s) for realm");
return -1;
- }
+ }
+ }
+
/* send a TID request to the AAA server(s), and get the answer(s) */
/* TBD -- Handle multiple servers */
exit(1);
}
- /* read and parse initial configuration */
- if (NULL == (jcfg = tr_read_config (n, cfg_files))) {
- fprintf (stderr, "Error reading or parsing configuration files, exiting.\n");
- exit(1);
- }
- if (TR_CFG_SUCCESS != tr_parse_config(tr, jcfg)) {
+ if (TR_CFG_SUCCESS != tr_parse_config(tr, cfg_files)) {
fprintf (stderr, "Error decoding configuration information, exiting.\n");
exit(1);
}
+%global optflags %{optflags} -Wno-parentheses
Name: trust_router
-Version: 1.2
+Version: 1.3.2
Release: 1%{?dist}
Summary: Moonshot Trust Router
BuildRequires: krb5-devel
BuildRequires: jansson-devel >= 2.4
-BuildRequires: sqlite-devel, openssl-devel
-Requires: moonshot-gss-eap
+BuildRequires: sqlite-devel, openssl-devel, libtalloc-devel
+Requires: moonshot-gss-eap, sqlite
%description
The trust router provides a mechanism for discovering the topology of
make install DESTDIR=$RPM_BUILD_ROOT
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
+# Install config files
+install -D -m 755 redhat/init $RPM_BUILD_ROOT/%{_initrddir}/trust_router
+install -D -m 640 redhat/trusts.cfg $RPM_BUILD_ROOT/%{_sysconfdir}/trust_router/trusts.cfg
+install -D -m 640 redhat/default-main.cfg $RPM_BUILD_ROOT/%{_sysconfdir}/trust_router/conf.d/default/main.cfg
+install -D -m 640 redhat/tr-test-main.cfg $RPM_BUILD_ROOT/%{_sysconfdir}/trust_router/conf.d/tr-test/main.cfg
+install -D -m 640 redhat/sysconfig $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/trust_router
+
+# Link shared config
+ln -s ../../trusts.cfg $RPM_BUILD_ROOT/%{_sysconfdir}/trust_router/conf.d/default/trusts.cfg
+ln -s ../../trusts.cfg $RPM_BUILD_ROOT/%{_sysconfdir}/trust_router/conf.d/tr-test/trusts.cfg
+
+# Install wrapper scripts
+install -D -m 755 redhat/tidc-wrapper $RPM_BUILD_ROOT/%{_bindir}/tidc-wrapper
+install -D -m 755 redhat/trust_router-wrapper $RPM_BUILD_ROOT/%{_bindir}/trust_router-wrapper
+
+# As we're building an RPM, we don't need the init scripts etc. in /usr/share
+rm -rf $RPM_BUILD_ROOT/%{_datadir}/trust_router/redhat
+
%clean
rm -rf $RPM_BUILD_ROOT
+%pre
+getent group trustrouter > /dev/null || groupadd -r trustrouter
+getent passwd trustrouter > /dev/null || useradd -r -g trustrouter -d /var/lib/trustrouter -s /sbin/nologin -c "GSS-EAP Trust Router service account" trustrouter
+exit 0
+
+
%post libs -p /sbin/ldconfig
%postun libs -p /sbin/ldconfig
+%post
+# Data directory
+test -d /var/lib/trust_router ||mkdir /var/lib/trust_router
+chown trustrouter:trustrouter /var/lib/trust_router
+sqlite3 </usr/share/trust_router/schema.sql /var/lib/trust_router/keys
+chown trustrouter:trustrouter /var/lib/trust_router/keys
+chmod 660 /var/lib/trust_router/keys
+
+# Log Directory
+test -d /var/log/trust_router ||mkdir /var/log/trust_router
+chown root:trustrouter /var/log/trust_router
+chmod 770 /var/log/trust_router
+
+
%files
%defattr(-,root,root,-)
%doc README
%{_bindir}/*
+%{_datadir}/trust_router/schema.sql
+#/lib/systemd/system/tids.service
+
+%{_initrddir}/trust_router
+
+%config(noreplace) %{_sysconfdir}/sysconfig/trust_router
+
+%dir %attr(755,root,trustrouter) %{_sysconfdir}/trust_router
+%dir %attr(755,root,trustrouter) %{_sysconfdir}/trust_router/conf.d/
+%dir %attr(755,root,trustrouter) %{_sysconfdir}/trust_router/conf.d/default
+%dir %attr(755,root,trustrouter) %{_sysconfdir}/trust_router/conf.d/tr-test
+
+%attr(640,root,trustrouter) %config(noreplace) %{_sysconfdir}/trust_router/trusts.cfg
+%attr(640,root,trustrouter) %config(noreplace) %{_sysconfdir}/trust_router/conf.d/default/main.cfg
+%attr(640,root,trustrouter) %config(noreplace) %{_sysconfdir}/trust_router/conf.d/tr-test/main.cfg
+%attr(640,root,trustrouter) %config(noreplace) %{_sysconfdir}/trust_router/conf.d/default/trusts.cfg
+%attr(640,root,trustrouter) %config(noreplace) %{_sysconfdir}/trust_router/conf.d/tr-test/trusts.cfg
%files libs
%defattr(-,root,root,-)