Support 'show serial' monitoring request
authorJennifer Richards <jennifer@painless-security.com>
Fri, 20 Apr 2018 18:47:12 +0000 (14:47 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Fri, 20 Apr 2018 18:47:12 +0000 (14:47 -0400)
CMakeLists.txt
Makefile.am
common/tr_config.c
common/tr_config_encoders.c [new file with mode: 0644]
include/tr_config.h
tr/tr_main.c

index c031f68..8e16f20 100644 (file)
@@ -96,7 +96,7 @@ set(SOURCE_FILES
     trp/trp_upd.c
     trp/trpc.c
     trp/trps.c include/tr_name_internal.h mon/mon_req.c mon/mon_req_encode.c mon/mon_req_decode.c
-        mon/mon_resp.c mon/mon_common.c mon/mon_resp_encode.c mon/mon_resp_decode.c tr/tr_mon.c mon/mons.c include/tr_socket.h common/tr_gss.c include/tr_gss.h common/tr_config_internal.c mon/mons_handlers.c include/mons_handlers.h tr/tr_tid_mons.c tr/tr_tid_mons.c trp/trp_route.c include/trp_route.h trp/trp_rtable_encoders.c trp/trp_route_encoders.c trp/trp_peer.c include/trp_peer.h trp/trp_peer_encoders.c trp/trp_ptable_encoders.c common/tr_idp_encoders.c common/tr_comm_encoders.c common/tr_rp_client.c include/tr_rp_client.h common/tr_rp_client_encoders.c common/tr_filter_encoders.c)
+        mon/mon_resp.c mon/mon_common.c mon/mon_resp_encode.c mon/mon_resp_decode.c tr/tr_mon.c mon/mons.c include/tr_socket.h common/tr_gss.c include/tr_gss.h common/tr_config_internal.c mon/mons_handlers.c include/mons_handlers.h tr/tr_tid_mons.c tr/tr_tid_mons.c trp/trp_route.c include/trp_route.h trp/trp_rtable_encoders.c trp/trp_route_encoders.c trp/trp_peer.c include/trp_peer.h trp/trp_peer_encoders.c trp/trp_ptable_encoders.c common/tr_idp_encoders.c common/tr_comm_encoders.c common/tr_rp_client.c include/tr_rp_client.h common/tr_rp_client_encoders.c common/tr_filter_encoders.c common/tr_config_encoders.c)
 
 # Does not actually build!
 add_executable(trust_router ${SOURCE_FILES})
index 5ef3761..142fea6 100644 (file)
@@ -49,6 +49,7 @@ trp/trp_req.c \
 trp/trp_upd.c \
 common/tr_config.c \
 common/tr_config_internal.c \
+common/tr_config_encoders.c \
 common/tr_mq.c
 
 # general monitoring message sources
index dc6f77b..5fc4884 100644 (file)
@@ -125,6 +125,13 @@ void tr_print_comm_rps(TR_COMM_TABLE *ctab, TR_COMM *comm)
   talloc_free(tmp_ctx);
 }
 
+static int tr_cfg_destructor(void *object)
+{
+  TR_CFG *cfg = talloc_get_type_abort(object, TR_CFG);
+  if (cfg->files)
+    g_array_unref(cfg->files);
+  return 0;
+}
 TR_CFG *tr_cfg_new(TALLOC_CTX *mem_ctx)
 {
   TR_CFG *cfg=talloc(mem_ctx, TR_CFG);
@@ -136,8 +143,14 @@ TR_CFG *tr_cfg_new(TALLOC_CTX *mem_ctx)
     cfg->ctable=tr_comm_table_new(cfg);
     if (cfg->ctable==NULL) {
       talloc_free(cfg);
-      cfg=NULL;
+      return NULL;
+    }
+    cfg->files = g_array_new(FALSE, FALSE, sizeof(TR_CFG_FILE));
+    if (cfg->files == NULL) {
+      talloc_free(cfg);
+      return NULL;
     }
+    talloc_set_destructor((void *)cfg, tr_cfg_destructor);
   }
   return cfg;
 }
