Fix segfault issues. Comm updates now sent, but ignored.
authorJennifer Richards <jennifer@painless-security.com>
Tue, 25 Oct 2016 20:59:49 +0000 (16:59 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Tue, 25 Oct 2016 21:00:12 +0000 (17:00 -0400)
common/tr_apc.c
common/tr_comm.c
common/tr_config.c
common/tr_msg.c
trp/trp_upd.c
trp/trps.c

index bb37a10..9fa9294 100644 (file)
@@ -101,9 +101,12 @@ TR_APC *tr_apc_dup(TALLOC_CTX *mem_ctx, TR_APC *apc)
 {
   TALLOC_CTX *tmp_ctx=talloc_new(NULL);
   TR_APC *cur=NULL;
-  TR_APC *new=tr_apc_dup(tmp_ctx, apc);
+  TR_APC *new=NULL;
 
-  if (new==NULL)
+  if (apc==NULL)
+    return NULL;
+
+  if (NULL==(new=tr_apc_dup_one(tmp_ctx, apc)))
     return NULL;
   
   for (cur=new,apc=apc->next; apc!=NULL; cur=cur->next,apc=apc->next) {
index 2dd637a..5fe33b6 100644 (file)
@@ -464,24 +464,16 @@ static void tr_realm_free(TR_REALM *realm)
 
 static void tr_realm_set_rp(TR_REALM *realm, TR_RP_REALM *rp)
 {
-  if (realm->rp!=NULL)
-    talloc_free(realm->rp);
-  if (realm->idp!=NULL) {
-    talloc_free(realm->idp);
+  if (realm->idp!=NULL)
     realm->idp=NULL;
-  }
   realm->role=TR_ROLE_RP;
   realm->rp=rp;
 }
 
 static void tr_realm_set_idp(TR_REALM *realm, TR_IDP_REALM *idp)
 {
-  if (realm->idp!=NULL)
-    talloc_free(realm->idp);
-  if (realm->rp!=NULL) {
-    talloc_free(realm->rp);
+  if (realm->rp!=NULL)
     realm->rp=NULL;
-  }
   realm->role=TR_ROLE_IDP;
   realm->idp=idp;
 }
@@ -699,6 +691,7 @@ TR_COMM_MEMB *tr_comm_memb_new(TALLOC_CTX *mem_ctx)
   TR_COMM_MEMB *memb=talloc(mem_ctx, TR_COMM_MEMB);
   if (memb!=NULL) {
     memb->next=NULL;
+    memb->origin_next=NULL;
     memb->idp=NULL;
     memb->rp=NULL;
     memb->comm=NULL;
index ea9efe9..5ada21d 100644 (file)
@@ -1834,7 +1834,7 @@ static TR_CFG_RC tr_cfg_parse_comms (TR_CFG *trc, json_t *jcfg)
                                                 trc, 
                                                 json_array_get(jcomms, i), 
                                                &rc))) {
-       return rc;
+        return rc;
       }
       tr_debug("tr_cfg_parse_comms: Community configured: %s.",
                tr_comm_get_id(comm)->buf);
index aaddb11..48965e5 100644 (file)
@@ -70,23 +70,23 @@ static int tr_msg_get_json_integer(json_t *jmsg, const char *attr, int *dest)
 
 /* Read attribute attr from msg as a string. Copies string into mem_ctx context so jmsg can
  * be destroyed safely. Returns nonzero on error. */
-static int tr_msg_get_json_string(json_t *jmsg, const char *attr, char **dest, TALLOC_CTX *mem_ctx)
+static TRP_RC tr_msg_get_json_string(json_t *jmsg, const char *attr, char **dest, TALLOC_CTX *mem_ctx)
 {
   json_t *obj;
 
   obj=json_object_get(jmsg, attr);
   if (obj == NULL)
-    return -1;
+    return TRP_ERROR;
 
   /* check type */
   if (!json_is_string(obj))
-    return -1;
+    return TRP_ERROR;
 
   *dest=talloc_strdup(mem_ctx, json_string_value(obj));
   if (*dest==NULL)
-    return -1;
+    return TRP_ERROR;
 
-  return 0;
+  return TRP_SUCCESS;
 }
 
 enum msg_type tr_msg_get_msg_type(TR_MSG *msg) 
@@ -631,7 +631,7 @@ static TR_APC *tr_msg_decode_apcs(TALLOC_CTX *mem_ctx, json_t *jarray, TRP_RC *r
   *rc=TRP_SUCCESS;
 
   if (apc_list!=NULL)
-    talloc_steal(apc_list, mem_ctx);
+    talloc_steal(mem_ctx, apc_list);
 
 cleanup:
   talloc_free(tmp_ctx);
@@ -845,7 +845,7 @@ static TRP_INFOREC *tr_msg_decode_trp_inforec(TALLOC_CTX *mem_ctx, json_t *jreco
   TRP_RC rc=TRP_ERROR;
   char *s=NULL;
   
-  if (0!=tr_msg_get_json_string(jrecord, "record_type", &s, tmp_ctx))
+  if (TRP_SUCCESS!=tr_msg_get_json_string(jrecord, "record_type", &s, tmp_ctx))
     goto cleanup;
 
   rectype=trp_inforec_type_from_string(s);
@@ -1167,6 +1167,7 @@ char *tr_msg_encode(TR_MSG *msg)
     }
 
   encoded=json_dumps(jmsg, 0);
+  tr_debug("tr_msg_encode: outgoing msg=%s", encoded);
   json_decref(jmsg);
   return encoded;
 }
index a76c76b..1623b84 100644 (file)
@@ -163,6 +163,7 @@ static TRP_INFOREC_DATA *trp_inforec_comm_new(TALLOC_CTX *mem_ctx)
     new_rec->owner_realm=NULL;
     new_rec->owner_contact=NULL;
     new_rec->provenance=NULL;
+    new_rec->interval=0;
     talloc_set_destructor((void *)new_rec, trp_inforec_comm_destructor);
     new_data->comm=new_rec;
   }
