Peer organizations now parsed and added to peer table.
authorJennifer Richards <jennifer@painless-security.com>
Tue, 23 Aug 2016 21:12:51 +0000 (17:12 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Tue, 23 Aug 2016 21:12:51 +0000 (17:12 -0400)
This is feature completeness for initial Dynamic Trust Router
release, not yet debugged.

12 files changed:
Makefile.am
common/tr_config.c
common/tr_filter.c
common/tr_rp.c
include/tr_config.h
include/tr_rp.h
include/trp_internal.h
include/trp_ptable.h
tr/tr_main.c
tr/tr_trp.c
trp/trp_ptable.c
trp/trps.c

index 090034e..d509db5 100644 (file)
@@ -43,6 +43,7 @@ common/tr_comm.c \
 common/tr_filter.c \
 common/tr_rp.c \
 common/tr_mq.c \
+common/tr_gss.c \
 tr/tr.c \
 tr/tr_event.c \
 tr/tr_cfgwatch.c \
@@ -74,6 +75,7 @@ tid/tid_req.c \
 tid/tid_resp.c \
 common/tr_msg.c \
 common/tr_name.c \
+common/tr_gss.c \
 common/tr_idp.c \
 common/tr_apc.c \
 common/tr_comm.c \
@@ -86,6 +88,7 @@ trp_msgtst_LDADD =  $(GLIB_LIBS)
 
 trp_test_rtbl_test_SOURCES = trp/test/rtbl_test.c \
 common/tr_name.c \
+common/tr_gss.c \
 common/tr_debug.c \
 trp/trp_rtable.c
 
@@ -126,6 +129,7 @@ common/tr_filter.c \
 common/tr_constraint.c \
 common/tr_debug.c \
 common/tr_name.c \
+common/tr_gss.c \
 common/tr_apc.c \
 common/tr_comm.c \
 tid/tid_req.c \
index 0cebfbf..b733787 100644 (file)
 #include <tr_cfgwatch.h>
 #include <tr_comm.h>
 #include <tr_config.h>
+#include <tr_gss.h>
 #include <tr_debug.h>
 #include <tr_filter.h>
 #include <trust_router/tr_constraint.h>
 #include <tr_idp.h>
 #include <tr.h>
+#include <trust_router/trp.h>
 
 void tr_print_config (TR_CFG *cfg) {
   tr_notice("tr_print_config: Logging running trust router configuration.");
@@ -871,41 +873,58 @@ cleanup:
   return realms;
 }
 
-static TR_CFG_RC tr_cfg_parse_gss_names(TR_RP_CLIENT *client, json_t *jgss_names)
+static TR_GSS_NAMES *tr_cfg_parse_gss_names(TALLOC_CTX *mem_ctx, json_t *jgss_names, TR_CFG_RC *rc)
 {
+  TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+  TR_GSS_NAMES *gn=NULL;
   json_t *jname=NULL;
   int ii=0;
   TR_NAME *name=NULL;
 
-  if ((client==NULL) || (jgss_names==NULL)) {
+  if ((rc==NULL) || (jgss_names==NULL)) {
     tr_err("tr_cfg_parse_gss_names: Bad parameters.");
-    return TR_CFG_BAD_PARAMS;
+    *rc=TR_CFG_BAD_PARAMS;
+
   }
 
   if (!json_is_array(jgss_names)) {
     tr_err("tr_cfg_parse_gss_names: gss_names not an array.");
-    return TR_CFG_NOPARSE;
+    *rc=TR_CFG_NOPARSE;
+    goto cleanup;
   }
 
+  gn=tr_gss_names_new(tmp_ctx);
   for (ii=0; ii<json_array_size(jgss_names); ii++) {
     jname=json_array_get(jgss_names, ii);
     if (!json_is_string(jname)) {
       tr_err("tr_cfg_parse_gss_names: Encountered non-string gss name.");
-      return TR_CFG_NOPARSE;
+      *rc=TR_CFG_NOPARSE;
+      goto cleanup;
     }
+
     name=tr_new_name(json_string_value(jname));
     if (name==NULL) {
       tr_err("tr_cfg_parse_gss_names: Out of memory allocating gss name.");
-      return TR_CFG_NOMEM;
+      *rc=TR_CFG_NOMEM;
+      goto cleanup;
     }
-    if (tr_rp_client_add_gss_name(client, name)!=0) {
+
+    if (tr_gss_names_add(gn, name)!=0) {
       tr_free_name(name);
       tr_err("tr_cfg_parse_gss_names: Unable to add gss name to RP client.");
-      return TR_CFG_ERROR;
+      *rc=TR_CFG_ERROR;
+      goto cleanup;
     }
   }
 
-  return TR_CFG_SUCCESS;
+  talloc_steal(mem_ctx, gn);
+  *rc=TR_CFG_SUCCESS;
+
+ cleanup:
+  talloc_free(tmp_ctx);
+  if ((*rc!=TR_CFG_SUCCESS) && (gn!=NULL))
+    gn=NULL;
+  return gn;
 }
 
 /* parses rp client */
@@ -931,7 +950,8 @@ static TR_RP_CLIENT *tr_cfg_parse_one_rp_client(TALLOC_CTX *mem_ctx, json_t *jre
     goto cleanup;
   }
 
-  call_rc=tr_cfg_parse_gss_names(client, json_object_get(jrealm, "gss_names"));
+  client->gss_names=tr_cfg_parse_gss_names(client, json_object_get(jrealm, "gss_names"), &call_rc);
+
   if (call_rc!=TR_CFG_SUCCESS) {
     tr_err("tr_cfg_parse_one_rp_client: could not parse gss_names.");
     *rc=TR_CFG_NOPARSE;
@@ -1128,9 +1148,6 @@ cleanup:
     if (new_idp_realms!=NULL) {
       trc->idp_realms=tr_idp_realm_add(trc->idp_realms, new_idp_realms); /* fixes talloc contexts except for head*/
       talloc_steal(trc, trc->idp_realms); /* make sure the head is in the right context */
-#if 0
-      trc->comms=tr_cfg_comm_idp_update(trc, trc->comms, new_idp_realms, &rc); /* put realm info in community table */
-#endif
     }
 
     if (new_rp_clients!=NULL) {
@@ -1167,6 +1184,94 @@ static TR_CFG_RC tr_cfg_parse_local_orgs(TR_CFG *trc, json_t *jcfg)
 
   return TR_CFG_SUCCESS;
 }
+
+static TR_CFG_RC tr_cfg_parse_one_peer_org(TR_CFG *trc, json_t *jporg)
+{
+  TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+  json_t *jhost=NULL;
+  json_t *jport=NULL;
+  json_t *jgss=NULL;
+  TRP_PEER *new_peer=NULL;
+  TR_GSS_NAMES *names=NULL;
+  TR_CFG_RC rc=TR_CFG_ERROR;
+
+  jhost=json_object_get(jporg, "hostname");
+  jport=json_object_get(jporg, "port");
+  jgss=json_object_get(jporg, "gss_names");
+
+  if ((jhost==NULL) || (!json_is_string(jhost))) {
+    tr_err("tr_cfg_parse_one_peer_org: hostname not specified or not a string.");
+    rc=TR_CFG_NOPARSE;
+    goto cleanup;
+  }
+
+  if ((jport!=NULL) && (!json_is_number(jport))) {
+    /* note that not specifying the port is allowed, but if set it must be a number */
+    tr_err("tr_cfg_parse_one_peer_org: port is not a number.");
+    rc=TR_CFG_NOPARSE;
+    goto cleanup;
+  }
+  
+  if ((jgss==NULL) || (!json_is_array(jgss))) {
+    tr_err("tr_cfg_parse_one_peer_org: gss_names not specified or not an array.");
+    rc=TR_CFG_NOPARSE;
+    goto cleanup;
+  }
+
+  new_peer=trp_peer_new(tmp_ctx);
+  if (new_peer==NULL) {
+    tr_err("tr_cfg_parse_one_peer_org: could not allocate new peer.");
+    rc=TR_CFG_NOMEM;
+    goto cleanup;
+  }
+
+  trp_peer_set_server(new_peer, json_string_value(jhost));
+  if (jport==NULL)
+    trp_peer_set_port(new_peer, TRP_PORT);
+  else
+    trp_peer_set_port(new_peer, json_integer_value(jport));
+
+  names=tr_cfg_parse_gss_names(tmp_ctx, jgss, &rc);
+  if (rc!=TR_CFG_SUCCESS) {
+    tr_err("tr_cfg_parse_one_peer_org: unable to parse gss names.");
+    rc=TR_CFG_NOPARSE;
+    goto cleanup;
+  }
+  trp_peer_set_gss_names(new_peer, names);
+
+  /* success! */
+  trp_ptable_add(trc->peers, new_peer);
+  rc=TR_CFG_SUCCESS;
+
+ cleanup:
+  talloc_free(tmp_ctx);
+  return rc;
+}
+
+/* Parse peer organizations, if present. Returns success if there are none. */
+static TR_CFG_RC tr_cfg_parse_peer_orgs(TR_CFG *trc, json_t *jcfg)
+{
+  json_t *jpeerorgs=NULL;
+  int ii=0;
+
+  jpeerorgs=json_object_get(jcfg, "peer_organizations");
+  if (jpeerorgs==NULL)
+    return TR_CFG_SUCCESS;
+
+  if (!json_is_array(jpeerorgs)) {
+    tr_err("tr_cfg_parse_peer_orgs: peer_organizations is not an array.");
+    return TR_CFG_NOPARSE;
+  }
+
+  for (ii=0; ii<json_array_size(jpeerorgs); ii++) {
+    if (tr_cfg_parse_one_peer_org(trc, json_array_get(jpeerorgs, ii))!=TR_CFG_SUCCESS) {
+      tr_err("tr_cfg_parse_peer_orgs: error parsing peer_organization %d.", ii+1);
+      return TR_CFG_NOPARSE;
+    }
+  }
+
+  return TR_CFG_SUCCESS;
+}
              
 static TR_CFG_RC tr_cfg_parse_default_servers (TR_CFG *trc, json_t *jcfg) 
 {
@@ -1461,18 +1566,9 @@ TR_CFG_RC tr_cfg_parse_one_config_file(TR_CFG *cfg, const char *file_with_path)
     }
   }
 
-  /* TODO: parse using the new functions */
-#if 0
-  if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(cfg, jcfg)) ||
-      (TR_CFG_SUCCESS != tr_cfg_parse_rp_clients(cfg, jcfg)) ||
-      (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(cfg, jcfg)) ||
-      (TR_CFG_SUCCESS != tr_cfg_parse_default_servers(cfg, jcfg)) ||
-      (TR_CFG_SUCCESS != tr_cfg_parse_comms(cfg, jcfg))) {
-
-  }
-#endif
   if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(cfg, jcfg)) ||
       (TR_CFG_SUCCESS != tr_cfg_parse_local_orgs(cfg, jcfg)) ||
