Merge branch 'milestone/monitoring' into jennifer/request_id
authorJennifer Richards <jennifer@painless-security.com>
Thu, 3 May 2018 20:50:54 +0000 (16:50 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Thu, 3 May 2018 20:50:54 +0000 (16:50 -0400)
# Conflicts:
# include/trust_router/tid.h
# tid/tidc.c
# tr/tr_tid.c

Makefile.am
common/tr_msg.c
common/tr_rand_id.c [new file with mode: 0644]
include/tid_internal.h
include/tr_rand_id.h [new file with mode: 0644]
include/trust_router/tid.h
tid/tid_req.c
tid/tid_resp.c
tid/tidc.c
tid/tids.c
tr/tr_tid.c

index 1c933d6..1231793 100644 (file)
@@ -32,7 +32,8 @@ common_srcs = common/tr_name.c \
 tid_srcs = tid/tid_resp.c \
 tid/tid_req.c \
 tid/tids.c \
-tid/tidc.c
+tid/tidc.c \
+common/tr_rand_id.c
 
 trp_srcs = trp/trp_conn.c \
 trp/trps.c \
@@ -96,6 +97,7 @@ common/tr_debug.c \
 common/tr_name.c \
 common/tr_constraint.c \
 common/tr_dh.c \
+common/tr_rand_id.c \
 tid/tid_req.c \
 tid/tid_resp.c
 
@@ -145,6 +147,7 @@ tr_trmon_LDFLAGS = $(AM_LDFLAGS) -pthread
 
 trp_msgtst_SOURCES = trp/msgtst.c \
 $(common_srcs) \
+common/tr_rand_id.c \
 trp/trp_req.c \
 trp/trp_upd.c \
 tid/tid_resp.c \
index ab80345..50e8bc9 100644 (file)
@@ -329,12 +329,17 @@ static json_t * tr_msg_encode_tidreq(TID_REQ *req)
 
   jstr = tr_name_to_json_string(req->comm);
   json_object_set_new(jreq, "community", jstr);
-  
+
   if (req->orig_coi) {
     jstr = tr_name_to_json_string(req->orig_coi);
     json_object_set_new(jreq, "orig_coi", jstr);
   }
 
+  if (tid_req_get_request_id(req)) {
+    jstr = tr_name_to_json_string(tid_req_get_request_id(req));
+    json_object_set_new(jreq, "request_id", jstr);
+  }
+
   json_object_set_new(jreq, "dh_info", tr_msg_encode_dh(req->tidc_dh));
 
   if (req->cons)
@@ -356,6 +361,7 @@ static TID_REQ *tr_msg_decode_tidreq(TALLOC_CTX *mem_ctx, json_t *jreq)
   json_t *jrealm = NULL;
   json_t *jcomm = NULL;
   json_t *jorig_coi = NULL;
+  json_t *jrequest_id = NULL;
   json_t *jdh = NULL;
   json_t *jpath = NULL;
   json_t *jexpire_interval = NULL;
@@ -378,9 +384,9 @@ static TID_REQ *tr_msg_decode_tidreq(TALLOC_CTX *mem_ctx, json_t *jreq)
   jpath = json_object_get(jreq, "path");
   jexpire_interval = json_object_get(jreq, "expiration_interval");
 
-  treq->rp_realm = tr_new_name((char *)json_string_value(jrp_realm));
-  treq->realm = tr_new_name((char *)json_string_value(jrealm));
-  treq->comm = tr_new_name((char *)json_string_value(jcomm));
+  treq->rp_realm = tr_new_name(json_string_value(jrp_realm));
+  treq->realm = tr_new_name(json_string_value(jrealm));
+  treq->comm = tr_new_name(json_string_value(jcomm));
 
   /* Get DH Info from the request */
   if (NULL == (jdh = json_object_get(jreq, "dh_info"))) {
@@ -392,7 +398,12 @@ static TID_REQ *tr_msg_decode_tidreq(TALLOC_CTX *mem_ctx, json_t *jreq)
 
   /* store optional "orig_coi" field */
   if (NULL != (jorig_coi = json_object_get(jreq, "orig_coi"))) {
-    treq->orig_coi = tr_new_name((char *)json_string_value(jorig_coi));
+    treq->orig_coi = tr_new_name(json_string_value(jorig_coi));
+  }
+
+  /* store optional "request_id" field */
+  if (NULL != (jrequest_id = json_object_get(jreq, "request_id"))) {
+    tid_req_set_request_id(treq, tr_new_name(json_string_value(jrequest_id)));
   }
 
   treq->cons = (TR_CONSTRAINT_SET *) json_object_get(jreq, "constraints");
@@ -573,6 +584,11 @@ static json_t * tr_msg_encode_tidresp(TID_RESP *resp)
     json_object_set_new(jresp, "orig_coi", jstr);
   }
 
+  if (tid_resp_get_request_id(resp)) {
+    jstr = tr_name_to_json_string(tid_resp_get_request_id(resp));
+    json_object_set_new(jresp, "request_id", jstr);
+  }
+
   if (NULL == resp->servers) {
     tr_debug("tr_msg_encode_tidresp(): No servers to encode.");
   }
@@ -595,6 +611,7 @@ static TID_RESP *tr_msg_decode_tidresp(TALLOC_CTX *mem_ctx, json_t *jresp)
   json_t *jrealm = NULL;
   json_t *jcomm = NULL;
   json_t *jorig_coi = NULL;
+  json_t *jrequest_id = NULL;
   json_t *jservers = NULL;
   json_t *jerr_msg = NULL;
 
@@ -648,10 +665,16 @@ static TID_RESP *tr_msg_decode_tidresp(TALLOC_CTX *mem_ctx, json_t *jresp)
 
   /* store optional "orig_coi" field */
   if ((NULL != (jorig_coi = json_object_get(jresp, "orig_coi"))) &&
-      (!json_is_object(jorig_coi))) {
+      json_is_string(jorig_coi)) {
     tresp->orig_coi = tr_new_name(json_string_value(jorig_coi));
   }
-     
+
+  /* store optional "request_id" field */
+  if ((NULL != (jrequest_id = json_object_get(jresp, "request_id"))) &&
+      json_is_string(jrequest_id)) {
+    tid_resp_set_request_id(tresp, tr_new_name(json_string_value(jrequest_id)));
+  }
+
   return tresp;
 }
 