@@ -193,7 +194,7 @@ void trp_inforec_set_next(TRP_INFOREC *rec, TRP_INFOREC *next_rec)
 
 TRP_INFOREC_TYPE trp_inforec_get_type(TRP_INFOREC *rec)
 {
-  if (rec)
+  if (rec!=NULL)
     return rec->type;
   else
     return TRP_INFOREC_TYPE_UNKNOWN;
@@ -261,15 +262,17 @@ TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop)
 {
   switch (rec->type) {
   case TRP_INFOREC_TYPE_ROUTE:
-    if (rec->data->route!=NULL) {
-      rec->data->route->next_hop=next_hop;
-      return TRP_SUCCESS;
-    }
+    if (rec->data->route==NULL)
+      return TRP_ERROR;
+    rec->data->route->next_hop=next_hop;
+    break;
+  case TRP_INFOREC_TYPE_COMMUNITY:
+    /* next hop not used for community records */
     break;
   default:
     break;
   }
-  return TRP_ERROR;
+  return TRP_SUCCESS;
 }
 
 unsigned int trp_inforec_get_metric(TRP_INFOREC *rec)
@@ -414,10 +417,11 @@ TRP_RC trp_inforec_set_apcs(TRP_INFOREC *rec, TR_APC *apcs)
       rec->data->comm->apcs=apcs;
       talloc_steal(rec, apcs);
       return TRP_SUCCESS;
-  default:
-    break;
     }
     break;
+
+  default:
+    break;
   }
   return TRP_ERROR;
 }
@@ -511,6 +515,36 @@ TRP_RC trp_inforec_set_provenance(TRP_INFOREC *rec, json_t *prov)
   return TRP_ERROR;
 }
 
+static TRP_RC trp_inforec_add_to_provenance(TRP_INFOREC *rec, TR_NAME *peer)
+{
+  json_t *jpeer=NULL;
+
+  switch (rec->type) {
+  case TRP_INFOREC_TYPE_ROUTE:
+    /* no provenance list */
+    break;
+  case TRP_INFOREC_TYPE_COMMUNITY:
+    jpeer=tr_name_to_json_string(peer);
+    if (jpeer==NULL)
+      return TRP_ERROR;
+    if (rec->data->comm->provenance==NULL) {
+      rec->data->comm->provenance=json_array();
+      if (rec->data->comm->provenance==NULL) {
+        json_decref(jpeer);
+        return TRP_ERROR;
+      }
+    }
+    if (0!=json_array_append_new(rec->data->comm->provenance, jpeer)) {
+      json_decref(jpeer);
+      return TRP_ERROR;
+    }
+    break;
+  default:
+    break;
+  }
+  return TRP_SUCCESS;
+}
+
 /* generic record type */
 TRP_INFOREC *trp_inforec_new(TALLOC_CTX *mem_ctx, TRP_INFOREC_TYPE type)
 {
@@ -642,7 +676,18 @@ TR_NAME *trp_upd_dup_peer(TRP_UPD *upd)
 
 void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer)
 {
+  TRP_INFOREC *rec=NULL;
+  TR_NAME *cpy=NULL;
+
   upd->peer=peer;
+
+  /* add to provenance list of any records that need it */
+  for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
+    if (trp_inforec_add_to_provenance(rec, cpy=tr_dup_name(peer)) != TRP_SUCCESS) {
+      tr_err("trp_upd_set_peer: error adding peer to provenance list.");
+      tr_free_name(cpy);
+    }
+  }
 }
 
 void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
@@ -652,7 +697,7 @@ void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
   
   for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
     if (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname)) != TRP_SUCCESS) {
-      tr_err("trp_upd_set_peer: error setting peer.");
+      tr_err("trp_upd_set_next_hop: error setting next hop.");
       tr_free_name(cpy);
     }
   }