+      (TR_CFG_SUCCESS != tr_cfg_parse_peer_orgs(cfg, jcfg)) ||
       (TR_CFG_SUCCESS != tr_cfg_parse_default_servers(cfg, jcfg)) ||
       (TR_CFG_SUCCESS != tr_cfg_parse_comms(cfg, jcfg)))
     return TR_CFG_ERROR;
@@ -1501,6 +1597,8 @@ TR_CFG_RC tr_parse_config(TR_CFG_MGR *cfg_mgr, const char *config_dir, int n, st
     goto cleanup;
   }
 
+  cfg_mgr->new->peers=trp_ptable_new(cfg_mgr);
+
   /* Parse configuration information from each config file */
   for (ii=0; ii<n; ii++) {
     file_with_path=join_paths(tmp_ctx, config_dir, cfg_files[ii]->d_name); /* must free result with talloc_free */
@@ -1558,7 +1656,6 @@ TR_IDP_REALM *tr_cfg_find_idp (TR_CFG *tr_cfg, TR_NAME *idp_id, TR_CFG_RC *rc)
 TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *tr_cfg, TR_NAME *rp_gss, TR_CFG_RC *rc)
 {
   TR_RP_CLIENT *cfg_rp;
-  int i;
 
   if ((!tr_cfg) || (!rp_gss)) {
     if (rc)
@@ -1567,11 +1664,9 @@ TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *tr_cfg, TR_NAME *rp_gss, TR_CFG_RC *rc)
   }
 
   for (cfg_rp = tr_cfg->rp_clients; NULL != cfg_rp; cfg_rp = cfg_rp->next) {
-    for (i = 0; i < TR_MAX_GSS_NAMES; i++) {
-      if (!tr_name_cmp (rp_gss, cfg_rp->gss_names[i])) {
-        tr_debug("tr_cfg_find_rp: Found %s.", rp_gss->buf);
-        return cfg_rp;
-      }
+    if (tr_gss_names_matches(cfg_rp->gss_names, rp_gss)) {
+      tr_debug("tr_cfg_find_rp: Found %s.", rp_gss->buf);
+      return cfg_rp;
     }
   }
   /* if we didn't find one, return NULL */ 
index cc59dd0..65ee1f9 100644 (file)
@@ -126,13 +126,14 @@ int tr_fspec_add_match(TR_FSPEC *fspec, TR_NAME *match)
     return -1; /* no space left */
 }
 