diff --git a/common/tr_rand_id.c b/common/tr_rand_id.c
new file mode 100644 (file)
index 0000000..a2a0a10
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/rand.h>
+#include <talloc.h>
+
+#include <tr_rand_id.h>
+
+static char *bytes_to_hex(TALLOC_CTX *mem_ctx, const unsigned char *bytes, size_t len)
+{
+  char *hex = talloc_size(mem_ctx, 1 + len * 2 * sizeof(char));
+  char *p = NULL;
+
+  if (hex) {
+    p = hex;
+    while(len--) {
+      p += sprintf(p, "%02x", *(bytes++));
+    }
+  }
+
+  return hex;
+}
+
+/**
+ * Generate n random bytes of data
+ *
+ * @param dst destination buffer, at least n bytes long
+ * @param n number of bytes to generate
+ * @return -1 on error
+ */
+static int random_bytes(unsigned char *dst, size_t n)
+{
+  return RAND_pseudo_bytes(dst, n);
+}
+
+#define ID_LENGTH 15
+/**
+ * Generate a random ID
+ *
+ * @param mem_ctx talloc context for the result
+ * @return random string of hex characters or null if it is unable to generate them
+ */
+char *tr_random_id(TALLOC_CTX *mem_ctx)
+{
+  unsigned char bytes[ID_LENGTH];
+  char *hex = NULL;
+
+  if (random_bytes(bytes, ID_LENGTH) >= 0)
+    hex = bytes_to_hex(mem_ctx, bytes, ID_LENGTH);
+
+  return hex;
+}
index 6b6fb78..8613eb8 100644 (file)
@@ -52,6 +52,7 @@ struct tid_srvr_blk {
 
 struct tid_resp {
   TID_RC result;
+  TR_NAME *request_id;
   TR_NAME *err_msg;
   TR_NAME *rp_realm;
   TR_NAME *realm;
@@ -67,6 +68,7 @@ struct tid_req {
   int resp_sent;
   int conn;
   int free_conn; /* free conn and gss ctx*/
+  TR_NAME *request_id;
   gss_ctx_id_t gssctx;
   int resp_rcvd;
   TR_NAME *rp_realm;
diff --git a/include/tr_rand_id.h b/include/tr_rand_id.h
new file mode 100644 (file)
index 0000000..8632c89
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TRUST_ROUTER_TR_RAND_ID_H
+#define TRUST_ROUTER_TR_RAND_ID_H
+
+char *tr_random_id(TALLOC_CTX *mem_ctx);
+
+#endif //TRUST_ROUTER_TR_RAND_ID_H
index 35ec577..38833f1 100644 (file)
@@ -96,6 +96,8 @@ TR_EXPORT TR_NAME *tid_req_get_comm(TID_REQ *req);
 void tid_req_set_comm(TID_REQ *req, TR_NAME *comm);
 TR_EXPORT TR_NAME *tid_req_get_orig_coi(TID_REQ *req);
 void tid_req_set_orig_coi(TID_REQ *req, TR_NAME *orig_coi);
+TR_EXPORT TR_NAME *tid_req_get_request_id(TID_REQ *req);
+void tid_req_set_request_id(TID_REQ *req, TR_NAME *request_id);
 TR_EXPORT TIDC_RESP_FUNC *tid_req_get_resp_func(TID_REQ *req);
 void tid_req_set_resp_func(TID_REQ *req, TIDC_RESP_FUNC *resp_func);
 TR_EXPORT void *tid_req_get_cookie(TID_REQ *req);
@@ -120,6 +122,8 @@ TR_EXPORT TR_NAME *tid_resp_get_comm(TID_RESP *resp);
 void tid_resp_set_comm(TID_RESP *resp, TR_NAME *comm);
 TR_EXPORT TR_NAME *tid_resp_get_orig_coi(TID_RESP *resp);
 void tid_resp_set_orig_coi(TID_RESP *resp, TR_NAME *orig_coi);
+TR_EXPORT TR_NAME *tid_resp_get_request_id(TID_RESP *resp);
+void tid_resp_set_request_id(TID_RESP *resp, TR_NAME *request_id);
 TR_EXPORT TID_SRVR_BLK *tid_resp_get_server(TID_RESP *resp, size_t index);
 TR_EXPORT size_t tid_resp_get_num_servers(const TID_RESP *resp);
 TR_EXPORT const TID_PATH *tid_resp_get_error_path(const TID_RESP *);
index 88dd991..002b720 100644 (file)
@@ -63,6 +63,8 @@ static int destroy_tid_req(TID_REQ *req)
     tr_free_name(req->comm);
   if (req->orig_coi!=NULL)
     tr_free_name(req->orig_coi);
+  if (req->request_id!=NULL)
+    tr_free_name(req->request_id);
   return 0;
 }
 
@@ -76,6 +78,7 @@ TID_REQ *tid_req_new()
   assert(req->json_references);
   req->conn = -1;
   req->free_conn = 1;
+  req->request_id = NULL;
   return req;
 }
 
@@ -169,6 +172,16 @@ void tid_req_set_orig_coi(TID_REQ *req, TR_NAME *orig_coi)
   req->orig_coi = orig_coi;
 }
 
