Merge pull request #92 from painless-security/jennifer/reduce_logging
authorMark Donnelly <mark@painless-security.com>
Fri, 1 Jun 2018 13:34:51 +0000 (09:34 -0400)
committerGitHub <noreply@github.com>
Fri, 1 Jun 2018 13:34:51 +0000 (09:34 -0400)
Reduce logging during connection accept and validate internal configuration

1  2 
common/tr_config_internal.c
common/tr_socket.c
include/tr_config.h
mon/mons.c
tid/tids.c

@@@ -71,38 -71,6 +71,38 @@@ static TR_CFG_RC tr_cfg_parse_boolean(j
  }
  
  /**
 + * Parse a signed integer
 + *
 + * If the key does not exist in the src object, returns success but does fill in *dest.
 + *
 + * @param src JSON object to pull a value from
 + * @param key key to pull
 + * @param dest (output) pointer to an allocated integer
 + * @return TR_CFG_SUCCESS or an error code
 + */
 +static TR_CFG_RC tr_cfg_parse_integer(json_t *src, const char *key, int *dest)
 +{
 +  json_t *jtmp;
 +
 +  /* Validate parameters */
 +  if ((src == NULL) || (key == NULL) || (dest == NULL))
 +    return TR_CFG_BAD_PARAMS;
 +
 +  /* See if we have a value for this key; do nothing if not */
 +  jtmp = json_object_get(src, key);
 +  if (jtmp) {
 +    if (json_is_number(jtmp)) {
 +      *dest = (int) json_integer_value(jtmp);
 +    } else {
 +      tr_debug("tr_cfg_parse_unsigned: Parsing error, %s is not a number.", key);
 +      return TR_CFG_NOPARSE;
 +    }
 +  }
 +
 +  return TR_CFG_SUCCESS;
 +}
 +
 +/**
   * Parse an unsigned integer
   *
   * If the key does not exist in the src object, returns success but does fill in *dest.
@@@ -123,11 -91,14 +123,14 @@@ static TR_CFG_RC tr_cfg_parse_unsigned(
    /* See if we have a value for this key; do nothing if not */
    jtmp = json_object_get(src, key);
    if (jtmp) {
-     if (json_is_number(jtmp)) {
-       *dest = (unsigned int) json_integer_value(jtmp);
-     } else {
+     if (! json_is_number(jtmp)) {
        tr_debug("tr_cfg_parse_unsigned: Parsing error, %s is not a number.", key);
        return TR_CFG_NOPARSE;
+     } else if (json_integer_value(jtmp) < 0) {
+       tr_debug("tr_cfg_parse_unsigned: Value %d < 0.", json_integer_value(jtmp));
+       return TR_CFG_NOPARSE;
+     } else {
+       *dest = (unsigned int) json_integer_value(jtmp);
      }
    }
  
@@@ -182,7 -153,7 +185,7 @@@ static void set_defaults(TR_CFG_INTERNA
    cfg->max_tree_depth = TR_DEFAULT_MAX_TREE_DEPTH;
    cfg->tids_port = TR_DEFAULT_TIDS_PORT;
    cfg->trps_port = TR_DEFAULT_TRPS_PORT;
 -  cfg->monitoring_port = TR_DEFAULT_MONITORING_PORT;
 +  cfg->mons_port = TR_DEFAULT_MONITORING_PORT;
    cfg->cfg_poll_interval = TR_CFGWATCH_DEFAULT_POLL;
    cfg->cfg_settling_time = TR_CFGWATCH_DEFAULT_SETTLE;
    cfg->trp_connect_interval = TR_DEFAULT_TRP_CONNECT_INTERVAL;
@@@ -209,7 -180,7 +212,7 @@@ static TR_CFG_RC tr_cfg_parse_monitorin
  
    NOPARSE_UNLESS(tr_cfg_parse_boolean(jmon, "enabled", &enabled));
    if (enabled) {
 -    NOPARSE_UNLESS(tr_cfg_parse_unsigned(jmon, "port", &(trc->internal->monitoring_port)));
 +    NOPARSE_UNLESS(tr_cfg_parse_integer(jmon, "port", &(trc->internal->mons_port)));
      NOPARSE_UNLESS(tr_cfg_parse_gss_names(trc->internal,
                                            json_object_get(jmon, "authorized_credentials"),
                                            &(trc->internal->monitoring_credentials)));
@@@ -245,8 -216,8 +248,8 @@@ TR_CFG_RC tr_cfg_parse_internal(TR_CFG 
    talloc_steal(trc->internal, trc->internal->hostname);
  
    NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "max_tree_depth",           &(trc->internal->max_tree_depth)));
 -  NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "tids_port",                &(trc->internal->tids_port)));
 -  NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "trps_port",                &(trc->internal->trps_port)));
 +  NOPARSE_UNLESS(tr_cfg_parse_integer(jint, "tids_port",                &(trc->internal->tids_port)));
 +  NOPARSE_UNLESS(tr_cfg_parse_integer(jint, "trps_port",                &(trc->internal->trps_port)));
    NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "cfg_poll_interval",        &(trc->internal->cfg_poll_interval)));
    NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "cfg_settling_time",        &(trc->internal->cfg_settling_time)));
    NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "trp_connect_interval",     &(trc->internal->trp_connect_interval)));
    tr_debug("tr_cfg_parse_internal: Internal config parsed.");
    return TR_CFG_SUCCESS;
  }
