From 2723a185ec02fb023a3b25c47cb40178f696eee0 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Tue, 29 May 2018 15:07:55 -0400 Subject: [PATCH] Validate internal configuration more thoroughly --- common/tr_config.c | 7 ++- common/tr_config_internal.c | 114 ++++++++++++++++++++++++++++++++++++++++++-- include/tr_config.h | 9 ++++ 3 files changed, 123 insertions(+), 7 deletions(-) diff --git a/common/tr_config.c b/common/tr_config.c index 2ddda12..e0becec 100644 --- a/common/tr_config.c +++ b/common/tr_config.c @@ -195,11 +195,10 @@ TR_CFG_RC tr_cfg_validate(TR_CFG *trc) if (!trc) return TR_CFG_BAD_PARAMS; - if ((NULL == trc->internal)|| - (NULL == trc->internal->hostname)) { - tr_debug("tr_cfg_validate: Error: No internal configuration, or no hostname."); + /* validate the internal config - error messages will be generated there, so don't genreate + * our own */ + if (tr_cfg_validate_internal(trc->internal) != TR_CFG_SUCCESS) rc = TR_CFG_ERROR; - } if (NULL == trc->rp_clients) { tr_debug("tr_cfg_validate: Error: No RP Clients configured"); diff --git a/common/tr_config_internal.c b/common/tr_config_internal.c index d06dc51..dfb3d1d 100644 --- a/common/tr_config_internal.c +++ b/common/tr_config_internal.c @@ -91,11 +91,14 @@ static TR_CFG_RC tr_cfg_parse_unsigned(json_t *src, const char *key, unsigned in /* 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); } } @@ -247,3 +250,108 @@ TR_CFG_RC tr_cfg_parse_internal(TR_CFG *trc, json_t *jint) 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; +} \ No newline at end of file diff --git a/include/tr_config.h b/include/tr_config.h index 8dc66c4..9077607 100644 --- a/include/tr_config.h +++ b/include/tr_config.h @@ -64,6 +64,14 @@ #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 { @@ -131,6 +139,7 @@ void tr_print_comm_rps(TR_COMM_TABLE *ctab, TR_COMM *comm); /* 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); -- 2.1.4