Encode route_req messages.
authorJennifer Richards <jennifer@painless-security.com>
Wed, 15 Jun 2016 16:17:17 +0000 (12:17 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Wed, 15 Jun 2016 16:17:17 +0000 (12:17 -0400)
include/trp_internal.h
trp/msgtst.c
trp/trp_msg.c

index 3f081cf..cc65efc 100644 (file)
@@ -42,7 +42,7 @@ typedef struct trp_msg_info_route TRP_MSG_INFO_ROUTE;
 struct trp_msg_info_route {
   void *next;
   TRP_MSG_INFO_TYPE type;
-  TR_NAME *community;
+  TR_NAME *comm;
   TR_NAME *realm;
   TR_NAME *trust_router;
   unsigned int metric;
@@ -51,14 +51,14 @@ struct trp_msg_info_route {
 
 /* TODO: define struct trp_msg_info_community */
 
-typedef struct trp_msg_body_update {
+typedef struct trp_route_update {
   void *records;
-} TRP_MSG_BODY_UPDATE;
+} TRP_ROUTE_UPDATE;
 
-typedef struct trp_msg_body_route_req {
-  TR_NAME *community;
+typedef struct trp_route_req {
+  TR_NAME *comm;
   TR_NAME *realm;
-} TRP_MSG_BODY_ROUTE_REQ;
+} TRP_ROUTE_REQ;
 
 TRP_MSG_TYPE trp_msg_type_from_string(const char *s);
 const char *trp_msg_type_to_string(TRP_MSG_TYPE msgtype);
@@ -68,6 +68,7 @@ const char *trp_msg_info_type_to_string(TRP_MSG_INFO_TYPE msgtype);
 TRP_MSG *trp_msg_new(TALLOC_CTX *mem_ctx);
 void trp_msg_destroy(TRP_MSG *msg);
 void trp_msg_pprint(TRP_MSG *msg);
+char *trp_encode_msg(TRP_MSG *msg);
 
 
 typedef struct trps_instance TRPS_INSTANCE;
index 2b73eb3..5622e3a 100644 (file)
@@ -53,11 +53,15 @@ int main(int argc, const char *argv[])
   if (rc==TRP_SUCCESS)
     trp_msg_print(msg);
 
-  talloc_report_full(main_ctx, stderr);
+  printf("\nEncoding...\n");
+
+  printf("Result: \n%s\n\n", trp_encode_msg(msg));
+
+  talloc_report_full(main_ctx, stdout);
 
   if (rc==TRP_SUCCESS)
     talloc_free(msg);
 
-  talloc_report_full(main_ctx, stderr);
+  talloc_report_full(main_ctx, stdout);
   return 0;
 }
index ea90cf1..10f15f5 100644 (file)
@@ -1,3 +1,4 @@
+#include <jansson.h>
 #include <talloc.h>
 
 #include <tr_name.h>
@@ -6,13 +7,14 @@
 
 
 /* static prototypes */
-static void *trp_msg_body_update_new(TALLOC_CTX *mem_ctx);
+static void *trp_route_update_new(TALLOC_CTX *mem_ctx);
 static TRP_RC trp_parse_update(TRP_MSG *msg, json_t *jmsg);
-static void trp_msg_body_update_print(void *);
+static void trp_route_update_print(void *);
 
-static void *trp_msg_body_route_req_new(TALLOC_CTX *mem_ctx);
+static void *trp_route_req_new(TALLOC_CTX *mem_ctx);
+static json_t *trp_encode_route_req(void *req_in);
 static TRP_RC trp_parse_route_req(TRP_MSG *msg, json_t *jmsg);
-static void trp_msg_body_route_req_print(void *);
+static void trp_route_req_print(void *);
 
 static void *trp_msg_info_route_new(TALLOC_CTX *mem_ctx);
 static TRP_RC trp_parse_info_route(TRP_MSG *msg, json_t *jmsg);
@@ -22,20 +24,21 @@ static void trp_msg_info_route_print(void *);
 struct trp_msg_type_entry {
   const char *name;
   TRP_MSG_TYPE type;
-  void *(*allocator)(TALLOC_CTX *);
-  TRP_RC (*parser)(TRP_MSG *, json_t *);
-  void (*printer)(void *);
+  void *(*allocate)(TALLOC_CTX *);
+  json_t *(*encode)(void *);
+  TRP_RC (*parse)(TRP_MSG *, json_t *);
+  void (*print)(void *);
 };
 static struct trp_msg_type_entry trp_msg_type_table[] = {
-  { "update", TRP_MSG_TYPE_UPDATE, trp_msg_body_update_new, trp_parse_update, trp_msg_body_update_print },
-  { "route_req", TRP_MSG_TYPE_ROUTE_REQ, trp_msg_body_route_req_new, trp_parse_route_req, trp_msg_body_route_req_print },
-  { NULL, TRP_MSG_TYPE_UNKNOWN, NULL, NULL, NULL } /* must be the last entry */
+  { "update", TRP_MSG_TYPE_UPDATE, trp_route_update_new, NULL, trp_parse_update, trp_route_update_print },
+  { "route_req", TRP_MSG_TYPE_ROUTE_REQ, trp_route_req_new, trp_encode_route_req, trp_parse_route_req, trp_route_req_print },
+  { NULL, TRP_MSG_TYPE_UNKNOWN, NULL, NULL, NULL, NULL } /* must be the last entry */
 };
 
 struct trp_msg_info_type_entry {
   const char *name;
   TRP_MSG_INFO_TYPE type;
-  void (*printer)(void *);
+  void (*print)(void *);
 };
 static struct trp_msg_info_type_entry trp_msg_info_type_table[] = {
   { "route_info", TRP_MSG_INFO_TYPE_ROUTE, trp_msg_info_route_print },
@@ -50,11 +53,11 @@ static void msg_body_type_check(TRP_MSG_TYPE msgtype, void *p)
 {
   switch (msgtype) {
   case TRP_MSG_TYPE_UPDATE:
-    talloc_get_type_abort(p, TRP_MSG_BODY_UPDATE);
+    talloc_get_type_abort(p, TRP_ROUTE_UPDATE);
     break;
 
   case TRP_MSG_TYPE_ROUTE_REQ:
-    talloc_get_type_abort(p, TRP_MSG_BODY_ROUTE_REQ);
+    talloc_get_type_abort(p, TRP_ROUTE_REQ);
     break;
 
   default:
@@ -192,9 +195,9 @@ static int trp_msg_info_route_destructor(void *object)
   TRP_MSG_INFO_ROUTE *body=talloc_get_type_abort(object, TRP_MSG_INFO_ROUTE);
   
   /* clean up TR_NAME data, which are not managed by talloc */
-  if (body->community != NULL) {
-    tr_free_name(body->community);
-    body->community=NULL;
+  if (body->comm != NULL) {
+    tr_free_name(body->comm);
+    body->comm=NULL;
     tr_debug("trp_msg_info_route_destructor: freed community");
   }
   if (body->realm != NULL) {
@@ -218,7 +221,7 @@ static void *trp_msg_info_route_new(TALLOC_CTX *mem_ctx)
   if (new_rec != NULL) {
     new_rec->next=NULL;
     new_rec->type=TRP_MSG_INFO_TYPE_UNKNOWN;
-    new_rec->community=NULL;
+    new_rec->comm=NULL;
     new_rec->realm=NULL;
     new_rec->trust_router=NULL;
     new_rec->metric=TRP_METRIC_INFINITY;
@@ -252,11 +255,11 @@ static TRP_RC trp_parse_update_record(TRP_MSG_INFO_ROUTE *rec, json_t *jrecord)
   rc=trp_get_json_string(jrecord, "community", &s, tmp_ctx);
   if (rc != TRP_SUCCESS)
     goto cleanup;
-  if (NULL==(rec->community=tr_new_name(s)))
+  if (NULL==(rec->comm=tr_new_name(s)))
     goto cleanup;
   talloc_free(s); s=NULL;
 
-  tr_debug("trp_parse_update_record: 'community' is '%.*s'.", rec->community->len, rec->community->buf);
+  tr_debug("trp_parse_update_record: 'community' is '%.*s'.", rec->comm->len, rec->comm->buf);
 
   rc=trp_get_json_string(jrecord, "realm", &s, tmp_ctx);
   if (rc != TRP_SUCCESS)
@@ -295,9 +298,9 @@ static TRP_RC trp_parse_update_record(TRP_MSG_INFO_ROUTE *rec, json_t *jrecord)
 cleanup:
   if (rc != TRP_SUCCESS) {
     /* clean up TR_NAME data, which is not managed by talloc */
-    if (rec->community != NULL) {
-      tr_free_name(rec->community);
-      rec->community=NULL;
+    if (rec->comm != NULL) {
+      tr_free_name(rec->comm);
+      rec->comm=NULL;
     }
     if (rec->realm != NULL) {
       tr_free_name(rec->realm);
@@ -315,9 +318,9 @@ cleanup:
 
 
 
-static void *trp_msg_body_update_new(TALLOC_CTX *mem_ctx)
+static void *trp_route_update_new(TALLOC_CTX *mem_ctx)
 {
-  TRP_MSG_BODY_UPDATE *new_body=talloc(mem_ctx, TRP_MSG_BODY_UPDATE);
+  TRP_ROUTE_UPDATE *new_body=talloc(mem_ctx, TRP_ROUTE_UPDATE);
 
   if (new_body!=NULL) {
     new_body->records=NULL;
@@ -328,14 +331,15 @@ static void *trp_msg_body_update_new(TALLOC_CTX *mem_ctx)
  *
  * An error will be returned if any unparseable records are encountered. 
  *
- * TODO: clean up return codes. */
+ * TODO: clean up return codes. 
+ * TODO: should take a body, not a msg */
 static TRP_RC trp_parse_update(TRP_MSG *msg, json_t *jbody)
 {
   TALLOC_CTX *tmp_ctx=talloc_new(NULL);
   json_t *jrecords=NULL;
   size_t ii=0;
   size_t nrec=0;
-  TRP_MSG_BODY_UPDATE *msg_body=NULL;
+  TRP_ROUTE_UPDATE *msg_body=NULL;
   TRP_MSG_INFO_ROUTE *new_rec=NULL;
   TRP_MSG_INFO_ROUTE *list_tail=NULL;
   TRP_RC rc=TRP_ERROR;
@@ -344,7 +348,7 @@ static TRP_RC trp_parse_update(TRP_MSG *msg, json_t *jbody)
     rc=TRP_BADTYPE;
     goto cleanup;
   }
-  msg_body=talloc_get_type(msg->body, TRP_MSG_BODY_UPDATE);
+  msg_body=talloc_get_type(msg->body, TRP_ROUTE_UPDATE);
   if (msg_body==NULL) {
     rc=TRP_BADTYPE;
     goto cleanup;
@@ -400,7 +404,7 @@ static void trp_msg_info_route_print(void *rec_in)
   while (rec!=NULL) {
     printf("    [record_type=%s\n     community=%.*s\n     realm=%.*s\n     trust_router=%.*s\n     metric=%d\n     interval=%d]\n",
            trp_msg_info_type_to_string(rec->type),
-           rec->community->len, rec->community->buf,
+           rec->comm->len, rec->comm->buf,
            rec->realm->len, rec->realm->buf,
            rec->trust_router->len, rec->trust_router->buf,
            rec->metric, rec->interval);
@@ -409,40 +413,53 @@ static void trp_msg_info_route_print(void *rec_in)
 }
 
 
-static int trp_msg_body_route_req_destructor(void *object)
+static int trp_route_req_destructor(void *object)
 {
-  TRP_MSG_BODY_ROUTE_REQ *body=talloc_get_type_abort(object, TRP_MSG_BODY_ROUTE_REQ);
+  TRP_ROUTE_REQ *body=talloc_get_type_abort(object, TRP_ROUTE_REQ);
   
   /* clean up TR_NAME data, which are not managed by talloc */
-  if (body->community != NULL) {
-    tr_free_name(body->community);
-    body->community=NULL;
-    tr_debug("trp_msg_body_route_req_destructor: freed community");
+  if (body->comm != NULL) {
+    tr_free_name(body->comm);
+    body->comm=NULL;
+    tr_debug("trp_route_req_destructor: freed community");
   }
   if (body->realm != NULL) {
     tr_free_name(body->realm);
     body->realm=NULL;
-    tr_debug("trp_msg_body_route_req_destructor: freed realm");
+    tr_debug("trp_route_req_destructor: freed realm");
   }
   return 0;
 }
-static void *trp_msg_body_route_req_new(TALLOC_CTX *mem_ctx)
+
+void *trp_route_req_new(TALLOC_CTX *mem_ctx)
 {
-  TRP_MSG_BODY_ROUTE_REQ *new_body=talloc(mem_ctx, TRP_MSG_BODY_ROUTE_REQ);
+  TRP_ROUTE_REQ *new_body=talloc(mem_ctx, TRP_ROUTE_REQ);
 
   if (new_body != NULL) {
-    new_body->community=NULL;
+    new_body->comm=NULL;
     new_body->realm=NULL;
   }
 
-  talloc_set_destructor((void *)new_body, trp_msg_body_route_req_destructor);
+  talloc_set_destructor((void *)new_body, trp_route_req_destructor);
   return new_body;
 }
 
+void trp_route_req_set_comm(TRP_ROUTE_REQ *req, TR_NAME *comm)
+{
+  req->comm=comm;
+}
+
+void trp_route_req_set_realm(TRP_ROUTE_REQ *req, TR_NAME *realm)
+{
+  req->realm=realm;
+}
+
+/* TODO: clean up return codes. 
+ * TODO: should take a body, not a msg */
 static TRP_RC trp_parse_route_req(TRP_MSG *msg, json_t *jbody)
 {
   TALLOC_CTX *tmp_ctx=talloc_new(NULL);
-  TRP_MSG_BODY_ROUTE_REQ *msg_body=NULL;
+  TRP_ROUTE_REQ *msg_body=NULL;
   char *s=NULL;
   TRP_RC rc=TRP_ERROR;
 
@@ -451,7 +468,7 @@ static TRP_RC trp_parse_route_req(TRP_MSG *msg, json_t *jbody)
     rc=TRP_BADTYPE;
     goto cleanup;
   }
-  msg_body=talloc_get_type(msg->body, TRP_MSG_BODY_ROUTE_REQ);
+  msg_body=talloc_get_type(msg->body, TRP_ROUTE_REQ);
   if (msg_body==NULL) {
     rc=TRP_BADTYPE;
     goto cleanup;
@@ -460,7 +477,7 @@ static TRP_RC trp_parse_route_req(TRP_MSG *msg, json_t *jbody)
   rc=trp_get_json_string(jbody, "community", &s, tmp_ctx);
   if (rc!=TRP_SUCCESS)
     goto cleanup;
-  msg_body->community=tr_new_name(s);
+  msg_body->comm=tr_new_name(s);
   talloc_free(s); s=NULL;
 
   rc=trp_get_json_string(jbody, "realm", &s, tmp_ctx);
@@ -475,9 +492,84 @@ cleanup:
   return rc;
 }
 
-static void trp_msg_body_update_print(void *body_in)
+static json_t *trp_encode_body(TRP_MSG_TYPE type, void *body)
+{
+  struct trp_msg_type_entry *msgtype=get_trp_msg_type_entry(type);
+
+  if ((msgtype->type==TRP_MSG_TYPE_UNKNOWN) || (msgtype->encode==NULL))
+    return NULL;
+
+  tr_debug("trp_encode_body: encoding type %s", trp_msg_type_to_string(type));
+
+  return msgtype->encode(body);
+}
+
+/* TODO: error checking */
+char *trp_encode_msg(TRP_MSG *msg)
+{
+  json_t *jmsg=NULL;
+  json_t *jtype=NULL;
+  json_t *jbody=NULL;
+  char *encoded=NULL;
+
+  jbody=trp_encode_body(msg->type, msg->body);
+  if (jbody!=NULL) {
+    jmsg=json_object();
+
+    jtype=json_string(trp_msg_type_to_string(msg->type));
+    json_object_set_new(jmsg, "message_type", jtype);
+    json_object_set_new(jmsg, "body", jbody);
+
+    encoded=json_dumps(jmsg, 0);
+    json_decref(jmsg);
+  }
+  return encoded;
+}
+
+/* TODO: error checking */
+static json_t *trp_encode_route_req(void *req_in)
+{
+  TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+  TRP_ROUTE_REQ *req=talloc_get_type(req_in, TRP_ROUTE_REQ); /* null if wrong type */
+  TRP_RC rc=TRP_ERROR;
+  json_t *jbody=NULL;
+  json_t *jstr=NULL;
+  char *s=NULL;
+
+  if (req!=NULL) {
+    jbody=json_object();
+
+    s=talloc_strndup(tmp_ctx, req->comm->buf, req->comm->len); /* ensures null term */
+    if (s==NULL) {
+      tr_debug("trp_encode_route_req: could not allocate community string");
+      json_decref(jbody);
+      jbody=NULL;
+      goto cleanup;
+    }
+    jstr=json_string(s);
+    talloc_free(s);
+    json_object_set_new(jbody, "community", jstr);
+    
+    s=talloc_strndup(tmp_ctx, req->realm->buf, req->realm->len); /* ensures null term */
+    if (s==NULL) {
+      tr_debug("trp_encode_route_req: could not allocate realm string");
+      json_decref(jbody);
+      jbody=NULL;
+      goto cleanup;
+    }
+    jstr=json_string(s);
+    talloc_free(s);
+    json_object_set_new(jbody, "realm", jstr);
+  }
+
+cleanup:
+  talloc_free(tmp_ctx);
+  return jbody;
+}
+
+static void trp_route_update_print(void *body_in)
 {
-  TRP_MSG_BODY_UPDATE *body=talloc_get_type(body_in, TRP_MSG_BODY_UPDATE); /* null if wrong type */
+  TRP_ROUTE_UPDATE *body=talloc_get_type(body_in, TRP_ROUTE_UPDATE); /* null if wrong type */
 
   if (body!=NULL) {
     printf("  {records=\n");
@@ -486,13 +578,13 @@ static void trp_msg_body_update_print(void *body_in)
   }
 }
 
-static void trp_msg_body_route_req_print(void *body_in)
+static void trp_route_req_print(void *body_in)
 {
-  TRP_MSG_BODY_ROUTE_REQ *body=talloc_get_type(body_in, TRP_MSG_BODY_ROUTE_REQ); /* null if wrong type */
+  TRP_ROUTE_REQ *body=talloc_get_type(body_in, TRP_ROUTE_REQ); /* null if wrong type */
 
   if (body!=NULL) {
     printf("  {community=%.*s\n   realm=%.*s}\n",
-           body->community->len, body->community->buf,
+           body->comm->len, body->comm->buf,
            body->realm->len, body->realm->buf);
   }
 }
@@ -500,7 +592,7 @@ static void trp_msg_body_route_req_print(void *body_in)
 static void trp_msg_body_print(void *body, TRP_MSG_TYPE msgtype)
 {
   struct trp_msg_type_entry *info=get_trp_msg_type_entry(msgtype);
-  info->printer(body);
+  info->print(body);
 }
 
 void trp_msg_print(TRP_MSG *msg)
@@ -522,7 +614,7 @@ static void *trp_msg_body_new(TALLOC_CTX *mem_ctx, TRP_MSG_TYPE msgtype)
     return NULL;
   }
 
-  new_body=info->allocator(mem_ctx);
+  new_body=info->allocate(mem_ctx);
   msg_body_type_check(msgtype, new_body); /* aborts program on type violation */
   return new_body;
 }
@@ -537,7 +629,7 @@ static TRP_RC trp_parse_msg_body(TRP_MSG *msg, json_t *jbody)
     return TRP_ERROR;
   }
 
-  return info->parser(msg, jbody);
+  return info->parse(msg, jbody);
 }