Completion of constraints code, not fully tested.
authorMargaret Wasserman <mrw@painless-security.com>
Fri, 14 Feb 2014 00:57:13 +0000 (19:57 -0500)
committerMargaret Wasserman <mrw@painless-security.com>
Fri, 14 Feb 2014 00:57:13 +0000 (19:57 -0500)
Makefile.am
common/tr_config.c
common/tr_constraint.c
common/tr_filter.c
include/tr_constraint.h
include/tr_filter.h
include/trust_router/tid.h
tr/portal.cfg
tr/tr_main.c

index c1c389f..e8233aa 100644 (file)
@@ -14,6 +14,7 @@ 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
 
@@ -39,14 +40,14 @@ libtr_tid_la_LDFLAGS = $(AM_LDFLAGS) -version-info 0 -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
+       include/trust_router/tr_versioning.h
 
 noinst_HEADERS = include/gsscon.h include/tr_config.h \
-include/tr_msg.h \
-include/tr.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/tr_constraint.h
 
 
 EXTRA_DIST = trust_router.spec
index d101d9b..4f90e16 100644 (file)
@@ -40,7 +40,7 @@
 #include <tr_config.h>
 #include <tr.h>
 #include <tr_filter.h>
-
+#include <tr_constraint.h>
 void tr_print_config (FILE *stream, TR_CFG *cfg) {
   fprintf(stream, "tr_print_config: Not yet implemented.\n");
   return;
@@ -109,17 +109,40 @@ static TR_CFG_RC tr_cfg_parse_internal (TR_INSTANCE *tr, json_t *jcfg) {
   }
 }
 
-static TR_CONSTRAINT *tr_cfg_parse_one_constraint (TR_INSTANCE *tr, const char *ctype, json_t *jdc, TR_CFG_RC *rc)
+static TR_CONSTRAINT *tr_cfg_parse_one_constraint (TR_INSTANCE *tr, char *ctype, json_t *jc, TR_CFG_RC *rc)
 {
+  TR_CONSTRAINT *cons;
+  int i;
+
+  if ((!tr) || (!ctype) || (!jc) || (!rc) ||
+      (!json_is_array(jc)) ||
+      (0 >= json_array_size(jc)) ||
+      (TR_MAX_CONST_MATCHES < json_array_size(jc)) ||
+      (!json_is_string(json_array_get(jc, 0)))) {
+    fprintf(stderr, "tr_cfg_parse_one_constraint: config error.\n");
+    *rc = TR_CFG_NOPARSE;
+    return NULL;
+  }
+
   if (NULL == (cons = malloc(sizeof(TR_CONSTRAINT)))) {
-    fprintf(stderr, "tr_cfg_parse_one_constraint: Out of memory.\n");
+    fprintf(stderr, "tr_cfg_parse_one_constraint: Out of memory (cons).\n");
     *rc = TR_CFG_NOMEM;
     return NULL;
   }
 
-  memset(filt, 0, sizeof(TR_FILTER));
+  memset(cons, 0, sizeof(TR_CONSTRAINT));
 
-  
+  if (NULL == (cons->type = tr_new_name(ctype))) {
+    fprintf(stderr, "tr_cfg_parse_one_constraint: Out of memory (type).\n");
+    *rc = TR_CFG_NOMEM;
+    return NULL;
+  }
+
+  for (i = 0; i < json_array_size(jc); i++) {
+    cons->matches[i] = tr_new_name((char *)(json_string_value(json_array_get(jc, i))));
+  }
+
+  return cons;
 }
 
 static TR_FILTER *tr_cfg_parse_one_filter (TR_INSTANCE *tr, json_t *jfilt, TR_CFG_RC *rc)
@@ -172,7 +195,7 @@ static TR_FILTER *tr_cfg_parse_one_filter (TR_INSTANCE *tr, json_t *jfilt, TR_CF
     tr_filter_free(filt);
     return NULL;
   }