+ static int invalid_port(int port)
+ {
+   return ((port <= 0) || (port > 65536));
+ }
+ /**
+  * Validate the internal configuration of the trust router
+  *
+  * Validates fields, emitting errors if there are any. Safe to call with
+  * a null int_cfg, but this results in an error being returned.
+  *
+  * @param int_cfg pointer to an internal configuration (NULL is safe)
+  * @return success or error
+  */
+ TR_CFG_RC tr_cfg_validate_internal(TR_CFG_INTERNAL *int_cfg)
+ {
+   TR_CFG_RC rc;
+   /* ensure we have an internal configuration and exit if not  */
+   if (NULL == int_cfg) {
+     tr_debug("tr_cfg_validate_internal: No internal configuration present.");
+     return TR_CFG_BAD_PARAMS;
+   }
+   /* Assume we are going to succeed. If any errors are encountered, emit a message
+    * and set the return code to an error. Don't exit early, emit all the errors
+    * at once if we can. */
+   rc = TR_CFG_SUCCESS;
+   /*** Validate hostname ***/
+   if (NULL == int_cfg->hostname) {
+     tr_debug("tr_cfg_validate_internal: No hostname specified.");
+     rc = TR_CFG_ERROR;
+   }
+   /*** Validate various intervals ***/
+   if (TR_MIN_TRP_CONNECT_INTERVAL > int_cfg->trp_connect_interval) {
+     tr_debug(
+         "tr_cfg_validate_internal: Error: trp_connect_interval must be at least %d (currently %d).",
+         TR_MIN_TRP_CONNECT_INTERVAL, int_cfg->trp_connect_interval);
+     rc = TR_CFG_ERROR;
+   }
+   if (TR_MIN_TRP_SWEEP_INTERVAL > int_cfg->trp_sweep_interval) {
+     tr_debug(
+         "tr_cfg_validate_internal: Error: trp_sweep_interval must be at least %d (currently %d).",
+         TR_MIN_TRP_SWEEP_INTERVAL, int_cfg->trp_sweep_interval);
+     rc = TR_CFG_ERROR;
+   }
+   if (TR_MIN_TRP_UPDATE_INTERVAL > int_cfg->trp_update_interval) {
+     tr_debug(
+         "tr_cfg_validate_internal: Error: trp_update_interval must be at least %d (currently %d).",
+         TR_MIN_TRP_UPDATE_INTERVAL, int_cfg->trp_update_interval);
+     rc = TR_CFG_ERROR;
+   }
+   if (TR_MIN_CFG_POLL_INTERVAL > int_cfg->cfg_poll_interval) {
+     tr_debug(
+         "tr_cfg_validate_internal: Error: cfg_poll_interval must be at least %d (currently %d).",
+         TR_MIN_CFG_POLL_INTERVAL, int_cfg->cfg_poll_interval);
+     rc = TR_CFG_ERROR;
+   }
+   if (TR_MIN_CFG_SETTLING_TIME > int_cfg->cfg_settling_time) {
+     tr_debug(
+         "tr_cfg_validate_internal: Error: cfg_settling_time must be at least %d (currently %d).",
+         TR_MIN_CFG_SETTLING_TIME, int_cfg->cfg_settling_time);
+     rc = TR_CFG_ERROR;
+   }
+   /*** Validate ports ***/
+   if (invalid_port(int_cfg->tids_port)) {
+     tr_debug("tr_cfg_validate_internal: Error: invalid tids_port (%d).", int_cfg->tids_port);
+     rc = TR_CFG_ERROR;
+   }
+   if (invalid_port(int_cfg->trps_port)) {
+     tr_debug("tr_cfg_validate_internal: Error: invalid trps_port (%d).", int_cfg->trps_port);
+     rc = TR_CFG_ERROR;
+   }
+   if (invalid_port(int_cfg->monitoring_port)) {
+     tr_debug("tr_cfg_validate_internal: Error: invalid monitoring port (%d).", int_cfg->monitoring_port);
+     rc = TR_CFG_ERROR;
+   }
+   /*** Validate tid request timeout ***/
+   if (TR_MIN_TID_REQ_TIMEOUT > int_cfg->tid_req_timeout) {
+     tr_debug("tr_cfg_validate_internal: Error: tid_request_timeout must be at least %d (currently %d).",
+              TR_MIN_TID_REQ_TIMEOUT, int_cfg->tid_req_timeout);
+     rc = TR_CFG_ERROR;
+   }
+   /*** Validate tid response parameters ***/
+   if ((int_cfg->tid_resp_numer <= 0)
+       || (int_cfg->tid_resp_denom <= 0)
+       || (int_cfg->tid_resp_numer > int_cfg->tid_resp_denom)) {
+     tr_debug("tr_cfg_validate_internal: Error: invalid tid_response_numerator / tid_response_denominator. Both must be positive and the numerator/denominator ratio must be <= 1 (currently %d/%d).",
+              int_cfg->tid_resp_numer, int_cfg->tid_resp_denom);
+     rc = TR_CFG_ERROR;
+   }
+   return rc;
+ }
diff --combined common/tr_socket.c
@@@ -55,7 -55,7 +55,7 @@@
   * @param max_fd maximum number of file descriptors to write
   * @return number of file descriptors written into the output array
   */
 -nfds_t tr_sock_listen_all(unsigned int port, int *fd_out, nfds_t max_fd)
 +nfds_t tr_sock_listen_all(int port, int *fd_out, nfds_t max_fd)
  {
    int rc = 0;
    int conn = -1;
@@@ -188,9 -188,9 +188,9 @@@ int tr_sock_accept(int sock
    if (0 > (conn = accept(sock, (struct sockaddr *)&(peeraddr), &addr_len))) {
      if (strerror_r(errno, err, sizeof(err)))
        snprintf(err, sizeof(err), "errno = %d", errno);
-     tr_err("tr_sock_accept: Unable to accept connection: %s", err);
+     tr_debug("tr_sock_accept: Unable to accept connection: %s", err);
    } else {
-     tr_notice("tr_sock_accept: Incoming connection on fd %d from %s",
+     tr_info("tr_sock_accept: Incoming connection on fd %d from %s",
                conn,
                tr_sock_ip_address((struct sockaddr *)&peeraddr,
                                   peeraddr_string,
diff --combined include/tr_config.h
  #define TR_DEFAULT_TID_RESP_NUMER 2
  #define TR_DEFAULT_TID_RESP_DENOM 3
  
+ /* limits on values for validations */
+ #define TR_MIN_TRP_CONNECT_INTERVAL 5
+ #define TR_MIN_TRP_SWEEP_INTERVAL 5
+ #define TR_MIN_TRP_UPDATE_INTERVAL 5
+ #define TR_MIN_CFG_POLL_INTERVAL 1
+ #define TR_MIN_CFG_SETTLING_TIME 0
+ #define TR_MIN_TID_REQ_TIMEOUT 1
  #define TR_CFG_INVALID_SERIAL -1
  
  typedef enum tr_cfg_rc {
@@@ -76,9 -84,9 +84,9 @@@
  
  typedef struct tr_cfg_internal {
    unsigned int max_tree_depth;
 -  unsigned int tids_port;
 -  unsigned int trps_port;
 -  unsigned int monitoring_port;
 +  int tids_port;
 +  int trps_port;
 +  int mons_port;
    const char *hostname;
    int log_threshold;
    int console_threshold;
@@@ -131,6 -139,7 +139,7 @@@ void tr_print_comm_rps(TR_COMM_TABLE *c
  
  /* tr_config_internal.c */
  TR_CFG_RC tr_cfg_parse_internal(TR_CFG *trc, json_t *jint);
+ TR_CFG_RC tr_cfg_validate_internal(TR_CFG_INTERNAL *int_cfg);
  
  /* tr_config_comms.c */
  TR_IDP_REALM *tr_cfg_find_idp (TR_CFG *tr_cfg, TR_NAME *idp_id, TR_CFG_RC *rc);
diff --combined mon/mons.c
@@@ -73,7 -73,7 +73,7 @@@ MONS_INSTANCE *mons_new(TALLOC_CTX *mem
  
    if (mons) {
      mons->hostname = NULL;
 -    mons->port = 0;
 +    mons->mon_port = 0;
      mons->tids = NULL;
      mons->trps = NULL;
      mons->req_handler = NULL;
@@@ -175,22 -175,16 +175,22 @@@ cleanup
   * @param max_fd
   * @return
   */
 -int mons_get_listener(MONS_INSTANCE *mons, MONS_REQ_FUNC *req_handler, MONS_AUTH_FUNC *auth_handler, const char *hostname,
 -                      unsigned int port, void *cookie, int *fd_out, size_t max_fd)
 +int mons_get_listener(MONS_INSTANCE *mons,
 +                      MONS_REQ_FUNC *req_handler,
 +                      MONS_AUTH_FUNC *auth_handler,
 +                      const char *hostname,
 +                      int port,
 +                      void *cookie,
 +                      int *fd_out,
 +                      size_t max_fd)
  {
    size_t n_fd=0;
    size_t ii=0;
  
 -  mons->port = port;
 +  mons->mon_port = port;
    n_fd = tr_sock_listen_all(port, fd_out, max_fd);
    if (n_fd<=0)
 -    tr_err("mons_get_listener: Error opening port %d");
 +    tr_err("mons_get_listener: Error opening port %d", port);
    else {
      /* opening port succeeded */
      tr_info("mons_get_listener: Opened port %d.", port);
@@@ -275,7 -269,7 +275,7 @@@ int mons_accept(MONS_INSTANCE *mons, in
    int pid=-1;
  
    if (0 > (conn = tr_sock_accept(listen))) {
-     tr_err("mons_accept: Error accepting connection");
+     tr_debug("mons_accept: Error accepting connection");
      return 1;
    }
  
diff --combined tid/tids.c
@@@ -356,7 -356,7 +356,7 @@@ nfds_t tids_get_listener(TIDS_INSTANCE 
                           TIDS_REQ_FUNC *req_handler,
                           tids_auth_func *auth_handler,
                           const char *hostname,
 -                         unsigned int port,
 +                         int port,
                           void *cookie,
                           int *fd_out,
                           size_t max_fd)
    n_fd = tr_sock_listen_all(port, fd_out, max_fd);
  
    if (n_fd == 0)
 -    tr_err("tids_get_listener: Error opening port %d");
 +    tr_err("tids_get_listener: Error opening port %d", port);
    else {
      /* opening port succeeded */
      tr_info("tids_get_listener: Opened port %d.", port);
@@@ -464,7 -464,7 +464,7 @@@ int tids_accept(TIDS_INSTANCE *tids, in
    struct tid_process tp = {0};
  
    if (0 > (conn = tr_sock_accept(listen))) {
-     tr_err("tids_accept: Error accepting connection");
+     tr_debug("tids_accept: Error accepting connection");
      return 1;
    }
  
@@@ -574,12 -574,12 +574,12 @@@ void tids_sweep_procs(TIDS_INSTANCE *ti
  }
  
  /* Process tids requests forever. Should not return except on error. */
 -int tids_start (TIDS_INSTANCE *tids,
 -                TIDS_REQ_FUNC *req_handler,
 -                tids_auth_func *auth_handler,
 -                const char *hostname,
 -                unsigned int port,
 -                void *cookie)
 +int tids_start(TIDS_INSTANCE *tids,
 +               TIDS_REQ_FUNC *req_handler,
 +               tids_auth_func *auth_handler,
 +               const char *hostname,
 +               int port,
 +               void *cookie)
  {
    int fd[TR_MAX_SOCKETS]={0};
    nfds_t n_fd=0;
  
        if (poll_fd[ii].revents & POLLIN) {
          if (tids_accept(tids, poll_fd[ii].fd))
-           tr_err("tids_start: error in tids_accept().");
+           tr_debug("tids_start: error in tids_accept().");
        }
      }
    }