-/* returns 1 if the spec exactly matches */
+/* returns 1 if the spec matches */
 int tr_fspec_matches(TR_FSPEC *fspec, TR_NAME *name)
 {
   int ii=0;
 
   for (ii=0; ii<TR_MAX_FILTER_MATCHES; ii++) {
-    if (0!=tr_prefix_wildcard_match(name->buf, fspec->match[ii]->buf))
+    if ((fspec->match[ii]!=NULL) &&
+        (0!=tr_prefix_wildcard_match(name->buf, fspec->match[ii]->buf)))
       return 1;
   }
   return 0;
index 4196d3d..96c7254 100644 (file)
 
 #include <tr.h>
 #include <trust_router/tr_name.h>
+#include <tr_gss.h>
 #include <tr_config.h>
 #include <tr_rp.h>
 #include <tr_debug.h>
 
 static int tr_rp_client_destructor(void *obj)
 {
-  TR_RP_CLIENT *client=talloc_get_type_abort(obj, TR_RP_CLIENT);
-  int ii=0;
-
-  for (ii=0; ii<TR_MAX_GSS_NAMES; ii++) {
-    if (client->gss_names[ii]!=NULL)
-      tr_free_name(client->gss_names[ii]);
-  }
   return 0;
 }
 
 TR_RP_CLIENT *tr_rp_client_new(TALLOC_CTX *mem_ctx)
 {
   TR_RP_CLIENT *client=talloc(mem_ctx, TR_RP_CLIENT);
-  int ii=0;
 
   if (client!=NULL) {
     client->next=NULL;
     client->comm_next=NULL;
-    for (ii=0; ii<TR_MAX_GSS_NAMES; ii++)
-      client->gss_names[ii]=NULL;
+    client->gss_names=NULL;
     client->filter=NULL;
     talloc_set_destructor((void *)client, tr_rp_client_destructor);
   }
@@ -100,14 +92,7 @@ TR_RP_CLIENT *tr_rp_client_add(TR_RP_CLIENT *clients, TR_RP_CLIENT *new)
 
 int tr_rp_client_add_gss_name(TR_RP_CLIENT *rp_client, TR_NAME *gss_name)
 {
-  int ii=0;
-  for (ii=0; ii<TR_MAX_GSS_NAMES; ii++) {
-    if (NULL==rp_client->gss_names[ii]) {
-      rp_client->gss_names[ii]=gss_name;
-      return 0; /* success */
-    }
-  }
-  return -1; /* error */
+  return tr_gss_names_add(rp_client->gss_names, gss_name);
 }
 
 int tr_rp_client_set_filter(TR_RP_CLIENT *client, TR_FILTER *filt)
@@ -122,7 +107,6 @@ int tr_rp_client_set_filter(TR_RP_CLIENT *client, TR_FILTER *filt)
 TR_RP_CLIENT *tr_rp_client_lookup(TR_RP_CLIENT *rp_clients, TR_NAME *gss_name)
 {
   TR_RP_CLIENT *rp = NULL;
-  int i = 0;
 
   if ((!rp_clients) || (!gss_name)) {
     tr_debug("tr_rp_client_lookup: Bad parameters.");
@@ -130,14 +114,11 @@ TR_RP_CLIENT *tr_rp_client_lookup(TR_RP_CLIENT *rp_clients, TR_NAME *gss_name)
   }
 
   for (rp = rp_clients; NULL != rp; rp = rp->next) {
-    for (i = 0; ((i < TR_MAX_GSS_NAMES) && (NULL != (rp->gss_names[i]))); i++) {
-       if (!tr_name_cmp(gss_name, rp->gss_names[i])) {
-       return rp;
-      }
-    }
+    if (tr_gss_names_matches(rp->gss_names, gss_name))
+      return rp;
   } 
   return NULL;
- }
+}
 
 /* talloc note: lists of idp realms should be assembled using
  * tr_idp_realm_add(). This will put all of the elements in the
index 20f0365..8bd9e5b 100644 (file)
@@ -45,6 +45,7 @@
 #include <tr_comm.h>
 #include <tr_rp.h>
 #include <tr_idp.h>
+#include <trp_ptable.h>
 #include <trp_internal.h>
 
 #define TR_DEFAULT_MAX_TREE_DEPTH 12
@@ -84,6 +85,7 @@ 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 */
+  TRP_PTABLE *peers; /* TRP peer table */
   TR_COMM *comms;                      /* locally-known communities */
   TR_AAA_SERVER *default_servers;      /* default server list */
   /* TBD -- Global Filters */
index c991ff7..9db8c15 100644 (file)
 
 #include <talloc.h>
 
+#include <tr_gss.h>
 #include <tr_filter.h>
 
-#define TR_MAX_GSS_NAMES 5
-
 typedef struct tr_rp_client {
   struct tr_rp_client *next;
   struct tr_rp_client *comm_next;
-  TR_NAME *gss_names[TR_MAX_GSS_NAMES];
+  TR_GSS_NAMES *gss_names;
   TR_FILTER *filter;
 } TR_RP_CLIENT;
 
index ca870c1..c6828f6 100644 (file)
@@ -163,6 +163,7 @@ TRP_RC trpc_send_msg(TRPC_INSTANCE *trpc, const char *msg_content);
 
 TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx);
 void trps_free (TRPS_INSTANCE *trps);