+void tid_req_set_request_id(TID_REQ *req, TR_NAME *request_id)
+{
+  req->request_id = request_id;
+}
+
+TR_NAME *tid_req_get_request_id(TID_REQ *req)
+{
+  return(req->request_id);
+}
+
 TIDC_RESP_FUNC *tid_req_get_resp_func(TID_REQ *req)
 {
   return(req->resp_func);
@@ -215,7 +228,13 @@ TID_REQ *tid_dup_req (TID_REQ *orig_req)
       tr_crit("tid_dup_req: Can't duplicate request (orig_coi).");
     }
   }
-  
+
+  if (orig_req->request_id) {
+    if (NULL == (new_req->request_id = tr_dup_name(orig_req->request_id))) {
+      tr_crit("tid_dup_req: Can't duplicate request (request_id).");
+    }
+  }
+
   return new_req;
 }
 
index dbbc906..3ff3d02 100644 (file)
@@ -53,6 +53,8 @@ static int tid_resp_destructor(void *obj)
     tr_free_name(resp->comm);
   if (resp->orig_coi!=NULL)
     tr_free_name(resp->orig_coi);
+  if (resp->request_id!=NULL)
+    tr_free_name(resp->request_id);
   return 0;
 }
 
@@ -68,6 +70,7 @@ TID_RESP *tid_resp_new(TALLOC_CTX *mem_ctx)
     resp->cons=NULL;
     resp->orig_coi=NULL;
     resp->servers=NULL;
+    resp->request_id=NULL;
     resp->error_path=NULL;
     talloc_set_destructor((void *)resp, tid_resp_destructor);
   }
@@ -192,6 +195,16 @@ void tid_resp_set_orig_coi(TID_RESP *resp, TR_NAME *orig_coi)
   resp->orig_coi = orig_coi;
 }
 
