Bug fixes to make TID forwarding work between trust routers.
authorJennifer Richards <jennifer@painless-security.com>
Wed, 7 Sep 2016 17:55:16 +0000 (17:55 +0000)
committerJennifer Richards <jennifer@painless-security.com>
Wed, 7 Sep 2016 17:55:16 +0000 (17:55 +0000)
  - use server hostname instead of GSS name as next_hop in routes
  - don't segfault when finding selected route if none selected
  - report useful message on error in JSON parsing

common/tr_config.c
include/trp_internal.h
include/trp_rtable.h
include/trust_router/trp.h
trp/trp_rtable.c
trp/trp_upd.c
trp/trps.c

index 3a4cf2a..22df406 100644 (file)
@@ -1851,6 +1851,14 @@ static char *join_paths(TALLOC_CTX *mem_ctx, const char *p1, const char *p2)
   return talloc_asprintf(mem_ctx, "%s/%s", p1, p2); /* returns NULL on a failure */
 }
 
+static void tr_cfg_log_json_error(const char *label, json_error_t *rc)
+{
+  tr_debug("%s: JSON parse error on line %d: %s",
+          label,
+          rc->line,
+          rc->text);
+}
+
 TR_CFG_RC tr_cfg_parse_one_config_file(TR_CFG *cfg, const char *file_with_path)
 {
   json_t *jcfg=NULL;
@@ -1859,8 +1867,9 @@ TR_CFG_RC tr_cfg_parse_one_config_file(TR_CFG *cfg, const char *file_with_path)
 
   if (NULL==(jcfg=json_load_file(file_with_path, 
                                  JSON_DISABLE_EOF_CHECK, &rc))) {
-    tr_debug("tr_parse_one_config_file: Error parsing config file %s.", 
+    tr_debug("tr_cfg_parse_one_config_file: Error parsing config file %s.", 
              file_with_path);
+    tr_cfg_log_json_error("tr_cfg_parse_one_config_file", &rc);
     return TR_CFG_NOPARSE;
   }
 
index c6828f6..35f3f97 100644 (file)
@@ -18,6 +18,7 @@ typedef struct trp_inforec_route {
   TR_NAME *realm;
   TR_NAME *trust_router;
   TR_NAME *next_hop;
+  unsigned int next_hop_port;
   unsigned int metric;
   unsigned int interval;
 } TRP_INFOREC_ROUTE;
index a8f66be..9342a07 100644 (file)
@@ -12,7 +12,9 @@ typedef struct trp_route {
   TR_NAME *realm;
   TR_NAME *peer;
   unsigned int metric;
-  TR_NAME *trust_router;
+  TR_NAME *trust_router; /* hostname */
+  unsigned int trp_port;
+  unsigned int tid_port;
   TR_NAME *next_hop;
   int selected;
   unsigned int interval; /* interval from route update */
index 57f0a83..c8b2490 100644 (file)
@@ -45,6 +45,7 @@ void trp_upd_add_inforec(TRP_UPD *upd, TRP_INFOREC *rec);
 TR_EXPORT TR_NAME *trp_upd_get_peer(TRP_UPD *upd);
 TR_NAME *trp_upd_dup_peer(TRP_UPD *upd);
 void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer);
+void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port);
 TR_EXPORT TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type);
 void trp_inforec_free(TRP_INFOREC *rec);
 TR_EXPORT TRP_INFOREC *trp_inforec_get_next(TRP_INFOREC *rec);
index 3e4434e..6919241 100644 (file)
@@ -8,6 +8,8 @@
 #include <trp_internal.h>
 #include <trp_rtable.h>
 #include <tr_debug.h>
+#include <trust_router/trp.h>
+#include <trust_router/tid.h>
 
 /* Note: be careful mixing talloc with glib. */
 
@@ -34,6 +36,8 @@ TRP_ROUTE *trp_route_new(TALLOC_CTX *mem_ctx)
     entry->comm=NULL;
     entry->realm=NULL;
     entry->trust_router=NULL;
+    entry->trp_port=TRP_PORT;
+    entry->tid_port=TID_PORT;
     entry->peer=NULL;
     entry->next_hop=NULL;
     entry->selected=0;
@@ -135,6 +139,7 @@ unsigned int trp_route_get_metric(TRP_ROUTE *entry)
   return entry->metric;
 }
 
+/* TODO: set the hostname and port for the next hop. Currently assume default TID port. --jlr */
 void trp_route_set_next_hop(TRP_ROUTE *entry, TR_NAME *next_hop)
 {
   if (entry->next_hop!=NULL)
@@ -610,6 +615,7 @@ static char *timespec_to_str(struct timespec *ts)
 TRP_ROUTE *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *comm, TR_NAME *realm)
 {
   size_t n=0;
+  int ii=0;
   TRP_ROUTE **entry=trp_rtable_get_realm_entries(rtbl, comm, realm, &n);
   TRP_ROUTE *selected=NULL;
 
@@ -618,11 +624,13 @@ TRP_ROUTE *trp_rtable_get_selected_entry(TRP_RTABLE *rtbl, TR_NAME *comm, TR_NAM
 
   tr_debug("trp_rtable_get_selected_entry: looking through route table entries for realm %.*s.",
            realm->len, realm->buf);
-  while(n-- && !trp_route_is_selected(entry[n])) { }
-  tr_debug("trp_rtable_get_selected_entry: n=%d.", n);
-
-  if (n>=0)
-    selected=entry[n];
+  for(ii=0; ii<n; ii++) {
+    if (trp_route_is_selected(entry[ii])) {
+      selected=entry[ii];
+      break;
+    }
+  }
+  tr_debug("trp_rtable_get_selected_entry: ii=%d.", ii);
 
   talloc_free(entry);
   return selected;
index 245ac1e..1821b76 100644 (file)
@@ -94,6 +94,7 @@ static void *trp_inforec_route_new(TALLOC_CTX *mem_ctx)
     new_rec->realm=NULL;
     new_rec->trust_router=NULL;
     new_rec->next_hop=NULL;
+    new_rec->next_hop_port=0;
     new_rec->metric=TRP_METRIC_INFINITY;
     new_rec->interval=0;
     talloc_set_destructor((void *)new_rec, trp_inforec_route_destructor);
@@ -235,6 +236,7 @@ TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router)
   return TRP_ERROR;
 }
 
