From d0cb62ba0250c3d95ac50c53a6c96789d58f6527 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 20 Apr 2018 18:32:38 -0400 Subject: [PATCH] Read GSS credentials for monitoring service Some refactoring here and there, too. --- common/tr_config_internal.c | 34 ++++++++++++++++++++++++++++++++++ common/tr_config_orgs.c | 2 +- common/tr_config_rp_clients.c | 30 +++++++++++++++--------------- common/tr_gss_names.c | 31 +++++++++++++++++++++++++++++++ common/tr_socket.c | 2 +- include/tr_config.h | 4 +++- include/tr_gss_names.h | 1 + tr/tr_mon.c | 10 ++++++++-- tr/tr_trp.c | 10 ++++++++++ 9 files changed, 104 insertions(+), 20 deletions(-) diff --git a/common/tr_config_internal.c b/common/tr_config_internal.c index 82a57e2..0ab306c 100644 --- a/common/tr_config_internal.c +++ b/common/tr_config_internal.c @@ -39,6 +39,38 @@ #include /** + * Parse a boolean + * + * 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_boolean(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_boolean(jtmp)) { + *dest = json_boolean_value(jtmp); + } else { + tr_debug("tr_cfg_parse_unsigned: Parsing error, %s is not a boolean.", 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. @@ -118,6 +150,7 @@ static void set_defaults(TR_CFG_INTERNAL *cfg) 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->cfg_poll_interval = TR_CFGWATCH_DEFAULT_POLL; cfg->cfg_settling_time = TR_CFGWATCH_DEFAULT_SETTLE; cfg->trp_connect_interval = TR_DEFAULT_TRP_CONNECT_INTERVAL; @@ -128,6 +161,7 @@ static void set_defaults(TR_CFG_INTERNAL *cfg) cfg->tid_resp_denom = TR_DEFAULT_TID_RESP_DENOM; cfg->log_threshold = TR_DEFAULT_LOG_THRESHOLD; cfg->console_threshold = TR_DEFAULT_CONSOLE_THRESHOLD; + cfg->monitoring_credentials = NULL; } /* Helper that checks return value of a parse fn and returns if it failed */ diff --git a/common/tr_config_orgs.c b/common/tr_config_orgs.c index 5674fce..f6925ca 100644 --- a/common/tr_config_orgs.c +++ b/common/tr_config_orgs.c @@ -215,7 +215,7 @@ static TR_CFG_RC tr_cfg_parse_one_peer_org(TR_CFG *trc, json_t *jporg) else trp_peer_set_port(new_peer, json_integer_value(jport)); - names=tr_cfg_parse_gss_names(tmp_ctx, jgss, &rc); + rc = tr_cfg_parse_gss_names(tmp_ctx, jgss, &names); if (rc!=TR_CFG_SUCCESS) { tr_err("tr_cfg_parse_one_peer_org: unable to parse gss names."); rc=TR_CFG_NOPARSE; diff --git a/common/tr_config_rp_clients.c b/common/tr_config_rp_clients.c index 01b36ba..960edce 100644 --- a/common/tr_config_rp_clients.c +++ b/common/tr_config_rp_clients.c @@ -54,23 +54,24 @@ #endif -TR_GSS_NAMES *tr_cfg_parse_gss_names(TALLOC_CTX *mem_ctx, json_t *jgss_names, TR_CFG_RC *rc) +TR_CFG_RC tr_cfg_parse_gss_names(TALLOC_CTX *mem_ctx, json_t *jgss_names, TR_GSS_NAMES **gssn_out) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_GSS_NAMES *gn=NULL; json_t *jname=NULL; - int ii=0; + size_t ii=0; TR_NAME *name=NULL; + TR_CFG_RC rc = TR_CFG_ERROR; - if ((rc==NULL) || (jgss_names==NULL)) { + if (jgss_names==NULL) { tr_err("tr_cfg_parse_gss_names: Bad parameters."); - *rc=TR_CFG_BAD_PARAMS; - + rc=TR_CFG_BAD_PARAMS; + goto cleanup; } if (!json_is_array(jgss_names)) { tr_err("tr_cfg_parse_gss_names: gss_names not an array."); - *rc=TR_CFG_NOPARSE; + rc=TR_CFG_NOPARSE; goto cleanup; } @@ -79,33 +80,32 @@ TR_GSS_NAMES *tr_cfg_parse_gss_names(TALLOC_CTX *mem_ctx, json_t *jgss_names, TR jname=json_array_get(jgss_names, ii); if (!json_is_string(jname)) { tr_err("tr_cfg_parse_gss_names: Encountered non-string gss name."); - *rc=TR_CFG_NOPARSE; + rc=TR_CFG_NOPARSE; goto cleanup; } name=tr_new_name(json_string_value(jname)); if (name==NULL) { tr_err("tr_cfg_parse_gss_names: Out of memory allocating gss name."); - *rc=TR_CFG_NOMEM; + rc=TR_CFG_NOMEM; goto cleanup; } if (tr_gss_names_add(gn, name)!=0) { tr_free_name(name); tr_err("tr_cfg_parse_gss_names: Unable to add gss name to RP client."); - *rc=TR_CFG_ERROR; + rc=TR_CFG_ERROR; goto cleanup; } } - talloc_steal(mem_ctx, gn); - *rc=TR_CFG_SUCCESS; + *gssn_out = gn; + talloc_steal(mem_ctx, *gssn_out); + rc=TR_CFG_SUCCESS; cleanup: talloc_free(tmp_ctx); - if ((*rc!=TR_CFG_SUCCESS) && (gn!=NULL)) - gn=NULL; - return gn; + return rc; } /* default filter accepts realm and *.realm */ @@ -306,7 +306,7 @@ static TR_RP_CLIENT *tr_cfg_parse_one_rp_client(TALLOC_CTX *mem_ctx, json_t *jre goto cleanup; } - client->gss_names=tr_cfg_parse_gss_names(client, json_object_get(jrealm, "gss_names"), &call_rc); + call_rc = tr_cfg_parse_gss_names(client, json_object_get(jrealm, "gss_names"), &(client->gss_names)); if (call_rc!=TR_CFG_SUCCESS) { tr_err("tr_cfg_parse_one_rp_client: could not parse gss_names."); diff --git a/common/tr_gss_names.c b/common/tr_gss_names.c index 970efdb..df15202 100644 --- a/common/tr_gss_names.c +++ b/common/tr_gss_names.c @@ -35,6 +35,7 @@ #include #include +#include static int tr_gss_names_destructor(void *obj) { @@ -81,6 +82,36 @@ int tr_gss_names_add(TR_GSS_NAMES *gn, TR_NAME *new) return -1; } +/** + * Create a duplicate GSS names struct + * + * @param mem_ctx + * @param orig + * @return + */ +TR_GSS_NAMES *tr_gss_names_dup(TALLOC_CTX *mem_ctx, TR_GSS_NAMES *orig) +{ + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + TR_GSS_NAMES *new = tr_gss_names_new(tmp_ctx); + TR_GSS_NAMES_ITER *iter = tr_gss_names_iter_new(tmp_ctx); + TR_NAME *this = NULL; + + if ( !orig || !new || !iter ) { + talloc_free(tmp_ctx); + return NULL; + } + this = tr_gss_names_iter_first(iter, orig); + while (this) { + if (tr_gss_names_add(new, tr_dup_name(this)) != 0) { + talloc_free(tmp_ctx); + return NULL; + } + this = tr_gss_names_iter_next(iter); + } + /* success */ + talloc_steal(mem_ctx, new); + return new; +} int tr_gss_names_matches(TR_GSS_NAMES *gn, TR_NAME *name) { int ii=0; diff --git a/common/tr_socket.c b/common/tr_socket.c index 313d931..7f1c917 100644 --- a/common/tr_socket.c +++ b/common/tr_socket.c @@ -129,7 +129,7 @@ nfds_t tr_sock_listen_all(unsigned int port, int *fd_out, nfds_t max_fd) return 0; } - tr_debug("tr_sock_listen_all: monitoring interface listening on port %d on %d socket%s", + tr_debug("tr_sock_listen_all: listening on port %d on %d socket%s", port, n_opened, (n_opened==1)?"":"s"); diff --git a/include/tr_config.h b/include/tr_config.h index e83071c..30317de 100644 --- a/include/tr_config.h +++ b/include/tr_config.h @@ -53,6 +53,7 @@ #define TR_DEFAULT_MAX_TREE_DEPTH 12 #define TR_DEFAULT_TRPS_PORT 12308 #define TR_DEFAULT_TIDS_PORT 12309 +#define TR_DEFAULT_MONITORING_PORT 0 /* defaults to being turned off */ #define TR_DEFAULT_LOG_THRESHOLD LOG_INFO #define TR_DEFAULT_CONSOLE_THRESHOLD LOG_NOTICE #define TR_DEFAULT_APC_EXPIRATION_INTERVAL 43200 @@ -89,6 +90,7 @@ typedef struct tr_cfg_internal { unsigned int tid_req_timeout; unsigned int tid_resp_numer; /* numerator of fraction of AAA servers to wait for in unshared mode */ unsigned int tid_resp_denom; /* denominator of fraction of AAA servers to wait for in unshared mode */ + TR_GSS_NAMES *monitoring_credentials; } TR_CFG_INTERNAL; /* record of files loaded for this configuration */ @@ -150,7 +152,7 @@ TR_APC *tr_cfg_parse_apcs(TALLOC_CTX *mem_ctx, json_t *japcs, TR_CFG_RC *rc); /* tr_config_rp_clients.c */ TR_RP_CLIENT *tr_cfg_parse_rp_clients(TALLOC_CTX *mem_ctx, json_t *jrealms, TR_CFG_RC *rc); -TR_GSS_NAMES *tr_cfg_parse_gss_names(TALLOC_CTX *mem_ctx, json_t *jgss_names, TR_CFG_RC *rc); +TR_CFG_RC tr_cfg_parse_gss_names(TALLOC_CTX *mem_ctx, json_t *jgss_names, TR_GSS_NAMES **gssn_out); /* tr_config_encoders.c */ json_t *tr_cfg_files_to_json_array(TR_CFG *cfg); diff --git a/include/tr_gss_names.h b/include/tr_gss_names.h index 7585798..f8f97a2 100644 --- a/include/tr_gss_names.h +++ b/include/tr_gss_names.h @@ -52,6 +52,7 @@ typedef struct tr_gss_names_iter { TR_GSS_NAMES *tr_gss_names_new(TALLOC_CTX *mem_ctx); void tr_gss_names_free(TR_GSS_NAMES *gn); int tr_gss_names_add(TR_GSS_NAMES *gn, TR_NAME *new); +TR_GSS_NAMES *tr_gss_names_dup(TALLOC_CTX *mem_ctx, TR_GSS_NAMES *orig); int tr_gss_names_matches(TR_GSS_NAMES *gn, TR_NAME *name); TR_GSS_NAMES_ITER *tr_gss_names_iter_new(TALLOC_CTX *mem_ctx); diff --git a/tr/tr_mon.c b/tr/tr_mon.c index 8138198..beb258e 100644 --- a/tr/tr_mon.c +++ b/tr/tr_mon.c @@ -96,13 +96,13 @@ static int tr_mons_auth_handler(gss_name_t client_name, TR_NAME *gss_name, void { struct tr_mons_event_cookie *cookie=talloc_get_type_abort(cookie_in, struct tr_mons_event_cookie); MONS_INSTANCE *mons = cookie->mons; - TR_CFG_MGR *cfg_mgr = cookie->cfg_mgr; - if ((!client_name) || (!gss_name) || (!mons) || (!cfg_mgr)) { + if ((!client_name) || (!gss_name) || (!mons)) { tr_debug("tr_mons_gss_handler: Bad parameters."); return -1; } + tr_debug("tr_mons_gss_handler: %p", mons->authorized_gss_names); /* Ensure at least one client exists using this GSS name */ if (! tr_gss_names_matches(mons->authorized_gss_names, gss_name)) { tr_info("tr_mons_gss_handler: Unauthorized request from %.*s", gss_name->len, gss_name->buf); @@ -145,6 +145,12 @@ int tr_mons_event_init(struct event_base *base, goto cleanup; } + if (cfg_mgr->active->internal->monitoring_port == 0) { + tr_notice("tr_mons_event_init: monitoring is disabled, not enabling events or opening sockets"); + retval = 0; + goto cleanup; + } + /* Create the cookie for callbacks. We'll put it in the mons context, so it will * be cleaned up when mons is freed by talloc_free. */ cookie=talloc(tmp_ctx, struct tr_mons_event_cookie); diff --git a/tr/tr_trp.c b/tr/tr_trp.c index 9dc1f8d..e075d58 100644 --- a/tr/tr_trp.c +++ b/tr/tr_trp.c @@ -876,6 +876,16 @@ void tr_config_changed(TR_CFG *new_cfg, void *cookie) tr->tids->hostname = new_cfg->internal->hostname; tr->mons->hostname = new_cfg->internal->hostname; + /* Update the authorized monitoring gss names */ + if (tr->mons->authorized_gss_names) { + tr_debug("tr_config_changed: freeing tr->mons->authorized_gss_names"); + tr_gss_names_free(tr->mons->authorized_gss_names); + } + tr->mons->authorized_gss_names = tr_gss_names_dup(tr->mons, new_cfg->internal->monitoring_credentials); + if (tr->mons->authorized_gss_names == NULL) { + tr_err("tr_config_changed: Error configuring monitoring credentials"); + } + trps_set_connect_interval(trps, new_cfg->internal->trp_connect_interval); trps_set_update_interval(trps, new_cfg->internal->trp_update_interval); trps_set_sweep_interval(trps, new_cfg->internal->trp_sweep_interval); -- 2.1.4