+void trps_set_ptable(TRPS_INSTANCE *trps, TRP_PTABLE *ptable);
 TRP_RC trps_init_rtable(TRPS_INSTANCE *trps);
 void trps_clear_rtable(TRPS_INSTANCE *trps);
 void trps_set_connect_interval(TRPS_INSTANCE *trps, unsigned int interval);
index 6881ee8..ca022ad 100644 (file)
@@ -5,7 +5,8 @@
 #include <talloc.h>
 
 #include <trust_router/tr_name.h>
-#include <trp_internal.h>
+#include <tr_gss.h>
+#include <trust_router/trp.h>
 
 typedef enum trp_peer_conn_status {
   PEER_DISCONNECTED=0,
@@ -16,7 +17,7 @@ typedef struct trp_peer TRP_PEER;
 struct trp_peer {
   TRP_PEER *next; /* for making a linked list */
   char *server;
-  TR_NAME *gssname;
+  TR_GSS_NAMES *gss_names;
   TR_NAME *servicename;
   unsigned int port;
   unsigned int linkcost;
@@ -38,7 +39,7 @@ TRP_PTABLE *trp_ptable_new(TALLOC_CTX *memctx);
 void trp_ptable_free(TRP_PTABLE *ptbl);
 TRP_RC trp_ptable_add(TRP_PTABLE *ptbl, TRP_PEER *newpeer);
 TRP_RC trp_ptable_remove(TRP_PTABLE *ptbl, TRP_PEER *peer);
-TRP_PEER *trp_ptable_find_gssname(TRP_PTABLE *ptbl, TR_NAME *gssname);
+TRP_PEER *trp_ptable_find_gss_name(TRP_PTABLE *ptbl, TR_NAME *gssname);
 TRP_PEER *trp_ptable_find_servicename(TRP_PTABLE *ptbl, TR_NAME *servicename);
 char *trp_ptable_to_str(TALLOC_CTX *memctx, TRP_PTABLE *ptbl, const char *sep, const char *lineterm);
 
@@ -49,11 +50,13 @@ void trp_ptable_iter_free(TRP_PTABLE_ITER *iter);
 
 TRP_PEER *trp_peer_new(TALLOC_CTX *memctx);
 void trp_peer_free(TRP_PEER *peer);
+TR_NAME *trp_peer_get_label(TRP_PEER *peer);
+TR_NAME *trp_peer_dup_label(TRP_PEER *peer);
 char *trp_peer_get_server(TRP_PEER *peer);
-void trp_peer_set_server(TRP_PEER *peer, char *server);
-void trp_peer_set_gssname(TRP_PEER *peer, TR_NAME *gssname);
-TR_NAME *trp_peer_get_gssname(TRP_PEER *peer);
-TR_NAME *trp_peer_dup_gssname(TRP_PEER *peer);
+void trp_peer_set_server(TRP_PEER *peer, const char *server);
+void trp_peer_add_gss_name(TRP_PEER *peer, TR_NAME *gssname);
+void trp_peer_set_gss_names(TRP_PEER *peer, TR_GSS_NAMES *gss_names);
+TR_GSS_NAMES *trp_peer_get_gss_names(TRP_PEER *peer);
 TR_NAME *trp_peer_get_servicename(TRP_PEER *peer);
 TR_NAME *trp_peer_dup_servicename(TRP_PEER *peer);
 unsigned int trp_peer_get_port(TRP_PEER *peer);
index 15c17a1..e18945c 100644 (file)
@@ -292,7 +292,7 @@ int main(int argc, char *argv[])
       return 1;
     }
     trp_peer_set_server(hc_peer, "epsilon.vmnet");
-    trp_peer_set_gssname(hc_peer, tr_new_name("tr-epsilon-vmnet@apc.painless-security.com"));
+    trp_peer_add_gss_name(hc_peer, tr_new_name("tr-epsilon-vmnet@apc.painless-security.com"));
     trp_peer_set_conn_status_cb(hc_peer, tr_peer_status_change, (void *)(tr->trps));
     switch (tr->trps->port) {
     case 10000:
@@ -316,7 +316,7 @@ int main(int argc, char *argv[])
       return 1;
     }
     trp_peer_set_server(hc_peer, "epsilon-trpc.vmnet");
-    trp_peer_set_gssname(hc_peer, tr_new_name("trpc@apc.painless-security.com"));
+    trp_peer_add_gss_name(hc_peer, tr_new_name("trpc@apc.painless-security.com"));
     trp_peer_set_port(hc_peer, 10002); /* not really used */
     if (TRP_SUCCESS != trps_add_peer(tr->trps, hc_peer)) {
       tr_crit("Unable to add peer.");
index 0d87439..ab391a5 100644 (file)
@@ -757,8 +757,9 @@ TRP_RC tr_connect_to_peers(TRPS_INSTANCE *trps, struct event *ev)
        peer=trp_ptable_iter_next(iter))
   {
     if (trps_find_trpc(trps, peer)==NULL) {
+      TR_NAME *label=trp_peer_get_label(peer);
       tr_debug("tr_connect_to_peers: %.*s missing connection.",
-               trp_peer_get_gssname(peer)->len, trp_peer_get_gssname(peer)->buf);
+               label->len, label->buf);
       /* has it been long enough since we last tried? */
       if (tr_conn_attempt_due(trps, peer, &curtime)) {
         trp_peer_set_last_conn_attempt(peer, &curtime); /* we are trying again now */
@@ -795,6 +796,7 @@ void tr_config_changed(TR_CFG *new_cfg, void *cookie)
   trps_set_connect_interval(trps, new_cfg->internal->trp_connect_interval);
   trps_set_update_interval(trps, new_cfg->internal->trp_update_interval);
   trps_set_sweep_interval(trps, new_cfg->internal->trp_sweep_interval);
+  trps_set_ptable(trps, new_cfg->peers);
   trps_clear_rtable(trps); /* should we do this every time??? */
   tr_add_local_routes(trps, new_cfg); /* should we do this every time??? */
   trps_update_active_routes(trps); /* find new routes */
index 14a2509..53963e8 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <trust_router/tr_name.h>
 #include <trp_internal.h>
+#include <tr_gss.h>
 #include <trp_ptable.h>
 #include <tr_debug.h>
 
@@ -11,8 +12,6 @@ static int trp_peer_destructor(void *object)
   TRP_PEER *peer=talloc_get_type_abort(object, TRP_PEER);
   if (peer->servicename!=NULL)
     tr_free_name(peer->servicename);
-  if (peer->gssname!=NULL)
-    tr_free_name(peer->gssname);
   return 0;
 }
 TRP_PEER *trp_peer_new(TALLOC_CTX *memctx)
@@ -22,7 +21,7 @@ TRP_PEER *trp_peer_new(TALLOC_CTX *memctx)
     peer->next=NULL;
     peer->server=NULL;
     peer->servicename=NULL;
-    peer->gssname=NULL;
+    peer->gss_names=NULL;
     peer->port=0;
     peer->linkcost=TRP_LINKCOST_DEFAULT;
     peer->last_conn_attempt=(struct timespec){0,0};
@@ -48,6 +47,29 @@ static TRP_PEER *trp_peer_tail(TRP_PEER *peer)
   return peer;
 }
 
+
+/* Get a name that identifies this peer for display to the user, etc. 
+ * Do not modify or free the label. */
+TR_NAME *trp_peer_get_label(TRP_PEER *peer)
+{
+  TR_GSS_NAMES_ITER *iter=tr_gss_names_iter_new(NULL);
+  TR_NAME *name=NULL;
+
+  /* for now, use the first gss name */
+  if (iter!=NULL) {
+    name=tr_gss_names_iter_first(iter, peer->gss_names);
+    talloc_free(iter);
+  }
+  return name;
+}
+
+/* Get a name that identifies this peer for display to the user, etc. 
+ * Makes a copy, caller is responsible for freeing.  */
+TR_NAME *trp_peer_dup_label(TRP_PEER *peer)
+{
+  return tr_dup_name(trp_peer_get_label(peer));;
+}
+
 char *trp_peer_get_server(TRP_PEER *peer)
 {
   return peer->server;
@@ -70,28 +92,33 @@ static void trp_peer_set_servicename(TRP_PEER *peer, const char *server)
   }
 }
 