+/* TODO: need to return hostname/port --jlr */
 TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec)
 {
   switch (rec->type) {
@@ -427,12 +429,16 @@ TR_NAME *trp_upd_dup_peer(TRP_UPD *upd)
 
 void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer)
 {
+  upd->peer=peer;
+}
+
+void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
+{
   TRP_INFOREC *rec=NULL;
   TR_NAME *cpy=NULL;
-
-  upd->peer=peer;
+  
   for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
-    if (trp_inforec_set_next_hop(rec, cpy=tr_dup_name(peer)) != TRP_SUCCESS) {
+    if (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname)) != TRP_SUCCESS) {
       tr_err("trp_upd_set_peer: error setting peer.");
       tr_free_name(cpy);
     }
index 409e541..1c6cde5 100644 (file)
@@ -277,7 +277,8 @@ static TRP_RC trps_read_message(TRPS_INSTANCE *trps, TRP_CONNECTION *conn, TR_MS
   int err=0;
   char *buf=NULL;
   size_t buflen = 0;
-  TR_NAME *peer=NULL;
+  TRP_PEER *peer=NULL; /* entry in the peer table */
+  TR_NAME *conn_peer=NULL; /* name from the TRP_CONN, which comes from the gss context */
 
   tr_debug("trps_read_message: started");
   if (err = gsscon_read_encrypted_token(trp_connection_get_fd(conn),
@@ -290,27 +291,39 @@ static TRP_RC trps_read_message(TRPS_INSTANCE *trps, TRP_CONNECTION *conn, TR_MS
     return TRP_ERROR;
   }
 
-  tr_debug("trps_read_message(): message received, %u bytes.", (unsigned) buflen);
-  tr_debug("trps_read_message(): %.*s", buflen, buf);
+  tr_debug("trps_read_message: message received, %u bytes.", (unsigned) buflen);
+  tr_debug("trps_read_message: %.*s", buflen, buf);
 
   *msg=tr_msg_decode(buf, buflen);
   free(buf);
   if (*msg==NULL)
     return TRP_NOPARSE;
 
-  peer=trp_connection_get_peer(conn);
+  conn_peer=trp_connection_get_peer(conn);
+  if (conn_peer==NULL) {
+    tr_err("trps_read_message: connection has no peer name");
+    return TRP_ERROR;
+  }
+
+  peer=trps_get_peer_by_gssname(trps, conn_peer);
+  if (peer==NULL) {
+    tr_err("trps_read_message: could not find peer with gssname=%s", trp_connection_get_gssname(conn));
+    return TRP_ERROR;
+  }
+
   /* verify we received a message we support, otherwise drop it now */
   switch (tr_msg_get_msg_type(*msg)) {
   case TRP_UPDATE:
-    trp_upd_set_peer(tr_msg_get_trp_upd(*msg), tr_dup_name(peer));
+    trp_upd_set_peer(tr_msg_get_trp_upd(*msg), tr_dup_name(conn_peer));
+    trp_upd_set_next_hop(tr_msg_get_trp_upd(*msg), trp_peer_get_server(peer), 0); /* TODO: 0 should be the configured TID port */
     break;
 
   case TRP_REQUEST:
-    trp_req_set_peer(tr_msg_get_trp_req(*msg), tr_dup_name(peer));
+    trp_req_set_peer(tr_msg_get_trp_req(*msg), tr_dup_name(conn_peer));
     break;
 
   default:
-    tr_debug("trps_read_message: received unsupported message from %.*s", peer->len, peer->buf);
+    tr_debug("trps_read_message: received unsupported message from %.*s", conn_peer->len, conn_peer->buf);
     tr_msg_free_decoded(*msg);
     *msg=NULL;
     return TRP_UNSUPPORTED;
@@ -537,6 +550,7 @@ static TRP_RC trps_accept_update(TRPS_INSTANCE *trps, TRP_UPD *upd, TRP_INFOREC
     trp_route_set_peer(entry, trp_upd_dup_peer(upd));
     trp_route_set_trust_router(entry, trp_inforec_dup_trust_router(rec));
     trp_route_set_next_hop(entry, trp_inforec_dup_next_hop(rec));
+    /* TODO: pass next hop port (now defaults to TID_PORT) --jlr */
     if ((trp_route_get_comm(entry)==NULL)
        ||(trp_route_get_realm(entry)==NULL)
        ||(trp_route_get_peer(entry)==NULL)