-  
+
   /* For each filter line... */
   for (i = 0; i < json_array_size(jfls); i++) {
 
@@ -184,26 +207,6 @@ static TR_FILTER *tr_cfg_parse_one_filter (TR_INSTANCE *tr, json_t *jfilt, TR_CF
       return NULL;
     }
  
-    if ((NULL != (jrc = json_object_get(json_array_get(jfls, i), "realm_constraints"))) &&
-       (json_is_array(jrc)) &&
-       (0 != json_array_size(jrc)) &&
-       (TR_MAX_CONST_MATCHES >= json_array_size(jrc))) {
-      if (NULL == (filt->realm_cons = tr_cfg_parse_one_constraint(tr, "realm", jrc, rc)))
-       fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing realm constraint");
-      tr_filter_free(filt);
-      return NULL;
-    }
-
-    if ((NULL != (jdc = json_object_get(json_array_get(jfls, i), "domain_constraints"))) &&
-       (json_is_array(jdc)) &&
-       (0 != json_array_size(jdc)) &&
-       (TR_MAX_CONST_MATCHES >= json_array_size(jdc))) {
-      if (NULL == (filt->realm_cons = tr_cfg_parse_one_constraint(tr, "domain", jdc, rc)))
-       fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing domain constraint");
-      tr_filter_free(filt);
-      return NULL;
-    }
-
     if ((NULL == (jfspecs = json_object_get(json_array_get(jfls, i), "filter_specs"))) ||
        (!json_is_array(jfspecs)) ||
        (0 == json_array_size(jfspecs))) {
@@ -221,7 +224,7 @@ static TR_FILTER *tr_cfg_parse_one_filter (TR_INSTANCE *tr, json_t *jfilt, TR_CF
     }
 
     if (NULL == (filt->lines[i] = malloc(sizeof(TR_FLINE)))) {
-      fprintf(stderr, "tr_config_parse_one_filter: Out of memory.\n");
+      fprintf(stderr, "tr_config_parse_one_filter: Out of memory (fline).\n");
       *rc = TR_CFG_NOMEM;
       tr_filter_free(filt);
       return NULL;
@@ -241,7 +244,31 @@ static TR_FILTER *tr_cfg_parse_one_filter (TR_INSTANCE *tr, json_t *jfilt, TR_CF
       tr_filter_free(filt);
       return NULL;
     }
-      
+
+    if ((NULL != (jrc = json_object_get(json_array_get(jfls, i), "realm_constraints"))) &&
+       (json_is_array(jrc)) &&
+       (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))) {
+       fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing realm constraint");
+      tr_filter_free(filt);
+      return NULL;
+      }
+    }
+
+    if ((NULL != (jdc = json_object_get(json_array_get(jfls, i), "domain_constraints"))) &&
+       (json_is_array(jdc)) &&
+       (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))) {
+       fprintf(stderr, "tr_cfg_parse_one_filter: Error parsing domain constraint");
+      tr_filter_free(filt);
+      return NULL;
+      }
+    }
+
     /*For each filter spec within the filter line... */
     for (j = 0; j <json_array_size(jfspecs); j++) {
       
@@ -273,6 +300,7 @@ static TR_FILTER *tr_cfg_parse_one_filter (TR_INSTANCE *tr, json_t *jfilt, TR_CF
       }
     }
   }
+
   return filt;
 }
 
@@ -826,7 +854,7 @@ json_t *tr_read_config (int n, struct dirent **cfg_files) {
     }
   }
 
-  //  fprintf(stderr, "tr_read_config: Merged configuration complete:\n%s\n", json_dumps(jcfg, 0));
+  fprintf(stderr, "tr_read_config: Merged configuration complete:\n%s\n", json_dumps(jcfg, 0));
 
   return jcfg;
 }
index 0910d76..c6360ce 100644 (file)
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
-
 #include <jansson.h>
 
+#include <tr_filter.h>
+#include <tr_constraint.h>
+
+TR_CONSTRAINT_SET *tr_constraint_set_from_fline (TR_FLINE *fline)
+{
+  json_t *cset = NULL;
+
+  if (!fline)
+    return NULL;
+
+  if (fline->realm_cons)
+    tr_constraint_add_to_set(&cset, fline->realm_cons);
+  if (fline->domain_cons)
+    tr_constraint_add_to_set(&cset, fline->domain_cons);
+  
+   return cset;
+}
+
+/* A constraint set is represented in json as an array of constraint
+ * objects.  So, a constraint set (cset) that consists of one realm
+ * constraint and one domain constraint might look like:
+ *
+ *     {cset: [{domain: [a.com, b.co.uk]},
+ *             {realm: [c.net, d.org]}]}
+ */
+
+void tr_constraint_add_to_set (TR_CONSTRAINT_SET **cset, TR_CONSTRAINT *cons)
+{
+  json_t *jcons = NULL;
+  json_t *jmatches = NULL;
+  int i = 0;
+
+  if ((!cset) || (!cons))
+    return;
+
+  /* If we don't already have a json object, create one */
+  if (!(*cset))
+    *cset = json_array();
+
+  /* Create a json object representing cons */
+  jmatches = json_array();
+  jcons = json_object();
+
+  for (i = 0; ((i < TR_MAX_CONST_MATCHES) && (NULL != cons->matches[i])); i++) {
+    json_array_append_new(jmatches, json_string(cons->matches[i]->buf));
+  }
+
+  json_object_set_new(jcons, cons->type->buf, jmatches);
+  
+  /* Add the created object to the cset object */
+  json_array_append_new(*cset, jcons);
+} 
+
index 5b13e0e..4f782dc 100644 (file)
@@ -88,7 +88,14 @@ int tr_filter_process_rp_permitted (TR_NAME *rp_realm, TR_FILTER *rpp_filter, TR
          (rpp_filter->lines[i]->specs[j]) && 
          (tr_prefix_wildcard_match(rp_realm->buf, rpp_filter->lines[i]->specs[j]->match->buf))) {
        *out_action = rpp_filter->lines[i]->action;
-       *out_constraints = rpp_filter->lines[i]->constraints;
+       *out_constraints = in_constraints;
+       if (rpp_filter->lines[i]->realm_cons)
+         tr_constraint_add_to_set(out_constraints, 
+                                  rpp_filter->lines[i]->realm_cons);
+       if (rpp_filter->lines[i]->domain_cons)
+         tr_constraint_add_to_set(out_constraints, 
+                                  rpp_filter->lines[i]->domain_cons);
+
        return TR_FILTER_MATCH;
       }
     }