-/* copies input; on error, peer->gssname will be null */
-void trp_peer_set_server(TRP_PEER *peer, char *server)
+/* copies input; on error, peer->servicename will be null */
+void trp_peer_set_server(TRP_PEER *peer, const char *server)
 {
   peer->server=talloc_strdup(peer, server); /* will be null on error */
   trp_peer_set_servicename(peer, server);
 }
 
-void trp_peer_set_gssname(TRP_PEER *peer, TR_NAME *gssname)
+void trp_peer_add_gss_name(TRP_PEER *peer, TR_NAME *gss_name)
 {
-  peer->gssname=gssname;
+  if (peer->gss_names==NULL)
+    trp_peer_set_gss_names(peer, tr_gss_names_new(peer));
+  tr_gss_names_add(peer->gss_names, gss_name);
 }
 
-/* get the peer gssname, caller must not free the result */
-TR_NAME *trp_peer_get_gssname(TRP_PEER *peer)
+void trp_peer_set_gss_names(TRP_PEER *peer, TR_GSS_NAMES *gss_names)
 {
-  return peer->gssname;
+  if (peer->gss_names!=NULL)
+    talloc_free(peer->gss_names);
+
+  peer->gss_names=gss_names;
+  talloc_steal(peer, gss_names);
 }
 