@@ -1784,7 +1797,6 @@ static void tr_cfg_log_json_error(const char *label, json_error_t *rc)
 static json_t *tr_cfg_parse_one_config_file(const char *file_with_path)
 {
   json_t *jcfg=NULL;
-  json_t *jser=NULL;
   json_error_t rc;
 
   if (NULL==(jcfg=json_load_file(file_with_path, 
@@ -1795,16 +1807,20 @@ static json_t *tr_cfg_parse_one_config_file(const char *file_with_path)
     return NULL;
   }
 
-  // Look for serial number and log it if it exists (borrowed reference, so no need to free it later)
-  if (NULL!=(jser=json_object_get(jcfg, "serial_number"))) {
-    if (json_is_number(jser)) {
-      tr_notice("tr_parse_one_config_file: Attempting to load revision %" JSON_INTEGER_FORMAT " of '%s'.",
-                json_integer_value(jser),
-                file_with_path);
+  return jcfg;
+}
+
+/* extract serial number */
+static json_int_t get_cfg_serial(json_t *jcfg)
+{
+  json_t *jser=NULL;
+
+  if (NULL != (jser = json_object_get(jcfg, "serial_number"))) {
+    if (json_is_integer(jser)) {
+      return json_integer_value(jser);
     }
   }
-
-  return jcfg;
+  return TR_CFG_INVALID_SERIAL;
 }
 
 /**
@@ -1829,11 +1845,12 @@ static void tr_cfg_parse_free_jcfgs(unsigned int n_jcfgs, json_t **jcfgs)
  * @param cfg_files
  * @return
  */
-static json_t **tr_cfg_parse_config_files(TALLOC_CTX *mem_ctx, unsigned int n_files, char **files_with_paths)
+static json_t **tr_cfg_parse_config_files(TALLOC_CTX *mem_ctx, unsigned int n_files, GArray *files)
 {
   TALLOC_CTX *tmp_ctx=talloc_new(NULL);
   unsigned int ii=0;
   json_t **jcfgs=NULL;
+  TR_CFG_FILE *this_file = NULL;
 
   /* first allocate the jcfgs */
   jcfgs=talloc_array(NULL, json_t *, n_files);
@@ -1842,14 +1859,28 @@ static json_t **tr_cfg_parse_config_files(TALLOC_CTX *mem_ctx, unsigned int n_fi
     goto cleanup;
   }
   for (ii=0; ii<n_files; ii++) {
-    jcfgs[ii]=tr_cfg_parse_one_config_file(files_with_paths[ii]);
+    this_file = &g_array_index(files, TR_CFG_FILE, ii);
+    jcfgs[ii]=tr_cfg_parse_one_config_file(this_file->name);
     if (jcfgs[ii]==NULL) {
-      tr_err("tr_parse_config: Error parsing JSON in %s", files_with_paths[ii]);
+      tr_err("tr_parse_config: Error parsing JSON in %s", this_file->name);
       tr_cfg_parse_free_jcfgs(ii, jcfgs); /* frees the JSON objects and the jcfgs array */
       jcfgs=NULL;
       goto cleanup;
     }
+
+    this_file->serial = get_cfg_serial(jcfgs[ii]);
+    if (this_file->serial != TR_CFG_INVALID_SERIAL) {
+      tr_notice("tr_parse_one_config_file: Attempting to load revision %"
+                    JSON_INTEGER_FORMAT
+                    " of '%s'.",
+                this_file->serial,
+                this_file->name);
+    } else {
+      tr_notice("tr_parse_one_config_file: Attempting to load '%s'.",
+                this_file->name);
+    }
   }
+
 cleanup:
   if (jcfgs)
     talloc_steal(mem_ctx, jcfgs); /* give this to the caller's context if we succeeded */
@@ -1899,9 +1930,20 @@ static TR_CFG_RC tr_cfg_parse_helper(TR_CFG *cfg,
   return ret;
 }
 
+static void add_files(TR_CFG *cfg, unsigned int n, char **filenames)
+{
+  TR_CFG_FILE frec = {0};
+
+  while ((n--) > 0) {
+    frec.name = talloc_strdup(cfg, filenames[n]);
+    frec.serial = TR_CFG_INVALID_SERIAL;
+
+    g_array_append_val(cfg->files, frec);
+  }
+}
 
 /**
- *  Reads configuration files in config_dir ("" or "./" will use the current directory).
+ *  Read a list of configuration files
  *
  * @param cfg_mgr Configuration manager
  * @param n_files Number of entries in cfg_files
@@ -1928,8 +1970,11 @@ TR_CFG_RC tr_parse_config(TR_CFG_MGR *cfg_mgr, unsigned int n_files, char **file
     goto cleanup;
   }
 
+  /* add the list of files to the config */
+  add_files(cfg_mgr->new, n_files, files_with_paths);
+
   /* first parse the json */
-  jcfgs=tr_cfg_parse_config_files(tmp_ctx, n_files, files_with_paths);
+  jcfgs=tr_cfg_parse_config_files(tmp_ctx, n_files, cfg_mgr->new->files);
   if (jcfgs==NULL) {
     cfg_rc=TR_CFG_NOPARSE;
     goto cleanup;
@@ -2006,7 +2051,7 @@ TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *tr_cfg, TR_NAME *rp_gss, TR_CFG_RC *rc)
 }
 
 static int is_cfg_file(const struct dirent *dent) {
-  int n;
+  size_t n;
 
   /* Only accept filenames ending in ".cfg" and starting with a character
    * other than an ASCII '.' */
diff --git a/common/tr_config_encoders.c b/common/tr_config_encoders.c
new file mode 100644 (file)
index 0000000..47331d9
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012, 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 <jansson.h>
+#include <tr_config.h>
+
+/* helper for below */
+#define OBJECT_SET_OR_FAIL(jobj, key, val)     \
+do {                                           \
+  if (val)                                     \
+    json_object_set_new((jobj),(key),(val));   \
+  else                                         \
+    goto cleanup;                              \
+} while (0)
+
+#define ARRAY_APPEND_OR_FAIL(jary, val)        \
+do {                                           \
+  if (val)                                     \
+    json_array_append_new((jary),(val));       \
+  else                                         \
+    goto cleanup;                              \
+} while (0)
+
+static json_t *tr_cfg_file_to_json(TR_CFG_FILE *cfg_file)
+{
+  json_t *file_json = NULL;
+  json_t *retval = NULL;
+
+  file_json = json_object();
+  if (file_json == NULL)
+    goto cleanup;
+
+  OBJECT_SET_OR_FAIL(file_json, "name", json_string(cfg_file->name));
+  if (cfg_file->serial != TR_CFG_INVALID_SERIAL)
+    OBJECT_SET_OR_FAIL(file_json, "serial", json_integer(cfg_file->serial));
+
+  /* succeeded - set the return value and increment the reference count */
+  retval = file_json;
+  json_incref(retval);
+
+cleanup:
+  if (file_json)
+    json_decref(file_json);
+
+  return retval;
+}
+
+json_t *tr_cfg_files_to_json_array(TR_CFG *cfg)
+{
+  guint ii;
+  json_t *jarray = json_array();
+  json_t *retval = NULL;
+
+  if (jarray == NULL)
+    goto cleanup;
+
+  for (ii=0; ii<cfg->files->len; ii++) {
+    ARRAY_APPEND_OR_FAIL(jarray,
+                         tr_cfg_file_to_json(
+                             &g_array_index(cfg->files, TR_CFG_FILE, ii)));
+  }
+
+  /* success */
+  retval = jarray;
+  json_incref(retval);
+
+cleanup:
+  if (jarray)
+    json_decref(jarray);
+
+  return retval;
+}
index 64339e7..c2a0a50 100644 (file)
@@ -41,6 +41,7 @@
 #include <syslog.h>
 #include <sys/time.h>
 #include <talloc.h>
+#include <gmodule.h>
 
 #include <tr_comm.h>
 #include <tr_rp.h>
@@ -62,6 +63,8 @@
 #define TR_DEFAULT_TID_RESP_NUMER 2
 #define TR_DEFAULT_TID_RESP_DENOM 3
 
+#define TR_CFG_INVALID_SERIAL -1
+
 typedef enum tr_cfg_rc {
   TR_CFG_SUCCESS = 0,  /* No error */
   TR_CFG_ERROR,                /* General processing error */
@@ -88,13 +91,20 @@ typedef struct tr_cfg_internal {
   unsigned int tid_resp_denom; /* denominator of fraction of AAA servers to wait for in unshared mode */
 } TR_CFG_INTERNAL;
 
+/* record of files loaded for this configuration */
+typedef struct tr_cfg_file {
+  const char *name;
+  json_int_t serial;
+} TR_CFG_FILE;
+
 typedef struct tr_cfg {
   TR_CFG_INTERNAL *internal;           /* internal trust router config */
   TR_RP_CLIENT *rp_clients;            /* locally associated RP Clients */
   TRP_PTABLE *peers; /* TRP peer table */
   TR_COMM_TABLE *ctable; /* communities/realms */
   TR_AAA_SERVER *default_servers;      /* default server list */
-  /* TBD -- Global Filters */
+
+  GArray *files; /* files loaded to make this configuration */
 } TR_CFG;
 
 typedef struct tr_cfg_mgr {
@@ -123,4 +133,7 @@ TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *cfg, TR_NAME *rp_gss, TR_CFG_RC *rc);
 /* tr_config_internal.c */
 TR_CFG_RC tr_cfg_parse_internal(TR_CFG *trc, json_t *jint);
 
+/* tr_config_encoders.c */
+json_t *tr_cfg_files_to_json_array(TR_CFG *cfg);
+
 #endif
index 6260bbb..35c32e0 100644 (file)
@@ -167,6 +167,14 @@ static MON_RC tr_handle_show_rp_clients(void *cookie, json_t **response_ptr)
   return (*response_ptr == NULL) ? MON_NOMEM : MON_SUCCESS;
 }
 
+static MON_RC tr_handle_show_cfg_serial(void *cookie, json_t **response_ptr)
+{
+  TR_CFG_MGR *cfg_mgr = talloc_get_type_abort(cookie, TR_CFG_MGR);
+
+  *response_ptr = tr_cfg_files_to_json_array(cfg_mgr->active);
+  return (*response_ptr == NULL) ? MON_NOMEM : MON_SUCCESS;
+}
+
 
 
 int main(int argc, char *argv[])
@@ -242,6 +250,7 @@ int main(int argc, char *argv[])
 
   /* Register monitoring handlers */
   mons_register_handler(tr->mons, MON_CMD_SHOW, OPT_TYPE_SHOW_VERSION, tr_handle_version, NULL);
+  mons_register_handler(tr->mons, MON_CMD_SHOW, OPT_TYPE_SHOW_SERIAL, tr_handle_show_cfg_serial, tr->cfg_mgr);
   mons_register_handler(tr->mons, MON_CMD_SHOW, OPT_TYPE_SHOW_UPTIME, tr_handle_uptime, &start_time);
   mons_register_handler(tr->mons, MON_CMD_SHOW, OPT_TYPE_SHOW_RP_CLIENTS, tr_handle_show_rp_clients, tr->cfg_mgr);
   tr_tid_register_mons_handlers(tr->tids, tr->mons);