+TR_EXPORT TR_NAME *tid_resp_get_request_id(TID_RESP *resp)
+{
+  return(resp->request_id);
+}
+
+void tid_resp_set_request_id(TID_RESP *resp, TR_NAME *request_id)
+{
+  resp->request_id = request_id;
+}
+
 TR_EXPORT TID_SRVR_BLK *tid_resp_get_server(TID_RESP *resp,
                                            size_t index)
 {
index 94cd98d..90335f0 100644 (file)
@@ -41,6 +41,7 @@
 #include <tid_internal.h>
 #include <tr_msg.h>
 #include <tr_debug.h>
+#include <tr_rand_id.h>
 
 
 int tmp_len = 32;
@@ -96,6 +97,7 @@ int tidc_send_request (TIDC_INSTANCE *tidc,
                        void *cookie)
 {
   TID_REQ *tid_req = NULL;
+  char *request_id = NULL;
   int rc;
   int orig_conn = 0;
   gss_ctx_id_t *orig_gss_ctx = NULL;
@@ -129,6 +131,17 @@ int tidc_send_request (TIDC_INSTANCE *tidc,
 
   tid_req->tidc_dh = tr_dh_dup(tidc->gssc->client_dh);
 
+  /* generate an ID */
+  request_id = tr_random_id(NULL);
+  if (request_id) {
+    if (tid_req->request_id = tr_new_name(request_id))
+      tr_debug("tidc_send_request: Created TID request ID: %s", request_id);
+    else
+      tr_debug("tidc_send_request: Unable to set request ID, proceeding without one");
+    talloc_free(request_id);
+  } else
+    tr_debug("tidc_send_request: Failed to generate a TID request ID, proceeding without one");
+
   rc = tidc_fwd_request(tidc, tid_req, resp_handler, cookie);
   goto cleanup;
  error:
@@ -150,6 +163,7 @@ int tidc_fwd_request(TIDC_INSTANCE *tidc,
   TALLOC_CTX *tmp_ctx = talloc_new(NULL);
   TR_MSG *msg = NULL;
   TR_MSG *resp_msg = NULL;
+  TID_RESP *tid_resp = NULL;
   int rc = 0;
 
   /* Create and populate a TID msg structure */
@@ -168,11 +182,27 @@ int tidc_fwd_request(TIDC_INSTANCE *tidc,
     goto error;
 
   /* TBD -- Check if this is actually a valid response */
-  if (TID_RESPONSE != tr_msg_get_msg_type(resp_msg)) {
+  tid_resp = tr_msg_get_resp(resp_msg);
+  if (tid_resp == NULL) {
     tr_err( "tidc_fwd_request: Error, no response in the response!\n");
     goto error;
   }
 
+  /* Check whether the request IDs matched and warn if not. Do nothing if we don't get
+   * an ID on the return - it is not mandatory to preserve that field. */
+  if (tid_req->request_id) {
+    if ((tid_resp->request_id)
+        && (tr_name_cmp(tid_resp->request_id, tid_req->request_id) != 0)) {
+      /* Requests present but do not match */
+      tr_warning("tidc_fwd_request: Sent request ID %.*s, received response for %.*s",
+                 tid_req->request_id->len, tid_req->request_id->buf,
+                 tid_resp->request_id->len, tid_resp->request_id->buf);
+    }
+  } else if (tid_resp->request_id) {
+    tr_warning("tidc_fwd_request: Sent request without ID, received response for %.*s",
+               tid_resp->request_id->len, tid_resp->request_id->buf);
+  }
+
   if (resp_handler) {
     /* Call the caller's response function. It must copy any data it needs before returning. */
     tr_debug("tidc_fwd_request: calling response callback function.");
index 6a5b172..9b9d51f 100644 (file)
@@ -80,6 +80,12 @@ static TID_RESP *tids_create_response(TALLOC_CTX *mem_ctx, TID_REQ *req)
       goto cleanup;
     }
   }
+  if (req->request_id) {
+    if (NULL == (resp->request_id = tr_dup_name(req->request_id))) {
+      tr_crit("tids_create_response: Error allocating fields in response.");
+      goto cleanup;
+    }
+  }
 
   success=1;
 
index 038cc3c..62722e8 100644 (file)
@@ -346,6 +346,12 @@ static int tr_tids_req_handler(TIDS_INSTANCE *tids,
 
   tr_debug("tr_tids_req_handler: Request received (conn = %d)! Realm = %s, Comm = %s", orig_req->conn, 
            orig_req->realm->buf, orig_req->comm->buf);
+  if (orig_req->request_id)
+    tr_debug("tr_tids_req_handler: TID request ID: %.*s", orig_req->request_id->len, orig_req->request_id->buf);
+  else
+    tr_debug("tr_tids_req_handler: TID request ID: none");
+
+  tids->req_count++;
 
   /* Duplicate the request, so we can modify and forward it */
   if (NULL == (fwd_req=tid_dup_req(orig_req))) {