-/* get a copy of the peer gssname, caller must free via tr_free_name() */
-TR_NAME *trp_peer_dup_gssname(TRP_PEER *peer)
+/* get the peer gss_names, caller must not free the result */
+TR_GSS_NAMES *trp_peer_get_gss_names(TRP_PEER *peer)
 {
-  return tr_dup_name(peer->gssname);
+  return peer->gss_names;
 }
 
 /* get the service name (i.e., gssname we see when we connect to this peer) */
@@ -162,10 +189,11 @@ TRP_PTABLE *trp_ptable_new(TALLOC_CTX *memctx)
 
 void trp_peer_set_outgoing_status(TRP_PEER *peer, TRP_PEER_CONN_STATUS status)
 {
+  TR_NAME *peer_label=trp_peer_get_label(peer);
   int was_connected=trp_peer_is_connected(peer);
   peer->outgoing_status=status;
   tr_debug("trp_peer_set_outgoing_status: %s: status=%d peer connected was %d now %d.",
-           trp_peer_get_gssname(peer)->buf, status, was_connected, trp_peer_is_connected(peer));
+           peer_label->buf, status, was_connected, trp_peer_is_connected(peer));
   if ((trp_peer_is_connected(peer) != was_connected) && (peer->conn_status_cb!=NULL))
     peer->conn_status_cb(peer, peer->conn_status_cookie);
 }
@@ -177,10 +205,11 @@ TRP_PEER_CONN_STATUS trp_peer_get_outgoing_status(TRP_PEER *peer)
 
 void trp_peer_set_incoming_status(TRP_PEER *peer, TRP_PEER_CONN_STATUS status)
 {
+  TR_NAME *peer_label=trp_peer_get_label(peer);
   int was_connected=trp_peer_is_connected(peer);
   peer->incoming_status=status;
   tr_debug("trp_peer_set_incoming_status: %s: status=%d peer connected was %d now %d.",
-           trp_peer_get_gssname(peer)->buf, status, was_connected, trp_peer_is_connected(peer));
+           peer_label->buf, status, was_connected, trp_peer_is_connected(peer));
   if ((trp_peer_is_connected(peer) != was_connected) && (peer->conn_status_cb!=NULL))
     peer->conn_status_cb(peer, peer->conn_status_cookie);
 }