index 674af3d..e181dc9 100644 (file)
@@ -523,6 +523,9 @@ static TRP_RC trps_validate_inforec(TRPS_INSTANCE *trps, TRP_INFOREC *rec)
     }
     break;
 
+  case TRP_INFOREC_TYPE_COMMUNITY:
+    /* TODO: handle community updates -jlr*/
+    
   default:
     tr_notice("trps_validate_inforec: unsupported record type.");
     return TRP_UNSUPPORTED;
@@ -1032,9 +1035,10 @@ static TRP_INFOREC *trps_memb_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *trp
     goto cleanup;
   }
 
-  if ((TRP_SUCCESS!=trp_inforec_set_apcs(rec,
-                                         tr_apc_dup(rec, tr_comm_get_apcs(comm)))) ||
-      (NULL==trp_inforec_get_apcs(rec))) {
+  if ((NULL!=tr_comm_get_apcs(comm)) &&
+      ( (TRP_SUCCESS!=trp_inforec_set_apcs(rec,
+                                           tr_apc_dup(rec, tr_comm_get_apcs(comm)))) ||
+        (NULL==trp_inforec_get_apcs(rec)))) {
     rec=NULL;
     goto cleanup;
   }
@@ -1090,7 +1094,7 @@ static TRP_UPD *trps_comm_update(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *trps, TR_NA
 
   iter=tr_comm_iter_new(tmp_ctx);
   if (iter==NULL) {
-    tr_err("tr_comm_update: unable to allocate iterator.");
+    tr_err("trps_comm_update: unable to allocate iterator.");
     upd=NULL;
     goto cleanup;
   }
@@ -1116,7 +1120,7 @@ static TRP_UPD *trps_comm_update(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *trps, TR_NA
          memb=tr_comm_memb_iter_next(iter)) {
       rec=trps_memb_to_inforec(tmp_ctx, trps, memb);
       if (rec==NULL) {
-        tr_err("tr_comm_update: unable to allocate inforec.");
+        tr_err("trps_comm_update: unable to allocate inforec.");
         upd=NULL;
         goto cleanup;
       }
@@ -1159,20 +1163,22 @@ static TRP_RC trps_select_comm_updates_for_peer(TALLOC_CTX *mem_ctx, GPtrArray *
        comm!=NULL;
        comm=tr_comm_table_iter_next(comm_iter)) {
     /* do every realm in this community */
+    tr_debug("trps_select_comm_updates_for_peer: looking through community %.*s",
+             tr_comm_get_id(comm)->len,
+             tr_comm_get_id(comm)->buf);
     for (realm=tr_realm_iter_first(realm_iter, trps->ctable, tr_comm_get_id(comm));
          realm!=NULL;
          realm=tr_realm_iter_next(realm_iter)) {
       /* get the update for this comm/realm */
-      upd=trps_comm_update(tmp_ctx, trps, peer_gssname, comm, realm);
-      if (upd!=NULL) {
+      tr_debug("trps_select_comm_updates_for_peer: adding realm %.*s",
+               tr_realm_get_id(realm)->len,
+               tr_realm_get_id(realm)->buf);
+      upd=trps_comm_update(mem_ctx, trps, peer_gssname, comm, realm);
+      if (upd!=NULL)
         g_ptr_array_add(updates, upd);
-      }
     }
   }
 
-  /* move anything needed into mem_ctx */
-  
-
 cleanup:
   talloc_free(tmp_ctx);
   return rc;
@@ -1228,6 +1234,7 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps,
   }
 
   /* First, gather route updates. */
+  tr_debug("trps_update_one_peer: selecting route updates for %.*s.", peer_label->len, peer_label->buf);
   if ((comm==NULL) && (realm==NULL)) {
     /* do all realms */
     rc=trps_select_route_updates_for_peer(tmp_ctx,
@@ -1263,6 +1270,7 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps,
   }
 
   /* Second, gather community updates */
+  tr_debug("trps_update_one_peer: selecting community updates for %.*s.", peer_label->len, peer_label->buf);
   rc=trps_select_comm_updates_for_peer(tmp_ctx, updates, trps, peer_label);
 
   /* see if we have anything to send */
@@ -1270,7 +1278,8 @@ static TRP_RC trps_update_one_peer(TRPS_INSTANCE *trps,
     tr_debug("trps_update_one_peer: no updates for %.*s", peer_label->len, peer_label->buf);
   else {
     tr_debug("trps_update_one_peer: sending %d update messages.", updates->len);
-    for (ii=0; NULL!=(upd=(TRP_UPD *)g_ptr_array_index(updates, ii)); ii++) {
+    for (ii=0; ii<updates->len; ii++) {
+      upd=(TRP_UPD *)g_ptr_array_index(updates, ii);
       /* now encode the update message */
       tr_msg_set_trp_upd(&msg, upd);
       encoded=tr_msg_encode(&msg);