index 7245d33..d740a3a 100644 (file)
  *
  */
 
+#ifndef TR_CONSTRAINT_H
+#define TR_CONSTRAINT_H
+
+#include <trust_router/tr_name.h>
 #include <jansson.h>
 
-#define TR_MAX_CONST_MATCHES 24;
+#define TR_MAX_CONST_MATCHES 24
 
+typedef struct tr_fline TR_FLINE;
 typedef json_t TR_CONSTRAINT_SET;
 
-typedef tr_constraint {
-  TR_NAME type;
-  TR_NAME matches[TR_MAX_CONST_MATCHES];
+typedef struct tr_constraint {
+  TR_NAME *type;
+  TR_NAME *matches[TR_MAX_CONST_MATCHES];
 } TR_CONSTRAINT;
+
+TR_CONSTRAINT_SET *tr_constraint_set_from_fline (TR_FLINE *fline);
+void tr_constraint_add_to_set (TR_CONSTRAINT_SET **cs, TR_CONSTRAINT *c);
+
+#endif
index b391f64..2e4b10b 100644 (file)
@@ -63,8 +63,8 @@ typedef struct tr_fspec {
 typedef struct tr_fline {
   int action;
   TR_FSPEC *specs[TR_MAX_FILTER_SPECS];
-  TR_CONSTRAINT realm_cons;
-  TR_CONSTRAINT domain_cons;
+  TR_CONSTRAINT *realm_cons;
+  TR_CONSTRAINT *domain_cons;
 } TR_FLINE;
   
 typedef struct tr_filter {
index 2e5d4ee..ce2ad3d 100644 (file)
 
 #include <trust_router/tr_name.h>
 #include <trust_router/tr_versioning.h>
+#include <tr_constraint.h>
+
 #include <gssapi.h>
 
 #define TID_PORT       12309
 
-
-
 typedef enum tid_rc {
   TID_SUCCESS = 0,
   TID_ERROR
@@ -64,6 +64,7 @@ typedef struct tid_resp {
   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 */
@@ -84,6 +85,7 @@ struct tid_req {
   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;
index 5541fd4..0998e1f 100644 (file)
@@ -79,9 +79,7 @@
         "filter_lines": [
           {
             "action": "accept",
-            "domain_constraints": [
-
-            ],
+            "domain_constraints": ["*.exchange.ja.net"],
             "filter_specs": [
               {
                 "field": "rp_realm",
@@ -92,9 +90,7 @@
                 "match": "*.exchange.ja.net"
               }
             ],
-            "realm_constraints": [
-
-            ]
+            "realm_constraints": ["*.exchange.ja.net", "a.com"]
           }
         ],
         "type": "rp_permitted"
         "filter_lines": [
           {
             "action": "accept",
-            "domain_constraints": [
-
-            ],
+            "domain_constraints": ["*.bob.sr3.offcenter.org"],
             "filter_specs": [
               {
                 "field": "rp_realm",
                 "match": "*.sr3.offcenter.org"
               }
             ],
-            "realm_constraints": [
-
-            ]
+            "realm_constraints": ["*.sr3.offcenter.org" ]
           }
         ],
         "type": "rp_permitted"
index c1bf619..319ab33 100644 (file)
@@ -78,7 +78,6 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
   TID_REQ *fwd_req = NULL;
   TR_COMM *cfg_comm = NULL;
   TR_COMM *cfg_apc = NULL;
-  TR_CONSTRAINT_SET *ocons = NULL;
   int oaction = TR_FILTER_ACTION_REJECT;
   int rc = 0;
 
@@ -114,15 +113,12 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
     return -1;
   }
 
-  if ((TR_FILTER_NO_MATCH == tr_filter_process_rp_permitted(orig_req->rp_realm, ((TR_INSTANCE *)tr)->rp_gss->filter, NULL, &ocons, &oaction)) ||
+  if ((TR_FILTER_NO_MATCH == tr_filter_process_rp_permitted(orig_req->rp_realm, ((TR_INSTANCE *)tr)->rp_gss->filter, orig_req->cons, &fwd_req->cons, &oaction)) ||
       (TR_FILTER_ACTION_REJECT == oaction)) {
     fprintf(stderr, "tr_tids_req_handler: RP realm (%s) does not match RP Realm filter for GSS name\n", orig_req->rp_realm->buf);
     tids_send_err_response(tids, orig_req, "RP Realm filter error");
     return -1;
   }
-
-  /* TBD -- add constraints to request for further forwarding. */
-
   /* Check that the rp_realm and target_realm are members of the community in the request */
   if (NULL == (tr_find_comm_rp(cfg_comm, orig_req->rp_realm))) {
     fprintf(stderr, "tr_tids_req_hander: RP Realm (%s) not member of community (%s).\n", orig_req->rp_realm->buf, orig_req->comm->buf);