@@ -202,12 +231,12 @@ void trp_ptable_free(TRP_PTABLE *ptbl)
 
 TRP_RC trp_ptable_add(TRP_PTABLE *ptbl, TRP_PEER *newpeer)
 {
-  if (ptbl->head==NULL) {
+  if (ptbl->head==NULL)
     ptbl->head=newpeer;
-  } else {
+  else
     trp_peer_tail(ptbl->head)->next=newpeer;
-    talloc_steal(ptbl, newpeer);
-  }
+
+  talloc_steal(ptbl, newpeer);
   return TRP_SUCCESS;
 }
 
@@ -236,10 +265,10 @@ TRP_RC trp_ptable_remove(TRP_PTABLE *ptbl, TRP_PEER *peer)
   return TRP_ERROR;
 }
 
-TRP_PEER *trp_ptable_find_gssname(TRP_PTABLE *ptbl, TR_NAME *gssname)
+TRP_PEER *trp_ptable_find_gss_name(TRP_PTABLE *ptbl, TR_NAME *gssname)
 {
   TRP_PEER *cur=ptbl->head;
-  while ((cur!=NULL) && (0 != tr_name_cmp(trp_peer_get_gssname(cur), gssname)))
+  while ((cur!=NULL) && (!tr_gss_names_matches(trp_peer_get_gss_names(cur), gssname)))
     cur=cur->next;
   return cur;
 }
@@ -291,13 +320,17 @@ TRP_PTABLE_ITER *trp_ptable_iter_new(TALLOC_CTX *mem_ctx)
 
 TRP_PEER *trp_ptable_iter_first(TRP_PTABLE_ITER *iter, TRP_PTABLE *ptbl)
 {
-  *iter=ptbl->head;
+  if (ptbl==NULL)
+    *iter=NULL;
+  else
+    *iter=ptbl->head;
   return *iter;
 }
 
 TRP_PEER *trp_ptable_iter_next(TRP_PTABLE_ITER *iter)
 {
-  *iter=(*iter)->next;
+  if (*iter!=NULL)
+    *iter=(*iter)->next;
   return *iter;
 }
 
index 1997c54..7c8f6ac 100644 (file)
@@ -8,6 +8,7 @@
 #include <tr_rp.h>
 #include <trust_router/tr_name.h>
 #include <trp_internal.h>
+#include <tr_gss.h>
 #include <trp_ptable.h>
 #include <trp_rtable.h>
 #include <tr_debug.h>
@@ -32,6 +33,7 @@ TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx)
     trps->trpc=NULL;
     trps->update_interval=(struct timeval){0,0};
     trps->sweep_interval=(struct timeval){0,0};
+    trps->ptable=NULL;
 
     trps->mq=tr_mq_new(trps);
     if (trps->mq==NULL) {
@@ -40,13 +42,6 @@ TRPS_INSTANCE *trps_new (TALLOC_CTX *mem_ctx)
       return NULL;
     }
 
-    trps->ptable=trp_ptable_new(trps);
-    if (trps->ptable==NULL) {
-      /* failed to allocate ptable */
-      talloc_free(trps);
-      return NULL;
-    }
-
     trps->rtable=NULL;
     if (trps_init_rtable(trps) != TRP_SUCCESS) {
       /* failed to allocate rtable */
@@ -128,15 +123,22 @@ void trps_set_sweep_interval(TRPS_INSTANCE *trps, unsigned int interval)
   trps->sweep_interval.tv_usec=0;
 }
 
+void trps_set_ptable(TRPS_INSTANCE *trps, TRP_PTABLE *ptable)
+{
+  if (trps->ptable!=NULL)
+    trp_ptable_free(trps->ptable);
+  trps->ptable=ptable;
+}
+
 TRPC_INSTANCE *trps_find_trpc(TRPS_INSTANCE *trps, TRP_PEER *peer)
 {
   TRPC_INSTANCE *cur=NULL;
   TR_NAME *name=NULL;
-  TR_NAME *peer_gssname=trp_peer_get_gssname(peer);
+  TR_GSS_NAMES *peer_gssnames=trp_peer_get_gss_names(peer);
 
   for (cur=trps->trpc; cur!=NULL; cur=trpc_get_next(cur)) {
     name=trpc_get_gssname(cur);
-    if ((name!=NULL) && (0==tr_name_cmp(peer_gssname, name))) {
+    if ((name!=NULL) && (tr_gss_names_matches(peer_gssnames, name))) {
       break;
     }
   }
@@ -898,7 +900,7 @@ static TRP_INFOREC *trps_route_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *tr
 
 /* all routes to a single peer, unless comm/realm are specified (both or neither must be NULL) */
 static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps,
-                                   TR_NAME *peer_gssname,
+                                   TRP_PEER *peer,
                                    TRP_UPDATE_TYPE update_type,
                                    TR_NAME *comm,
                                    TR_NAME *realm)
@@ -911,20 +913,20 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps,
   size_t n_updates=0, ii=0;
   char *encoded=NULL;
   TRP_RC rc=TRP_ERROR;
-  TRP_PEER *peer=trps_get_peer_by_gssname(trps, peer_gssname);
+  TR_NAME *peer_label=trp_peer_get_label(peer);
 
   switch (update_type) {
   case TRP_UPDATE_TRIGGERED:
     tr_debug("trps_update_one_peer: preparing triggered route update for %.*s",
-             peer_gssname->len, peer_gssname->buf);
+             peer_label->len, peer_label->buf);
     break;
   case TRP_UPDATE_SCHEDULED:
     tr_debug("trps_update_one_peer: preparing scheduled route update for %.*s",
-             peer_gssname->len, peer_gssname->buf);
+             peer_label->len, peer_label->buf);
     break;
   case TRP_UPDATE_REQUESTED:
     tr_debug("trps_update_one_peer: preparing requested route update for %.*s",
-             peer_gssname->len, peer_gssname->buf);
+             peer_label->len, peer_label->buf);
   }
 
   /* do not fill in peer, recipient does that */
@@ -932,7 +934,7 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps,
     /* do all realms */
     update_list=trps_select_updates_for_peer(tmp_ctx,
                                              trps,
-                                             peer_gssname,
+                                             peer_label,
                                              update_type==TRP_UPDATE_TRIGGERED,
                                             &n_updates);
   } else if ((comm!=NULL) && (realm!=NULL)) {
@@ -943,7 +945,7 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps,
       rc=TRP_NOMEM;
       goto cleanup;
     }
-    *update_list=trps_select_realm_update(trps, comm, realm, peer_gssname);
+    *update_list=trps_select_realm_update(trps, comm, realm, peer_label);
     if (*update_list==NULL) {
       /* we have no actual update to send back, MUST send a retraction */
       tr_debug("trps_update_one_peer: community/realm without route requested, sending mandatory retraction.");
@@ -1011,6 +1013,9 @@ TRP_RC trps_update(TRPS_INSTANCE *trps, TRP_UPDATE_TYPE update_type)
   TRP_PEER *peer=NULL;
   TRP_RC rc=TRP_SUCCESS;
 
+  if (trps->ptable==NULL)
+    return TRP_SUCCESS; /* no peers, nothing to do */
+
   if (iter==NULL) {
     tr_err("trps_update: failed to allocate peer table iterator.");
     talloc_free(tmp_ctx);
@@ -1022,12 +1027,12 @@ TRP_RC trps_update(TRPS_INSTANCE *trps, TRP_UPDATE_TYPE update_type)
        peer=trp_ptable_iter_next(iter))
   {
     if (!trps_peer_connected(trps, peer)) {
-      TR_NAME *peer_gssname=trp_peer_get_gssname(peer);
+      TR_NAME *peer_label=trp_peer_get_label(peer);
       tr_debug("trps_update: no TRP connection to %.*s, skipping.",
-               peer_gssname->len, peer_gssname->buf);
+               peer_label->len, peer_label->buf);
       continue;
     }
-    rc=trps_update_one_peer(trps, trp_peer_get_gssname(peer), update_type, NULL, NULL);
+    rc=trps_update_one_peer(trps, peer, update_type, NULL, NULL);
   }
   
   trp_ptable_iter_free(iter);
@@ -1045,16 +1050,27 @@ TRP_RC trps_add_route(TRPS_INSTANCE *trps, TRP_ROUTE *route)
 /* steals the peer object */
 TRP_RC trps_add_peer(TRPS_INSTANCE *trps, TRP_PEER *peer)
 {
+  if (trps->ptable==NULL) {
+    trps->ptable=trp_ptable_new(trps);
+    if (trps->ptable==NULL)
+      return TRP_NOMEM;
+  }
   return trp_ptable_add(trps->ptable, peer);
 }
 
 TRP_PEER *trps_get_peer_by_gssname(TRPS_INSTANCE *trps, TR_NAME *gssname)
 {
-  return trp_ptable_find_gssname(trps->ptable, gssname);
+  if (trps->ptable==NULL)
+    return NULL;
+
+  return trp_ptable_find_gss_name(trps->ptable, gssname);
 }
 
 TRP_PEER *trps_get_peer_by_servicename(TRPS_INSTANCE *trps, TR_NAME *servicename)
 {
+  if (trps->ptable==NULL)
+    return NULL;
+
   return trp_ptable_find_servicename(trps->ptable, servicename);
 }
 
@@ -1092,7 +1108,11 @@ static TRP_RC trps_handle_request(TRPS_INSTANCE *trps, TRP_REQ *req)
     tr_debug("trps_handle_request: all routes requested.");
     /* leave comm/realm NULL */
   }
-  return trps_update_one_peer(trps, trp_req_get_peer(req), TRP_UPDATE_REQUESTED, comm, realm);
+  return trps_update_one_peer(trps,
+                              trps_get_peer_by_gssname(trps, trp_req_get_peer(req)),
+                              TRP_UPDATE_REQUESTED,
+                              comm,
+                              realm);
 }